(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.
This commit is contained in:
Paul Eggert 2005-04-04 19:51:49 +00:00
parent 7c7da0b74e
commit 6be7cfe6d3

View File

@ -175,12 +175,13 @@ typedef struct
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 @@ item:
| day
{ pc->days_seen++; }
| rel
{ pc->rels_seen++; }
{ pc->rels_seen = true; }
| number
;
@ -306,9 +307,15 @@ time:
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 @@ unsigned_seconds:
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 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
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 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
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 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
*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 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
}
/* 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