Fix date.c build in msvc. Ported the win32 implementations of gmtime_r, localtime_r, and gettimeofday to be part of the posix compatibility layer, and fixed git_signature_now to use them.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
diff --git a/src/date.c b/src/date.c
index b4708b8..90f2f14 100644
--- a/src/date.c
+++ b/src/date.c
@@ -4,11 +4,18 @@
* Copyright (C) Linus Torvalds, 2005
*/
+#include "common.h"
+
+#ifndef GIT_WIN32
+#include <sys/time.h>
+#endif
+
#include "date.h"
#include "cache.h"
+#include "posix.h"
#include <ctype.h>
-#include <sys/time.h>
+#include <time.h>
typedef enum {
DATE_NORMAL = 0,
@@ -299,7 +306,7 @@ static int match_multi_number(unsigned long num, char c, const char *date, char
* We just do a binary 'and' to see if the sign bit
* is set in all the values.
*/
-static inline int nodate(struct tm *tm)
+static int nodate(struct tm *tm)
{
return (tm->tm_year &
tm->tm_mon &
@@ -599,9 +606,9 @@ static void date_tea(struct tm *tm, struct tm *now, int *num)
static void date_pm(struct tm *tm, struct tm *now, int *num)
{
- GIT_UNUSED(now);
int hour, n = *num;
*num = 0;
+ GIT_UNUSED(now);
hour = tm->tm_hour;
if (n) {
@@ -614,9 +621,9 @@ static void date_pm(struct tm *tm, struct tm *now, int *num)
static void date_am(struct tm *tm, struct tm *now, int *num)
{
- GIT_UNUSED(now);
int hour, n = *num;
*num = 0;
+ GIT_UNUSED(now);
hour = tm->tm_hour;
if (n) {
@@ -629,9 +636,9 @@ static void date_am(struct tm *tm, struct tm *now, int *num)
static void date_never(struct tm *tm, struct tm *now, int *num)
{
+ time_t n = 0;
GIT_UNUSED(now);
GIT_UNUSED(num);
- time_t n = 0;
localtime_r(&n, tm);
}
@@ -821,7 +828,7 @@ static unsigned long approxidate_str(const char *date,
{
int number = 0;
int touched = 0;
- struct tm tm, now;
+ struct tm tm = {0}, now;
time_t time_sec;
time_sec = tv->tv_sec;
diff --git a/src/revparse.c b/src/revparse.c
index 3487f56..8eb5c11 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -199,10 +199,12 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char *
git_reference_free(ref);
}
} else {
+ int date_error = 0;
+ time_t timestamp;
git_buf datebuf = GIT_BUF_INIT;
+
git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3);
- int date_error = 0;
- time_t timestamp = approxidate_careful(git_buf_cstr(&datebuf), &date_error);
+ timestamp = approxidate_careful(git_buf_cstr(&datebuf), &date_error);
/* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */
if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) {
@@ -267,8 +269,10 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char *
/* TODO: clunky. Factor "now" into a utility */
git_signature *sig;
+ git_time as_of;
+
git_signature_now(&sig, "blah", "blah");
- git_time as_of = sig->when;
+ as_of = sig->when;
git_signature_free(sig);
as_of.time = (timestamp > 0)
diff --git a/src/signature.c b/src/signature.c
index 4d6d11c..74ef843 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -113,26 +113,14 @@ int git_signature_now(git_signature **sig_out, const char *name, const char *ema
time_t offset;
struct tm *utc_tm, *local_tm;
git_signature *sig;
-
-#ifndef GIT_WIN32
struct tm _utc, _local;
-#endif
*sig_out = NULL;
time(&now);
- /**
- * On Win32, `gmtime_r` doesn't exist but
- * `gmtime` is threadsafe, so we can use that
- */
-#ifdef GIT_WIN32
- utc_tm = gmtime(&now);
- local_tm = localtime(&now);
-#else
utc_tm = gmtime_r(&now, &_utc);
local_tm = localtime_r(&now, &_local);
-#endif
offset = mktime(local_tm) - mktime(utc_tm);
offset /= 60;
diff --git a/src/util.h b/src/util.h
index 4d1ee68..9003c08 100644
--- a/src/util.h
+++ b/src/util.h
@@ -213,7 +213,7 @@ GIT_INLINE(int) git__time_cmp(const git_time *a, const git_time *b)
{
/* Adjust for time zones. Times are in seconds, offsets are in minutes. */
git_time_t adjusted_a = a->time + ((b->offset - a->offset) * 60);
- return adjusted_a - b->time;
+ return (int)(adjusted_a - b->time);
}
#endif /* INCLUDE_util_h__ */
diff --git a/src/win32/posix.h b/src/win32/posix.h
index 2666fcc..55732f5 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -52,4 +52,8 @@ extern int p_rename(const char *from, const char *to);
extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags);
extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags);
+extern struct tm * localtime_r (const time_t *timer, struct tm *result);
+extern struct tm * gmtime_r (const time_t *timer, struct tm *result);
+extern int gettimeofday(struct timeval *tv, struct timezone *tz);
+
#endif
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 10de70d..092bafe 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -470,3 +470,79 @@ int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags)
return send(socket, buffer, (int)length, flags);
}
+
+/**
+ * Borrowed from http://old.nabble.com/Porting-localtime_r-and-gmtime_r-td15282276.html
+ * On Win32, `gmtime_r` doesn't exist but `gmtime` is threadsafe, so we can use that
+ */
+struct tm *
+localtime_r (const time_t *timer, struct tm *result)
+{
+ struct tm *local_result;
+ local_result = localtime (timer);
+
+ if (local_result == NULL || result == NULL)
+ return NULL;
+
+ memcpy (result, local_result, sizeof (struct tm));
+ return result;
+}
+struct tm *
+gmtime_r (const time_t *timer, struct tm *result)
+{
+ struct tm *local_result;
+ local_result = gmtime (timer);
+
+ if (local_result == NULL || result == NULL)
+ return NULL;
+
+ memcpy (result, local_result, sizeof (struct tm));
+ return result;
+}
+
+#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
+#else
+#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
+#endif
+
+struct timezone
+{
+ int tz_minuteswest; /* minutes W of Greenwich */
+ int tz_dsttime; /* type of dst correction */
+};
+
+int gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+ FILETIME ft;
+ unsigned __int64 tmpres = 0;
+ static int tzflag;
+
+ if (NULL != tv)
+ {
+ GetSystemTimeAsFileTime(&ft);
+
+ tmpres |= ft.dwHighDateTime;
+ tmpres <<= 32;
+ tmpres |= ft.dwLowDateTime;
+
+ /*converting file time to unix epoch*/
+ tmpres /= 10; /*convert into microseconds*/
+ tmpres -= DELTA_EPOCH_IN_MICROSECS;
+ tv->tv_sec = (long)(tmpres / 1000000UL);
+ tv->tv_usec = (long)(tmpres % 1000000UL);
+ }
+
+ if (NULL != tz)
+ {
+ if (!tzflag)
+ {
+ _tzset();
+ tzflag++;
+ }
+ tz->tz_minuteswest = _timezone / 60;
+ tz->tz_dsttime = _daylight;
+ }
+
+ return 0;
+}