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