]> git.proxmox.com Git - libgit2.git/blobdiff - src/date.c
push: remove own copy of callbacks
[libgit2.git] / src / date.c
index f0e637a45486ef19905f9405bdcdd1863c772436..0e1b31aeed3f0cd2d4ff08200cb633a603229309 100644 (file)
@@ -106,24 +106,24 @@ static const struct {
        { "MESZ",  +1, 1, },    /* Middle European Summer */
        { "FWT",   +1, 0, },    /* French Winter */
        { "FST",   +1, 1, },    /* French Summer */
-       { "EET",   +2, 0, },    /* Eastern Europe, USSR Zone 1 */
+       { "EET",   +2, 0, },    /* Eastern Europe */
        { "EEST",  +2, 1, },    /* Eastern European Daylight */
        { "WAST",  +7, 0, },    /* West Australian Standard */
        { "WADT",  +7, 1, },    /* West Australian Daylight */
-       { "CCT",   +8, 0, },    /* China Coast, USSR Zone 7 */
-       { "JST",   +9, 0, },    /* Japan Standard, USSR Zone 8 */
+       { "CCT",   +8, 0, },    /* China Coast */
+       { "JST",   +9, 0, },    /* Japan Standard */
        { "EAST", +10, 0, },    /* Eastern Australian Standard */
        { "EADT", +10, 1, },    /* Eastern Australian Daylight */
-       { "GST",  +10, 0, },    /* Guam Standard, USSR Zone 9 */
+       { "GST",  +10, 0, },    /* Guam Standard */
        { "NZT",  +12, 0, },    /* New Zealand */
        { "NZST", +12, 0, },    /* New Zealand Standard */
        { "NZDT", +12, 1, },    /* New Zealand Daylight */
        { "IDLE", +12, 0, },    /* International Date Line East */
 };
 
-static int match_string(const char *date, const char *str)
+static size_t match_string(const char *date, const char *str)
 {
-       int i = 0;
+       size_t i = 0;
 
        for (i = 0; *date; date++, str++, i++) {
                if (*date == *str)
@@ -149,12 +149,12 @@ static int skip_alpha(const char *date)
 /*
 * Parse month, weekday, or timezone name
 */
-static int match_alpha(const char *date, struct tm *tm, int *offset)
+static size_t match_alpha(const char *date, struct tm *tm, int *offset)
 {
        unsigned int i;
 
        for (i = 0; i < 12; i++) {
-               int match = match_string(date, month_names[i]);
+               size_t match = match_string(date, month_names[i]);
                if (match >= 3) {
                        tm->tm_mon = i;
                        return match;
@@ -162,7 +162,7 @@ static int match_alpha(const char *date, struct tm *tm, int *offset)
        }
 
        for (i = 0; i < 7; i++) {
-               int match = match_string(date, weekday_names[i]);
+               size_t match = match_string(date, weekday_names[i]);
                if (match >= 3) {
                        tm->tm_wday = i;
                        return match;
@@ -170,8 +170,8 @@ static int match_alpha(const char *date, struct tm *tm, int *offset)
        }
 
        for (i = 0; i < ARRAY_SIZE(timezone_names); i++) {
-               int match = match_string(date, timezone_names[i].name);
-               if (match >= 3 || match == (int)strlen(timezone_names[i].name)) {
+               size_t match = match_string(date, timezone_names[i].name);
+               if (match >= 3 || match == strlen(timezone_names[i].name)) {
                        int off = timezone_names[i].offset;
 
                        /* This is bogus, but we like summer */
@@ -195,7 +195,7 @@ static int match_alpha(const char *date, struct tm *tm, int *offset)
                return 2;
        }
 
-       /* BAD CRAP */
+       /* BAD */
        return skip_alpha(date);
 }
 
@@ -241,7 +241,7 @@ static int is_date(int year, int month, int day, struct tm *now_tm, time_t now,
        return 0;
 }
 
-static int match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
+static size_t match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
 {
        time_t now;
        struct tm now_tm;
@@ -319,9 +319,9 @@ static int nodate(struct tm *tm)
 /*
  * We've seen a digit. Time? Year? Date?
  */
-static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
+static size_t match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
 {
-       int n;
+       size_t n;
        char *end;
        unsigned long num;
 
@@ -349,7 +349,7 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
        case '/':
        case '-':
                if (isdigit(end[1])) {
-                       int match = match_multi_number(num, *end, date, end, tm);
+                       size_t match = match_multi_number(num, *end, date, end, tm);
                        if (match)
                                return match;
                }
@@ -413,11 +413,11 @@ static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt
        return n;
 }
 
-static int match_tz(const char *date, int *offp)
+static size_t match_tz(const char *date, int *offp)
 {
        char *end;
        int hour = strtoul(date + 1, &end, 10);
-       int n = end - (date + 1);
+       size_t n = end - (date + 1);
        int min = 0;
 
        if (n == 4) {
@@ -425,16 +425,16 @@ static int match_tz(const char *date, int *offp)
                min = hour % 100;
                hour = hour / 100;
        } else if (n != 2) {
-               min = 99; /* random crap */
+               min = 99; /* random stuff */
        } else if (*end == ':') {
                /* hh:mm? */
                min = strtoul(end + 1, &end, 10);
                if (end - (date + 1) != 5)
-                       min = 99; /* random crap */
+                       min = 99; /* random stuff */
        } /* otherwise we parsed "hh" */
 
        /*
-        * Don't accept any random crap. Even though some places have
+        * Don't accept any random stuff. Even though some places have
         * offset larger than 12 hours (e.g. Pacific/Kiritimati is at
         * UTC+14), there is something wrong if hour part is much
         * larger than that. We might also want to check that the
@@ -506,7 +506,7 @@ static int parse_date_basic(const char *date, git_time_t *timestamp, int *offset
            !match_object_header_date(date + 1, timestamp, offset))
                return 0; /* success */
        for (;;) {
-               int match = 0;
+               size_t match = 0;
                unsigned char c = *date;
 
                /* Stop at end of string or newline */
@@ -521,7 +521,7 @@ static int parse_date_basic(const char *date, git_time_t *timestamp, int *offset
                        match = match_tz(date, offset);
 
                if (!match) {
-                       /* BAD CRAP */
+                       /* BAD */
                        match = 1;
                }
 
@@ -681,11 +681,11 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
        const char *end = date;
        int i;
 
-       while (isalpha(*++end));
-               ;
+       while (isalpha(*++end))
+               /* scan to non-alpha */;
 
        for (i = 0; i < 12; i++) {
-               int match = match_string(date, month_names[i]);
+               size_t match = match_string(date, month_names[i]);
                if (match >= 3) {
                        tm->tm_mon = i;
                        *touched = 1;
@@ -694,7 +694,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
        }
 
        for (s = special; s->name; s++) {
-               int len = strlen(s->name);
+               size_t len = strlen(s->name);
                if (match_string(date, s->name) == len) {
                        s->fn(tm, now, num);
                        *touched = 1;
@@ -704,7 +704,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
 
        if (!*num) {
                for (i = 1; i < 11; i++) {
-                       int len = strlen(number_name[i]);
+                       size_t len = strlen(number_name[i]);
                        if (match_string(date, number_name[i]) == len) {
                                *num = i;
                                *touched = 1;
@@ -720,7 +720,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
 
        tl = typelen;
        while (tl->type) {
-               int len = strlen(tl->type);
+               size_t len = strlen(tl->type);
                if (match_string(date, tl->type) >= len-1) {
                        update_tm(tm, now, tl->length * *num);
                        *num = 0;
@@ -731,7 +731,7 @@ static const char *approxidate_alpha(const char *date, struct tm *tm, struct tm
        }
 
        for (i = 0; i < 7; i++) {
-               int match = match_string(date, weekday_names[i]);
+               size_t match = match_string(date, weekday_names[i]);
                if (match >= 3) {
                        int diff, n = *num -1;
                        *num = 0;
@@ -783,7 +783,7 @@ static const char *approxidate_digit(const char *date, struct tm *tm, int *num)
        case '/':
        case '-':
                if (isdigit(end[1])) {
-                       int match = match_multi_number(number, *end, date, end, tm);
+                       size_t match = match_multi_number(number, *end, date, end, tm);
                        if (match)
                                return date + match;
                }
@@ -817,21 +817,19 @@ static void pending_number(struct tm *tm, int *num)
                                tm->tm_year = number;
                        else if (number < 38)
                                tm->tm_year = 100 + number;
-                       /* We screw up for number = 00 ? */
+                       /* We mess up for number = 00 ? */
                }
        }
 }
 
 static git_time_t approxidate_str(const char *date,
-                                  const struct timeval *tv,
-                                  int *error_ret)
+       time_t time_sec,
+       int *error_ret)
 {
        int number = 0;
        int touched = 0;
        struct tm tm = {0}, now;
-       time_t time_sec;
 
-       time_sec = tv->tv_sec;
        p_localtime_r(&time_sec, &tm);
        now = tm;
 
@@ -861,16 +859,46 @@ static git_time_t approxidate_str(const char *date,
 
 int git__date_parse(git_time_t *out, const char *date)
 {
-       struct timeval tv;
+       time_t time_sec;
        git_time_t timestamp;
        int offset, error_ret=0;
 
        if (!parse_date_basic(date, &timestamp, &offset)) {
-      *out = timestamp;
+               *out = timestamp;
                return 0;
        }
 
-       p_gettimeofday(&tv, NULL);
-       *out = approxidate_str(date, &tv, &error_ret);
+       if (time(&time_sec) == -1)
+               return -1;
+
+       *out = approxidate_str(date, time_sec, &error_ret);
    return error_ret;
 }
+
+int git__date_rfc2822_fmt(char *out, size_t len, const git_time *date)
+{
+       int written;
+       struct tm gmt;
+       time_t t;
+
+       assert(out && date);
+
+       t = (time_t) (date->time + date->offset * 60);
+
+       if (p_gmtime_r (&t, &gmt) == NULL)
+               return -1;
+
+       written = p_snprintf(out, len, "%.3s, %u %.3s %.4u %02u:%02u:%02u %+03d%02d",
+               weekday_names[gmt.tm_wday],
+               gmt.tm_mday,
+               month_names[gmt.tm_mon],
+               gmt.tm_year + 1900,
+               gmt.tm_hour, gmt.tm_min, gmt.tm_sec,
+               date->offset / 60, date->offset % 60);
+
+       if (written < 0 || (written > (int) len - 1))
+               return -1;
+
+       return 0;
+}
+