{"thread":{"id":"23997","subject":"[PATCH] Refactor parse_date for approxidate functions","startedAt":"2010-06-03T20:28:55Z","lastAt":"2010-06-03T20:28:55Z","messageCount":1,"participants":["Ramkumar Ramachandra"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"142925","messageId":"1275596935-17312-1-git-send-email-artagnon@gmail.com","threadId":"23997","inReplyTo":null,"subject":"[PATCH] Refactor parse_date for approxidate functions","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2010-06-03T20:28:55Z","receivedAt":"2010-06-03T20:28:55Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"approxidate_relative and approxidate_careful both use parse_date to\ndump the timestamp to a character buffer and parse it back into a long\nunsigned using strtoul(). Avoid doing this by creating a new\nparse_date_toffset method.\n\nNoticed-by: Jonathan Nieder <jrnieder@gmail.com>\nSigned-off-by: Ramkumar Ramachandra <artagnon@gmail.com>\n---\n date.c |   56 +++++++++++++++++++++++++++++++++++++-------------------\n 1 files changed, 37 insertions(+), 19 deletions(-)\n\ndiff --git a/date.c b/date.c\nindex 002aa3c..21b4096 100644\n--- a/date.c\n+++ b/date.c\n@@ -585,11 +585,17 @@ static int date_string(unsigned long date, int offset, char *buf, int len)\n \n /* Gr. strptime is crap for this; it doesn't have a way to require RFC2822\n    (i.e. English) day/month names, and it doesn't work correctly with %z. */\n-int parse_date(const char *date, char *result, int maxlen)\n+int parse_date_toffset(const char *date, unsigned long *timestamp, int *offset)\n {\n \tstruct tm tm;\n-\tint offset, tm_gmt;\n-\ttime_t then;\n+\tint tm_gmt;\n+\tunsigned long dummy_timestamp;\n+\tint dummy_offset;\n+\n+\tif(!timestamp)\n+\t\ttimestamp = &dummy_timestamp;\n+\tif(!offset)\n+\t\toffset = &dummy_offset;\n \n \tmemset(&tm, 0, sizeof(tm));\n \ttm.tm_year = -1;\n@@ -599,7 +605,7 @@ int parse_date(const char *date, char *result, int maxlen)\n \ttm.tm_hour = -1;\n \ttm.tm_min = -1;\n \ttm.tm_sec = -1;\n-\toffset = -1;\n+\t*offset = -1;\n \ttm_gmt = 0;\n \n \tfor (;;) {\n@@ -611,11 +617,11 @@ int parse_date(const char *date, char *result, int maxlen)\n \t\t\tbreak;\n \n \t\tif (isalpha(c))\n-\t\t\tmatch = match_alpha(date, &tm, &offset);\n+\t\t\tmatch = match_alpha(date, &tm, offset);\n \t\telse if (isdigit(c))\n-\t\t\tmatch = match_digit(date, &tm, &offset, &tm_gmt);\n+\t\t\tmatch = match_digit(date, &tm, offset, &tm_gmt);\n \t\telse if ((c == '-' || c == '+') && isdigit(date[1]))\n-\t\t\tmatch = match_tz(date, &offset);\n+\t\t\tmatch = match_tz(date, offset);\n \n \t\tif (!match) {\n \t\t\t/* BAD CRAP */\n@@ -626,16 +632,26 @@ int parse_date(const char *date, char *result, int maxlen)\n \t}\n \n \t/* mktime uses local timezone */\n-\tthen = tm_to_time_t(&tm);\n-\tif (offset == -1)\n-\t\toffset = (then - mktime(&tm)) / 60;\n+\t*timestamp = tm_to_time_t(&tm);\n+\tif (*offset == -1)\n+\t\t*offset = (*timestamp - mktime(&tm)) / 60;\n \n-\tif (then == -1)\n+\tif (*timestamp == -1)\n \t\treturn -1;\n \n \tif (!tm_gmt)\n-\t\tthen -= offset * 60;\n-\treturn date_string(then, offset, result, maxlen);\n+\t\t*timestamp -= *offset * 60;\n+\treturn 1; /* success */\n+}\n+\n+int parse_date(const char *date, char *result, int maxlen)\n+{\n+\tunsigned long timestamp;\n+\tint offset;\n+\tif(parse_date_toffset(date, &timestamp, &offset) > 0)\n+\t\treturn date_string(timestamp, offset, result, maxlen);\n+\telse\n+\t\treturn -1;\n }\n \n enum date_mode parse_date_format(const char *format)\n@@ -983,11 +999,12 @@ static unsigned long approxidate_str(const char *date,\n \n unsigned long approxidate_relative(const char *date, const struct timeval *tv)\n {\n-\tchar buffer[50];\n+\tunsigned long timestamp;\n+\tint offset;\n \tint errors = 0;\n \n-\tif (parse_date(date, buffer, sizeof(buffer)) > 0)\n-\t\treturn strtoul(buffer, NULL, 0);\n+\tif(parse_date_toffset(date, &timestamp, &offset) > 0)\n+\t\treturn timestamp;\n \n \treturn approxidate_str(date, tv, &errors);\n }\n@@ -995,14 +1012,15 @@ unsigned long approxidate_relative(const char *date, const struct timeval *tv)\n unsigned long approxidate_careful(const char *date, int *error_ret)\n {\n \tstruct timeval tv;\n-\tchar buffer[50];\n+\tunsigned long timestamp;\n+\tint offset;\n \tint dummy = 0;\n \tif (!error_ret)\n \t\terror_ret = &dummy;\n \n-\tif (parse_date(date, buffer, sizeof(buffer)) > 0) {\n+\tif(parse_date_toffset(date, &timestamp, &offset) > 0) {\n \t\t*error_ret = 0;\n-\t\treturn strtoul(buffer, NULL, 0);\n+\t\treturn timestamp;\n \t}\n \n \tgettimeofday(&tv, NULL);\n-- \n1.7.1\n"}]}