Commit 1ce4cc01 by Ben Straub

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.
parent 7c22e72b
...@@ -4,11 +4,18 @@ ...@@ -4,11 +4,18 @@
* Copyright (C) Linus Torvalds, 2005 * Copyright (C) Linus Torvalds, 2005
*/ */
#include "common.h"
#ifndef GIT_WIN32
#include <sys/time.h>
#endif
#include "date.h" #include "date.h"
#include "cache.h" #include "cache.h"
#include "posix.h"
#include <ctype.h> #include <ctype.h>
#include <sys/time.h> #include <time.h>
typedef enum { typedef enum {
DATE_NORMAL = 0, DATE_NORMAL = 0,
...@@ -299,7 +306,7 @@ static int match_multi_number(unsigned long num, char c, const char *date, char ...@@ -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 * We just do a binary 'and' to see if the sign bit
* is set in all the values. * is set in all the values.
*/ */
static inline int nodate(struct tm *tm) static int nodate(struct tm *tm)
{ {
return (tm->tm_year & return (tm->tm_year &
tm->tm_mon & tm->tm_mon &
...@@ -599,9 +606,9 @@ static void date_tea(struct tm *tm, struct tm *now, int *num) ...@@ -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) static void date_pm(struct tm *tm, struct tm *now, int *num)
{ {
GIT_UNUSED(now);
int hour, n = *num; int hour, n = *num;
*num = 0; *num = 0;
GIT_UNUSED(now);
hour = tm->tm_hour; hour = tm->tm_hour;
if (n) { if (n) {
...@@ -614,9 +621,9 @@ static void date_pm(struct tm *tm, struct tm *now, int *num) ...@@ -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) static void date_am(struct tm *tm, struct tm *now, int *num)
{ {
GIT_UNUSED(now);
int hour, n = *num; int hour, n = *num;
*num = 0; *num = 0;
GIT_UNUSED(now);
hour = tm->tm_hour; hour = tm->tm_hour;
if (n) { if (n) {
...@@ -629,9 +636,9 @@ static void date_am(struct tm *tm, struct tm *now, int *num) ...@@ -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) static void date_never(struct tm *tm, struct tm *now, int *num)
{ {
time_t n = 0;
GIT_UNUSED(now); GIT_UNUSED(now);
GIT_UNUSED(num); GIT_UNUSED(num);
time_t n = 0;
localtime_r(&n, tm); localtime_r(&n, tm);
} }
...@@ -821,7 +828,7 @@ static unsigned long approxidate_str(const char *date, ...@@ -821,7 +828,7 @@ static unsigned long approxidate_str(const char *date,
{ {
int number = 0; int number = 0;
int touched = 0; int touched = 0;
struct tm tm, now; struct tm tm = {0}, now;
time_t time_sec; time_t time_sec;
time_sec = tv->tv_sec; time_sec = tv->tv_sec;
......
...@@ -199,10 +199,12 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char * ...@@ -199,10 +199,12 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char *
git_reference_free(ref); git_reference_free(ref);
} }
} else { } else {
int date_error = 0;
time_t timestamp;
git_buf datebuf = GIT_BUF_INIT; git_buf datebuf = GIT_BUF_INIT;
git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3); git_buf_put(&datebuf, reflogspec+2, reflogspeclen-3);
int date_error = 0; timestamp = approxidate_careful(git_buf_cstr(&datebuf), &date_error);
time_t timestamp = approxidate_careful(git_buf_cstr(&datebuf), &date_error);
/* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */ /* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */
if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) { if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) {
...@@ -267,8 +269,10 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char * ...@@ -267,8 +269,10 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char *
/* TODO: clunky. Factor "now" into a utility */ /* TODO: clunky. Factor "now" into a utility */
git_signature *sig; git_signature *sig;
git_time as_of;
git_signature_now(&sig, "blah", "blah"); git_signature_now(&sig, "blah", "blah");
git_time as_of = sig->when; as_of = sig->when;
git_signature_free(sig); git_signature_free(sig);
as_of.time = (timestamp > 0) as_of.time = (timestamp > 0)
......
...@@ -113,26 +113,14 @@ int git_signature_now(git_signature **sig_out, const char *name, const char *ema ...@@ -113,26 +113,14 @@ int git_signature_now(git_signature **sig_out, const char *name, const char *ema
time_t offset; time_t offset;
struct tm *utc_tm, *local_tm; struct tm *utc_tm, *local_tm;
git_signature *sig; git_signature *sig;
#ifndef GIT_WIN32
struct tm _utc, _local; struct tm _utc, _local;
#endif
*sig_out = NULL; *sig_out = NULL;
time(&now); 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); utc_tm = gmtime_r(&now, &_utc);
local_tm = localtime_r(&now, &_local); local_tm = localtime_r(&now, &_local);
#endif
offset = mktime(local_tm) - mktime(utc_tm); offset = mktime(local_tm) - mktime(utc_tm);
offset /= 60; offset /= 60;
......
...@@ -213,7 +213,7 @@ GIT_INLINE(int) git__time_cmp(const git_time *a, const git_time *b) ...@@ -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. */ /* Adjust for time zones. Times are in seconds, offsets are in minutes. */
git_time_t adjusted_a = a->time + ((b->offset - a->offset) * 60); 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__ */ #endif /* INCLUDE_util_h__ */
...@@ -52,4 +52,8 @@ extern int p_rename(const char *from, const char *to); ...@@ -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_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 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 #endif
...@@ -470,3 +470,79 @@ int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags) ...@@ -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); 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment