[PATCH] Refactor parse_date for approxidate functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <jrnieder@xxxxxxxxx>
Signed-off-by: Ramkumar Ramachandra <artagnon@xxxxxxxxx>
---
 date.c |   56 +++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/date.c b/date.c
index 002aa3c..21b4096 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, &timestamp, &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, &timestamp, &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, &timestamp, &offset) > 0) {
 		*error_ret = 0;
-		return strtoul(buffer, NULL, 0);
+		return timestamp;
 	}
 
 	gettimeofday(&tv, NULL);
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]