#include <ctype.h>
#include <limits.h>
-#include <stdlib.h> /* for `free'; used by Bison 1.27 */
#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
# define IN_CTYPE_DOMAIN(c) 1
#include <string.h>
-#if USE_UNLOCKED_IO
-# include "unlocked-io.h"
-#endif
-
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
# define __attribute__(x)
#endif
table local_time_zone_table[3];
} parser_control;
-#define PC (* (parser_control *) parm)
-#define YYLEX_PARAM parm
-#define YYPARSE_PARAM parm
-
-static int yyerror ();
-static int yylex ();
+union YYSTYPE;
+static int yylex (union YYSTYPE *, parser_control *);
+static int yyerror (parser_control *, char *);
%}
/* We want a reentrant parser. */
-%pure_parser
+%pure-parser
+%parse-param { parser_control *pc }
+%lex-param { parser_control *pc }
/* This grammar has 13 shift/reduce conflicts. */
%expect 13
timespec:
'@' seconds
{
- PC.seconds = $2;
- PC.timespec_seen = true;
+ pc->seconds = $2;
+ pc->timespec_seen = true;
}
;
item:
time
- { PC.times_seen++; }
+ { pc->times_seen++; }
| local_zone
- { PC.local_zones_seen++; }
+ { pc->local_zones_seen++; }
| zone
- { PC.zones_seen++; }
+ { pc->zones_seen++; }
| date
- { PC.dates_seen++; }
+ { pc->dates_seen++; }
| day
- { PC.days_seen++; }
+ { pc->days_seen++; }
| rel
- { PC.rels_seen++; }
+ { pc->rels_seen++; }
| number
;
time:
tUNUMBER tMERIDIAN
{
- PC.hour = $1.value;
- PC.minutes = 0;
- PC.seconds.tv_sec = 0;
- PC.seconds.tv_nsec = 0;
- PC.meridian = $2;
+ pc->hour = $1.value;
+ pc->minutes = 0;
+ pc->seconds.tv_sec = 0;
+ pc->seconds.tv_nsec = 0;
+ pc->meridian = $2;
}
| tUNUMBER ':' tUNUMBER o_merid
{
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds.tv_sec = 0;
- PC.seconds.tv_nsec = 0;
- PC.meridian = $4;
+ pc->hour = $1.value;
+ pc->minutes = $3.value;
+ pc->seconds.tv_sec = 0;
+ pc->seconds.tv_nsec = 0;
+ pc->meridian = $4;
}
| tUNUMBER ':' tUNUMBER tSNUMBER
{
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds.tv_sec = 0;
- PC.seconds.tv_nsec = 0;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = $4.value % 100 + ($4.value / 100) * 60;
+ pc->hour = $1.value;
+ pc->minutes = $3.value;
+ pc->seconds.tv_sec = 0;
+ pc->seconds.tv_nsec = 0;
+ pc->meridian = MER24;
+ pc->zones_seen++;
+ pc->time_zone = $4.value % 100 + ($4.value / 100) * 60;
}
| tUNUMBER ':' tUNUMBER ':' unsigned_seconds o_merid
{
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds = $5;
- PC.meridian = $6;
+ pc->hour = $1.value;
+ pc->minutes = $3.value;
+ pc->seconds = $5;
+ pc->meridian = $6;
}
| tUNUMBER ':' tUNUMBER ':' unsigned_seconds tSNUMBER
{
- PC.hour = $1.value;
- PC.minutes = $3.value;
- PC.seconds = $5;
- PC.meridian = MER24;
- PC.zones_seen++;
- PC.time_zone = $6.value % 100 + ($6.value / 100) * 60;
+ pc->hour = $1.value;
+ pc->minutes = $3.value;
+ pc->seconds = $5;
+ pc->meridian = MER24;
+ pc->zones_seen++;
+ pc->time_zone = $6.value % 100 + ($6.value / 100) * 60;
}
;
local_zone:
tLOCAL_ZONE
- { PC.local_isdst = $1; }
+ { pc->local_isdst = $1; }
| tLOCAL_ZONE tDST
- { PC.local_isdst = $1 < 0 ? 1 : $1 + 1; }
+ { pc->local_isdst = $1 < 0 ? 1 : $1 + 1; }
;
zone:
tZONE
- { PC.time_zone = $1; }
+ { pc->time_zone = $1; }
| tDAYZONE
- { PC.time_zone = $1 + 60; }
+ { pc->time_zone = $1 + 60; }
| tZONE tDST
- { PC.time_zone = $1 + 60; }
+ { pc->time_zone = $1 + 60; }
;
day:
tDAY
{
- PC.day_ordinal = 1;
- PC.day_number = $1;
+ pc->day_ordinal = 1;
+ pc->day_number = $1;
}
| tDAY ','
{
- PC.day_ordinal = 1;
- PC.day_number = $1;
+ pc->day_ordinal = 1;
+ pc->day_number = $1;
}
| tUNUMBER tDAY
{
- PC.day_ordinal = $1.value;
- PC.day_number = $2;
+ pc->day_ordinal = $1.value;
+ pc->day_number = $2;
}
;
date:
tUNUMBER '/' tUNUMBER
{
- PC.month = $1.value;
- PC.day = $3.value;
+ pc->month = $1.value;
+ pc->day = $3.value;
}
| tUNUMBER '/' tUNUMBER '/' tUNUMBER
{
you want portability, use the ISO 8601 format. */
if (4 <= $1.digits)
{
- PC.year = $1;
- PC.month = $3.value;
- PC.day = $5.value;
+ pc->year = $1;
+ pc->month = $3.value;
+ pc->day = $5.value;
}
else
{
- PC.month = $1.value;
- PC.day = $3.value;
- PC.year = $5;
+ pc->month = $1.value;
+ pc->day = $3.value;
+ pc->year = $5;
}
}
| tUNUMBER tSNUMBER tSNUMBER
{
/* ISO 8601 format. YYYY-MM-DD. */
- PC.year = $1;
- PC.month = -$2.value;
- PC.day = -$3.value;
+ pc->year = $1;
+ pc->month = -$2.value;
+ pc->day = -$3.value;
}
| tUNUMBER tMONTH tSNUMBER
{
/* e.g. 17-JUN-1992. */
- PC.day = $1.value;
- PC.month = $2;
- PC.year.value = -$3.value;
- PC.year.digits = $3.digits;
+ pc->day = $1.value;
+ pc->month = $2;
+ pc->year.value = -$3.value;
+ pc->year.digits = $3.digits;
}
| tMONTH tSNUMBER tSNUMBER
{
/* e.g. JUN-17-1992. */
- PC.month = $1;
- PC.day = -$2.value;
- PC.year.value = -$3.value;
- PC.year.digits = $3.digits;
+ pc->month = $1;
+ pc->day = -$2.value;
+ pc->year.value = -$3.value;
+ pc->year.digits = $3.digits;
}
| tMONTH tUNUMBER
{
- PC.month = $1;
- PC.day = $2.value;
+ pc->month = $1;
+ pc->day = $2.value;
}
| tMONTH tUNUMBER ',' tUNUMBER
{
- PC.month = $1;
- PC.day = $2.value;
- PC.year = $4;
+ pc->month = $1;
+ pc->day = $2.value;
+ pc->year = $4;
}
| tUNUMBER tMONTH
{
- PC.day = $1.value;
- PC.month = $2;
+ pc->day = $1.value;
+ pc->month = $2;
}
| tUNUMBER tMONTH tUNUMBER
{
- PC.day = $1.value;
- PC.month = $2;
- PC.year = $3;
+ pc->day = $1.value;
+ pc->month = $2;
+ pc->year = $3;
}
;
rel:
relunit tAGO
{
- PC.rel_ns = -PC.rel_ns;
- PC.rel_seconds = -PC.rel_seconds;
- PC.rel_minutes = -PC.rel_minutes;
- PC.rel_hour = -PC.rel_hour;
- PC.rel_day = -PC.rel_day;
- PC.rel_month = -PC.rel_month;
- PC.rel_year = -PC.rel_year;
+ pc->rel_ns = -pc->rel_ns;
+ pc->rel_seconds = -pc->rel_seconds;
+ pc->rel_minutes = -pc->rel_minutes;
+ pc->rel_hour = -pc->rel_hour;
+ pc->rel_day = -pc->rel_day;
+ pc->rel_month = -pc->rel_month;
+ pc->rel_year = -pc->rel_year;
}
| relunit
;
relunit:
tUNUMBER tYEAR_UNIT
- { PC.rel_year += $1.value * $2; }
+ { pc->rel_year += $1.value * $2; }
| tSNUMBER tYEAR_UNIT
- { PC.rel_year += $1.value * $2; }
+ { pc->rel_year += $1.value * $2; }
| tYEAR_UNIT
- { PC.rel_year += $1; }
+ { pc->rel_year += $1; }
| tUNUMBER tMONTH_UNIT
- { PC.rel_month += $1.value * $2; }
+ { pc->rel_month += $1.value * $2; }
| tSNUMBER tMONTH_UNIT
- { PC.rel_month += $1.value * $2; }
+ { pc->rel_month += $1.value * $2; }
| tMONTH_UNIT
- { PC.rel_month += $1; }
+ { pc->rel_month += $1; }
| tUNUMBER tDAY_UNIT
- { PC.rel_day += $1.value * $2; }
+ { pc->rel_day += $1.value * $2; }
| tSNUMBER tDAY_UNIT
- { PC.rel_day += $1.value * $2; }
+ { pc->rel_day += $1.value * $2; }
| tDAY_UNIT
- { PC.rel_day += $1; }
+ { pc->rel_day += $1; }
| tUNUMBER tHOUR_UNIT
- { PC.rel_hour += $1.value * $2; }
+ { pc->rel_hour += $1.value * $2; }
| tSNUMBER tHOUR_UNIT
- { PC.rel_hour += $1.value * $2; }
+ { pc->rel_hour += $1.value * $2; }
| tHOUR_UNIT
- { PC.rel_hour += $1; }
+ { pc->rel_hour += $1; }
| tUNUMBER tMINUTE_UNIT
- { PC.rel_minutes += $1.value * $2; }
+ { pc->rel_minutes += $1.value * $2; }
| tSNUMBER tMINUTE_UNIT
- { PC.rel_minutes += $1.value * $2; }
+ { pc->rel_minutes += $1.value * $2; }
| tMINUTE_UNIT
- { PC.rel_minutes += $1; }
+ { pc->rel_minutes += $1; }
| tUNUMBER tSEC_UNIT
- { PC.rel_seconds += $1.value * $2; }
+ { pc->rel_seconds += $1.value * $2; }
| tSNUMBER tSEC_UNIT
- { PC.rel_seconds += $1.value * $2; }
+ { pc->rel_seconds += $1.value * $2; }
| tSDECIMAL_NUMBER tSEC_UNIT
- { PC.rel_seconds += $1.tv_sec * $2; PC.rel_ns += $1.tv_nsec * $2; }
+ { pc->rel_seconds += $1.tv_sec * $2; pc->rel_ns += $1.tv_nsec * $2; }
| tUDECIMAL_NUMBER tSEC_UNIT
- { PC.rel_seconds += $1.tv_sec * $2; PC.rel_ns += $1.tv_nsec * $2; }
+ { pc->rel_seconds += $1.tv_sec * $2; pc->rel_ns += $1.tv_nsec * $2; }
| tSEC_UNIT
- { PC.rel_seconds += $1; }
+ { pc->rel_seconds += $1; }
;
seconds: signed_seconds | unsigned_seconds;
number:
tUNUMBER
{
- if (PC.dates_seen
- && ! PC.rels_seen && (PC.times_seen || 2 < $1.digits))
- PC.year = $1;
+ if (pc->dates_seen
+ && ! pc->rels_seen && (pc->times_seen || 2 < $1.digits))
+ pc->year = $1;
else
{
if (4 < $1.digits)
{
- PC.dates_seen++;
- PC.day = $1.value % 100;
- PC.month = ($1.value / 100) % 100;
- PC.year.value = $1.value / 10000;
- PC.year.digits = $1.digits - 4;
+ pc->dates_seen++;
+ pc->day = $1.value % 100;
+ pc->month = ($1.value / 100) % 100;
+ pc->year.value = $1.value / 10000;
+ pc->year.digits = $1.digits - 4;
}
else
{
- PC.times_seen++;
+ pc->times_seen++;
if ($1.digits <= 2)
{
- PC.hour = $1.value;
- PC.minutes = 0;
+ pc->hour = $1.value;
+ pc->minutes = 0;
}
else
{
- PC.hour = $1.value / 100;
- PC.minutes = $1.value % 100;
+ pc->hour = $1.value / 100;
+ pc->minutes = $1.value % 100;
}
- PC.seconds.tv_sec = 0;
- PC.seconds.tv_nsec = 0;
- PC.meridian = MER24;
+ pc->seconds.tv_sec = 0;
+ pc->seconds.tv_nsec = 0;
+ pc->meridian = MER24;
}
}
}
{ "A.M.", tMERIDIAN, MERam },
{ "PM", tMERIDIAN, MERpm },
{ "P.M.", tMERIDIAN, MERpm },
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
static table const dst_table[] =
{ "THURS", tDAY, 4 },
{ "FRIDAY", tDAY, 5 },
{ "SATURDAY", tDAY, 6 },
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
static table const time_units_table[] =
{ "MIN", tMINUTE_UNIT, 1 },
{ "SECOND", tSEC_UNIT, 1 },
{ "SEC", tSEC_UNIT, 1 },
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
/* Assorted relative-time words. */
{ "ELEVENTH", tUNUMBER, 11 },
{ "TWELFTH", tUNUMBER, 12 },
{ "AGO", tAGO, 1 },
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
/* The time zone table. This table is necessarily incomplete, as time
{ "GST", tZONE, HOUR (10) }, /* Guam Standard */
{ "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
{ "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
/* Military time zone table. */
{ "X", tZONE, HOUR (11) },
{ "Y", tZONE, HOUR (12) },
{ "Z", tZONE, HOUR ( 0) },
- { 0, 0, 0 }
+ { NULL, 0, 0 }
};
\f
{
switch (meridian)
{
+ default: /* Pacify GCC. */
case MER24:
return 0 <= hours && hours < 24 ? hours : -1;
case MERam:
return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
case MERpm:
return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
- default:
- abort ();
}
- /* NOTREACHED */
}
static long int
if (strcmp (name, tp->name) == 0)
return tp;
- return 0;
+ return NULL;
}
#if ! HAVE_TM_GMTOFF
if (period_found && (tp = lookup_zone (pc, word)))
return tp;
- return 0;
+ return NULL;
}
static int
/* Do nothing if the parser reports an error. */
static int
-yyerror (char *s ATTRIBUTE_UNUSED)
+yyerror (parser_control *pc ATTRIBUTE_UNUSED, char *s ATTRIBUTE_UNUSED)
{
return 0;
}
pc.local_time_zone_table[0].name = tmp->tm_zone;
pc.local_time_zone_table[0].type = tLOCAL_ZONE;
pc.local_time_zone_table[0].value = tmp->tm_isdst;
- pc.local_time_zone_table[1].name = 0;
+ pc.local_time_zone_table[1].name = NULL;
/* Probe the names used in the next three calendar quarters, looking
for a tm_isdst different from the one we already have. */
pc.local_time_zone_table[1].name = probe_tm->tm_zone;
pc.local_time_zone_table[1].type = tLOCAL_ZONE;
pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
- pc.local_time_zone_table[2].name = 0;
+ pc.local_time_zone_table[2].name = NULL;
}
break;
}
pc.local_time_zone_table[i].type = tLOCAL_ZONE;
pc.local_time_zone_table[i].value = i;
}
- pc.local_time_zone_table[i].name = 0;
+ pc.local_time_zone_table[i].name = NULL;
}
#else
- pc.local_time_zone_table[0].name = 0;
+ pc.local_time_zone_table[0].name = NULL;
#endif
#endif
daylight times. So if we see that abbreviation, we don't
know whether it's daylight time. */
pc.local_time_zone_table[0].value = -1;
- pc.local_time_zone_table[1].name = 0;
+ pc.local_time_zone_table[1].name = NULL;
}
if (yyparse (&pc) != 0)
printf ("Enter date, or blank line to exit.\n\t> ");
fflush (stdout);
- buff[BUFSIZ - 1] = 0;
+ buff[BUFSIZ - 1] = '\0';
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
{
struct timespec d;
}
return 0;
}
-#endif /* defined TEST */
+#endif /* TEST */