diff options
author | Ben Straub <bstraub@github.com> | 2012-05-15 15:41:05 -0700 |
---|---|---|
committer | Ben Straub <bstraub@github.com> | 2012-05-15 15:41:05 -0700 |
commit | 1ce4cc0164fbc14fcb7f686483aa581bc946bfdb (patch) | |
tree | 628f63f6508247275eac89357b8b1b960d68f23b | |
parent | 7c22e72ba65fa4ac9c2989d115435aa60788136c (diff) | |
download | libgit2-1ce4cc0164fbc14fcb7f686483aa581bc946bfdb.tar.gz |
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.
-rw-r--r-- | src/date.c | 19 | ||||
-rw-r--r-- | src/revparse.c | 10 | ||||
-rw-r--r-- | src/signature.c | 12 | ||||
-rw-r--r-- | src/util.h | 2 | ||||
-rw-r--r-- | src/win32/posix.h | 4 | ||||
-rw-r--r-- | src/win32/posix_w32.c | 76 |
6 files changed, 101 insertions, 22 deletions
diff --git a/src/date.c b/src/date.c index b4708b8ef..90f2f149e 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 3487f5638..8eb5c11ae 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 4d6d11c70..74ef84376 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 4d1ee680d..9003c08ad 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 2666fccb4..55732f5ac 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 10de70da8..092bafed0 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; +} |