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