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