1 /* A Bison parser, made by GNU Bison 3.6.2.  */
2 
3 /* Bison implementation for Yacc-like parsers in C
4 
5    Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation,
6    Inc.
7 
8    This program is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20 
21 /* As a special exception, you may create a larger work that contains
22    part or all of the Bison parser skeleton and distribute that work
23    under terms of your choice, so long as that work isn't itself a
24    parser generator using the skeleton or a modified version thereof
25    as a parser skeleton.  Alternatively, if you modify or redistribute
26    the parser skeleton itself, you may (at your option) remove this
27    special exception, which will cause the skeleton and the resulting
28    Bison output files to be licensed under the GNU General Public
29    License without this special exception.
30 
31    This special exception was added by the Free Software Foundation in
32    version 2.2 of Bison.  */
33 
34 /* C LALR(1) parser skeleton written by Richard Stallman, by
35    simplifying the original so-called "semantic" parser.  */
36 
37 /* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
38    especially those whose name start with YY_ or yy_.  They are
39    private implementation details that can be changed or removed.  */
40 
41 /* All symbols defined below should begin with yy or YY, to avoid
42    infringing on user name space.  This should be done even for local
43    variables, as they might otherwise be expanded by user macros.
44    There are some unavoidable exceptions within include files to
45    define necessary library symbols; they are noted "INFRINGES ON
46    USER NAME SPACE" below.  */
47 
48 /* Identify Bison output.  */
49 #define YYBISON 1
50 
51 /* Bison version.  */
52 #define YYBISON_VERSION "3.6.2"
53 
54 /* Skeleton name.  */
55 #define YYSKELETON_NAME "yacc.c"
56 
57 /* Pure parsers.  */
58 #define YYPURE 1
59 
60 /* Push parsers.  */
61 #define YYPUSH 0
62 
63 /* Pull parsers.  */
64 #define YYPULL 1
65 
66 
67 
68 
69 /* First part of user prologue.  */
70 #line 1 "parse-datetime.y"
71 
72 /* Parse a string into an internal timestamp.
73 
74    Copyright (C) 1999-2000, 2002-2021 Free Software Foundation, Inc.
75 
76    This program is free software: you can redistribute it and/or modify
77    it under the terms of the GNU General Public License as published by
78    the Free Software Foundation; either version 3 of the License, or
79    (at your option) any later version.
80 
81    This program is distributed in the hope that it will be useful,
82    but WITHOUT ANY WARRANTY; without even the implied warranty of
83    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
84    GNU General Public License for more details.
85 
86    You should have received a copy of the GNU General Public License
87    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
88 
89 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
90    at the University of North Carolina at Chapel Hill.  Later tweaked by
91    a couple of people on Usenet.  Completely overhauled by Rich $alz
92    <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
93 
94    Modified by Assaf Gordon <assafgordon@gmail.com> in 2016 to add
95    debug output.
96 
97    Modified by Paul Eggert <eggert@twinsun.com> in 1999 to do the
98    right thing about local DST.  Also modified by Paul Eggert
99    <eggert@cs.ucla.edu> in 2004 to support nanosecond-resolution
100    timestamps, in 2004 to support TZ strings in dates, and in 2017 and 2020 to
101    check for integer overflow and to support longer-than-'long'
102    'time_t' and 'tv_nsec'.  */
103 
104 #include <config.h>
105 
106 #include "parse-datetime.h"
107 
108 #include "idx.h"
109 #include "intprops.h"
110 #include "timespec.h"
111 #include "verify.h"
112 #include "strftime.h"
113 
114 /* There's no need to extend the stack, so there's no need to involve
115    alloca.  */
116 #define YYSTACK_USE_ALLOCA 0
117 
118 /* Tell Bison how much stack space is needed.  20 should be plenty for
119    this grammar, which is not right recursive.  Beware setting it too
120    high, since that might cause problems on machines whose
121    implementations have lame stack-overflow checking.  */
122 #define YYMAXDEPTH 20
123 #define YYINITDEPTH YYMAXDEPTH
124 
125 /* Since the code of parse-datetime.y is not included in the Emacs executable
126    itself, there is no need to #define static in this file.  Even if
127    the code were included in the Emacs executable, it probably
128    wouldn't do any harm to #undef it here; this will only cause
129    problems if we try to write to a static variable, which I don't
130    think this code needs to do.  */
131 #ifdef emacs
132 # undef static
133 #endif
134 
135 #include <inttypes.h>
136 #include <c-ctype.h>
137 #include <stdarg.h>
138 #include <stdio.h>
139 #include <stdlib.h>
140 #include <string.h>
141 
142 #include "gettext.h"
143 
144 #define _(str) gettext (str)
145 
146 /* Bison's skeleton tests _STDLIB_H, while some stdlib.h headers
147    use _STDLIB_H_ as witness.  Map the latter to the one bison uses.  */
148 /* FIXME: this is temporary.  Remove when we have a mechanism to ensure
149    that the version we're using is fixed, too.  */
150 #ifdef _STDLIB_H_
151 # undef _STDLIB_H
152 # define _STDLIB_H 1
153 #endif
154 
155 /* Shift A right by B bits portably, by dividing A by 2**B and
156    truncating towards minus infinity.  A and B should be free of side
157    effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
158    INT_BITS is the number of useful bits in an int.  GNU code can
159    assume that INT_BITS is at least 32.
160 
161    ISO C99 says that A >> B is implementation-defined if A < 0.  Some
162    implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
163    right in the usual way when A < 0, so SHR falls back on division if
164    ordinary A >> B doesn't seem to be the usual signed shift.  */
165 #define SHR(a, b)       \
166   (-1 >> 1 == -1        \
167    ? (a) >> (b)         \
168    : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
169 
170 #define HOUR(x) (60 * 60 * (x))
171 
172 #define STREQ(a, b) (strcmp (a, b) == 0)
173 
174 /* Verify that time_t is an integer as POSIX requires, and that every
175    time_t value fits in intmax_t.  Please file a bug report if these
176    assumptions are false on your platform.  */
177 verify (TYPE_IS_INTEGER (time_t));
178 verify (!TYPE_SIGNED (time_t) || INTMAX_MIN <= TYPE_MINIMUM (time_t));
179 verify (TYPE_MAXIMUM (time_t) <= INTMAX_MAX);
180 
181 /* True if N is out of range for time_t.  */
182 static bool
time_overflow(intmax_t n)183 time_overflow (intmax_t n)
184 {
185   return ! ((TYPE_SIGNED (time_t) ? TYPE_MINIMUM (time_t) <= n : 0 <= n)
186             && n <= TYPE_MAXIMUM (time_t));
187 }
188 
189 /* Convert a possibly-signed character to an unsigned character.  This is
190    a bit safer than casting to unsigned char, since it catches some type
191    errors that the cast doesn't.  */
to_uchar(char ch)192 static unsigned char to_uchar (char ch) { return ch; }
193 
194 static void _GL_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
dbg_printf(char const * msg,...)195 dbg_printf (char const *msg, ...)
196 {
197   va_list args;
198   /* TODO: use gnulib's 'program_name' instead?  */
199   fputs ("date: ", stderr);
200 
201   va_start (args, msg);
202   vfprintf (stderr, msg, args);
203   va_end (args);
204 }
205 
206 
207 /* An integer value, and the number of digits in its textual
208    representation.  */
209 typedef struct
210 {
211   bool negative;
212   intmax_t value;
213   idx_t digits;
214 } textint;
215 
216 /* An entry in the lexical lookup table.  */
217 typedef struct
218 {
219   char const *name;
220   int type;
221   int value;
222 } table;
223 
224 /* Meridian: am, pm, or 24-hour style.  */
225 enum { MERam, MERpm, MER24 };
226 
227 /* A reasonable upper bound for the buffer used in debug output.  */
228 enum { DBGBUFSIZE = 100 };
229 
230 enum { BILLION = 1000000000, LOG10_BILLION = 9 };
231 
232 /* Relative times.  */
233 typedef struct
234 {
235   /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */
236   intmax_t year;
237   intmax_t month;
238   intmax_t day;
239   intmax_t hour;
240   intmax_t minutes;
241   intmax_t seconds;
242   int ns;
243 } relative_time;
244 
245 #if HAVE_COMPOUND_LITERALS
246 # define RELATIVE_TIME_0 ((relative_time) { 0, 0, 0, 0, 0, 0, 0 })
247 #else
248 static relative_time const RELATIVE_TIME_0;
249 #endif
250 
251 /* Information passed to and from the parser.  */
252 typedef struct
253 {
254   /* The input string remaining to be parsed.  */
255   const char *input;
256 
257   /* N, if this is the Nth Tuesday.  */
258   intmax_t day_ordinal;
259 
260   /* Day of week; Sunday is 0.  */
261   int day_number;
262 
263   /* tm_isdst flag for the local zone.  */
264   int local_isdst;
265 
266   /* Time zone, in seconds east of UT.  */
267   int time_zone;
268 
269   /* Style used for time.  */
270   int meridian;
271 
272   /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds.  */
273   textint year;
274   intmax_t month;
275   intmax_t day;
276   intmax_t hour;
277   intmax_t minutes;
278   struct timespec seconds; /* includes nanoseconds */
279 
280   /* Relative year, month, day, hour, minutes, seconds, and nanoseconds.  */
281   relative_time rel;
282 
283   /* Presence or counts of nonterminals of various flavors parsed so far.  */
284   bool timespec_seen;
285   bool rels_seen;
286   idx_t dates_seen;
287   idx_t days_seen;
288   idx_t local_zones_seen;
289   idx_t dsts_seen;
290   idx_t times_seen;
291   idx_t zones_seen;
292   bool year_seen;
293 
294   /* Print debugging output to stderr.  */
295   bool parse_datetime_debug;
296 
297   /* Which of the 'seen' parts have been printed when debugging.  */
298   bool debug_dates_seen;
299   bool debug_days_seen;
300   bool debug_local_zones_seen;
301   bool debug_times_seen;
302   bool debug_zones_seen;
303   bool debug_year_seen;
304 
305   /* The user specified explicit ordinal day value.  */
306   bool debug_ordinal_day_seen;
307 
308   /* Table of local time zone abbreviations, terminated by a null entry.  */
309   table local_time_zone_table[3];
310 } parser_control;
311 
312 union YYSTYPE;
313 static int yylex (union YYSTYPE *, parser_control *);
314 static int yyerror (parser_control const *, char const *);
315 static bool time_zone_hhmm (parser_control *, textint, intmax_t);
316 
317 /* Extract into *PC any date and time info from a string of digits
318    of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
319    YYYY, ...).  */
320 static void
digits_to_date_time(parser_control * pc,textint text_int)321 digits_to_date_time (parser_control *pc, textint text_int)
322 {
323   if (pc->dates_seen && ! pc->year.digits
324       && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))
325     {
326       pc->year_seen = true;
327       pc->year = text_int;
328     }
329   else
330     {
331       if (4 < text_int.digits)
332         {
333           pc->dates_seen++;
334           pc->day = text_int.value % 100;
335           pc->month = (text_int.value / 100) % 100;
336           pc->year.value = text_int.value / 10000;
337           pc->year.digits = text_int.digits - 4;
338         }
339       else
340         {
341           pc->times_seen++;
342           if (text_int.digits <= 2)
343             {
344               pc->hour = text_int.value;
345               pc->minutes = 0;
346             }
347           else
348             {
349               pc->hour = text_int.value / 100;
350               pc->minutes = text_int.value % 100;
351             }
352           pc->seconds.tv_sec = 0;
353           pc->seconds.tv_nsec = 0;
354           pc->meridian = MER24;
355         }
356     }
357 }
358 
359 /* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1).  Return true
360    if successful, false if an overflow occurred.  */
361 static bool
apply_relative_time(parser_control * pc,relative_time rel,int factor)362 apply_relative_time (parser_control *pc, relative_time rel, int factor)
363 {
364   if (factor < 0
365       ? (INT_SUBTRACT_WRAPV (pc->rel.ns, rel.ns, &pc->rel.ns)
366          | INT_SUBTRACT_WRAPV (pc->rel.seconds, rel.seconds, &pc->rel.seconds)
367          | INT_SUBTRACT_WRAPV (pc->rel.minutes, rel.minutes, &pc->rel.minutes)
368          | INT_SUBTRACT_WRAPV (pc->rel.hour, rel.hour, &pc->rel.hour)
369          | INT_SUBTRACT_WRAPV (pc->rel.day, rel.day, &pc->rel.day)
370          | INT_SUBTRACT_WRAPV (pc->rel.month, rel.month, &pc->rel.month)
371          | INT_SUBTRACT_WRAPV (pc->rel.year, rel.year, &pc->rel.year))
372       : (INT_ADD_WRAPV (pc->rel.ns, rel.ns, &pc->rel.ns)
373          | INT_ADD_WRAPV (pc->rel.seconds, rel.seconds, &pc->rel.seconds)
374          | INT_ADD_WRAPV (pc->rel.minutes, rel.minutes, &pc->rel.minutes)
375          | INT_ADD_WRAPV (pc->rel.hour, rel.hour, &pc->rel.hour)
376          | INT_ADD_WRAPV (pc->rel.day, rel.day, &pc->rel.day)
377          | INT_ADD_WRAPV (pc->rel.month, rel.month, &pc->rel.month)
378          | INT_ADD_WRAPV (pc->rel.year, rel.year, &pc->rel.year)))
379     return false;
380   pc->rels_seen = true;
381   return true;
382 }
383 
384 /* Set PC-> hour, minutes, seconds and nanoseconds members from arguments.  */
385 static void
set_hhmmss(parser_control * pc,intmax_t hour,intmax_t minutes,time_t sec,int nsec)386 set_hhmmss (parser_control *pc, intmax_t hour, intmax_t minutes,
387             time_t sec, int nsec)
388 {
389   pc->hour = hour;
390   pc->minutes = minutes;
391   pc->seconds.tv_sec = sec;
392   pc->seconds.tv_nsec = nsec;
393 }
394 
395 /* Return a textual representation of the day ordinal/number values
396    in the parser_control struct (e.g., "last wed", "this tues", "thu").  */
397 static const char *
str_days(parser_control * pc,char * buffer,int n)398 str_days (parser_control *pc, char *buffer, int n)
399 {
400   /* TODO: use relative_time_table for reverse lookup.  */
401   static char const ordinal_values[][11] = {
402      "last",
403      "this",
404      "next/first",
405      "(SECOND)", /* SECOND is commented out in relative_time_table.  */
406      "third",
407      "fourth",
408      "fifth",
409      "sixth",
410      "seventh",
411      "eight",
412      "ninth",
413      "tenth",
414      "eleventh",
415      "twelfth"
416   };
417 
418   static char const days_values[][4] = {
419      "Sun",
420      "Mon",
421      "Tue",
422      "Wed",
423      "Thu",
424      "Fri",
425      "Sat"
426   };
427 
428   int len;
429 
430   /* Don't add an ordinal prefix if the user didn't specify it
431      (e.g., "this wed" vs "wed").  */
432   if (pc->debug_ordinal_day_seen)
433     {
434       /* Use word description if possible (e.g., -1 = last, 3 = third).  */
435       len = (-1 <= pc->day_ordinal && pc->day_ordinal <= 12
436              ? snprintf (buffer, n, "%s", ordinal_values[pc->day_ordinal + 1])
437              : snprintf (buffer, n, "%"PRIdMAX, pc->day_ordinal));
438     }
439   else
440     {
441       buffer[0] = '\0';
442       len = 0;
443     }
444 
445   /* Add the day name */
446   if (0 <= pc->day_number && pc->day_number <= 6 && 0 <= len && len < n)
447     snprintf (buffer + len, n - len, &" %s"[len == 0],
448               days_values[pc->day_number]);
449   else
450     {
451       /* invalid day_number value - should never happen */
452     }
453   return buffer;
454 }
455 
456 /* Convert a time zone to its string representation.  */
457 
458 enum { TIME_ZONE_BUFSIZE = INT_STRLEN_BOUND (intmax_t) + sizeof ":MM:SS" } ;
459 
460 static char const *
time_zone_str(int time_zone,char time_zone_buf[TIME_ZONE_BUFSIZE])461 time_zone_str (int time_zone, char time_zone_buf[TIME_ZONE_BUFSIZE])
462 {
463   char *p = time_zone_buf;
464   char sign = time_zone < 0 ? '-' : '+';
465   int hour = abs (time_zone / (60 * 60));
466   p += sprintf (time_zone_buf, "%c%02d", sign, hour);
467   int offset_from_hour = abs (time_zone % (60 * 60));
468   if (offset_from_hour != 0)
469     {
470       int mm = offset_from_hour / 60;
471       int ss = offset_from_hour % 60;
472       *p++ = ':';
473       *p++ = '0' + mm / 10;
474       *p++ = '0' + mm % 10;
475       if (ss)
476         {
477           *p++ = ':';
478           *p++ = '0' + ss / 10;
479           *p++ = '0' + ss % 10;
480         }
481       *p = '\0';
482     }
483   return time_zone_buf;
484 }
485 
486 /* debugging: print the current time in the parser_control structure.
487    The parser will increment "*_seen" members for those which were parsed.
488    This function will print only newly seen parts.  */
489 static void
debug_print_current_time(char const * item,parser_control * pc)490 debug_print_current_time (char const *item, parser_control *pc)
491 {
492   bool space = false;
493 
494   if (!pc->parse_datetime_debug)
495     return;
496 
497   /* no newline, more items printed below */
498   dbg_printf (_("parsed %s part: "), item);
499 
500   if (pc->dates_seen && !pc->debug_dates_seen)
501     {
502       /*TODO: use pc->year.negative?  */
503       fprintf (stderr, "(Y-M-D) %04"PRIdMAX"-%02"PRIdMAX"-%02"PRIdMAX,
504               pc->year.value, pc->month, pc->day);
505       pc->debug_dates_seen = true;
506       space = true;
507     }
508 
509   if (pc->year_seen != pc->debug_year_seen)
510     {
511       if (space)
512         fputc (' ', stderr);
513       fprintf (stderr, _("year: %04"PRIdMAX), pc->year.value);
514 
515       pc->debug_year_seen = pc->year_seen;
516       space = true;
517     }
518 
519   if (pc->times_seen && !pc->debug_times_seen)
520     {
521       intmax_t sec = pc->seconds.tv_sec;
522       fprintf (stderr, &" %02"PRIdMAX":%02"PRIdMAX":%02"PRIdMAX[!space],
523                pc->hour, pc->minutes, sec);
524       if (pc->seconds.tv_nsec != 0)
525         {
526           int nsec = pc->seconds.tv_nsec;
527           fprintf (stderr, ".%09d", nsec);
528         }
529       if (pc->meridian == MERpm)
530         fputs ("pm", stderr);
531 
532       pc->debug_times_seen = true;
533       space = true;
534     }
535 
536   if (pc->days_seen && !pc->debug_days_seen)
537     {
538       if (space)
539         fputc (' ', stderr);
540       char tmp[DBGBUFSIZE];
541       fprintf (stderr, _("%s (day ordinal=%"PRIdMAX" number=%d)"),
542                str_days (pc, tmp, sizeof tmp),
543                pc->day_ordinal, pc->day_number);
544       pc->debug_days_seen = true;
545       space = true;
546     }
547 
548   /* local zone strings only change the DST settings,
549      not the timezone value.  If seen, inform about the DST.  */
550   if (pc->local_zones_seen && !pc->debug_local_zones_seen)
551     {
552       fprintf (stderr, &" isdst=%d%s"[!space],
553                pc->local_isdst, pc->dsts_seen ? " DST" : "");
554       pc->debug_local_zones_seen = true;
555       space = true;
556     }
557 
558   if (pc->zones_seen && !pc->debug_zones_seen)
559     {
560       char time_zone_buf[TIME_ZONE_BUFSIZE];
561       fprintf (stderr, &" UTC%s"[!space],
562                time_zone_str (pc->time_zone, time_zone_buf));
563       pc->debug_zones_seen = true;
564       space = true;
565     }
566 
567   if (pc->timespec_seen)
568     {
569       intmax_t sec = pc->seconds.tv_sec;
570       if (space)
571         fputc (' ', stderr);
572       fprintf (stderr, _("number of seconds: %"PRIdMAX), sec);
573     }
574 
575   fputc ('\n', stderr);
576 }
577 
578 /* Debugging: print the current relative values.  */
579 
580 static bool
print_rel_part(bool space,intmax_t val,char const * name)581 print_rel_part (bool space, intmax_t val, char const *name)
582 {
583   if (val == 0)
584     return space;
585   fprintf (stderr, &" %+"PRIdMAX" %s"[!space], val, name);
586   return true;
587 }
588 
589 static void
debug_print_relative_time(char const * item,parser_control const * pc)590 debug_print_relative_time (char const *item, parser_control const *pc)
591 {
592   bool space = false;
593 
594   if (!pc->parse_datetime_debug)
595     return;
596 
597   /* no newline, more items printed below */
598   dbg_printf (_("parsed %s part: "), item);
599 
600   if (pc->rel.year == 0 && pc->rel.month == 0 && pc->rel.day == 0
601       && pc->rel.hour == 0 && pc->rel.minutes == 0 && pc->rel.seconds == 0
602       && pc->rel.ns == 0)
603     {
604       /* Special case: relative time of this/today/now */
605       fputs (_("today/this/now\n"), stderr);
606       return;
607     }
608 
609   space = print_rel_part (space, pc->rel.year, "year(s)");
610   space = print_rel_part (space, pc->rel.month, "month(s)");
611   space = print_rel_part (space, pc->rel.day, "day(s)");
612   space = print_rel_part (space, pc->rel.hour, "hour(s)");
613   space = print_rel_part (space, pc->rel.minutes, "minutes");
614   space = print_rel_part (space, pc->rel.seconds, "seconds");
615   print_rel_part (space, pc->rel.ns, "nanoseconds");
616 
617   fputc ('\n', stderr);
618 }
619 
620 
621 
622 
623 #line 624 "parse-datetime.c"
624 
625 # ifndef YY_CAST
626 #  ifdef __cplusplus
627 #   define YY_CAST(Type, Val) static_cast<Type> (Val)
628 #   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)
629 #  else
630 #   define YY_CAST(Type, Val) ((Type) (Val))
631 #   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))
632 #  endif
633 # endif
634 # ifndef YY_NULLPTR
635 #  if defined __cplusplus
636 #   if 201103L <= __cplusplus
637 #    define YY_NULLPTR nullptr
638 #   else
639 #    define YY_NULLPTR 0
640 #   endif
641 #  else
642 #   define YY_NULLPTR ((void*)0)
643 #  endif
644 # endif
645 
646 /* Use api.header.include to #include this header
647    instead of duplicating it here.  */
648 #ifndef YY_YY_PARSE_DATETIME_TAB_H_INCLUDED
649 # define YY_YY_PARSE_DATETIME_TAB_H_INCLUDED
650 /* Debug traces.  */
651 #ifndef YYDEBUG
652 # define YYDEBUG 0
653 #endif
654 #if YYDEBUG
655 extern int yydebug;
656 #endif
657 
658 /* Token kinds.  */
659 #ifndef YYTOKENTYPE
660 # define YYTOKENTYPE
661   enum yytokentype
662   {
663     YYEMPTY = -2,
664     YYEOF = 0,                     /* "end of file"  */
665     YYerror = 256,                 /* error  */
666     YYUNDEF = 257,                 /* "invalid token"  */
667     tAGO = 258,                    /* tAGO  */
668     tDST = 259,                    /* tDST  */
669     tYEAR_UNIT = 260,              /* tYEAR_UNIT  */
670     tMONTH_UNIT = 261,             /* tMONTH_UNIT  */
671     tHOUR_UNIT = 262,              /* tHOUR_UNIT  */
672     tMINUTE_UNIT = 263,            /* tMINUTE_UNIT  */
673     tSEC_UNIT = 264,               /* tSEC_UNIT  */
674     tDAY_UNIT = 265,               /* tDAY_UNIT  */
675     tDAY_SHIFT = 266,              /* tDAY_SHIFT  */
676     tDAY = 267,                    /* tDAY  */
677     tDAYZONE = 268,                /* tDAYZONE  */
678     tLOCAL_ZONE = 269,             /* tLOCAL_ZONE  */
679     tMERIDIAN = 270,               /* tMERIDIAN  */
680     tMONTH = 271,                  /* tMONTH  */
681     tORDINAL = 272,                /* tORDINAL  */
682     tZONE = 273,                   /* tZONE  */
683     tSNUMBER = 274,                /* tSNUMBER  */
684     tUNUMBER = 275,                /* tUNUMBER  */
685     tSDECIMAL_NUMBER = 276,        /* tSDECIMAL_NUMBER  */
686     tUDECIMAL_NUMBER = 277         /* tUDECIMAL_NUMBER  */
687   };
688   typedef enum yytokentype yytoken_kind_t;
689 #endif
690 
691 /* Value type.  */
692 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
693 union YYSTYPE
694 {
695 #line 564 "parse-datetime.y"
696 
697   intmax_t intval;
698   textint textintval;
699   struct timespec timespec;
700   relative_time rel;
701 
702 #line 703 "parse-datetime.c"
703 
704 };
705 typedef union YYSTYPE YYSTYPE;
706 # define YYSTYPE_IS_TRIVIAL 1
707 # define YYSTYPE_IS_DECLARED 1
708 #endif
709 
710 
711 
712 int yyparse (parser_control *pc);
713 
714 #endif /* !YY_YY_PARSE_DATETIME_TAB_H_INCLUDED  */
715 /* Symbol kind.  */
716 enum yysymbol_kind_t
717 {
718   YYSYMBOL_YYEMPTY = -2,
719   YYSYMBOL_YYEOF = 0,                      /* "end of file"  */
720   YYSYMBOL_YYerror = 1,                    /* error  */
721   YYSYMBOL_YYUNDEF = 2,                    /* "invalid token"  */
722   YYSYMBOL_tAGO = 3,                       /* tAGO  */
723   YYSYMBOL_tDST = 4,                       /* tDST  */
724   YYSYMBOL_tYEAR_UNIT = 5,                 /* tYEAR_UNIT  */
725   YYSYMBOL_tMONTH_UNIT = 6,                /* tMONTH_UNIT  */
726   YYSYMBOL_tHOUR_UNIT = 7,                 /* tHOUR_UNIT  */
727   YYSYMBOL_tMINUTE_UNIT = 8,               /* tMINUTE_UNIT  */
728   YYSYMBOL_tSEC_UNIT = 9,                  /* tSEC_UNIT  */
729   YYSYMBOL_tDAY_UNIT = 10,                 /* tDAY_UNIT  */
730   YYSYMBOL_tDAY_SHIFT = 11,                /* tDAY_SHIFT  */
731   YYSYMBOL_tDAY = 12,                      /* tDAY  */
732   YYSYMBOL_tDAYZONE = 13,                  /* tDAYZONE  */
733   YYSYMBOL_tLOCAL_ZONE = 14,               /* tLOCAL_ZONE  */
734   YYSYMBOL_tMERIDIAN = 15,                 /* tMERIDIAN  */
735   YYSYMBOL_tMONTH = 16,                    /* tMONTH  */
736   YYSYMBOL_tORDINAL = 17,                  /* tORDINAL  */
737   YYSYMBOL_tZONE = 18,                     /* tZONE  */
738   YYSYMBOL_tSNUMBER = 19,                  /* tSNUMBER  */
739   YYSYMBOL_tUNUMBER = 20,                  /* tUNUMBER  */
740   YYSYMBOL_tSDECIMAL_NUMBER = 21,          /* tSDECIMAL_NUMBER  */
741   YYSYMBOL_tUDECIMAL_NUMBER = 22,          /* tUDECIMAL_NUMBER  */
742   YYSYMBOL_23_ = 23,                       /* '@'  */
743   YYSYMBOL_24_T_ = 24,                     /* 'T'  */
744   YYSYMBOL_25_ = 25,                       /* ':'  */
745   YYSYMBOL_26_ = 26,                       /* ','  */
746   YYSYMBOL_27_ = 27,                       /* '/'  */
747   YYSYMBOL_YYACCEPT = 28,                  /* $accept  */
748   YYSYMBOL_spec = 29,                      /* spec  */
749   YYSYMBOL_timespec = 30,                  /* timespec  */
750   YYSYMBOL_items = 31,                     /* items  */
751   YYSYMBOL_item = 32,                      /* item  */
752   YYSYMBOL_datetime = 33,                  /* datetime  */
753   YYSYMBOL_iso_8601_datetime = 34,         /* iso_8601_datetime  */
754   YYSYMBOL_time = 35,                      /* time  */
755   YYSYMBOL_iso_8601_time = 36,             /* iso_8601_time  */
756   YYSYMBOL_o_zone_offset = 37,             /* o_zone_offset  */
757   YYSYMBOL_zone_offset = 38,               /* zone_offset  */
758   YYSYMBOL_local_zone = 39,                /* local_zone  */
759   YYSYMBOL_zone = 40,                      /* zone  */
760   YYSYMBOL_day = 41,                       /* day  */
761   YYSYMBOL_date = 42,                      /* date  */
762   YYSYMBOL_iso_8601_date = 43,             /* iso_8601_date  */
763   YYSYMBOL_rel = 44,                       /* rel  */
764   YYSYMBOL_relunit = 45,                   /* relunit  */
765   YYSYMBOL_relunit_snumber = 46,           /* relunit_snumber  */
766   YYSYMBOL_dayshift = 47,                  /* dayshift  */
767   YYSYMBOL_seconds = 48,                   /* seconds  */
768   YYSYMBOL_signed_seconds = 49,            /* signed_seconds  */
769   YYSYMBOL_unsigned_seconds = 50,          /* unsigned_seconds  */
770   YYSYMBOL_number = 51,                    /* number  */
771   YYSYMBOL_hybrid = 52,                    /* hybrid  */
772   YYSYMBOL_o_colon_minutes = 53            /* o_colon_minutes  */
773 };
774 typedef enum yysymbol_kind_t yysymbol_kind_t;
775 
776 
777 
778 
779 #ifdef short
780 # undef short
781 #endif
782 
783 /* On compilers that do not define __PTRDIFF_MAX__ etc., make sure
784    <limits.h> and (if available) <stdint.h> are included
785    so that the code can choose integer types of a good width.  */
786 
787 #ifndef __PTRDIFF_MAX__
788 # include <limits.h> /* INFRINGES ON USER NAME SPACE */
789 # if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
790 #  include <stdint.h> /* INFRINGES ON USER NAME SPACE */
791 #  define YY_STDINT_H
792 # endif
793 #endif
794 
795 /* Narrow types that promote to a signed type and that can represent a
796    signed or unsigned integer of at least N bits.  In tables they can
797    save space and decrease cache pressure.  Promoting to a signed type
798    helps avoid bugs in integer arithmetic.  */
799 
800 #ifdef __INT_LEAST8_MAX__
801 typedef __INT_LEAST8_TYPE__ yytype_int8;
802 #elif defined YY_STDINT_H
803 typedef int_least8_t yytype_int8;
804 #else
805 typedef signed char yytype_int8;
806 #endif
807 
808 #ifdef __INT_LEAST16_MAX__
809 typedef __INT_LEAST16_TYPE__ yytype_int16;
810 #elif defined YY_STDINT_H
811 typedef int_least16_t yytype_int16;
812 #else
813 typedef short yytype_int16;
814 #endif
815 
816 #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__
817 typedef __UINT_LEAST8_TYPE__ yytype_uint8;
818 #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \
819        && UINT_LEAST8_MAX <= INT_MAX)
820 typedef uint_least8_t yytype_uint8;
821 #elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX
822 typedef unsigned char yytype_uint8;
823 #else
824 typedef short yytype_uint8;
825 #endif
826 
827 #if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__
828 typedef __UINT_LEAST16_TYPE__ yytype_uint16;
829 #elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \
830        && UINT_LEAST16_MAX <= INT_MAX)
831 typedef uint_least16_t yytype_uint16;
832 #elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX
833 typedef unsigned short yytype_uint16;
834 #else
835 typedef int yytype_uint16;
836 #endif
837 
838 #ifndef YYPTRDIFF_T
839 # if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__
840 #  define YYPTRDIFF_T __PTRDIFF_TYPE__
841 #  define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__
842 # elif defined PTRDIFF_MAX
843 #  ifndef ptrdiff_t
844 #   include <stddef.h> /* INFRINGES ON USER NAME SPACE */
845 #  endif
846 #  define YYPTRDIFF_T ptrdiff_t
847 #  define YYPTRDIFF_MAXIMUM PTRDIFF_MAX
848 # else
849 #  define YYPTRDIFF_T long
850 #  define YYPTRDIFF_MAXIMUM LONG_MAX
851 # endif
852 #endif
853 
854 #ifndef YYSIZE_T
855 # ifdef __SIZE_TYPE__
856 #  define YYSIZE_T __SIZE_TYPE__
857 # elif defined size_t
858 #  define YYSIZE_T size_t
859 # elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
860 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
861 #  define YYSIZE_T size_t
862 # else
863 #  define YYSIZE_T unsigned
864 # endif
865 #endif
866 
867 #define YYSIZE_MAXIMUM                                  \
868   YY_CAST (YYPTRDIFF_T,                                 \
869            (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1)  \
870             ? YYPTRDIFF_MAXIMUM                         \
871             : YY_CAST (YYSIZE_T, -1)))
872 
873 #define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X))
874 
875 
876 /* Stored state numbers (used for stacks). */
877 typedef yytype_int8 yy_state_t;
878 
879 /* State numbers in computations.  */
880 typedef int yy_state_fast_t;
881 
882 #ifndef YY_
883 # if defined YYENABLE_NLS && YYENABLE_NLS
884 #  if ENABLE_NLS
885 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
886 #   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
887 #  endif
888 # endif
889 # ifndef YY_
890 #  define YY_(Msgid) Msgid
891 # endif
892 #endif
893 
894 
895 #ifndef YY_ATTRIBUTE_PURE
896 # if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)
897 #  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))
898 # else
899 #  define YY_ATTRIBUTE_PURE
900 # endif
901 #endif
902 
903 #ifndef YY_ATTRIBUTE_UNUSED
904 # if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)
905 #  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))
906 # else
907 #  define YY_ATTRIBUTE_UNUSED
908 # endif
909 #endif
910 
911 /* Suppress unused-variable warnings by "using" E.  */
912 #if ! defined lint || defined __GNUC__
913 # define YYUSE(E) ((void) (E))
914 #else
915 # define YYUSE(E) /* empty */
916 #endif
917 
918 #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
919 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
920 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                            \
921     _Pragma ("GCC diagnostic push")                                     \
922     _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")              \
923     _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
924 # define YY_IGNORE_MAYBE_UNINITIALIZED_END      \
925     _Pragma ("GCC diagnostic pop")
926 #else
927 # define YY_INITIAL_VALUE(Value) Value
928 #endif
929 #ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
930 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
931 # define YY_IGNORE_MAYBE_UNINITIALIZED_END
932 #endif
933 #ifndef YY_INITIAL_VALUE
934 # define YY_INITIAL_VALUE(Value) /* Nothing. */
935 #endif
936 
937 #if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__
938 # define YY_IGNORE_USELESS_CAST_BEGIN                          \
939     _Pragma ("GCC diagnostic push")                            \
940     _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"")
941 # define YY_IGNORE_USELESS_CAST_END            \
942     _Pragma ("GCC diagnostic pop")
943 #endif
944 #ifndef YY_IGNORE_USELESS_CAST_BEGIN
945 # define YY_IGNORE_USELESS_CAST_BEGIN
946 # define YY_IGNORE_USELESS_CAST_END
947 #endif
948 
949 
950 #define YY_ASSERT(E) ((void) (0 && (E)))
951 
952 #if !defined yyoverflow
953 
954 /* The parser invokes alloca or malloc; define the necessary symbols.  */
955 
956 # ifdef YYSTACK_USE_ALLOCA
957 #  if YYSTACK_USE_ALLOCA
958 #   ifdef __GNUC__
959 #    define YYSTACK_ALLOC __builtin_alloca
960 #   elif defined __BUILTIN_VA_ARG_INCR
961 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
962 #   elif defined _AIX
963 #    define YYSTACK_ALLOC __alloca
964 #   elif defined _MSC_VER
965 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
966 #    define alloca _alloca
967 #   else
968 #    define YYSTACK_ALLOC alloca
969 #    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
970 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
971       /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
972 #     ifndef EXIT_SUCCESS
973 #      define EXIT_SUCCESS 0
974 #     endif
975 #    endif
976 #   endif
977 #  endif
978 # endif
979 
980 # ifdef YYSTACK_ALLOC
981    /* Pacify GCC's 'empty if-body' warning.  */
982 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
983 #  ifndef YYSTACK_ALLOC_MAXIMUM
984     /* The OS might guarantee only one guard page at the bottom of the stack,
985        and a page size can be as small as 4096 bytes.  So we cannot safely
986        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
987        to allow for a few compiler-allocated temporary stack slots.  */
988 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
989 #  endif
990 # else
991 #  define YYSTACK_ALLOC YYMALLOC
992 #  define YYSTACK_FREE YYFREE
993 #  ifndef YYSTACK_ALLOC_MAXIMUM
994 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
995 #  endif
996 #  if (defined __cplusplus && ! defined EXIT_SUCCESS \
997        && ! ((defined YYMALLOC || defined malloc) \
998              && (defined YYFREE || defined free)))
999 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
1000 #   ifndef EXIT_SUCCESS
1001 #    define EXIT_SUCCESS 0
1002 #   endif
1003 #  endif
1004 #  ifndef YYMALLOC
1005 #   define YYMALLOC malloc
1006 #   if ! defined malloc && ! defined EXIT_SUCCESS
1007 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
1008 #   endif
1009 #  endif
1010 #  ifndef YYFREE
1011 #   define YYFREE free
1012 #   if ! defined free && ! defined EXIT_SUCCESS
1013 void free (void *); /* INFRINGES ON USER NAME SPACE */
1014 #   endif
1015 #  endif
1016 # endif
1017 #endif /* !defined yyoverflow */
1018 
1019 #if (! defined yyoverflow \
1020      && (! defined __cplusplus \
1021          || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
1022 
1023 /* A type that is properly aligned for any stack member.  */
1024 union yyalloc
1025 {
1026   yy_state_t yyss_alloc;
1027   YYSTYPE yyvs_alloc;
1028 };
1029 
1030 /* The size of the maximum gap between one aligned stack and the next.  */
1031 # define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1)
1032 
1033 /* The size of an array large to enough to hold all stacks, each with
1034    N elements.  */
1035 # define YYSTACK_BYTES(N) \
1036      ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \
1037       + YYSTACK_GAP_MAXIMUM)
1038 
1039 # define YYCOPY_NEEDED 1
1040 
1041 /* Relocate STACK from its old location to the new one.  The
1042    local variables YYSIZE and YYSTACKSIZE give the old and new number of
1043    elements in the stack, and YYPTR gives the new location of the
1044    stack.  Advance YYPTR to a properly aligned location for the next
1045    stack.  */
1046 # define YYSTACK_RELOCATE(Stack_alloc, Stack)                           \
1047     do                                                                  \
1048       {                                                                 \
1049         YYPTRDIFF_T yynewbytes;                                         \
1050         YYCOPY (&yyptr->Stack_alloc, Stack, yysize);                    \
1051         Stack = &yyptr->Stack_alloc;                                    \
1052         yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \
1053         yyptr += yynewbytes / YYSIZEOF (*yyptr);                        \
1054       }                                                                 \
1055     while (0)
1056 
1057 #endif
1058 
1059 #if defined YYCOPY_NEEDED && YYCOPY_NEEDED
1060 /* Copy COUNT objects from SRC to DST.  The source and destination do
1061    not overlap.  */
1062 # ifndef YYCOPY
1063 #  if defined __GNUC__ && 1 < __GNUC__
1064 #   define YYCOPY(Dst, Src, Count) \
1065       __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src)))
1066 #  else
1067 #   define YYCOPY(Dst, Src, Count)              \
1068       do                                        \
1069         {                                       \
1070           YYPTRDIFF_T yyi;                      \
1071           for (yyi = 0; yyi < (Count); yyi++)   \
1072             (Dst)[yyi] = (Src)[yyi];            \
1073         }                                       \
1074       while (0)
1075 #  endif
1076 # endif
1077 #endif /* !YYCOPY_NEEDED */
1078 
1079 /* YYFINAL -- State number of the termination state.  */
1080 #define YYFINAL  12
1081 /* YYLAST -- Last index in YYTABLE.  */
1082 #define YYLAST   112
1083 
1084 /* YYNTOKENS -- Number of terminals.  */
1085 #define YYNTOKENS  28
1086 /* YYNNTS -- Number of nonterminals.  */
1087 #define YYNNTS  26
1088 /* YYNRULES -- Number of rules.  */
1089 #define YYNRULES  91
1090 /* YYNSTATES -- Number of states.  */
1091 #define YYNSTATES  114
1092 
1093 #define YYMAXUTOK   277
1094 
1095 
1096 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
1097    as returned by yylex, with out-of-bounds checking.  */
1098 #define YYTRANSLATE(YYX)                                \
1099   (0 <= (YYX) && (YYX) <= YYMAXUTOK                     \
1100    ? YY_CAST (yysymbol_kind_t, yytranslate[YYX])        \
1101    : YYSYMBOL_YYUNDEF)
1102 
1103 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
1104    as returned by yylex.  */
1105 static const yytype_int8 yytranslate[] =
1106 {
1107        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1108        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1109        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1110        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1111        2,     2,     2,     2,    26,     2,     2,    27,     2,     2,
1112        2,     2,     2,     2,     2,     2,     2,     2,    25,     2,
1113        2,     2,     2,     2,    23,     2,     2,     2,     2,     2,
1114        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1115        2,     2,     2,     2,    24,     2,     2,     2,     2,     2,
1116        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1117        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1118        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1119        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1120        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1121        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1122        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1123        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1124        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1125        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1126        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1127        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1128        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1129        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1130        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1131        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
1132        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
1133        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
1134       15,    16,    17,    18,    19,    20,    21,    22
1135 };
1136 
1137 #if YYDEBUG
1138   /* YYRLINEYYN -- Source line where rule number YYN was defined.  */
1139 static const yytype_int16 yyrline[] =
1140 {
1141        0,   591,   591,   592,   596,   604,   606,   610,   615,   620,
1142      625,   630,   635,   640,   644,   648,   655,   659,   663,   668,
1143      673,   678,   682,   687,   692,   699,   701,   705,   730,   732,
1144      742,   744,   746,   751,   756,   759,   761,   766,   771,   776,
1145      782,   791,   796,   829,   837,   845,   850,   856,   861,   867,
1146      871,   881,   883,   885,   890,   892,   894,   896,   898,   900,
1147      902,   905,   908,   910,   912,   914,   916,   918,   920,   922,
1148      924,   926,   928,   930,   932,   936,   938,   940,   943,   945,
1149      947,   952,   956,   956,   959,   960,   966,   967,   973,   978,
1150      989,   990
1151 };
1152 #endif
1153 
1154 /** Accessing symbol of state STATE.  */
1155 #define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State])
1156 
1157 #if YYDEBUG || 0
1158 /* The user-facing name of the symbol whose (internal) number is
1159    YYSYMBOL.  No bounds checking.  */
1160 static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED;
1161 
1162 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
1163    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
1164 static const char *const yytname[] =
1165 {
1166   "\"end of file\"", "error", "\"invalid token\"", "tAGO", "tDST",
1167   "tYEAR_UNIT", "tMONTH_UNIT", "tHOUR_UNIT", "tMINUTE_UNIT", "tSEC_UNIT",
1168   "tDAY_UNIT", "tDAY_SHIFT", "tDAY", "tDAYZONE", "tLOCAL_ZONE",
1169   "tMERIDIAN", "tMONTH", "tORDINAL", "tZONE", "tSNUMBER", "tUNUMBER",
1170   "tSDECIMAL_NUMBER", "tUDECIMAL_NUMBER", "'@'", "'T'", "':'", "','",
1171   "'/'", "$accept", "spec", "timespec", "items", "item", "datetime",
1172   "iso_8601_datetime", "time", "iso_8601_time", "o_zone_offset",
1173   "zone_offset", "local_zone", "zone", "day", "date", "iso_8601_date",
1174   "rel", "relunit", "relunit_snumber", "dayshift", "seconds",
1175   "signed_seconds", "unsigned_seconds", "number", "hybrid",
1176   "o_colon_minutes", YY_NULLPTR
1177 };
1178 
1179 static const char *
yysymbol_name(yysymbol_kind_t yysymbol)1180 yysymbol_name (yysymbol_kind_t yysymbol)
1181 {
1182   return yytname[yysymbol];
1183 }
1184 #endif
1185 
1186 #ifdef YYPRINT
1187 /* YYTOKNUM[NUM] -- (External) token number corresponding to the
1188    (internal) symbol number NUM (which must be that of a token).  */
1189 static const yytype_int16 yytoknum[] =
1190 {
1191        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
1192      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
1193      275,   276,   277,    64,    84,    58,    44,    47
1194 };
1195 #endif
1196 
1197 #define YYPACT_NINF (-93)
1198 
1199 #define yypact_value_is_default(Yyn) \
1200   ((Yyn) == YYPACT_NINF)
1201 
1202 #define YYTABLE_NINF (-1)
1203 
1204 #define yytable_value_is_error(Yyn) \
1205   0
1206 
1207   /* YYPACTSTATE-NUM -- Index in YYTABLE of the portion describing
1208      STATE-NUM.  */
1209 static const yytype_int8 yypact[] =
1210 {
1211       38,    27,    77,   -93,    46,   -93,   -93,   -93,   -93,   -93,
1212      -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,
1213       62,   -93,    82,    -3,    66,     3,    74,    -4,    83,    84,
1214       75,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,
1215       71,   -93,    93,   -93,   -93,   -93,   -93,   -93,   -93,    78,
1216       72,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,    25,
1217      -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,
1218      -93,   -93,   -93,   -93,   -93,    21,    19,    79,    80,   -93,
1219      -93,   -93,   -93,   -93,    81,   -93,   -93,    85,    86,   -93,
1220      -93,   -93,   -93,   -93,    -6,    76,    17,   -93,   -93,   -93,
1221      -93,    87,    69,   -93,   -93,    88,    89,    -1,   -93,    18,
1222      -93,   -93,    69,    91
1223 };
1224 
1225   /* YYDEFACTSTATE-NUM -- Default reduction number in state STATE-NUM.
1226      Performed when YYTABLE does not specify something else to do.  Zero
1227      means the default is an error.  */
1228 static const yytype_int8 yydefact[] =
1229 {
1230        5,     0,     0,     2,     3,    85,    87,    84,    86,     4,
1231       82,    83,     1,    56,    59,    65,    68,    73,    62,    81,
1232       37,    35,    28,     0,     0,    30,     0,    88,     0,     0,
1233       31,     6,     7,    16,     8,    21,     9,    10,    12,    11,
1234       49,    13,    52,    74,    53,    14,    15,    38,    29,     0,
1235       45,    54,    57,    63,    66,    69,    60,    39,    36,    90,
1236       32,    75,    76,    78,    79,    80,    77,    55,    58,    64,
1237       67,    70,    61,    40,    18,    47,    90,     0,     0,    22,
1238       89,    71,    72,    33,     0,    51,    44,     0,     0,    34,
1239       43,    48,    50,    27,    25,    41,     0,    17,    46,    91,
1240       19,    90,     0,    23,    26,     0,     0,    25,    42,    25,
1241       20,    24,     0,    25
1242 };
1243 
1244   /* YYPGOTONTERM-NUM.  */
1245 static const yytype_int8 yypgoto[] =
1246 {
1247      -93,   -93,   -93,   -93,   -93,   -93,   -93,   -93,    20,   -68,
1248      -27,   -93,   -93,   -93,   -93,   -93,   -93,   -93,    60,   -93,
1249      -93,   -93,   -92,   -93,   -93,    43
1250 };
1251 
1252   /* YYDEFGOTONTERM-NUM.  */
1253 static const yytype_int8 yydefgoto[] =
1254 {
1255       -1,     2,     3,     4,    31,    32,    33,    34,    35,   103,
1256      104,    36,    37,    38,    39,    40,    41,    42,    43,    44,
1257        9,    10,    11,    45,    46,    93
1258 };
1259 
1260   /* YYTABLEYYPACT[STATE-NUM] -- What to do in state STATE-NUM.  If
1261      positive, shift that token.  If negative, reduce the rule whose
1262      number is the opposite.  If YYTABLE_NINF, syntax error.  */
1263 static const yytype_int8 yytable[] =
1264 {
1265       79,    67,    68,    69,    70,    71,    72,    58,    73,   100,
1266      107,    74,    75,   101,   110,    76,    49,    50,   101,   102,
1267      113,    77,    59,    78,    61,    62,    63,    64,    65,    66,
1268       61,    62,    63,    64,    65,    66,   101,   101,    92,   111,
1269       90,    91,   106,   112,    88,   111,     5,     6,     7,     8,
1270       88,    13,    14,    15,    16,    17,    18,    19,    20,    21,
1271       22,     1,    23,    24,    25,    26,    27,    28,    29,    79,
1272       30,    51,    52,    53,    54,    55,    56,    12,    57,    61,
1273       62,    63,    64,    65,    66,    60,    48,    80,    47,     6,
1274       83,     8,    81,    82,    26,    84,    85,    86,    87,    94,
1275       95,    96,    89,   105,    97,    98,    99,     0,   108,   109,
1276      101,     0,    88
1277 };
1278 
1279 static const yytype_int8 yycheck[] =
1280 {
1281       27,     5,     6,     7,     8,     9,    10,     4,    12,    15,
1282      102,    15,    16,    19,    15,    19,    19,    20,    19,    25,
1283      112,    25,    19,    27,     5,     6,     7,     8,     9,    10,
1284        5,     6,     7,     8,     9,    10,    19,    19,    19,   107,
1285       19,    20,    25,    25,    25,   113,    19,    20,    21,    22,
1286       25,     5,     6,     7,     8,     9,    10,    11,    12,    13,
1287       14,    23,    16,    17,    18,    19,    20,    21,    22,    96,
1288       24,     5,     6,     7,     8,     9,    10,     0,    12,     5,
1289        6,     7,     8,     9,    10,    25,     4,    27,    26,    20,
1290       30,    22,     9,     9,    19,    24,     3,    19,    26,    20,
1291       20,    20,    59,    27,    84,    20,    20,    -1,    20,    20,
1292       19,    -1,    25
1293 };
1294 
1295   /* YYSTOSSTATE-NUM -- The (internal number of the) accessing
1296      symbol of state STATE-NUM.  */
1297 static const yytype_int8 yystos[] =
1298 {
1299        0,    23,    29,    30,    31,    19,    20,    21,    22,    48,
1300       49,    50,     0,     5,     6,     7,     8,     9,    10,    11,
1301       12,    13,    14,    16,    17,    18,    19,    20,    21,    22,
1302       24,    32,    33,    34,    35,    36,    39,    40,    41,    42,
1303       43,    44,    45,    46,    47,    51,    52,    26,     4,    19,
1304       20,     5,     6,     7,     8,     9,    10,    12,     4,    19,
1305       46,     5,     6,     7,     8,     9,    10,     5,     6,     7,
1306        8,     9,    10,    12,    15,    16,    19,    25,    27,    38,
1307       46,     9,     9,    46,    24,     3,    19,    26,    25,    53,
1308       19,    20,    19,    53,    20,    20,    20,    36,    20,    20,
1309       15,    19,    25,    37,    38,    27,    25,    50,    20,    20,
1310       15,    37,    25,    50
1311 };
1312 
1313   /* YYR1YYN -- Symbol number of symbol that rule YYN derives.  */
1314 static const yytype_int8 yyr1[] =
1315 {
1316        0,    28,    29,    29,    30,    31,    31,    32,    32,    32,
1317       32,    32,    32,    32,    32,    32,    33,    34,    35,    35,
1318       35,    35,    36,    36,    36,    37,    37,    38,    39,    39,
1319       40,    40,    40,    40,    40,    40,    40,    41,    41,    41,
1320       41,    42,    42,    42,    42,    42,    42,    42,    42,    42,
1321       43,    44,    44,    44,    45,    45,    45,    45,    45,    45,
1322       45,    45,    45,    45,    45,    45,    45,    45,    45,    45,
1323       45,    45,    45,    45,    45,    46,    46,    46,    46,    46,
1324       46,    47,    48,    48,    49,    49,    50,    50,    51,    52,
1325       53,    53
1326 };
1327 
1328   /* YYR2YYN -- Number of symbols on the right hand side of rule YYN.  */
1329 static const yytype_int8 yyr2[] =
1330 {
1331        0,     2,     1,     1,     2,     0,     2,     1,     1,     1,
1332        1,     1,     1,     1,     1,     1,     1,     3,     2,     4,
1333        6,     1,     2,     4,     6,     0,     1,     2,     1,     2,
1334        1,     1,     2,     2,     3,     1,     2,     1,     2,     2,
1335        2,     3,     5,     3,     3,     2,     4,     2,     3,     1,
1336        3,     2,     1,     1,     2,     2,     1,     2,     2,     1,
1337        2,     2,     1,     2,     2,     1,     2,     2,     1,     2,
1338        2,     2,     2,     1,     1,     2,     2,     2,     2,     2,
1339        2,     1,     1,     1,     1,     1,     1,     1,     1,     2,
1340        0,     2
1341 };
1342 
1343 
1344 enum { YYENOMEM = -2 };
1345 
1346 #define yyerrok         (yyerrstatus = 0)
1347 #define yyclearin       (yychar = YYEMPTY)
1348 
1349 #define YYACCEPT        goto yyacceptlab
1350 #define YYABORT         goto yyabortlab
1351 #define YYERROR         goto yyerrorlab
1352 
1353 
1354 #define YYRECOVERING()  (!!yyerrstatus)
1355 
1356 #define YYBACKUP(Token, Value)                                    \
1357   do                                                              \
1358     if (yychar == YYEMPTY)                                        \
1359       {                                                           \
1360         yychar = (Token);                                         \
1361         yylval = (Value);                                         \
1362         YYPOPSTACK (yylen);                                       \
1363         yystate = *yyssp;                                         \
1364         goto yybackup;                                            \
1365       }                                                           \
1366     else                                                          \
1367       {                                                           \
1368         yyerror (pc, YY_("syntax error: cannot back up")); \
1369         YYERROR;                                                  \
1370       }                                                           \
1371   while (0)
1372 
1373 /* Backward compatibility with an undocumented macro.
1374    Use YYerror or YYUNDEF. */
1375 #define YYERRCODE YYUNDEF
1376 
1377 
1378 /* Enable debugging if requested.  */
1379 #if YYDEBUG
1380 
1381 # ifndef YYFPRINTF
1382 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1383 #  define YYFPRINTF fprintf
1384 # endif
1385 
1386 # define YYDPRINTF(Args)                        \
1387 do {                                            \
1388   if (yydebug)                                  \
1389     YYFPRINTF Args;                             \
1390 } while (0)
1391 
1392 /* This macro is provided for backward compatibility. */
1393 # ifndef YY_LOCATION_PRINT
1394 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1395 # endif
1396 
1397 
1398 # define YY_SYMBOL_PRINT(Title, Kind, Value, Location)                    \
1399 do {                                                                      \
1400   if (yydebug)                                                            \
1401     {                                                                     \
1402       YYFPRINTF (stderr, "%s ", Title);                                   \
1403       yy_symbol_print (stderr,                                            \
1404                   Kind, Value, pc); \
1405       YYFPRINTF (stderr, "\n");                                           \
1406     }                                                                     \
1407 } while (0)
1408 
1409 
1410 /*-----------------------------------.
1411 | Print this symbol's value on YYO.  |
1412 `-----------------------------------*/
1413 
1414 static void
yy_symbol_value_print(FILE * yyo,yysymbol_kind_t yykind,YYSTYPE const * const yyvaluep,parser_control * pc)1415 yy_symbol_value_print (FILE *yyo,
1416                        yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, parser_control *pc)
1417 {
1418   FILE *yyoutput = yyo;
1419   YYUSE (yyoutput);
1420   YYUSE (pc);
1421   if (!yyvaluep)
1422     return;
1423 # ifdef YYPRINT
1424   if (yykind < YYNTOKENS)
1425     YYPRINT (yyo, yytoknum[yykind], *yyvaluep);
1426 # endif
1427   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1428   YYUSE (yykind);
1429   YY_IGNORE_MAYBE_UNINITIALIZED_END
1430 }
1431 
1432 
1433 /*---------------------------.
1434 | Print this symbol on YYO.  |
1435 `---------------------------*/
1436 
1437 static void
yy_symbol_print(FILE * yyo,yysymbol_kind_t yykind,YYSTYPE const * const yyvaluep,parser_control * pc)1438 yy_symbol_print (FILE *yyo,
1439                  yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, parser_control *pc)
1440 {
1441   YYFPRINTF (yyo, "%s %s (",
1442              yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind));
1443 
1444   yy_symbol_value_print (yyo, yykind, yyvaluep, pc);
1445   YYFPRINTF (yyo, ")");
1446 }
1447 
1448 /*------------------------------------------------------------------.
1449 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1450 | TOP (included).                                                   |
1451 `------------------------------------------------------------------*/
1452 
1453 static void
yy_stack_print(yy_state_t * yybottom,yy_state_t * yytop)1454 yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop)
1455 {
1456   YYFPRINTF (stderr, "Stack now");
1457   for (; yybottom <= yytop; yybottom++)
1458     {
1459       int yybot = *yybottom;
1460       YYFPRINTF (stderr, " %d", yybot);
1461     }
1462   YYFPRINTF (stderr, "\n");
1463 }
1464 
1465 # define YY_STACK_PRINT(Bottom, Top)                            \
1466 do {                                                            \
1467   if (yydebug)                                                  \
1468     yy_stack_print ((Bottom), (Top));                           \
1469 } while (0)
1470 
1471 
1472 /*------------------------------------------------.
1473 | Report that the YYRULE is going to be reduced.  |
1474 `------------------------------------------------*/
1475 
1476 static void
yy_reduce_print(yy_state_t * yyssp,YYSTYPE * yyvsp,int yyrule,parser_control * pc)1477 yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp,
1478                  int yyrule, parser_control *pc)
1479 {
1480   int yylno = yyrline[yyrule];
1481   int yynrhs = yyr2[yyrule];
1482   int yyi;
1483   YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n",
1484              yyrule - 1, yylno);
1485   /* The symbols being reduced.  */
1486   for (yyi = 0; yyi < yynrhs; yyi++)
1487     {
1488       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
1489       yy_symbol_print (stderr,
1490                        YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]),
1491                        &yyvsp[(yyi + 1) - (yynrhs)], pc);
1492       YYFPRINTF (stderr, "\n");
1493     }
1494 }
1495 
1496 # define YY_REDUCE_PRINT(Rule)          \
1497 do {                                    \
1498   if (yydebug)                          \
1499     yy_reduce_print (yyssp, yyvsp, Rule, pc); \
1500 } while (0)
1501 
1502 /* Nonzero means print parse trace.  It is left uninitialized so that
1503    multiple parsers can coexist.  */
1504 int yydebug;
1505 #else /* !YYDEBUG */
1506 # define YYDPRINTF(Args) ((void) 0)
1507 # define YY_SYMBOL_PRINT(Title, Kind, Value, Location)
1508 # define YY_STACK_PRINT(Bottom, Top)
1509 # define YY_REDUCE_PRINT(Rule)
1510 #endif /* !YYDEBUG */
1511 
1512 
1513 /* YYINITDEPTH -- initial size of the parser's stacks.  */
1514 #ifndef YYINITDEPTH
1515 # define YYINITDEPTH 200
1516 #endif
1517 
1518 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1519    if the built-in stack extension method is used).
1520 
1521    Do not make this value too large; the results are undefined if
1522    YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1523    evaluated with infinite-precision integer arithmetic.  */
1524 
1525 #ifndef YYMAXDEPTH
1526 # define YYMAXDEPTH 10000
1527 #endif
1528 
1529 
1530 
1531 
1532 
1533 
1534 /*-----------------------------------------------.
1535 | Release the memory associated to this symbol.  |
1536 `-----------------------------------------------*/
1537 
1538 static void
yydestruct(const char * yymsg,yysymbol_kind_t yykind,YYSTYPE * yyvaluep,parser_control * pc)1539 yydestruct (const char *yymsg,
1540             yysymbol_kind_t yykind, YYSTYPE *yyvaluep, parser_control *pc)
1541 {
1542   YYUSE (yyvaluep);
1543   YYUSE (pc);
1544   if (!yymsg)
1545     yymsg = "Deleting";
1546   YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp);
1547 
1548   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1549   YYUSE (yykind);
1550   YY_IGNORE_MAYBE_UNINITIALIZED_END
1551 }
1552 
1553 
1554 
1555 
1556 
1557 
1558 /*----------.
1559 | yyparse.  |
1560 `----------*/
1561 
1562 int
yyparse(parser_control * pc)1563 yyparse (parser_control *pc)
1564 {
1565 /* The lookahead symbol.  */
1566 int yychar;
1567 
1568 
1569 /* The semantic value of the lookahead symbol.  */
1570 /* Default value used for initialization, for pacifying older GCCs
1571    or non-GCC compilers.  */
1572 YY_INITIAL_VALUE (static YYSTYPE yyval_default;)
1573 YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default);
1574 
1575     /* Number of syntax errors so far.  */
1576     int yynerrs;
1577 
1578     yy_state_fast_t yystate;
1579     /* Number of tokens to shift before error messages enabled.  */
1580     int yyerrstatus;
1581 
1582     /* The stacks and their tools:
1583        'yyss': related to states.
1584        'yyvs': related to semantic values.
1585 
1586        Refer to the stacks through separate pointers, to allow yyoverflow
1587        to reallocate them elsewhere.  */
1588 
1589     /* Their size.  */
1590     YYPTRDIFF_T yystacksize;
1591 
1592     /* The state stack.  */
1593     yy_state_t yyssa[YYINITDEPTH];
1594     yy_state_t *yyss;
1595     yy_state_t *yyssp;
1596 
1597     /* The semantic value stack.  */
1598     YYSTYPE yyvsa[YYINITDEPTH];
1599     YYSTYPE *yyvs;
1600     YYSTYPE *yyvsp;
1601 
1602   int yyn;
1603   /* The return value of yyparse.  */
1604   int yyresult;
1605   /* Lookahead token as an internal (translated) token number.  */
1606   yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY;
1607   /* The variables used to return semantic value and location from the
1608      action routines.  */
1609   YYSTYPE yyval;
1610 
1611 
1612 
1613 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
1614 
1615   /* The number of symbols on the RHS of the reduced rule.
1616      Keep to zero when no symbol should be popped.  */
1617   int yylen = 0;
1618 
1619   yynerrs = 0;
1620   yystate = 0;
1621   yyerrstatus = 0;
1622 
1623   yystacksize = YYINITDEPTH;
1624   yyssp = yyss = yyssa;
1625   yyvsp = yyvs = yyvsa;
1626 
1627 
1628   YYDPRINTF ((stderr, "Starting parse\n"));
1629 
1630   yychar = YYEMPTY; /* Cause a token to be read.  */
1631   goto yysetstate;
1632 
1633 
1634 /*------------------------------------------------------------.
1635 | yynewstate -- push a new state, which is found in yystate.  |
1636 `------------------------------------------------------------*/
1637 yynewstate:
1638   /* In all cases, when you get here, the value and location stacks
1639      have just been pushed.  So pushing a state here evens the stacks.  */
1640   yyssp++;
1641 
1642 
1643 /*--------------------------------------------------------------------.
1644 | yysetstate -- set current state (the top of the stack) to yystate.  |
1645 `--------------------------------------------------------------------*/
1646 yysetstate:
1647   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1648   YY_ASSERT (0 <= yystate && yystate < YYNSTATES);
1649   YY_IGNORE_USELESS_CAST_BEGIN
1650   *yyssp = YY_CAST (yy_state_t, yystate);
1651   YY_IGNORE_USELESS_CAST_END
1652   YY_STACK_PRINT (yyss, yyssp);
1653 
1654   if (yyss + yystacksize - 1 <= yyssp)
1655 #if !defined yyoverflow && !defined YYSTACK_RELOCATE
1656     goto yyexhaustedlab;
1657 #else
1658     {
1659       /* Get the current used size of the three stacks, in elements.  */
1660       YYPTRDIFF_T yysize = yyssp - yyss + 1;
1661 
1662 # if defined yyoverflow
1663       {
1664         /* Give user a chance to reallocate the stack.  Use copies of
1665            these so that the &'s don't force the real ones into
1666            memory.  */
1667         yy_state_t *yyss1 = yyss;
1668         YYSTYPE *yyvs1 = yyvs;
1669 
1670         /* Each stack pointer address is followed by the size of the
1671            data in use in that stack, in bytes.  This used to be a
1672            conditional around just the two extra args, but that might
1673            be undefined if yyoverflow is a macro.  */
1674         yyoverflow (YY_("memory exhausted"),
1675                     &yyss1, yysize * YYSIZEOF (*yyssp),
1676                     &yyvs1, yysize * YYSIZEOF (*yyvsp),
1677                     &yystacksize);
1678         yyss = yyss1;
1679         yyvs = yyvs1;
1680       }
1681 # else /* defined YYSTACK_RELOCATE */
1682       /* Extend the stack our own way.  */
1683       if (YYMAXDEPTH <= yystacksize)
1684         goto yyexhaustedlab;
1685       yystacksize *= 2;
1686       if (YYMAXDEPTH < yystacksize)
1687         yystacksize = YYMAXDEPTH;
1688 
1689       {
1690         yy_state_t *yyss1 = yyss;
1691         union yyalloc *yyptr =
1692           YY_CAST (union yyalloc *,
1693                    YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize))));
1694         if (! yyptr)
1695           goto yyexhaustedlab;
1696         YYSTACK_RELOCATE (yyss_alloc, yyss);
1697         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1698 #  undef YYSTACK_RELOCATE
1699         if (yyss1 != yyssa)
1700           YYSTACK_FREE (yyss1);
1701       }
1702 # endif
1703 
1704       yyssp = yyss + yysize - 1;
1705       yyvsp = yyvs + yysize - 1;
1706 
1707       YY_IGNORE_USELESS_CAST_BEGIN
1708       YYDPRINTF ((stderr, "Stack size increased to %ld\n",
1709                   YY_CAST (long, yystacksize)));
1710       YY_IGNORE_USELESS_CAST_END
1711 
1712       if (yyss + yystacksize - 1 <= yyssp)
1713         YYABORT;
1714     }
1715 #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
1716 
1717   if (yystate == YYFINAL)
1718     YYACCEPT;
1719 
1720   goto yybackup;
1721 
1722 
1723 /*-----------.
1724 | yybackup.  |
1725 `-----------*/
1726 yybackup:
1727   /* Do appropriate processing given the current state.  Read a
1728      lookahead token if we need one and don't already have one.  */
1729 
1730   /* First try to decide what to do without reference to lookahead token.  */
1731   yyn = yypact[yystate];
1732   if (yypact_value_is_default (yyn))
1733     goto yydefault;
1734 
1735   /* Not known => get a lookahead token if don't already have one.  */
1736 
1737   /* YYCHAR is either empty, or end-of-input, or a valid lookahead.  */
1738   if (yychar == YYEMPTY)
1739     {
1740       YYDPRINTF ((stderr, "Reading a token\n"));
1741       yychar = yylex (&yylval, pc);
1742     }
1743 
1744   if (yychar <= YYEOF)
1745     {
1746       yychar = YYEOF;
1747       yytoken = YYSYMBOL_YYEOF;
1748       YYDPRINTF ((stderr, "Now at end of input.\n"));
1749     }
1750   else if (yychar == YYerror)
1751     {
1752       /* The scanner already issued an error message, process directly
1753          to error recovery.  But do not keep the error token as
1754          lookahead, it is too special and may lead us to an endless
1755          loop in error recovery. */
1756       yychar = YYUNDEF;
1757       yytoken = YYSYMBOL_YYerror;
1758       goto yyerrlab1;
1759     }
1760   else
1761     {
1762       yytoken = YYTRANSLATE (yychar);
1763       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1764     }
1765 
1766   /* If the proper action on seeing token YYTOKEN is to reduce or to
1767      detect an error, take that action.  */
1768   yyn += yytoken;
1769   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1770     goto yydefault;
1771   yyn = yytable[yyn];
1772   if (yyn <= 0)
1773     {
1774       if (yytable_value_is_error (yyn))
1775         goto yyerrlab;
1776       yyn = -yyn;
1777       goto yyreduce;
1778     }
1779 
1780   /* Count tokens shifted since error; after three, turn off error
1781      status.  */
1782   if (yyerrstatus)
1783     yyerrstatus--;
1784 
1785   /* Shift the lookahead token.  */
1786   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1787   yystate = yyn;
1788   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1789   *++yyvsp = yylval;
1790   YY_IGNORE_MAYBE_UNINITIALIZED_END
1791 
1792   /* Discard the shifted token.  */
1793   yychar = YYEMPTY;
1794   goto yynewstate;
1795 
1796 
1797 /*-----------------------------------------------------------.
1798 | yydefault -- do the default action for the current state.  |
1799 `-----------------------------------------------------------*/
1800 yydefault:
1801   yyn = yydefact[yystate];
1802   if (yyn == 0)
1803     goto yyerrlab;
1804   goto yyreduce;
1805 
1806 
1807 /*-----------------------------.
1808 | yyreduce -- do a reduction.  |
1809 `-----------------------------*/
1810 yyreduce:
1811   /* yyn is the number of a rule to reduce with.  */
1812   yylen = yyr2[yyn];
1813 
1814   /* If YYLEN is nonzero, implement the default value of the action:
1815      '$$ = $1'.
1816 
1817      Otherwise, the following line sets YYVAL to garbage.
1818      This behavior is undocumented and Bison
1819      users should not rely upon it.  Assigning to YYVAL
1820      unconditionally makes the parser a bit smaller, and it avoids a
1821      GCC warning that YYVAL may be used uninitialized.  */
1822   yyval = yyvsp[1-yylen];
1823 
1824 
1825   YY_REDUCE_PRINT (yyn);
1826   switch (yyn)
1827     {
1828   case 4:
1829 #line 597 "parse-datetime.y"
1830       {
1831         pc->seconds = (yyvsp[0].timespec);
1832         pc->timespec_seen = true;
1833         debug_print_current_time (_("number of seconds"), pc);
1834       }
1835 #line 1836 "parse-datetime.c"
1836     break;
1837 
1838   case 7:
1839 #line 611 "parse-datetime.y"
1840       {
1841         pc->times_seen++; pc->dates_seen++;
1842         debug_print_current_time (_("datetime"), pc);
1843       }
1844 #line 1845 "parse-datetime.c"
1845     break;
1846 
1847   case 8:
1848 #line 616 "parse-datetime.y"
1849       {
1850         pc->times_seen++;
1851         debug_print_current_time (_("time"), pc);
1852       }
1853 #line 1854 "parse-datetime.c"
1854     break;
1855 
1856   case 9:
1857 #line 621 "parse-datetime.y"
1858       {
1859         pc->local_zones_seen++;
1860         debug_print_current_time (_("local_zone"), pc);
1861       }
1862 #line 1863 "parse-datetime.c"
1863     break;
1864 
1865   case 10:
1866 #line 626 "parse-datetime.y"
1867       {
1868         pc->zones_seen++;
1869         debug_print_current_time (_("zone"), pc);
1870       }
1871 #line 1872 "parse-datetime.c"
1872     break;
1873 
1874   case 11:
1875 #line 631 "parse-datetime.y"
1876       {
1877         pc->dates_seen++;
1878         debug_print_current_time (_("date"), pc);
1879       }
1880 #line 1881 "parse-datetime.c"
1881     break;
1882 
1883   case 12:
1884 #line 636 "parse-datetime.y"
1885       {
1886         pc->days_seen++;
1887         debug_print_current_time (_("day"), pc);
1888       }
1889 #line 1890 "parse-datetime.c"
1890     break;
1891 
1892   case 13:
1893 #line 641 "parse-datetime.y"
1894       {
1895         debug_print_relative_time (_("relative"), pc);
1896       }
1897 #line 1898 "parse-datetime.c"
1898     break;
1899 
1900   case 14:
1901 #line 645 "parse-datetime.y"
1902       {
1903         debug_print_current_time (_("number"), pc);
1904       }
1905 #line 1906 "parse-datetime.c"
1906     break;
1907 
1908   case 15:
1909 #line 649 "parse-datetime.y"
1910       {
1911         debug_print_relative_time (_("hybrid"), pc);
1912       }
1913 #line 1914 "parse-datetime.c"
1914     break;
1915 
1916   case 18:
1917 #line 664 "parse-datetime.y"
1918       {
1919         set_hhmmss (pc, (yyvsp[-1].textintval).value, 0, 0, 0);
1920         pc->meridian = (yyvsp[0].intval);
1921       }
1922 #line 1923 "parse-datetime.c"
1923     break;
1924 
1925   case 19:
1926 #line 669 "parse-datetime.y"
1927       {
1928         set_hhmmss (pc, (yyvsp[-3].textintval).value, (yyvsp[-1].textintval).value, 0, 0);
1929         pc->meridian = (yyvsp[0].intval);
1930       }
1931 #line 1932 "parse-datetime.c"
1932     break;
1933 
1934   case 20:
1935 #line 674 "parse-datetime.y"
1936       {
1937         set_hhmmss (pc, (yyvsp[-5].textintval).value, (yyvsp[-3].textintval).value, (yyvsp[-1].timespec).tv_sec, (yyvsp[-1].timespec).tv_nsec);
1938         pc->meridian = (yyvsp[0].intval);
1939       }
1940 #line 1941 "parse-datetime.c"
1941     break;
1942 
1943   case 22:
1944 #line 683 "parse-datetime.y"
1945       {
1946         set_hhmmss (pc, (yyvsp[-1].textintval).value, 0, 0, 0);
1947         pc->meridian = MER24;
1948       }
1949 #line 1950 "parse-datetime.c"
1950     break;
1951 
1952   case 23:
1953 #line 688 "parse-datetime.y"
1954       {
1955         set_hhmmss (pc, (yyvsp[-3].textintval).value, (yyvsp[-1].textintval).value, 0, 0);
1956         pc->meridian = MER24;
1957       }
1958 #line 1959 "parse-datetime.c"
1959     break;
1960 
1961   case 24:
1962 #line 693 "parse-datetime.y"
1963       {
1964         set_hhmmss (pc, (yyvsp[-5].textintval).value, (yyvsp[-3].textintval).value, (yyvsp[-1].timespec).tv_sec, (yyvsp[-1].timespec).tv_nsec);
1965         pc->meridian = MER24;
1966       }
1967 #line 1968 "parse-datetime.c"
1968     break;
1969 
1970   case 27:
1971 #line 706 "parse-datetime.y"
1972       {
1973         pc->zones_seen++;
1974         if (! time_zone_hhmm (pc, (yyvsp[-1].textintval), (yyvsp[0].intval))) YYABORT;
1975       }
1976 #line 1977 "parse-datetime.c"
1977     break;
1978 
1979   case 28:
1980 #line 731 "parse-datetime.y"
1981       { pc->local_isdst = (yyvsp[0].intval); }
1982 #line 1983 "parse-datetime.c"
1983     break;
1984 
1985   case 29:
1986 #line 733 "parse-datetime.y"
1987       {
1988         pc->local_isdst = 1;
1989         pc->dsts_seen++;
1990       }
1991 #line 1992 "parse-datetime.c"
1992     break;
1993 
1994   case 30:
1995 #line 743 "parse-datetime.y"
1996       { pc->time_zone = (yyvsp[0].intval); }
1997 #line 1998 "parse-datetime.c"
1998     break;
1999 
2000   case 31:
2001 #line 745 "parse-datetime.y"
2002       { pc->time_zone = -HOUR (7); }
2003 #line 2004 "parse-datetime.c"
2004     break;
2005 
2006   case 32:
2007 #line 747 "parse-datetime.y"
2008       { pc->time_zone = (yyvsp[-1].intval);
2009         if (! apply_relative_time (pc, (yyvsp[0].rel), 1)) YYABORT;
2010         debug_print_relative_time (_("relative"), pc);
2011       }
2012 #line 2013 "parse-datetime.c"
2013     break;
2014 
2015   case 33:
2016 #line 752 "parse-datetime.y"
2017       { pc->time_zone = -HOUR (7);
2018         if (! apply_relative_time (pc, (yyvsp[0].rel), 1)) YYABORT;
2019         debug_print_relative_time (_("relative"), pc);
2020       }
2021 #line 2022 "parse-datetime.c"
2022     break;
2023 
2024   case 34:
2025 #line 757 "parse-datetime.y"
2026       { if (! time_zone_hhmm (pc, (yyvsp[-1].textintval), (yyvsp[0].intval))) YYABORT;
2027         if (INT_ADD_WRAPV (pc->time_zone, (yyvsp[-2].intval), &pc->time_zone)) YYABORT; }
2028 #line 2029 "parse-datetime.c"
2029     break;
2030 
2031   case 35:
2032 #line 760 "parse-datetime.y"
2033       { pc->time_zone = (yyvsp[0].intval) + 60 * 60; }
2034 #line 2035 "parse-datetime.c"
2035     break;
2036 
2037   case 36:
2038 #line 762 "parse-datetime.y"
2039       { pc->time_zone = (yyvsp[-1].intval) + 60 * 60; }
2040 #line 2041 "parse-datetime.c"
2041     break;
2042 
2043   case 37:
2044 #line 767 "parse-datetime.y"
2045       {
2046         pc->day_ordinal = 0;
2047         pc->day_number = (yyvsp[0].intval);
2048       }
2049 #line 2050 "parse-datetime.c"
2050     break;
2051 
2052   case 38:
2053 #line 772 "parse-datetime.y"
2054       {
2055         pc->day_ordinal = 0;
2056         pc->day_number = (yyvsp[-1].intval);
2057       }
2058 #line 2059 "parse-datetime.c"
2059     break;
2060 
2061   case 39:
2062 #line 777 "parse-datetime.y"
2063       {
2064         pc->day_ordinal = (yyvsp[-1].intval);
2065         pc->day_number = (yyvsp[0].intval);
2066         pc->debug_ordinal_day_seen = true;
2067       }
2068 #line 2069 "parse-datetime.c"
2069     break;
2070 
2071   case 40:
2072 #line 783 "parse-datetime.y"
2073       {
2074         pc->day_ordinal = (yyvsp[-1].textintval).value;
2075         pc->day_number = (yyvsp[0].intval);
2076         pc->debug_ordinal_day_seen = true;
2077       }
2078 #line 2079 "parse-datetime.c"
2079     break;
2080 
2081   case 41:
2082 #line 792 "parse-datetime.y"
2083       {
2084         pc->month = (yyvsp[-2].textintval).value;
2085         pc->day = (yyvsp[0].textintval).value;
2086       }
2087 #line 2088 "parse-datetime.c"
2088     break;
2089 
2090   case 42:
2091 #line 797 "parse-datetime.y"
2092       {
2093         /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
2094            otherwise as MM/DD/YY.
2095            The goal in recognizing YYYY/MM/DD is solely to support legacy
2096            machine-generated dates like those in an RCS log listing.  If
2097            you want portability, use the ISO 8601 format.  */
2098         if (4 <= (yyvsp[-4].textintval).digits)
2099           {
2100             if (pc->parse_datetime_debug)
2101               {
2102                 intmax_t digits = (yyvsp[-4].textintval).digits;
2103                 dbg_printf (_("warning: value %"PRIdMAX" has %"PRIdMAX" digits. "
2104                               "Assuming YYYY/MM/DD\n"),
2105                             (yyvsp[-4].textintval).value, digits);
2106               }
2107 
2108             pc->year = (yyvsp[-4].textintval);
2109             pc->month = (yyvsp[-2].textintval).value;
2110             pc->day = (yyvsp[0].textintval).value;
2111           }
2112         else
2113           {
2114             if (pc->parse_datetime_debug)
2115               dbg_printf (_("warning: value %"PRIdMAX" has less than 4 digits. "
2116                             "Assuming MM/DD/YY[YY]\n"),
2117                           (yyvsp[-4].textintval).value);
2118 
2119             pc->month = (yyvsp[-4].textintval).value;
2120             pc->day = (yyvsp[-2].textintval).value;
2121             pc->year = (yyvsp[0].textintval);
2122           }
2123       }
2124 #line 2125 "parse-datetime.c"
2125     break;
2126 
2127   case 43:
2128 #line 830 "parse-datetime.y"
2129       {
2130         /* E.g., 17-JUN-1992.  */
2131         pc->day = (yyvsp[-2].textintval).value;
2132         pc->month = (yyvsp[-1].intval);
2133         if (INT_SUBTRACT_WRAPV (0, (yyvsp[0].textintval).value, &pc->year.value)) YYABORT;
2134         pc->year.digits = (yyvsp[0].textintval).digits;
2135       }
2136 #line 2137 "parse-datetime.c"
2137     break;
2138 
2139   case 44:
2140 #line 838 "parse-datetime.y"
2141       {
2142         /* E.g., JUN-17-1992.  */
2143         pc->month = (yyvsp[-2].intval);
2144         if (INT_SUBTRACT_WRAPV (0, (yyvsp[-1].textintval).value, &pc->day)) YYABORT;
2145         if (INT_SUBTRACT_WRAPV (0, (yyvsp[0].textintval).value, &pc->year.value)) YYABORT;
2146         pc->year.digits = (yyvsp[0].textintval).digits;
2147       }
2148 #line 2149 "parse-datetime.c"
2149     break;
2150 
2151   case 45:
2152 #line 846 "parse-datetime.y"
2153       {
2154         pc->month = (yyvsp[-1].intval);
2155         pc->day = (yyvsp[0].textintval).value;
2156       }
2157 #line 2158 "parse-datetime.c"
2158     break;
2159 
2160   case 46:
2161 #line 851 "parse-datetime.y"
2162       {
2163         pc->month = (yyvsp[-3].intval);
2164         pc->day = (yyvsp[-2].textintval).value;
2165         pc->year = (yyvsp[0].textintval);
2166       }
2167 #line 2168 "parse-datetime.c"
2168     break;
2169 
2170   case 47:
2171 #line 857 "parse-datetime.y"
2172       {
2173         pc->day = (yyvsp[-1].textintval).value;
2174         pc->month = (yyvsp[0].intval);
2175       }
2176 #line 2177 "parse-datetime.c"
2177     break;
2178 
2179   case 48:
2180 #line 862 "parse-datetime.y"
2181       {
2182         pc->day = (yyvsp[-2].textintval).value;
2183         pc->month = (yyvsp[-1].intval);
2184         pc->year = (yyvsp[0].textintval);
2185       }
2186 #line 2187 "parse-datetime.c"
2187     break;
2188 
2189   case 50:
2190 #line 872 "parse-datetime.y"
2191       {
2192         /* ISO 8601 format.  YYYY-MM-DD.  */
2193         pc->year = (yyvsp[-2].textintval);
2194         if (INT_SUBTRACT_WRAPV (0, (yyvsp[-1].textintval).value, &pc->month)) YYABORT;
2195         if (INT_SUBTRACT_WRAPV (0, (yyvsp[0].textintval).value, &pc->day)) YYABORT;
2196       }
2197 #line 2198 "parse-datetime.c"
2198     break;
2199 
2200   case 51:
2201 #line 882 "parse-datetime.y"
2202       { if (! apply_relative_time (pc, (yyvsp[-1].rel), (yyvsp[0].intval))) YYABORT; }
2203 #line 2204 "parse-datetime.c"
2204     break;
2205 
2206   case 52:
2207 #line 884 "parse-datetime.y"
2208       { if (! apply_relative_time (pc, (yyvsp[0].rel), 1)) YYABORT; }
2209 #line 2210 "parse-datetime.c"
2210     break;
2211 
2212   case 53:
2213 #line 886 "parse-datetime.y"
2214       { if (! apply_relative_time (pc, (yyvsp[0].rel), 1)) YYABORT; }
2215 #line 2216 "parse-datetime.c"
2216     break;
2217 
2218   case 54:
2219 #line 891 "parse-datetime.y"
2220       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[-1].intval); }
2221 #line 2222 "parse-datetime.c"
2222     break;
2223 
2224   case 55:
2225 #line 893 "parse-datetime.y"
2226       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[-1].textintval).value; }
2227 #line 2228 "parse-datetime.c"
2228     break;
2229 
2230   case 56:
2231 #line 895 "parse-datetime.y"
2232       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = 1; }
2233 #line 2234 "parse-datetime.c"
2234     break;
2235 
2236   case 57:
2237 #line 897 "parse-datetime.y"
2238       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[-1].intval); }
2239 #line 2240 "parse-datetime.c"
2240     break;
2241 
2242   case 58:
2243 #line 899 "parse-datetime.y"
2244       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[-1].textintval).value; }
2245 #line 2246 "parse-datetime.c"
2246     break;
2247 
2248   case 59:
2249 #line 901 "parse-datetime.y"
2250       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = 1; }
2251 #line 2252 "parse-datetime.c"
2252     break;
2253 
2254   case 60:
2255 #line 903 "parse-datetime.y"
2256       { (yyval.rel) = RELATIVE_TIME_0;
2257         if (INT_MULTIPLY_WRAPV ((yyvsp[-1].intval), (yyvsp[0].intval), &(yyval.rel).day)) YYABORT; }
2258 #line 2259 "parse-datetime.c"
2259     break;
2260 
2261   case 61:
2262 #line 906 "parse-datetime.y"
2263       { (yyval.rel) = RELATIVE_TIME_0;
2264         if (INT_MULTIPLY_WRAPV ((yyvsp[-1].textintval).value, (yyvsp[0].intval), &(yyval.rel).day)) YYABORT; }
2265 #line 2266 "parse-datetime.c"
2266     break;
2267 
2268   case 62:
2269 #line 909 "parse-datetime.y"
2270       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[0].intval); }
2271 #line 2272 "parse-datetime.c"
2272     break;
2273 
2274   case 63:
2275 #line 911 "parse-datetime.y"
2276       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[-1].intval); }
2277 #line 2278 "parse-datetime.c"
2278     break;
2279 
2280   case 64:
2281 #line 913 "parse-datetime.y"
2282       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[-1].textintval).value; }
2283 #line 2284 "parse-datetime.c"
2284     break;
2285 
2286   case 65:
2287 #line 915 "parse-datetime.y"
2288       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = 1; }
2289 #line 2290 "parse-datetime.c"
2290     break;
2291 
2292   case 66:
2293 #line 917 "parse-datetime.y"
2294       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[-1].intval); }
2295 #line 2296 "parse-datetime.c"
2296     break;
2297 
2298   case 67:
2299 #line 919 "parse-datetime.y"
2300       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[-1].textintval).value; }
2301 #line 2302 "parse-datetime.c"
2302     break;
2303 
2304   case 68:
2305 #line 921 "parse-datetime.y"
2306       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = 1; }
2307 #line 2308 "parse-datetime.c"
2308     break;
2309 
2310   case 69:
2311 #line 923 "parse-datetime.y"
2312       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[-1].intval); }
2313 #line 2314 "parse-datetime.c"
2314     break;
2315 
2316   case 70:
2317 #line 925 "parse-datetime.y"
2318       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[-1].textintval).value; }
2319 #line 2320 "parse-datetime.c"
2320     break;
2321 
2322   case 71:
2323 #line 927 "parse-datetime.y"
2324       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[-1].timespec).tv_sec; (yyval.rel).ns = (yyvsp[-1].timespec).tv_nsec; }
2325 #line 2326 "parse-datetime.c"
2326     break;
2327 
2328   case 72:
2329 #line 929 "parse-datetime.y"
2330       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[-1].timespec).tv_sec; (yyval.rel).ns = (yyvsp[-1].timespec).tv_nsec; }
2331 #line 2332 "parse-datetime.c"
2332     break;
2333 
2334   case 73:
2335 #line 931 "parse-datetime.y"
2336       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = 1; }
2337 #line 2338 "parse-datetime.c"
2338     break;
2339 
2340   case 75:
2341 #line 937 "parse-datetime.y"
2342       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).year = (yyvsp[-1].textintval).value; }
2343 #line 2344 "parse-datetime.c"
2344     break;
2345 
2346   case 76:
2347 #line 939 "parse-datetime.y"
2348       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).month = (yyvsp[-1].textintval).value; }
2349 #line 2350 "parse-datetime.c"
2350     break;
2351 
2352   case 77:
2353 #line 941 "parse-datetime.y"
2354       { (yyval.rel) = RELATIVE_TIME_0;
2355         if (INT_MULTIPLY_WRAPV ((yyvsp[-1].textintval).value, (yyvsp[0].intval), &(yyval.rel).day)) YYABORT; }
2356 #line 2357 "parse-datetime.c"
2357     break;
2358 
2359   case 78:
2360 #line 944 "parse-datetime.y"
2361       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).hour = (yyvsp[-1].textintval).value; }
2362 #line 2363 "parse-datetime.c"
2363     break;
2364 
2365   case 79:
2366 #line 946 "parse-datetime.y"
2367       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).minutes = (yyvsp[-1].textintval).value; }
2368 #line 2369 "parse-datetime.c"
2369     break;
2370 
2371   case 80:
2372 #line 948 "parse-datetime.y"
2373       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[-1].textintval).value; }
2374 #line 2375 "parse-datetime.c"
2375     break;
2376 
2377   case 81:
2378 #line 953 "parse-datetime.y"
2379       { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).day = (yyvsp[0].intval); }
2380 #line 2381 "parse-datetime.c"
2381     break;
2382 
2383   case 85:
2384 #line 961 "parse-datetime.y"
2385       { if (time_overflow ((yyvsp[0].textintval).value)) YYABORT;
2386         (yyval.timespec).tv_sec = (yyvsp[0].textintval).value; (yyval.timespec).tv_nsec = 0; }
2387 #line 2388 "parse-datetime.c"
2388     break;
2389 
2390   case 87:
2391 #line 968 "parse-datetime.y"
2392       { if (time_overflow ((yyvsp[0].textintval).value)) YYABORT;
2393         (yyval.timespec).tv_sec = (yyvsp[0].textintval).value; (yyval.timespec).tv_nsec = 0; }
2394 #line 2395 "parse-datetime.c"
2395     break;
2396 
2397   case 88:
2398 #line 974 "parse-datetime.y"
2399       { digits_to_date_time (pc, (yyvsp[0].textintval)); }
2400 #line 2401 "parse-datetime.c"
2401     break;
2402 
2403   case 89:
2404 #line 979 "parse-datetime.y"
2405       {
2406         /* Hybrid all-digit and relative offset, so that we accept e.g.,
2407            "YYYYMMDD +N days" as well as "YYYYMMDD N days".  */
2408         digits_to_date_time (pc, (yyvsp[-1].textintval));
2409         if (! apply_relative_time (pc, (yyvsp[0].rel), 1)) YYABORT;
2410       }
2411 #line 2412 "parse-datetime.c"
2412     break;
2413 
2414   case 90:
2415 #line 989 "parse-datetime.y"
2416       { (yyval.intval) = -1; }
2417 #line 2418 "parse-datetime.c"
2418     break;
2419 
2420   case 91:
2421 #line 991 "parse-datetime.y"
2422       { (yyval.intval) = (yyvsp[0].textintval).value; }
2423 #line 2424 "parse-datetime.c"
2424     break;
2425 
2426 
2427 #line 2428 "parse-datetime.c"
2428 
2429       default: break;
2430     }
2431   /* User semantic actions sometimes alter yychar, and that requires
2432      that yytoken be updated with the new translation.  We take the
2433      approach of translating immediately before every use of yytoken.
2434      One alternative is translating here after every semantic action,
2435      but that translation would be missed if the semantic action invokes
2436      YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
2437      if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
2438      incorrect destructor might then be invoked immediately.  In the
2439      case of YYERROR or YYBACKUP, subsequent parser actions might lead
2440      to an incorrect destructor call or verbose syntax error message
2441      before the lookahead is translated.  */
2442   YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc);
2443 
2444   YYPOPSTACK (yylen);
2445   yylen = 0;
2446 
2447   *++yyvsp = yyval;
2448 
2449   /* Now 'shift' the result of the reduction.  Determine what state
2450      that goes to, based on the state we popped back to and the rule
2451      number reduced by.  */
2452   {
2453     const int yylhs = yyr1[yyn] - YYNTOKENS;
2454     const int yyi = yypgoto[yylhs] + *yyssp;
2455     yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
2456                ? yytable[yyi]
2457                : yydefgoto[yylhs]);
2458   }
2459 
2460   goto yynewstate;
2461 
2462 
2463 /*--------------------------------------.
2464 | yyerrlab -- here on detecting error.  |
2465 `--------------------------------------*/
2466 yyerrlab:
2467   /* Make sure we have latest lookahead translation.  See comments at
2468      user semantic actions for why this is necessary.  */
2469   yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar);
2470   /* If not already recovering from an error, report this error.  */
2471   if (!yyerrstatus)
2472     {
2473       ++yynerrs;
2474       yyerror (pc, YY_("syntax error"));
2475     }
2476 
2477   if (yyerrstatus == 3)
2478     {
2479       /* If just tried and failed to reuse lookahead token after an
2480          error, discard it.  */
2481 
2482       if (yychar <= YYEOF)
2483         {
2484           /* Return failure if at end of input.  */
2485           if (yychar == YYEOF)
2486             YYABORT;
2487         }
2488       else
2489         {
2490           yydestruct ("Error: discarding",
2491                       yytoken, &yylval, pc);
2492           yychar = YYEMPTY;
2493         }
2494     }
2495 
2496   /* Else will try to reuse lookahead token after shifting the error
2497      token.  */
2498   goto yyerrlab1;
2499 
2500 
2501 /*---------------------------------------------------.
2502 | yyerrorlab -- error raised explicitly by YYERROR.  |
2503 `---------------------------------------------------*/
2504 yyerrorlab:
2505   /* Pacify compilers when the user code never invokes YYERROR and the
2506      label yyerrorlab therefore never appears in user code.  */
2507   if (0)
2508     YYERROR;
2509 
2510   /* Do not reclaim the symbols of the rule whose action triggered
2511      this YYERROR.  */
2512   YYPOPSTACK (yylen);
2513   yylen = 0;
2514   YY_STACK_PRINT (yyss, yyssp);
2515   yystate = *yyssp;
2516   goto yyerrlab1;
2517 
2518 
2519 /*-------------------------------------------------------------.
2520 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
2521 `-------------------------------------------------------------*/
2522 yyerrlab1:
2523   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
2524 
2525   /* Pop stack until we find a state that shifts the error token.  */
2526   for (;;)
2527     {
2528       yyn = yypact[yystate];
2529       if (!yypact_value_is_default (yyn))
2530         {
2531           yyn += YYSYMBOL_YYerror;
2532           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror)
2533             {
2534               yyn = yytable[yyn];
2535               if (0 < yyn)
2536                 break;
2537             }
2538         }
2539 
2540       /* Pop the current state because it cannot handle the error token.  */
2541       if (yyssp == yyss)
2542         YYABORT;
2543 
2544 
2545       yydestruct ("Error: popping",
2546                   YY_ACCESSING_SYMBOL (yystate), yyvsp, pc);
2547       YYPOPSTACK (1);
2548       yystate = *yyssp;
2549       YY_STACK_PRINT (yyss, yyssp);
2550     }
2551 
2552   YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
2553   *++yyvsp = yylval;
2554   YY_IGNORE_MAYBE_UNINITIALIZED_END
2555 
2556 
2557   /* Shift the error token.  */
2558   YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp);
2559 
2560   yystate = yyn;
2561   goto yynewstate;
2562 
2563 
2564 /*-------------------------------------.
2565 | yyacceptlab -- YYACCEPT comes here.  |
2566 `-------------------------------------*/
2567 yyacceptlab:
2568   yyresult = 0;
2569   goto yyreturn;
2570 
2571 
2572 /*-----------------------------------.
2573 | yyabortlab -- YYABORT comes here.  |
2574 `-----------------------------------*/
2575 yyabortlab:
2576   yyresult = 1;
2577   goto yyreturn;
2578 
2579 
2580 #if !defined yyoverflow
2581 /*-------------------------------------------------.
2582 | yyexhaustedlab -- memory exhaustion comes here.  |
2583 `-------------------------------------------------*/
2584 yyexhaustedlab:
2585   yyerror (pc, YY_("memory exhausted"));
2586   yyresult = 2;
2587   /* Fall through.  */
2588 #endif
2589 
2590 
2591 /*-----------------------------------------------------.
2592 | yyreturn -- parsing is finished, return the result.  |
2593 `-----------------------------------------------------*/
2594 yyreturn:
2595   if (yychar != YYEMPTY)
2596     {
2597       /* Make sure we have latest lookahead translation.  See comments at
2598          user semantic actions for why this is necessary.  */
2599       yytoken = YYTRANSLATE (yychar);
2600       yydestruct ("Cleanup: discarding lookahead",
2601                   yytoken, &yylval, pc);
2602     }
2603   /* Do not reclaim the symbols of the rule whose action triggered
2604      this YYABORT or YYACCEPT.  */
2605   YYPOPSTACK (yylen);
2606   YY_STACK_PRINT (yyss, yyssp);
2607   while (yyssp != yyss)
2608     {
2609       yydestruct ("Cleanup: popping",
2610                   YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, pc);
2611       YYPOPSTACK (1);
2612     }
2613 #ifndef yyoverflow
2614   if (yyss != yyssa)
2615     YYSTACK_FREE (yyss);
2616 #endif
2617 
2618   return yyresult;
2619 }
2620 
2621 #line 994 "parse-datetime.y"
2622 
2623 
2624 static table const meridian_table[] =
2625 {
2626   { "AM",   tMERIDIAN, MERam },
2627   { "A.M.", tMERIDIAN, MERam },
2628   { "PM",   tMERIDIAN, MERpm },
2629   { "P.M.", tMERIDIAN, MERpm },
2630   { NULL, 0, 0 }
2631 };
2632 
2633 static table const dst_table[] =
2634 {
2635   { "DST", tDST, 0 }
2636 };
2637 
2638 static table const month_and_day_table[] =
2639 {
2640   { "JANUARY",  tMONTH,  1 },
2641   { "FEBRUARY", tMONTH,  2 },
2642   { "MARCH",    tMONTH,  3 },
2643   { "APRIL",    tMONTH,  4 },
2644   { "MAY",      tMONTH,  5 },
2645   { "JUNE",     tMONTH,  6 },
2646   { "JULY",     tMONTH,  7 },
2647   { "AUGUST",   tMONTH,  8 },
2648   { "SEPTEMBER",tMONTH,  9 },
2649   { "SEPT",     tMONTH,  9 },
2650   { "OCTOBER",  tMONTH, 10 },
2651   { "NOVEMBER", tMONTH, 11 },
2652   { "DECEMBER", tMONTH, 12 },
2653   { "SUNDAY",   tDAY,    0 },
2654   { "MONDAY",   tDAY,    1 },
2655   { "TUESDAY",  tDAY,    2 },
2656   { "TUES",     tDAY,    2 },
2657   { "WEDNESDAY",tDAY,    3 },
2658   { "WEDNES",   tDAY,    3 },
2659   { "THURSDAY", tDAY,    4 },
2660   { "THUR",     tDAY,    4 },
2661   { "THURS",    tDAY,    4 },
2662   { "FRIDAY",   tDAY,    5 },
2663   { "SATURDAY", tDAY,    6 },
2664   { NULL, 0, 0 }
2665 };
2666 
2667 static table const time_units_table[] =
2668 {
2669   { "YEAR",     tYEAR_UNIT,      1 },
2670   { "MONTH",    tMONTH_UNIT,     1 },
2671   { "FORTNIGHT",tDAY_UNIT,      14 },
2672   { "WEEK",     tDAY_UNIT,       7 },
2673   { "DAY",      tDAY_UNIT,       1 },
2674   { "HOUR",     tHOUR_UNIT,      1 },
2675   { "MINUTE",   tMINUTE_UNIT,    1 },
2676   { "MIN",      tMINUTE_UNIT,    1 },
2677   { "SECOND",   tSEC_UNIT,       1 },
2678   { "SEC",      tSEC_UNIT,       1 },
2679   { NULL, 0, 0 }
2680 };
2681 
2682 /* Assorted relative-time words.  */
2683 static table const relative_time_table[] =
2684 {
2685   { "TOMORROW", tDAY_SHIFT,      1 },
2686   { "YESTERDAY",tDAY_SHIFT,     -1 },
2687   { "TODAY",    tDAY_SHIFT,      0 },
2688   { "NOW",      tDAY_SHIFT,      0 },
2689   { "LAST",     tORDINAL,       -1 },
2690   { "THIS",     tORDINAL,        0 },
2691   { "NEXT",     tORDINAL,        1 },
2692   { "FIRST",    tORDINAL,        1 },
2693 /*{ "SECOND",   tORDINAL,        2 }, */
2694   { "THIRD",    tORDINAL,        3 },
2695   { "FOURTH",   tORDINAL,        4 },
2696   { "FIFTH",    tORDINAL,        5 },
2697   { "SIXTH",    tORDINAL,        6 },
2698   { "SEVENTH",  tORDINAL,        7 },
2699   { "EIGHTH",   tORDINAL,        8 },
2700   { "NINTH",    tORDINAL,        9 },
2701   { "TENTH",    tORDINAL,       10 },
2702   { "ELEVENTH", tORDINAL,       11 },
2703   { "TWELFTH",  tORDINAL,       12 },
2704   { "AGO",      tAGO,           -1 },
2705   { "HENCE",    tAGO,            1 },
2706   { NULL, 0, 0 }
2707 };
2708 
2709 /* The universal time zone table.  These labels can be used even for
2710    timestamps that would not otherwise be valid, e.g., GMT timestamps
2711    oin London during summer.  */
2712 static table const universal_time_zone_table[] =
2713 {
2714   { "GMT",      tZONE,     HOUR ( 0) }, /* Greenwich Mean */
2715   { "UT",       tZONE,     HOUR ( 0) }, /* Universal (Coordinated) */
2716   { "UTC",      tZONE,     HOUR ( 0) },
2717   { NULL, 0, 0 }
2718 };
2719 
2720 /* The time zone table.  This table is necessarily incomplete, as time
2721    zone abbreviations are ambiguous; e.g., Australians interpret "EST"
2722    as Eastern time in Australia, not as US Eastern Standard Time.
2723    You cannot rely on parse_datetime to handle arbitrary time zone
2724    abbreviations; use numeric abbreviations like "-0500" instead.  */
2725 static table const time_zone_table[] =
2726 {
2727   { "WET",      tZONE,     HOUR ( 0) }, /* Western European */
2728   { "WEST",     tDAYZONE,  HOUR ( 0) }, /* Western European Summer */
2729   { "BST",      tDAYZONE,  HOUR ( 0) }, /* British Summer */
2730   { "ART",      tZONE,    -HOUR ( 3) }, /* Argentina */
2731   { "BRT",      tZONE,    -HOUR ( 3) }, /* Brazil */
2732   { "BRST",     tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
2733   { "NST",      tZONE,   -(HOUR ( 3) + 30 * 60) }, /* Newfoundland Standard */
2734   { "NDT",      tDAYZONE,-(HOUR ( 3) + 30 * 60) }, /* Newfoundland Daylight */
2735   { "AST",      tZONE,    -HOUR ( 4) }, /* Atlantic Standard */
2736   { "ADT",      tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
2737   { "CLT",      tZONE,    -HOUR ( 4) }, /* Chile */
2738   { "CLST",     tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
2739   { "EST",      tZONE,    -HOUR ( 5) }, /* Eastern Standard */
2740   { "EDT",      tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
2741   { "CST",      tZONE,    -HOUR ( 6) }, /* Central Standard */
2742   { "CDT",      tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
2743   { "MST",      tZONE,    -HOUR ( 7) }, /* Mountain Standard */
2744   { "MDT",      tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
2745   { "PST",      tZONE,    -HOUR ( 8) }, /* Pacific Standard */
2746   { "PDT",      tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
2747   { "AKST",     tZONE,    -HOUR ( 9) }, /* Alaska Standard */
2748   { "AKDT",     tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
2749   { "HST",      tZONE,    -HOUR (10) }, /* Hawaii Standard */
2750   { "HAST",     tZONE,    -HOUR (10) }, /* Hawaii-Aleutian Standard */
2751   { "HADT",     tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
2752   { "SST",      tZONE,    -HOUR (12) }, /* Samoa Standard */
2753   { "WAT",      tZONE,     HOUR ( 1) }, /* West Africa */
2754   { "CET",      tZONE,     HOUR ( 1) }, /* Central European */
2755   { "CEST",     tDAYZONE,  HOUR ( 1) }, /* Central European Summer */
2756   { "MET",      tZONE,     HOUR ( 1) }, /* Middle European */
2757   { "MEZ",      tZONE,     HOUR ( 1) }, /* Middle European */
2758   { "MEST",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
2759   { "MESZ",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
2760   { "EET",      tZONE,     HOUR ( 2) }, /* Eastern European */
2761   { "EEST",     tDAYZONE,  HOUR ( 2) }, /* Eastern European Summer */
2762   { "CAT",      tZONE,     HOUR ( 2) }, /* Central Africa */
2763   { "SAST",     tZONE,     HOUR ( 2) }, /* South Africa Standard */
2764   { "EAT",      tZONE,     HOUR ( 3) }, /* East Africa */
2765   { "MSK",      tZONE,     HOUR ( 3) }, /* Moscow */
2766   { "MSD",      tDAYZONE,  HOUR ( 3) }, /* Moscow Daylight */
2767   { "IST",      tZONE,    (HOUR ( 5) + 30 * 60) }, /* India Standard */
2768   { "SGT",      tZONE,     HOUR ( 8) }, /* Singapore */
2769   { "KST",      tZONE,     HOUR ( 9) }, /* Korea Standard */
2770   { "JST",      tZONE,     HOUR ( 9) }, /* Japan Standard */
2771   { "GST",      tZONE,     HOUR (10) }, /* Guam Standard */
2772   { "NZST",     tZONE,     HOUR (12) }, /* New Zealand Standard */
2773   { "NZDT",     tDAYZONE,  HOUR (12) }, /* New Zealand Daylight */
2774   { NULL, 0, 0 }
2775 };
2776 
2777 /* Military time zone table.
2778 
2779    RFC 822 got these backwards, but RFC 5322 makes the incorrect
2780    treatment optional, so do them the right way here.
2781 
2782    Note 'T' is a special case, as it is used as the separator in ISO
2783    8601 date and time of day representation.  */
2784 static table const military_table[] =
2785 {
2786   { "A", tZONE,  HOUR ( 1) },
2787   { "B", tZONE,  HOUR ( 2) },
2788   { "C", tZONE,  HOUR ( 3) },
2789   { "D", tZONE,  HOUR ( 4) },
2790   { "E", tZONE,  HOUR ( 5) },
2791   { "F", tZONE,  HOUR ( 6) },
2792   { "G", tZONE,  HOUR ( 7) },
2793   { "H", tZONE,  HOUR ( 8) },
2794   { "I", tZONE,  HOUR ( 9) },
2795   { "K", tZONE,  HOUR (10) },
2796   { "L", tZONE,  HOUR (11) },
2797   { "M", tZONE,  HOUR (12) },
2798   { "N", tZONE, -HOUR ( 1) },
2799   { "O", tZONE, -HOUR ( 2) },
2800   { "P", tZONE, -HOUR ( 3) },
2801   { "Q", tZONE, -HOUR ( 4) },
2802   { "R", tZONE, -HOUR ( 5) },
2803   { "S", tZONE, -HOUR ( 6) },
2804   { "T", 'T',    0 },
2805   { "U", tZONE, -HOUR ( 8) },
2806   { "V", tZONE, -HOUR ( 9) },
2807   { "W", tZONE, -HOUR (10) },
2808   { "X", tZONE, -HOUR (11) },
2809   { "Y", tZONE, -HOUR (12) },
2810   { "Z", tZONE,  HOUR ( 0) },
2811   { NULL, 0, 0 }
2812 };
2813 
2814 
2815 
2816 /* Convert a time zone expressed as HH:MM into an integer count of
2817    seconds.  If MM is negative, then S is of the form HHMM and needs
2818    to be picked apart; otherwise, S is of the form HH.  As specified in
2819    https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03, allow
2820    only valid TZ range, and consider first two digits as hours, if no
2821    minutes specified.  Return true if successful.  */
2822 
2823 static bool
time_zone_hhmm(parser_control * pc,textint s,intmax_t mm)2824 time_zone_hhmm (parser_control *pc, textint s, intmax_t mm)
2825 {
2826   intmax_t n_minutes;
2827   bool overflow = false;
2828 
2829   /* If the length of S is 1 or 2 and no minutes are specified,
2830      interpret it as a number of hours.  */
2831   if (s.digits <= 2 && mm < 0)
2832     s.value *= 100;
2833 
2834   if (mm < 0)
2835     n_minutes = (s.value / 100) * 60 + s.value % 100;
2836   else
2837     {
2838       overflow |= INT_MULTIPLY_WRAPV (s.value, 60, &n_minutes);
2839       overflow |= (s.negative
2840                    ? INT_SUBTRACT_WRAPV (n_minutes, mm, &n_minutes)
2841                    : INT_ADD_WRAPV (n_minutes, mm, &n_minutes));
2842     }
2843 
2844   if (overflow || ! (-24 * 60 <= n_minutes && n_minutes <= 24 * 60))
2845     return false;
2846   pc->time_zone = n_minutes * 60;
2847   return true;
2848 }
2849 
2850 static int
to_hour(intmax_t hours,int meridian)2851 to_hour (intmax_t hours, int meridian)
2852 {
2853   switch (meridian)
2854     {
2855     default: /* Pacify GCC.  */
2856     case MER24:
2857       return 0 <= hours && hours < 24 ? hours : -1;
2858     case MERam:
2859       return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
2860     case MERpm:
2861       return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
2862     }
2863 }
2864 
2865 enum { TM_YEAR_BASE = 1900 };
2866 enum { TM_YEAR_BUFSIZE = INT_BUFSIZE_BOUND (int) + 1 };
2867 
2868 /* Convert TM_YEAR, a year minus 1900, to a string that is numerically
2869    correct even if subtracting 1900 would overflow.  */
2870 
2871 static char const *
tm_year_str(int tm_year,char buf[TM_YEAR_BUFSIZE])2872 tm_year_str (int tm_year, char buf[TM_YEAR_BUFSIZE])
2873 {
2874   verify (TM_YEAR_BASE % 100 == 0);
2875   sprintf (buf, &"-%02d%02d"[-TM_YEAR_BASE <= tm_year],
2876            abs (tm_year / 100 + TM_YEAR_BASE / 100),
2877            abs (tm_year % 100));
2878   return buf;
2879 }
2880 
2881 /* Convert a text year number to a year minus 1900, working correctly
2882    even if the input is in the range INT_MAX .. INT_MAX + 1900 - 1.  */
2883 
2884 static bool
to_tm_year(textint textyear,bool debug,int * tm_year)2885 to_tm_year (textint textyear, bool debug, int *tm_year)
2886 {
2887   intmax_t year = textyear.value;
2888 
2889   /* XPG4 suggests that years 00-68 map to 2000-2068, and
2890      years 69-99 map to 1969-1999.  */
2891   if (0 <= year && textyear.digits == 2)
2892     {
2893       year += year < 69 ? 2000 : 1900;
2894       if (debug)
2895         dbg_printf (_("warning: adjusting year value %"PRIdMAX
2896                       " to %"PRIdMAX"\n"),
2897                     textyear.value, year);
2898     }
2899 
2900   if (year < 0
2901       ? INT_SUBTRACT_WRAPV (-TM_YEAR_BASE, year, tm_year)
2902       : INT_SUBTRACT_WRAPV (year, TM_YEAR_BASE, tm_year))
2903     {
2904       if (debug)
2905         dbg_printf (_("error: out-of-range year %"PRIdMAX"\n"), year);
2906       return false;
2907     }
2908 
2909   return true;
2910 }
2911 
2912 static table const * _GL_ATTRIBUTE_PURE
lookup_zone(parser_control const * pc,char const * name)2913 lookup_zone (parser_control const *pc, char const *name)
2914 {
2915   table const *tp;
2916 
2917   for (tp = universal_time_zone_table; tp->name; tp++)
2918     if (strcmp (name, tp->name) == 0)
2919       return tp;
2920 
2921   /* Try local zone abbreviations before those in time_zone_table, as
2922      the local ones are more likely to be right.  */
2923   for (tp = pc->local_time_zone_table; tp->name; tp++)
2924     if (strcmp (name, tp->name) == 0)
2925       return tp;
2926 
2927   for (tp = time_zone_table; tp->name; tp++)
2928     if (strcmp (name, tp->name) == 0)
2929       return tp;
2930 
2931   return NULL;
2932 }
2933 
2934 #if ! HAVE_TM_GMTOFF
2935 /* Yield the difference between *A and *B,
2936    measured in seconds, ignoring leap seconds.
2937    The body of this function is taken directly from the GNU C Library;
2938    see strftime.c.  */
2939 static int
tm_diff(const struct tm * a,const struct tm * b)2940 tm_diff (const struct tm *a, const struct tm *b)
2941 {
2942   /* Compute intervening leap days correctly even if year is negative.
2943      Take care to avoid int overflow in leap day calculations,
2944      but it's OK to assume that A and B are close to each other.  */
2945   int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
2946   int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
2947   int a100 = a4 / 25 - (a4 % 25 < 0);
2948   int b100 = b4 / 25 - (b4 % 25 < 0);
2949   int a400 = SHR (a100, 2);
2950   int b400 = SHR (b100, 2);
2951   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2952   int years = a->tm_year - b->tm_year;
2953   int days = (365 * years + intervening_leap_days
2954               + (a->tm_yday - b->tm_yday));
2955   return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2956                 + (a->tm_min - b->tm_min))
2957           + (a->tm_sec - b->tm_sec));
2958 }
2959 #endif /* ! HAVE_TM_GMTOFF */
2960 
2961 static table const *
lookup_word(parser_control const * pc,char * word)2962 lookup_word (parser_control const *pc, char *word)
2963 {
2964   char *p;
2965   char *q;
2966   idx_t wordlen;
2967   table const *tp;
2968   bool period_found;
2969   bool abbrev;
2970 
2971   /* Make it uppercase.  */
2972   for (p = word; *p; p++)
2973     *p = c_toupper (to_uchar (*p));
2974 
2975   for (tp = meridian_table; tp->name; tp++)
2976     if (strcmp (word, tp->name) == 0)
2977       return tp;
2978 
2979   /* See if we have an abbreviation for a month.  */
2980   wordlen = strlen (word);
2981   abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2982 
2983   for (tp = month_and_day_table; tp->name; tp++)
2984     if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2985       return tp;
2986 
2987   if ((tp = lookup_zone (pc, word)))
2988     return tp;
2989 
2990   if (strcmp (word, dst_table[0].name) == 0)
2991     return dst_table;
2992 
2993   for (tp = time_units_table; tp->name; tp++)
2994     if (strcmp (word, tp->name) == 0)
2995       return tp;
2996 
2997   /* Strip off any plural and try the units table again.  */
2998   if (word[wordlen - 1] == 'S')
2999     {
3000       word[wordlen - 1] = '\0';
3001       for (tp = time_units_table; tp->name; tp++)
3002         if (strcmp (word, tp->name) == 0)
3003           return tp;
3004       word[wordlen - 1] = 'S';  /* For "this" in relative_time_table.  */
3005     }
3006 
3007   for (tp = relative_time_table; tp->name; tp++)
3008     if (strcmp (word, tp->name) == 0)
3009       return tp;
3010 
3011   /* Military time zones.  */
3012   if (wordlen == 1)
3013     for (tp = military_table; tp->name; tp++)
3014       if (word[0] == tp->name[0])
3015         return tp;
3016 
3017   /* Drop out any periods and try the time zone table again.  */
3018   for (period_found = false, p = q = word; (*p = *q); q++)
3019     if (*q == '.')
3020       period_found = true;
3021     else
3022       p++;
3023   if (period_found && (tp = lookup_zone (pc, word)))
3024     return tp;
3025 
3026   return NULL;
3027 }
3028 
3029 static int
yylex(union YYSTYPE * lvalp,parser_control * pc)3030 yylex (union YYSTYPE *lvalp, parser_control *pc)
3031 {
3032   unsigned char c;
3033 
3034   for (;;)
3035     {
3036       while (c = *pc->input, c_isspace (c))
3037         pc->input++;
3038 
3039       if (c_isdigit (c) || c == '-' || c == '+')
3040         {
3041           char const *p = pc->input;
3042           int sign;
3043           if (c == '-' || c == '+')
3044             {
3045               sign = c == '-' ? -1 : 1;
3046               while (c = *(pc->input = ++p), c_isspace (c))
3047                 continue;
3048               if (! c_isdigit (c))
3049                 /* skip the '-' sign */
3050                 continue;
3051             }
3052           else
3053             sign = 0;
3054 
3055           time_t value = 0;
3056           do
3057             {
3058               if (INT_MULTIPLY_WRAPV (value, 10, &value))
3059                 return '?';
3060               if (INT_ADD_WRAPV (value, sign < 0 ? '0' - c : c - '0', &value))
3061                 return '?';
3062               c = *++p;
3063             }
3064           while (c_isdigit (c));
3065 
3066           if ((c == '.' || c == ',') && c_isdigit (p[1]))
3067             {
3068               time_t s = value;
3069               int digits;
3070 
3071               /* Accumulate fraction, to ns precision.  */
3072               p++;
3073               int ns = *p++ - '0';
3074               for (digits = 2; digits <= LOG10_BILLION; digits++)
3075                 {
3076                   ns *= 10;
3077                   if (c_isdigit (*p))
3078                     ns += *p++ - '0';
3079                 }
3080 
3081               /* Skip excess digits, truncating toward -Infinity.  */
3082               if (sign < 0)
3083                 for (; c_isdigit (*p); p++)
3084                   if (*p != '0')
3085                     {
3086                       ns++;
3087                       break;
3088                     }
3089               while (c_isdigit (*p))
3090                 p++;
3091 
3092               /* Adjust to the timespec convention, which is that
3093                  tv_nsec is always a positive offset even if tv_sec is
3094                  negative.  */
3095               if (sign < 0 && ns)
3096                 {
3097                   if (INT_SUBTRACT_WRAPV (s, 1, &s))
3098                     return '?';
3099                   ns = BILLION - ns;
3100                 }
3101 
3102               lvalp->timespec.tv_sec = s;
3103               lvalp->timespec.tv_nsec = ns;
3104               pc->input = p;
3105               return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;
3106             }
3107           else
3108             {
3109               lvalp->textintval.negative = sign < 0;
3110               lvalp->textintval.value = value;
3111               lvalp->textintval.digits = p - pc->input;
3112               pc->input = p;
3113               return sign ? tSNUMBER : tUNUMBER;
3114             }
3115         }
3116 
3117       if (c_isalpha (c))
3118         {
3119           char buff[20];
3120           char *p = buff;
3121           table const *tp;
3122 
3123           do
3124             {
3125               if (p < buff + sizeof buff - 1)
3126                 *p++ = c;
3127               c = *++pc->input;
3128             }
3129           while (c_isalpha (c) || c == '.');
3130 
3131           *p = '\0';
3132           tp = lookup_word (pc, buff);
3133           if (! tp)
3134             {
3135               if (pc->parse_datetime_debug)
3136                 dbg_printf (_("error: unknown word '%s'\n"), buff);
3137               return '?';
3138             }
3139           lvalp->intval = tp->value;
3140           return tp->type;
3141         }
3142 
3143       if (c != '(')
3144         return to_uchar (*pc->input++);
3145 
3146       idx_t count = 0;
3147       do
3148         {
3149           c = *pc->input++;
3150           if (c == '\0')
3151             return c;
3152           if (c == '(')
3153             count++;
3154           else if (c == ')')
3155             count--;
3156         }
3157       while (count != 0);
3158     }
3159 }
3160 
3161 /* Do nothing if the parser reports an error.  */
3162 static int
yyerror(parser_control const * pc _GL_UNUSED,char const * s _GL_UNUSED)3163 yyerror (parser_control const *pc _GL_UNUSED,
3164          char const *s _GL_UNUSED)
3165 {
3166   return 0;
3167 }
3168 
3169 /* If *TM0 is the old and *TM1 is the new value of a struct tm after
3170    passing it to mktime_z, return true if it's OK.  It's not OK if
3171    mktime failed or if *TM0 has out-of-range mainline members.
3172    The caller should set TM1->tm_wday to -1 before calling mktime,
3173    as a negative tm_wday is how mktime failure is inferred.  */
3174 
3175 static bool
mktime_ok(struct tm const * tm0,struct tm const * tm1)3176 mktime_ok (struct tm const *tm0, struct tm const *tm1)
3177 {
3178   if (tm1->tm_wday < 0)
3179     return false;
3180 
3181   return ! ((tm0->tm_sec ^ tm1->tm_sec)
3182             | (tm0->tm_min ^ tm1->tm_min)
3183             | (tm0->tm_hour ^ tm1->tm_hour)
3184             | (tm0->tm_mday ^ tm1->tm_mday)
3185             | (tm0->tm_mon ^ tm1->tm_mon)
3186             | (tm0->tm_year ^ tm1->tm_year));
3187 }
3188 
3189 /* Debugging: format a 'struct tm' into a buffer, taking the parser's
3190    timezone information into account (if pc != NULL).  */
3191 static char const *
debug_strfdatetime(struct tm const * tm,parser_control const * pc,char * buf,int n)3192 debug_strfdatetime (struct tm const *tm, parser_control const *pc,
3193                     char *buf, int n)
3194 {
3195   /* TODO:
3196      1. find an optimal way to print date string in a clear and unambiguous
3197         format.  Currently, always add '(Y-M-D)' prefix.
3198         Consider '2016y01m10d'  or 'year(2016) month(01) day(10)'.
3199 
3200         If the user needs debug printing, it means he/she already having
3201         issues with the parsing - better to avoid formats that could
3202         be mis-interpreted (e.g., just YYYY-MM-DD).
3203 
3204      2. Can strftime be used instead?
3205         depends if it is portable and can print invalid dates on all systems.
3206 
3207      3. Print timezone information ?
3208 
3209      4. Print DST information ?
3210 
3211      5. Print nanosecond information ?
3212 
3213      NOTE:
3214      Printed date/time values might not be valid, e.g., '2016-02-31'
3215      or '2016-19-2016' .  These are the values as parsed from the user
3216      string, before validation.
3217   */
3218   int m = nstrftime (buf, n, "(Y-M-D) %Y-%m-%d %H:%M:%S", tm, 0, 0);
3219 
3220   /* If parser_control information was provided (for timezone),
3221      and there's enough space in the buffer, add timezone info.  */
3222   if (pc && m < n && pc->zones_seen)
3223     {
3224       int tz = pc->time_zone;
3225 
3226       /* Account for DST if tLOCAL_ZONE was seen.  */
3227       if (pc->local_zones_seen && !pc->zones_seen && 0 < pc->local_isdst)
3228         tz += 60 * 60;
3229 
3230       char time_zone_buf[TIME_ZONE_BUFSIZE];
3231       snprintf (&buf[m], n - m, " TZ=%s", time_zone_str (tz, time_zone_buf));
3232     }
3233   return buf;
3234 }
3235 
3236 static char const *
debug_strfdate(struct tm const * tm,char * buf,int n)3237 debug_strfdate (struct tm const *tm, char *buf, int n)
3238 {
3239   char tm_year_buf[TM_YEAR_BUFSIZE];
3240   snprintf (buf, n, "(Y-M-D) %s-%02d-%02d",
3241             tm_year_str (tm->tm_year, tm_year_buf),
3242             tm->tm_mon + 1, tm->tm_mday);
3243   return buf;
3244 }
3245 
3246 static char const *
debug_strftime(struct tm const * tm,char * buf,int n)3247 debug_strftime (struct tm const *tm, char *buf, int n)
3248 {
3249   snprintf (buf, n, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
3250   return buf;
3251 }
3252 
3253 /* If mktime_ok failed, display the failed time values,
3254    and provide possible hints.  Example output:
3255 
3256     date: error: invalid date/time value:
3257     date:     user provided time: '(Y-M-D) 2006-04-02 02:45:00'
3258     date:        normalized time: '(Y-M-D) 2006-04-02 03:45:00'
3259     date:                                             __
3260     date:      possible reasons:
3261     date:        non-existing due to daylight-saving time;
3262     date:        numeric values overflow;
3263     date:        missing timezone;
3264  */
3265 static void
debug_mktime_not_ok(struct tm const * tm0,struct tm const * tm1,parser_control const * pc,bool time_zone_seen)3266 debug_mktime_not_ok (struct tm const *tm0, struct tm const *tm1,
3267                      parser_control const *pc, bool time_zone_seen)
3268 {
3269   /* TODO: handle t == -1 (as in 'mktime_ok').  */
3270   char tmp[DBGBUFSIZE];
3271   int i;
3272   const bool eq_sec   = (tm0->tm_sec  == tm1->tm_sec);
3273   const bool eq_min   = (tm0->tm_min  == tm1->tm_min);
3274   const bool eq_hour  = (tm0->tm_hour == tm1->tm_hour);
3275   const bool eq_mday  = (tm0->tm_mday == tm1->tm_mday);
3276   const bool eq_month = (tm0->tm_mon  == tm1->tm_mon);
3277   const bool eq_year  = (tm0->tm_year == tm1->tm_year);
3278 
3279   const bool dst_shift = eq_sec && eq_min && !eq_hour
3280                          && eq_mday && eq_month && eq_year;
3281 
3282   if (!pc->parse_datetime_debug)
3283     return;
3284 
3285   dbg_printf (_("error: invalid date/time value:\n"));
3286   dbg_printf (_("    user provided time: '%s'\n"),
3287               debug_strfdatetime (tm0, pc, tmp, sizeof tmp));
3288   dbg_printf (_("       normalized time: '%s'\n"),
3289               debug_strfdatetime (tm1, pc, tmp, sizeof tmp));
3290   /* The format must be aligned with debug_strfdatetime and the two
3291      DEBUG statements above.  This string is not translated.  */
3292   i = snprintf (tmp, sizeof tmp,
3293                 "                                 %4s %2s %2s %2s %2s %2s",
3294                 eq_year ? "" : "----",
3295                 eq_month ? "" : "--",
3296                 eq_mday ? "" : "--",
3297                 eq_hour ? "" : "--",
3298                 eq_min ? "" : "--",
3299                 eq_sec ? "" : "--");
3300   /* Trim trailing whitespace.  */
3301   if (0 <= i)
3302     {
3303       if (sizeof tmp - 1 < i)
3304         i = sizeof tmp - 1;
3305       while (0 < i && tmp[i - 1] == ' ')
3306         --i;
3307       tmp[i] = '\0';
3308     }
3309   dbg_printf ("%s\n", tmp);
3310 
3311   dbg_printf (_("     possible reasons:\n"));
3312   if (dst_shift)
3313     dbg_printf (_("       non-existing due to daylight-saving time;\n"));
3314   if (!eq_mday && !eq_month)
3315     dbg_printf (_("       invalid day/month combination;\n"));
3316   dbg_printf (_("       numeric values overflow;\n"));
3317   dbg_printf ("       %s\n", (time_zone_seen ? _("incorrect timezone")
3318                               : _("missing timezone")));
3319 }
3320 
3321 /* The original interface: run with debug=false and the default timezone.   */
3322 bool
parse_datetime(struct timespec * result,char const * p,struct timespec const * now)3323 parse_datetime (struct timespec *result, char const *p,
3324                 struct timespec const *now)
3325 {
3326   char const *tzstring = getenv ("TZ");
3327   timezone_t tz = tzalloc (tzstring);
3328   if (!tz)
3329     return false;
3330   bool ok = parse_datetime2 (result, p, now, 0, tz, tzstring);
3331   tzfree (tz);
3332   return ok;
3333 }
3334 
3335 /* Parse a date/time string, storing the resulting time value into *RESULT.
3336    The string itself is pointed to by P.  Return true if successful.
3337    P can be an incomplete or relative time specification; if so, use
3338    *NOW as the basis for the returned time.  Default to timezone
3339    TZDEFAULT, which corresponds to tzalloc (TZSTRING).  */
3340 bool
parse_datetime2(struct timespec * result,char const * p,struct timespec const * now,unsigned int flags,timezone_t tzdefault,char const * tzstring)3341 parse_datetime2 (struct timespec *result, char const *p,
3342                  struct timespec const *now, unsigned int flags,
3343                  timezone_t tzdefault, char const *tzstring)
3344 {
3345   struct tm tm;
3346   struct tm tm0;
3347   char time_zone_buf[TIME_ZONE_BUFSIZE];
3348   char dbg_tm[DBGBUFSIZE];
3349   bool ok = false;
3350   char const *input_sentinel = p + strlen (p);
3351   char *tz1alloc = NULL;
3352 
3353   /* A reasonable upper bound for the size of ordinary TZ strings.
3354      Use heap allocation if TZ's length exceeds this.  */
3355   enum { TZBUFSIZE = 100 };
3356   char tz1buf[TZBUFSIZE];
3357 
3358   struct timespec gettime_buffer;
3359   if (! now)
3360     {
3361       gettime (&gettime_buffer);
3362       now = &gettime_buffer;
3363     }
3364 
3365   time_t Start = now->tv_sec;
3366   int Start_ns = now->tv_nsec;
3367 
3368   unsigned char c;
3369   while (c = *p, c_isspace (c))
3370     p++;
3371 
3372   timezone_t tz = tzdefault;
3373 
3374   /* Store a local copy prior to first "goto".  Without this, a prior use
3375      below of RELATIVE_TIME_0 on the RHS might translate to an assignment-
3376      to-temporary, which would trigger a -Wjump-misses-init warning.  */
3377   const relative_time rel_time_0 = RELATIVE_TIME_0;
3378 
3379   if (strncmp (p, "TZ=\"", 4) == 0)
3380     {
3381       char const *tzbase = p + 4;
3382       idx_t tzsize = 1;
3383       char const *s;
3384 
3385       for (s = tzbase; *s; s++, tzsize++)
3386         if (*s == '\\')
3387           {
3388             s++;
3389             if (! (*s == '\\' || *s == '"'))
3390               break;
3391           }
3392         else if (*s == '"')
3393           {
3394             timezone_t tz1;
3395             char *tz1string = tz1buf;
3396             char *z;
3397             if (TZBUFSIZE < tzsize)
3398               {
3399                 tz1alloc = malloc (tzsize);
3400                 if (!tz1alloc)
3401                   goto fail;
3402                 tz1string = tz1alloc;
3403               }
3404             z = tz1string;
3405             for (s = tzbase; *s != '"'; s++)
3406               *z++ = *(s += *s == '\\');
3407             *z = '\0';
3408             tz1 = tzalloc (tz1string);
3409             if (!tz1)
3410               goto fail;
3411             tz = tz1;
3412             tzstring = tz1string;
3413 
3414             p = s + 1;
3415             while (c = *p, c_isspace (c))
3416               p++;
3417 
3418             break;
3419           }
3420     }
3421 
3422   struct tm tmp;
3423   if (! localtime_rz (tz, &now->tv_sec, &tmp))
3424     goto fail;
3425 
3426   /* As documented, be careful to treat the empty string just like
3427      a date string of "0".  Without this, an empty string would be
3428      declared invalid when parsed during a DST transition.  */
3429   if (*p == '\0')
3430     p = "0";
3431 
3432   parser_control pc;
3433   pc.input = p;
3434   pc.parse_datetime_debug = (flags & PARSE_DATETIME_DEBUG) != 0;
3435   if (INT_ADD_WRAPV (tmp.tm_year, TM_YEAR_BASE, &pc.year.value))
3436     {
3437       if (pc.parse_datetime_debug)
3438         dbg_printf (_("error: initial year out of range\n"));
3439       goto fail;
3440     }
3441   pc.year.digits = 0;
3442   pc.month = tmp.tm_mon + 1;
3443   pc.day = tmp.tm_mday;
3444   pc.hour = tmp.tm_hour;
3445   pc.minutes = tmp.tm_min;
3446   pc.seconds.tv_sec = tmp.tm_sec;
3447   pc.seconds.tv_nsec = Start_ns;
3448   tm.tm_isdst = tmp.tm_isdst;
3449 
3450   pc.meridian = MER24;
3451   pc.rel = rel_time_0;
3452   pc.timespec_seen = false;
3453   pc.rels_seen = false;
3454   pc.dates_seen = 0;
3455   pc.days_seen = 0;
3456   pc.times_seen = 0;
3457   pc.local_zones_seen = 0;
3458   pc.dsts_seen = 0;
3459   pc.zones_seen = 0;
3460   pc.year_seen = false;
3461   pc.debug_dates_seen = false;
3462   pc.debug_days_seen = false;
3463   pc.debug_times_seen = false;
3464   pc.debug_local_zones_seen = false;
3465   pc.debug_zones_seen = false;
3466   pc.debug_year_seen = false;
3467   pc.debug_ordinal_day_seen = false;
3468 
3469 #if HAVE_STRUCT_TM_TM_ZONE
3470   pc.local_time_zone_table[0].name = tmp.tm_zone;
3471   pc.local_time_zone_table[0].type = tLOCAL_ZONE;
3472   pc.local_time_zone_table[0].value = tmp.tm_isdst;
3473   pc.local_time_zone_table[1].name = NULL;
3474 
3475   /* Probe the names used in the next three calendar quarters, looking
3476      for a tm_isdst different from the one we already have.  */
3477   {
3478     int quarter;
3479     for (quarter = 1; quarter <= 3; quarter++)
3480       {
3481         time_t probe;
3482         if (INT_ADD_WRAPV (Start, quarter * (90 * 24 * 60 * 60), &probe))
3483           break;
3484         struct tm probe_tm;
3485         if (localtime_rz (tz, &probe, &probe_tm) && probe_tm.tm_zone
3486             && probe_tm.tm_isdst != pc.local_time_zone_table[0].value)
3487           {
3488               {
3489                 pc.local_time_zone_table[1].name = probe_tm.tm_zone;
3490                 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
3491                 pc.local_time_zone_table[1].value = probe_tm.tm_isdst;
3492                 pc.local_time_zone_table[2].name = NULL;
3493               }
3494             break;
3495           }
3496       }
3497   }
3498 #else
3499 #if HAVE_TZNAME
3500   {
3501 # if !HAVE_DECL_TZNAME
3502     extern char *tzname[];
3503 # endif
3504     int i;
3505     for (i = 0; i < 2; i++)
3506       {
3507         pc.local_time_zone_table[i].name = tzname[i];
3508         pc.local_time_zone_table[i].type = tLOCAL_ZONE;
3509         pc.local_time_zone_table[i].value = i;
3510       }
3511     pc.local_time_zone_table[i].name = NULL;
3512   }
3513 #else
3514   pc.local_time_zone_table[0].name = NULL;
3515 #endif
3516 #endif
3517 
3518   if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
3519       && ! strcmp (pc.local_time_zone_table[0].name,
3520                    pc.local_time_zone_table[1].name))
3521     {
3522       /* This locale uses the same abbreviation for standard and
3523          daylight times.  So if we see that abbreviation, we don't
3524          know whether it's daylight time.  */
3525       pc.local_time_zone_table[0].value = -1;
3526       pc.local_time_zone_table[1].name = NULL;
3527     }
3528 
3529   if (yyparse (&pc) != 0)
3530     {
3531       if (pc.parse_datetime_debug)
3532         dbg_printf ((input_sentinel <= pc.input
3533                      ? _("error: parsing failed\n")
3534                      : _("error: parsing failed, stopped at '%s'\n")),
3535                     pc.input);
3536       goto fail;
3537     }
3538 
3539 
3540   /* Determine effective timezone source.  */
3541 
3542   if (pc.parse_datetime_debug)
3543     {
3544       dbg_printf (_("input timezone: "));
3545 
3546       if (pc.timespec_seen)
3547         fprintf (stderr, _("'@timespec' - always UTC"));
3548       else if (pc.zones_seen)
3549         fprintf (stderr, _("parsed date/time string"));
3550       else if (tzstring)
3551         {
3552           if (tz != tzdefault)
3553             fprintf (stderr, _("TZ=\"%s\" in date string"), tzstring);
3554           else if (STREQ (tzstring, "UTC0"))
3555             {
3556               /* Special case: 'date -u' sets TZ="UTC0".  */
3557               fprintf (stderr, _("TZ=\"UTC0\" environment value or -u"));
3558             }
3559           else
3560             fprintf (stderr, _("TZ=\"%s\" environment value"), tzstring);
3561         }
3562       else
3563         fprintf (stderr, _("system default"));
3564 
3565       /* Account for DST changes if tLOCAL_ZONE was seen.
3566          local timezone only changes DST and is relative to the
3567          default timezone.*/
3568       if (pc.local_zones_seen && !pc.zones_seen && 0 < pc.local_isdst)
3569         fprintf (stderr, ", dst");
3570 
3571       if (pc.zones_seen)
3572         fprintf (stderr, " (%s)", time_zone_str (pc.time_zone, time_zone_buf));
3573 
3574       fputc ('\n', stderr);
3575     }
3576 
3577   if (pc.timespec_seen)
3578     *result = pc.seconds;
3579   else
3580     {
3581       if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
3582                | (pc.local_zones_seen + pc.zones_seen)))
3583         {
3584           if (pc.parse_datetime_debug)
3585             {
3586               if (pc.times_seen > 1)
3587                 dbg_printf ("error: seen multiple time parts\n");
3588               if (pc.dates_seen > 1)
3589                 dbg_printf ("error: seen multiple date parts\n");
3590               if (pc.days_seen > 1)
3591                 dbg_printf ("error: seen multiple days parts\n");
3592               if (pc.dsts_seen > 1)
3593                 dbg_printf ("error: seen multiple daylight-saving parts\n");
3594               if ((pc.local_zones_seen + pc.zones_seen) > 1)
3595                 dbg_printf ("error: seen multiple time-zone parts\n");
3596             }
3597           goto fail;
3598         }
3599 
3600       if (! to_tm_year (pc.year, pc.parse_datetime_debug, &tm.tm_year)
3601           || INT_ADD_WRAPV (pc.month, -1, &tm.tm_mon)
3602           || INT_ADD_WRAPV (pc.day, 0, &tm.tm_mday))
3603         {
3604           if (pc.parse_datetime_debug)
3605             dbg_printf (_("error: year, month, or day overflow\n"));
3606           goto fail;
3607         }
3608       if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
3609         {
3610           tm.tm_hour = to_hour (pc.hour, pc.meridian);
3611           if (tm.tm_hour < 0)
3612             {
3613               char const *mrd = (pc.meridian == MERam ? "am"
3614                                  : pc.meridian == MERpm ?"pm" : "");
3615               if (pc.parse_datetime_debug)
3616                 dbg_printf (_("error: invalid hour %"PRIdMAX"%s\n"),
3617                             pc.hour, mrd);
3618               goto fail;
3619             }
3620           tm.tm_min = pc.minutes;
3621           tm.tm_sec = pc.seconds.tv_sec;
3622           if (pc.parse_datetime_debug)
3623             dbg_printf ((pc.times_seen
3624                          ? _("using specified time as starting value: '%s'\n")
3625                          : _("using current time as starting value: '%s'\n")),
3626                         debug_strftime (&tm, dbg_tm, sizeof dbg_tm));
3627         }
3628       else
3629         {
3630           tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
3631           pc.seconds.tv_nsec = 0;
3632           if (pc.parse_datetime_debug)
3633             dbg_printf ("warning: using midnight as starting time: 00:00:00\n");
3634         }
3635 
3636       /* Let mktime deduce tm_isdst if we have an absolute timestamp.  */
3637       if (pc.dates_seen | pc.days_seen | pc.times_seen)
3638         tm.tm_isdst = -1;
3639 
3640       /* But if the input explicitly specifies local time with or without
3641          DST, give mktime that information.  */
3642       if (pc.local_zones_seen)
3643         tm.tm_isdst = pc.local_isdst;
3644 
3645       tm0.tm_sec = tm.tm_sec;
3646       tm0.tm_min = tm.tm_min;
3647       tm0.tm_hour = tm.tm_hour;
3648       tm0.tm_mday = tm.tm_mday;
3649       tm0.tm_mon = tm.tm_mon;
3650       tm0.tm_year = tm.tm_year;
3651       tm0.tm_isdst = tm.tm_isdst;
3652       tm.tm_wday = -1;
3653 
3654       Start = mktime_z (tz, &tm);
3655 
3656       if (! mktime_ok (&tm0, &tm))
3657         {
3658           bool repaired = false;
3659           bool time_zone_seen = pc.zones_seen != 0;
3660           if (time_zone_seen)
3661             {
3662               /* Guard against falsely reporting errors near the time_t
3663                  boundaries when parsing times in other time zones.  For
3664                  example, suppose the input string "1969-12-31 23:00:00 -0100",
3665                  the current time zone is 8 hours ahead of UTC, and the min
3666                  time_t value is 1970-01-01 00:00:00 UTC.  Then the min
3667                  localtime value is 1970-01-01 08:00:00, and mktime will
3668                  therefore fail on 1969-12-31 23:00:00.  To work around the
3669                  problem, set the time zone to 1 hour behind UTC temporarily
3670                  by setting TZ="XXX1:00" and try mktime again.  */
3671 
3672               char tz2buf[sizeof "XXX" - 1 + TIME_ZONE_BUFSIZE];
3673               tz2buf[0] = tz2buf[1] = tz2buf[2] = 'X';
3674               time_zone_str (pc.time_zone, &tz2buf[3]);
3675               timezone_t tz2 = tzalloc (tz2buf);
3676               if (!tz2)
3677                 {
3678                   if (pc.parse_datetime_debug)
3679                     dbg_printf (_("error: tzalloc (\"%s\") failed\n"), tz2buf);
3680                   goto fail;
3681                 }
3682               tm.tm_sec = tm0.tm_sec;
3683               tm.tm_min = tm0.tm_min;
3684               tm.tm_hour = tm0.tm_hour;
3685               tm.tm_mday = tm0.tm_mday;
3686               tm.tm_mon = tm0.tm_mon;
3687               tm.tm_year = tm0.tm_year;
3688               tm.tm_isdst = tm0.tm_isdst;
3689               tm.tm_wday = -1;
3690               Start = mktime_z (tz2, &tm);
3691               repaired = mktime_ok (&tm0, &tm);
3692               tzfree (tz2);
3693             }
3694 
3695           if (! repaired)
3696             {
3697               debug_mktime_not_ok (&tm0, &tm, &pc, time_zone_seen);
3698               goto fail;
3699             }
3700         }
3701 
3702       char dbg_ord[DBGBUFSIZE];
3703 
3704       if (pc.days_seen && ! pc.dates_seen)
3705         {
3706           intmax_t dayincr;
3707           if (INT_MULTIPLY_WRAPV ((pc.day_ordinal
3708                                    - (0 < pc.day_ordinal
3709                                       && tm.tm_wday != pc.day_number)),
3710                                   7, &dayincr)
3711               || INT_ADD_WRAPV ((pc.day_number - tm.tm_wday + 7) % 7,
3712                                 dayincr, &dayincr)
3713               || INT_ADD_WRAPV (dayincr, tm.tm_mday, &tm.tm_mday))
3714             Start = -1;
3715           else
3716             {
3717               tm.tm_isdst = -1;
3718               Start = mktime_z (tz, &tm);
3719             }
3720 
3721           if (Start == (time_t) -1)
3722             {
3723               if (pc.parse_datetime_debug)
3724                 dbg_printf (_("error: day '%s' "
3725                               "(day ordinal=%"PRIdMAX" number=%d) "
3726                               "resulted in an invalid date: '%s'\n"),
3727                             str_days (&pc, dbg_ord, sizeof dbg_ord),
3728                             pc.day_ordinal, pc.day_number,
3729                             debug_strfdatetime (&tm, &pc, dbg_tm,
3730                                                 sizeof dbg_tm));
3731               goto fail;
3732             }
3733 
3734           if (pc.parse_datetime_debug)
3735             dbg_printf (_("new start date: '%s' is '%s'\n"),
3736                         str_days (&pc, dbg_ord, sizeof dbg_ord),
3737                         debug_strfdatetime (&tm, &pc, dbg_tm, sizeof dbg_tm));
3738 
3739         }
3740 
3741       if (pc.parse_datetime_debug)
3742         {
3743           if (!pc.dates_seen && !pc.days_seen)
3744             dbg_printf (_("using current date as starting value: '%s'\n"),
3745                         debug_strfdate (&tm, dbg_tm, sizeof dbg_tm));
3746 
3747           if (pc.days_seen && pc.dates_seen)
3748             dbg_printf (_("warning: day (%s) ignored when explicit dates "
3749                           "are given\n"),
3750                         str_days (&pc, dbg_ord, sizeof dbg_ord));
3751 
3752           dbg_printf (_("starting date/time: '%s'\n"),
3753                       debug_strfdatetime (&tm, &pc, dbg_tm, sizeof dbg_tm));
3754         }
3755 
3756       /* Add relative date.  */
3757       if (pc.rel.year | pc.rel.month | pc.rel.day)
3758         {
3759           if (pc.parse_datetime_debug)
3760             {
3761               if ((pc.rel.year != 0 || pc.rel.month != 0) && tm.tm_mday != 15)
3762                 dbg_printf (_("warning: when adding relative months/years, "
3763                               "it is recommended to specify the 15th of the "
3764                               "months\n"));
3765 
3766               if (pc.rel.day != 0 && tm.tm_hour != 12)
3767                 dbg_printf (_("warning: when adding relative days, "
3768                               "it is recommended to specify noon\n"));
3769             }
3770 
3771           int year, month, day;
3772           if (INT_ADD_WRAPV (tm.tm_year, pc.rel.year, &year)
3773               || INT_ADD_WRAPV (tm.tm_mon, pc.rel.month, &month)
3774               || INT_ADD_WRAPV (tm.tm_mday, pc.rel.day, &day))
3775             {
3776               if (pc.parse_datetime_debug)
3777                 dbg_printf (_("error: %s:%d\n"), __FILE__, __LINE__);
3778               goto fail;
3779             }
3780           tm.tm_year = year;
3781           tm.tm_mon = month;
3782           tm.tm_mday = day;
3783           tm.tm_hour = tm0.tm_hour;
3784           tm.tm_min = tm0.tm_min;
3785           tm.tm_sec = tm0.tm_sec;
3786           tm.tm_isdst = tm0.tm_isdst;
3787           Start = mktime_z (tz, &tm);
3788           if (Start == (time_t) -1)
3789             {
3790               if (pc.parse_datetime_debug)
3791                 dbg_printf (_("error: adding relative date resulted "
3792                               "in an invalid date: '%s'\n"),
3793                             debug_strfdatetime (&tm, &pc, dbg_tm,
3794                                                 sizeof dbg_tm));
3795               goto fail;
3796             }
3797 
3798           if (pc.parse_datetime_debug)
3799             {
3800               dbg_printf (_("after date adjustment "
3801                             "(%+"PRIdMAX" years, %+"PRIdMAX" months, "
3802                             "%+"PRIdMAX" days),\n"),
3803                           pc.rel.year, pc.rel.month, pc.rel.day);
3804               dbg_printf (_("    new date/time = '%s'\n"),
3805                           debug_strfdatetime (&tm, &pc, dbg_tm,
3806                                               sizeof dbg_tm));
3807 
3808               /* Warn about crossing DST due to time adjustment.
3809                  Example: https://bugs.gnu.org/8357
3810                  env TZ=Europe/Helsinki \
3811                    date --debug \
3812                         -d 'Mon Mar 28 00:36:07 2011 EEST 1 day ago'
3813 
3814                  This case is different than DST changes due to time adjustment,
3815                  i.e., "1 day ago" vs "24 hours ago" are calculated in different
3816                  places.
3817 
3818                  'tm0.tm_isdst' contains the DST of the input date,
3819                  'tm.tm_isdst' is the normalized result after calling
3820                  mktime (&tm).
3821               */
3822               if (tm0.tm_isdst != -1 && tm.tm_isdst != tm0.tm_isdst)
3823                 dbg_printf (_("warning: daylight saving time changed after "
3824                               "date adjustment\n"));
3825 
3826               /* Warn if the user did not ask to adjust days but mday changed,
3827                  or
3828                  user did not ask to adjust months/days but the month changed.
3829 
3830                  Example for first case:
3831                  2016-05-31 + 1 month => 2016-06-31 => 2016-07-01.
3832                  User asked to adjust month, but the day changed from 31 to 01.
3833 
3834                  Example for second case:
3835                  2016-02-29 + 1 year => 2017-02-29 => 2017-03-01.
3836                  User asked to adjust year, but the month changed from 02 to 03.
3837               */
3838               if (pc.rel.day == 0
3839                   && (tm.tm_mday != day
3840                       || (pc.rel.month == 0 && tm.tm_mon != month)))
3841                 {
3842                   dbg_printf (_("warning: month/year adjustment resulted in "
3843                                 "shifted dates:\n"));
3844                   char tm_year_buf[TM_YEAR_BUFSIZE];
3845                   dbg_printf (_("     adjusted Y M D: %s %02d %02d\n"),
3846                               tm_year_str (year, tm_year_buf), month + 1, day);
3847                   dbg_printf (_("   normalized Y M D: %s %02d %02d\n"),
3848                               tm_year_str (tm.tm_year, tm_year_buf),
3849                               tm.tm_mon + 1, tm.tm_mday);
3850                 }
3851             }
3852 
3853         }
3854 
3855       /* The only "output" of this if-block is an updated Start value,
3856          so this block must follow others that clobber Start.  */
3857       if (pc.zones_seen)
3858         {
3859           bool overflow = false;
3860 #ifdef HAVE_TM_GMTOFF
3861           long int utcoff = tm.tm_gmtoff;
3862 #else
3863           time_t t = Start;
3864           struct tm gmt;
3865           int utcoff = (gmtime_r (&t, &gmt)
3866                         ? tm_diff (&tm, &gmt)
3867                         : (overflow = true, 0));
3868 #endif
3869           intmax_t delta;
3870           overflow |= INT_SUBTRACT_WRAPV (pc.time_zone, utcoff, &delta);
3871           time_t t1;
3872           overflow |= INT_SUBTRACT_WRAPV (Start, delta, &t1);
3873           if (overflow)
3874             {
3875               if (pc.parse_datetime_debug)
3876                 dbg_printf (_("error: timezone %d caused time_t overflow\n"),
3877                             pc.time_zone);
3878               goto fail;
3879             }
3880           Start = t1;
3881         }
3882 
3883       if (pc.parse_datetime_debug)
3884         {
3885           intmax_t Starti = Start;
3886           dbg_printf (_("'%s' = %"PRIdMAX" epoch-seconds\n"),
3887                       debug_strfdatetime (&tm, &pc, dbg_tm, sizeof dbg_tm),
3888                       Starti);
3889         }
3890 
3891 
3892       /* Add relative hours, minutes, and seconds.  On hosts that support
3893          leap seconds, ignore the possibility of leap seconds; e.g.,
3894          "+ 10 minutes" adds 600 seconds, even if one of them is a
3895          leap second.  Typically this is not what the user wants, but it's
3896          too hard to do it the other way, because the time zone indicator
3897          must be applied before relative times, and if mktime is applied
3898          again the time zone will be lost.  */
3899       {
3900         intmax_t orig_ns = pc.seconds.tv_nsec;
3901         intmax_t sum_ns = orig_ns + pc.rel.ns;
3902         int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
3903         int d4 = (sum_ns - normalized_ns) / BILLION;
3904         intmax_t d1, t1, d2, t2, t3;
3905         time_t t4;
3906         if (INT_MULTIPLY_WRAPV (pc.rel.hour, 60 * 60, &d1)
3907             || INT_ADD_WRAPV (Start, d1, &t1)
3908             || INT_MULTIPLY_WRAPV (pc.rel.minutes, 60, &d2)
3909             || INT_ADD_WRAPV (t1, d2, &t2)
3910             || INT_ADD_WRAPV (t2, pc.rel.seconds, &t3)
3911             || INT_ADD_WRAPV (t3, d4, &t4))
3912           {
3913             if (pc.parse_datetime_debug)
3914               dbg_printf (_("error: adding relative time caused an "
3915                             "overflow\n"));
3916             goto fail;
3917           }
3918 
3919         result->tv_sec = t4;
3920         result->tv_nsec = normalized_ns;
3921 
3922         if (pc.parse_datetime_debug
3923             && (pc.rel.hour | pc.rel.minutes | pc.rel.seconds | pc.rel.ns))
3924           {
3925             dbg_printf (_("after time adjustment (%+"PRIdMAX" hours, "
3926                           "%+"PRIdMAX" minutes, "
3927                           "%+"PRIdMAX" seconds, %+d ns),\n"),
3928                         pc.rel.hour, pc.rel.minutes, pc.rel.seconds,
3929                         pc.rel.ns);
3930             intmax_t t4i = t4;
3931             dbg_printf (_("    new time = %"PRIdMAX" epoch-seconds\n"), t4i);
3932 
3933             /* Warn about crossing DST due to time adjustment.
3934                Example: https://bugs.gnu.org/8357
3935                env TZ=Europe/Helsinki           \
3936                date --debug                                             \
3937                -d 'Mon Mar 28 00:36:07 2011 EEST 24 hours ago'
3938 
3939                This case is different than DST changes due to days adjustment,
3940                i.e., "1 day ago" vs "24 hours ago" are calculated in different
3941                places.
3942 
3943                'tm.tm_isdst' contains the date after date adjustment.  */
3944             struct tm lmt;
3945             if (tm.tm_isdst != -1 && localtime_rz (tz, &result->tv_sec, &lmt)
3946                 && tm.tm_isdst != lmt.tm_isdst)
3947               dbg_printf (_("warning: daylight saving time changed after "
3948                             "time adjustment\n"));
3949           }
3950       }
3951     }
3952 
3953   if (pc.parse_datetime_debug)
3954     {
3955       /* Special case: using 'date -u' simply set TZ=UTC0 */
3956       if (! tzstring)
3957         dbg_printf (_("timezone: system default\n"));
3958       else if (STREQ (tzstring, "UTC0"))
3959         dbg_printf (_("timezone: Universal Time\n"));
3960       else
3961         dbg_printf (_("timezone: TZ=\"%s\" environment value\n"), tzstring);
3962 
3963       intmax_t sec = result->tv_sec;
3964       int nsec = result->tv_nsec;
3965       dbg_printf (_("final: %"PRIdMAX".%09d (epoch-seconds)\n"),
3966                   sec, nsec);
3967 
3968       struct tm gmt, lmt;
3969       bool got_utc = !!gmtime_r (&result->tv_sec, &gmt);
3970       if (got_utc)
3971         dbg_printf (_("final: %s (UTC)\n"),
3972                     debug_strfdatetime (&gmt, NULL,
3973                                         dbg_tm, sizeof dbg_tm));
3974       if (localtime_rz (tz, &result->tv_sec, &lmt))
3975         {
3976 #ifdef HAVE_TM_GMTOFF
3977           bool got_utcoff = true;
3978           long int utcoff = lmt.tm_gmtoff;
3979 #else
3980           bool got_utcoff = got_utc;
3981           int utcoff;
3982           if (got_utcoff)
3983             utcoff = tm_diff (&lmt, &gmt);
3984 #endif
3985           if (got_utcoff)
3986             dbg_printf (_("final: %s (UTC%s)\n"),
3987                         debug_strfdatetime (&lmt, NULL, dbg_tm, sizeof dbg_tm),
3988                         time_zone_str (utcoff, time_zone_buf));
3989           else
3990             dbg_printf (_("final: %s (unknown time zone offset)\n"),
3991                         debug_strfdatetime (&lmt, NULL, dbg_tm, sizeof dbg_tm));
3992         }
3993     }
3994 
3995   ok = true;
3996 
3997  fail:
3998   if (tz != tzdefault)
3999     tzfree (tz);
4000   free (tz1alloc);
4001   return ok;
4002 }
4003 
4004 #if TEST
4005 
4006 int
main(int ac,char ** av)4007 main (int ac, char **av)
4008 {
4009   char buff[BUFSIZ];
4010 
4011   printf ("Enter date, or blank line to exit.\n\t> ");
4012   fflush (stdout);
4013 
4014   buff[BUFSIZ - 1] = '\0';
4015   while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
4016     {
4017       struct timespec d;
4018       struct tm const *tm;
4019       if (! parse_datetime (&d, buff, NULL))
4020         printf ("Bad format - couldn't convert.\n");
4021       else if (! (tm = localtime (&d.tv_sec)))
4022         {
4023           intmax_t sec = d.tv_sec;
4024           printf ("localtime (%"PRIdMAX") failed\n", sec);
4025         }
4026       else
4027         {
4028           int ns = d.tv_nsec;
4029           char tm_year_buf[TM_YEAR_BUFSIZE];
4030           printf ("%s-%02d-%02d %02d:%02d:%02d.%09d\n",
4031                   tm_year_str (tm->tm_year, tm_year_buf),
4032                   tm->tm_mon + 1, tm->tm_mday,
4033                   tm->tm_hour, tm->tm_min, tm->tm_sec, ns);
4034         }
4035       printf ("\t> ");
4036       fflush (stdout);
4037     }
4038   return 0;
4039 }
4040 #endif /* TEST */
4041