summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Straub <bstraub@github.com>2012-05-15 15:41:05 -0700
committerBen Straub <bstraub@github.com>2012-05-15 15:41:05 -0700
commit1ce4cc0164fbc14fcb7f686483aa581bc946bfdb (patch)
tree628f63f6508247275eac89357b8b1b960d68f23b
parent7c22e72ba65fa4ac9c2989d115435aa60788136c (diff)
downloadlibgit2-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.c19
-rw-r--r--src/revparse.c10
-rw-r--r--src/signature.c12
-rw-r--r--src/util.h2
-rw-r--r--src/win32/posix.h4
-rw-r--r--src/win32/posix_w32.c76
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;
+}