From c5043cc18579854681aa51ddb6e744fe2db24f51 Mon Sep 17 00:00:00 2001 From: Ramkumar Ramachandra Date: Thu, 3 Jun 2010 22:28:55 +0200 Subject: [PATCH] Refactor parse_date for approxidate functions approxidate_relative and approxidate_careful both use parse_date to dump the timestamp to a character buffer and parse it back into a long unsigned using strtoul(). Avoid doing this by creating a new parse_date_toffset method. Noticed-by: Jonathan Nieder Signed-off-by: Ramkumar Ramachandra Signed-off-by: Junio C Hamano --- date.c | 56 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/date.c b/date.c index 002aa3c8d..610ecf750 100644 --- a/date.c +++ b/date.c @@ -585,11 +585,17 @@ static int date_string(unsigned long date, int offset, char *buf, int len) /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822 (i.e. English) day/month names, and it doesn't work correctly with %z. */ -int parse_date(const char *date, char *result, int maxlen) +int parse_date_toffset(const char *date, unsigned long *timestamp, int *offset) { struct tm tm; - int offset, tm_gmt; - time_t then; + int tm_gmt; + unsigned long dummy_timestamp; + int dummy_offset; + + if (!timestamp) + timestamp = &dummy_timestamp; + if (!offset) + offset = &dummy_offset; memset(&tm, 0, sizeof(tm)); tm.tm_year = -1; @@ -599,7 +605,7 @@ int parse_date(const char *date, char *result, int maxlen) tm.tm_hour = -1; tm.tm_min = -1; tm.tm_sec = -1; - offset = -1; + *offset = -1; tm_gmt = 0; for (;;) { @@ -611,11 +617,11 @@ int parse_date(const char *date, char *result, int maxlen) break; if (isalpha(c)) - match = match_alpha(date, &tm, &offset); + match = match_alpha(date, &tm, offset); else if (isdigit(c)) - match = match_digit(date, &tm, &offset, &tm_gmt); + match = match_digit(date, &tm, offset, &tm_gmt); else if ((c == '-' || c == '+') && isdigit(date[1])) - match = match_tz(date, &offset); + match = match_tz(date, offset); if (!match) { /* BAD CRAP */ @@ -626,16 +632,26 @@ int parse_date(const char *date, char *result, int maxlen) } /* mktime uses local timezone */ - then = tm_to_time_t(&tm); - if (offset == -1) - offset = (then - mktime(&tm)) / 60; + *timestamp = tm_to_time_t(&tm); + if (*offset == -1) + *offset = (*timestamp - mktime(&tm)) / 60; - if (then == -1) + if (*timestamp == -1) return -1; if (!tm_gmt) - then -= offset * 60; - return date_string(then, offset, result, maxlen); + *timestamp -= *offset * 60; + return 1; /* success */ +} + +int parse_date(const char *date, char *result, int maxlen) +{ + unsigned long timestamp; + int offset; + if (parse_date_toffset(date, ×tamp, &offset) > 0) + return date_string(timestamp, offset, result, maxlen); + else + return -1; } enum date_mode parse_date_format(const char *format) @@ -983,11 +999,12 @@ static unsigned long approxidate_str(const char *date, unsigned long approxidate_relative(const char *date, const struct timeval *tv) { - char buffer[50]; + unsigned long timestamp; + int offset; int errors = 0; - if (parse_date(date, buffer, sizeof(buffer)) > 0) - return strtoul(buffer, NULL, 0); + if (parse_date_toffset(date, ×tamp, &offset) > 0) + return timestamp; return approxidate_str(date, tv, &errors); } @@ -995,14 +1012,15 @@ unsigned long approxidate_relative(const char *date, const struct timeval *tv) unsigned long approxidate_careful(const char *date, int *error_ret) { struct timeval tv; - char buffer[50]; + unsigned long timestamp; + int offset; int dummy = 0; if (!error_ret) error_ret = &dummy; - if (parse_date(date, buffer, sizeof(buffer)) > 0) { + if (parse_date_toffset(date, ×tamp, &offset) > 0) { *error_ret = 0; - return strtoul(buffer, NULL, 0); + return timestamp; } gettimeofday(&tv, NULL); -- 2.30.2