Module Name:    src
Committed By:   christos
Date:           Sat Oct 31 02:14:08 UTC 2015

Modified Files:
        src/lib/libc/time: strptime.c

Log Message:
make %Z and %z understand the same strings.


To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/lib/libc/time/strptime.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/strptime.c
diff -u src/lib/libc/time/strptime.c:1.56 src/lib/libc/time/strptime.c:1.57
--- src/lib/libc/time/strptime.c:1.56	Fri Oct 30 17:36:25 2015
+++ src/lib/libc/time/strptime.c	Fri Oct 30 22:14:08 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: strptime.c,v 1.56 2015/10/30 21:36:25 ginsbach Exp $	*/
+/*	$NetBSD: strptime.c,v 1.57 2015/10/31 02:14:08 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2005, 2008 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strptime.c,v 1.56 2015/10/30 21:36:25 ginsbach Exp $");
+__RCSID("$NetBSD: strptime.c,v 1.57 2015/10/31 02:14:08 christos Exp $");
 #endif
 
 #include "namespace.h"
@@ -79,7 +79,6 @@ static const u_char *find_string(const u
 #define HAVE_YEAR(s)		(s & S_YEAR)
 #define HAVE_HOUR(s)		(s & S_HOUR)
 
-static char gmt[] = { "GMT" };
 static char utc[] = { "UTC" };
 /* RFC-822/RFC-2822 */
 static const char * const nast[5] = {
@@ -117,19 +116,23 @@ first_wday_of(int yr)
 #define delim(p)	((p) == '\0' || isspace((unsigned char)(p)))
 
 static int
-fromzone(const unsigned char **bp, struct tm *tm)
+fromzone(const unsigned char **bp, struct tm *tm, int mandatory)
 {
 	timezone_t tz;
 	char buf[512], *p;
+	const unsigned char *rp;
 
-	for (p = buf; !delim(**bp) && p < &buf[sizeof(buf) - 1]; (*bp)++)
-		*p++ = **bp;
+	for (p = buf, rp = *bp; !delim(*rp) && p < &buf[sizeof(buf) - 1]; rp++)
+		*p++ = *rp;
 	*p = '\0';
 
+	if (mandatory)
+		*bp = rp;
 	tz = tzalloc(buf);
 	if (tz == NULL)
 		return 0;
 
+	*bp = rp;
 	tm->tm_isdst = 0;	/* XXX */
 #ifdef TM_GMTOFF
 	tm->TM_GMTOFF = tzgetgmtoff(tz, tm->tm_isdst);
@@ -154,7 +157,7 @@ strptime_l(const char *buf, const char *
 	unsigned char c;
 	const unsigned char *bp, *ep, *zname;
 	int alt_format, i, split_year = 0, neg = 0, state = 0,
-	    day_offset = -1, week_offset = 0, offs;
+	    day_offset = -1, week_offset = 0, offs, mandatory;
 	const char *new_fmt;
 
 	bp = (const u_char *)buf;
@@ -449,36 +452,9 @@ literal:
 			continue;
 
 		case 'Z':
-			tzset();
-			if (strncmp((const char *)bp, gmt, 3) == 0 ||
-			    strncmp((const char *)bp, utc, 3) == 0) {
-				tm->tm_isdst = 0;
-#ifdef TM_GMTOFF
-				tm->TM_GMTOFF = 0;
-#endif
-#ifdef TM_ZONE
-				tm->TM_ZONE = gmt;
-#endif
-				bp += 3;
-			} else {
-				ep = find_string(bp, &i,
-					       	 (const char * const *)tzname,
-					       	  NULL, 2);
-				if (ep != NULL) {
-					tm->tm_isdst = i;
-#ifdef TM_GMTOFF
-					tm->TM_GMTOFF = -timezone;
-#endif
-#ifdef TM_ZONE
-					tm->TM_ZONE = tzname[i];
-					bp = ep;
-#endif
-				} else
-					(void)fromzone(&bp, tm);
-			}
-			continue;
-
 		case 'z':
+			tzset();
+			mandatory = c == 'z';
 			/*
 			 * We recognize all ISO 8601 formats:
 			 * Z	= Zulu time/UTC
@@ -498,8 +474,9 @@ literal:
 			 * Note: J maybe used to denote non-nautical
 			 *       local time
 			 */
-			while (isspace(*bp))
-				bp++;
+			if (mandatory)
+				while (isspace(*bp))
+					bp++;
 
 			zname = bp;
 			switch (*bp++) {
@@ -597,14 +574,30 @@ namedzone:
 					bp = ep;
 					continue;
 				}
-
+				/*
+				 * Our current timezone
+				 */
+				ep = find_string(bp, &i,
+					       	 (const char * const *)tzname,
+					       	  NULL, 2);
+				if (ep != NULL) {
+					tm->tm_isdst = i;
+#ifdef TM_GMTOFF
+					tm->TM_GMTOFF = -timezone;
+#endif
+#ifdef TM_ZONE
+					tm->TM_ZONE = tzname[i];
+#endif
+					bp = ep;
+					continue;
+				}
 loadzone:
 				/*
 				 * The hard way, load the zone!
 				 */
-				if (fromzone(&bp, tm))
+				if (fromzone(&bp, tm, mandatory))
 					continue;
-				return NULL;
+				goto out;
 			}
 			offs = 0;
 			for (i = 0; i < 4; ) {
@@ -620,23 +613,28 @@ loadzone:
 				break;
 			}
 			if (isdigit(*bp))
-				return NULL;
+				goto out;
 			switch (i) {
 			case 2:
 				offs *= SECSPERHOUR;
 				break;
 			case 4:
 				i = offs % 100;
+				offs /= 100;
 				if (i >= SECSPERMIN)
-					return NULL;
+					goto out;
 				/* Convert minutes into decimal */
-				offs = (offs / 100) * SECSPERHOUR + i * SECSPERMIN;
+				offs = offs * SECSPERHOUR + i * SECSPERMIN;
 				break;
 			default:
-				return NULL;
+			out:
+				if (mandatory)
+					return NULL;
+				bp = zname;
+				continue;
 			}
 			if (offs >= (HOURSPERDAY * SECSPERHOUR))
-				return NULL;
+				goto out;
 			if (neg)
 				offs = -offs;
 			tm->tm_isdst = 0;	/* XXX */

Reply via email to