# HG changeset patch # User Paul Eggert # Date 1112644419 0 # Node ID cbe22a271d32c8c1e61fd8858461426d15c1dc37 # Parent 3293578b2f71cbb8105a866f17e1510c186a0434 (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. diff --git a/lib/getdate.y b/lib/getdate.y --- 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