changeset 5787:cbe22a271d32

(parser_control): rels_seen is now a boolean, not a count, since there's no maximum. All uses changed. Add member dsts_seen. (local_zone): Accumulate dsts_seen rather than relying on tm_isdst not being INT_MAX. (get_date): Initialize dsts_seen, and check that it doesn't go over 1. Use pc_rels_seen to decide whther a date is absolute. (number): Don't overwrite year. (get_date): Initialize pc.year.digits to 0, not 4, to enable above check.
author Paul Eggert <eggert@cs.ucla.edu>
date Mon, 04 Apr 2005 19:53:39 +0000
parents 3293578b2f71
children e8448ee7f92d
files lib/getdate.y
diffstat 1 files changed, 19 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/lib/getdate.y
+++ b/lib/getdate.y
@@ -175,12 +175,13 @@
   long int rel_seconds;
   long int rel_ns;
 
-  /* Counts of nonterminals of various flavors parsed so far.  */
+  /* Presence or counts of nonterminals of various flavors parsed so far.  */
   bool timespec_seen;
+  bool rels_seen;
   size_t dates_seen;
   size_t days_seen;
   size_t local_zones_seen;
-  size_t rels_seen;
+  size_t dsts_seen;
   size_t times_seen;
   size_t zones_seen;
 
@@ -255,7 +256,7 @@
   | day
       { pc->days_seen++; }
   | rel
-      { pc->rels_seen++; }
+      { pc->rels_seen = true; }
   | number
   ;
 
@@ -306,9 +307,15 @@
 
 local_zone:
     tLOCAL_ZONE
-      { pc->local_isdst = $1; }
+      {
+	pc->local_isdst = $1;
+	pc->dsts_seen += (0 < $1);
+      }
   | tLOCAL_ZONE tDST
-      { pc->local_isdst = $1 < 0 ? 1 : $1 + 1; }
+      {
+	pc->local_isdst = 1;
+	pc->dsts_seen += (0 < $1) + 1;
+      }
   ;
 
 zone:
@@ -504,7 +511,7 @@
 number:
     tUNUMBER
       {
-	if (pc->dates_seen
+	if (pc->dates_seen && ! pc->year.digits
 	    && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits))
 	  pc->year = $1;
 	else
@@ -1179,7 +1186,7 @@
   pc.input = p;
   pc.year.value = tmp->tm_year;
   pc.year.value += TM_YEAR_BASE;
-  pc.year.digits = 4;
+  pc.year.digits = 0;
   pc.month = tmp->tm_mon + 1;
   pc.day = tmp->tm_mday;
   pc.hour = tmp->tm_hour;
@@ -1197,11 +1204,12 @@
   pc.rel_month = 0;
   pc.rel_year = 0;
   pc.timespec_seen = false;
+  pc.rels_seen = false;
   pc.dates_seen = 0;
   pc.days_seen = 0;
-  pc.rels_seen = 0;
   pc.times_seen = 0;
   pc.local_zones_seen = 0;
+  pc.dsts_seen = 0;
   pc.zones_seen = 0;
 
 #if HAVE_STRUCT_TM_TM_ZONE
@@ -1269,9 +1277,8 @@
     *result = pc.seconds;
   else
     {
-      if (1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
-	  || 1 < (pc.local_zones_seen + pc.zones_seen)
-	  || (pc.local_zones_seen && 1 < pc.local_isdst))
+      if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
+	       | (pc.local_zones_seen + pc.zones_seen)))
 	goto fail;
 
       tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;
@@ -1292,7 +1299,7 @@
 	}
 
       /* Let mktime deduce tm_isdst if we have an absolute time stamp.  */
-      if (pc.dates_seen | pc.days_seen | pc.times_seen)
+      if (!pc.rels_seen)
 	tm.tm_isdst = -1;
 
       /* But if the input explicitly specifies local time with or without