Module Name:    src
Committed By:   apb
Date:           Sat Jan 19 15:23:33 UTC 2013

Modified Files:
        src/lib/libutil: parsedate.y

Log Message:
Distinguish between a non-error result of (time_t)-1 and an error result.
Modernise the test code inside #ifdef TEST.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/lib/libutil/parsedate.y

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

Modified files:

Index: src/lib/libutil/parsedate.y
diff -u src/lib/libutil/parsedate.y:1.13 src/lib/libutil/parsedate.y:1.14
--- src/lib/libutil/parsedate.y:1.13	Sat Jan 19 09:27:32 2013
+++ src/lib/libutil/parsedate.y	Sat Jan 19 15:23:33 2013
@@ -14,6 +14,7 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <errno.h>
 #include <string.h>
 #include <time.h>
 #include <util.h>
@@ -148,8 +149,8 @@ cvsstamp: tUNUMBER '.' tUNUMBER '.' tUNU
 	}
 	;
 
-epochdate: AT_SIGN tUNUMBER {
-            time_t    when = $2;
+epochdate: AT_SIGN at_number {
+            time_t    when = $<Number>2;
             struct tm tmbuf;
             if (gmtime_r(&when, &tmbuf) != NULL) {
 		param->yyYear = tmbuf.tm_year + 1900;
@@ -173,6 +174,8 @@ epochdate: AT_SIGN tUNUMBER {
 	}
 	;
 
+at_number : tUNUMBER | tSNUMBER ;
+
 time	: tUNUMBER tMERIDIAN {
 	    param->yyHour = $1;
 	    param->yyMinutes = 0;
@@ -883,6 +886,10 @@ parsedate(const char *p, const time_t *n
     time_t		Start;
     time_t		tod, rm;
     struct dateinfo	param;
+    int			saved_errno;
+    
+    saved_errno = errno;
+    errno = 0;
 
     if (now == NULL || zone == NULL) {
         now = &nowt;
@@ -927,14 +934,16 @@ parsedate(const char *p, const time_t *n
     param.yyHaveZone = 0;
 
     if (yyparse(&param, &p) || param.yyHaveTime > 1 || param.yyHaveZone > 1 ||
-	param.yyHaveDate > 1 || param.yyHaveDay > 1)
+	param.yyHaveDate > 1 || param.yyHaveDay > 1) {
+	errno = EINVAL;
 	return -1;
+    }
 
     if (param.yyHaveDate || param.yyHaveTime || param.yyHaveDay) {
 	Start = Convert(param.yyMonth, param.yyDay, param.yyYear, param.yyHour,
 	    param.yyMinutes, param.yySeconds, param.yyTimezone,
 	    param.yyMeridian, param.yyDSTmode);
-	if (Start == -1)
+	if (Start == -1 && errno != 0)
 	    return -1;
     }
     else {
@@ -945,7 +954,7 @@ parsedate(const char *p, const time_t *n
 
     Start += param.yyRelSeconds;
     rm = RelativeMonth(Start, param.yyRelMonth, param.yyTimezone);
-    if (rm == -1)
+    if (rm == -1 && errno != 0)
 	return -1;
     Start += rm;
 
@@ -954,6 +963,8 @@ parsedate(const char *p, const time_t *n
 	Start += tod;
     }
 
+    if (errno == 0)
+	errno = saved_errno;
     return Start;
 }
 
@@ -962,21 +973,21 @@ parsedate(const char *p, const time_t *n
 
 /* ARGSUSED */
 int
-main(ac, av)
-    int		ac;
-    char	*av[];
+main(int ac, char *av[])
 {
     char	buff[128];
     time_t	d;
 
     (void)printf("Enter date, or blank line to exit.\n\t> ");
     (void)fflush(stdout);
-    while (gets(buff) && buff[0]) {
+    while (fgets(buff, sizeof(buff), stdin) && buff[0] != '\n') {
+	errno = 0;
 	d = parsedate(buff, NULL, NULL);
-	if (d == -1)
-	    (void)printf("Bad format - couldn't convert.\n");
+	if (d == -1 && errno != 0)
+	    (void)printf("Bad format - couldn't convert: %s\n",
+	        strerror(errno));
 	else
-	    (void)printf("%s", ctime(&d));
+	    (void)printf("%jd\t%s", (intmax_t)d, ctime(&d));
 	(void)printf("\t> ");
 	(void)fflush(stdout);
     }

Reply via email to