1 /* A Bison parser, made by GNU Bison 1.875c. */
3 /* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
26 /* Written by Richard Stallman by simplifying the original so called
27 ``semantic'' parser. */
29 /* All symbols defined below should begin with yy or YY, to avoid
30 infringing on user name space. This should be done even for local
31 variables, as they might otherwise be expanded by user macros.
32 There are some unavoidable exceptions within include files to
33 define necessary library symbols; they are noted "INFRINGES ON
34 USER NAME SPACE" below. */
36 /* Identify Bison output. */
40 #define YYSKELETON_NAME "yacc.c"
45 /* Using locations. */
46 #define YYLSP_NEEDED 0
53 /* Put the tokens into the symbol table, so that GDB and other debuggers
73 tSDECIMAL_NUMBER
= 275,
74 tUDECIMAL_NUMBER
= 276
82 #define tHOUR_UNIT 263
83 #define tLOCAL_ZONE 264
85 #define tMINUTE_UNIT 266
87 #define tMONTH_UNIT 268
90 #define tYEAR_UNIT 271
94 #define tSDECIMAL_NUMBER 275
95 #define tUDECIMAL_NUMBER 276
100 /* Copy the first part of user declarations. */
103 /* Parse a string into an internal time stamp.
105 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software
108 This program is free software; you can redistribute it and/or modify
109 it under the terms of the GNU General Public License as published by
110 the Free Software Foundation; either version 2, or (at your option)
113 This program is distributed in the hope that it will be useful,
114 but WITHOUT ANY WARRANTY; without even the implied warranty of
115 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
116 GNU General Public License for more details.
118 You should have received a copy of the GNU General Public License
119 along with this program; if not, write to the Free Software Foundation,
120 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
122 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
123 at the University of North Carolina at Chapel Hill. Later tweaked by
124 a couple of people on Usenet. Completely overhauled by Rich $alz
125 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
127 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
128 the right thing about local DST. Also modified by Paul Eggert
129 <eggert@cs.ucla.edu> in February 2004 to support
130 nanosecond-resolution time stamps, and in October 2004 to support
131 TZ strings in dates. */
133 /* FIXME: Check for arithmetic overflow in all cases, not just
142 /* There's no need to extend the stack, so there's no need to involve
144 #define YYSTACK_USE_ALLOCA 0
146 /* Tell Bison how much stack space is needed. 20 should be plenty for
147 this grammar, which is not right recursive. Beware setting it too
148 high, since that might cause problems on machines whose
149 implementations have lame stack-overflow checking. */
150 #define YYMAXDEPTH 20
151 #define YYINITDEPTH YYMAXDEPTH
153 /* Since the code of getdate.y is not included in the Emacs executable
154 itself, there is no need to #define static in this file. Even if
155 the code were included in the Emacs executable, it probably
156 wouldn't do any harm to #undef it here; this will only cause
157 problems if we try to write to a static variable, which I don't
158 think this code needs to do. */
172 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
173 # define IN_CTYPE_DOMAIN(c) 1
175 # define IN_CTYPE_DOMAIN(c) isascii (c)
178 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
179 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
180 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
182 /* ISDIGIT differs from isdigit, as follows:
183 - Its arg may be any int or unsigned int; it need not be an unsigned char.
184 - It's guaranteed to evaluate its argument exactly once.
185 - It's typically faster.
186 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
187 isdigit unless it's important to use the locale's definition
188 of `digit' even when the host does not conform to POSIX. */
189 #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
191 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
192 # define __attribute__(x)
195 #ifndef ATTRIBUTE_UNUSED
196 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
199 /* Shift A right by B bits portably, by dividing A by 2**B and
200 truncating towards minus infinity. A and B should be free of side
201 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
202 INT_BITS is the number of useful bits in an int. GNU code can
203 assume that INT_BITS is at least 32.
205 ISO C99 says that A >> B is implementation-defined if A < 0. Some
206 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
207 right in the usual way when A < 0, so SHR falls back on division if
208 ordinary A >> B doesn't seem to be the usual signed shift. */
212 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
214 #define EPOCH_YEAR 1970
215 #define TM_YEAR_BASE 1900
217 #define HOUR(x) ((x) * 60)
219 /* An integer value, and the number of digits in its textual
228 /* An entry in the lexical lookup table. */
236 /* Meridian: am, pm, or 24-hour style. */
237 enum { MERam
, MERpm
, MER24
};
239 enum { BILLION
= 1000000000, LOG10_BILLION
= 9 };
241 /* Information passed to and from the parser. */
244 /* The input string remaining to be parsed. */
247 /* N, if this is the Nth Tuesday. */
248 long int day_ordinal
;
250 /* Day of week; Sunday is 0. */
253 /* tm_isdst flag for the local zone. */
256 /* Time zone, in minutes east of UTC. */
259 /* Style used for time. */
262 /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */
268 struct timespec seconds
; /* includes nanoseconds */
270 /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
275 long int rel_minutes
;
276 long int rel_seconds
;
279 /* Presence or counts of nonterminals of various flavors parsed so far. */
284 size_t local_zones_seen
;
289 /* Table of local time zone abbrevations, terminated by a null entry. */
290 table local_time_zone_table
[3];
294 static int yylex (union YYSTYPE
*, parser_control
*);
295 static int yyerror (parser_control
*, char *);
296 static long int time_zone_hhmm (textint
, long int);
300 /* Enabling traces. */
305 /* Enabling verbose error messages. */
306 #ifdef YYERROR_VERBOSE
307 # undef YYERROR_VERBOSE
308 # define YYERROR_VERBOSE 1
310 # define YYERROR_VERBOSE 0
313 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
314 #line 209 "getdate.y"
315 typedef union YYSTYPE
{
318 struct timespec timespec
;
320 /* Line 191 of yacc.c. */
321 #line 322 "getdate.c"
322 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
323 # define YYSTYPE_IS_DECLARED 1
324 # define YYSTYPE_IS_TRIVIAL 1
329 /* Copy the second part of user declarations. */
332 /* Line 214 of yacc.c. */
333 #line 334 "getdate.c"
335 #if ! defined (yyoverflow) || YYERROR_VERBOSE
341 # define YYMALLOC malloc
344 /* The parser invokes alloca or malloc; define the necessary symbols. */
346 # ifdef YYSTACK_USE_ALLOCA
347 # if YYSTACK_USE_ALLOCA
348 # define YYSTACK_ALLOC alloca
351 # if defined (alloca) || defined (_ALLOCA_H)
352 # define YYSTACK_ALLOC alloca
355 # define YYSTACK_ALLOC __builtin_alloca
360 # ifdef YYSTACK_ALLOC
361 /* Pacify GCC's `empty if-body' warning. */
362 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
364 # if defined (__STDC__) || defined (__cplusplus)
365 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
366 # define YYSIZE_T size_t
368 # define YYSTACK_ALLOC YYMALLOC
369 # define YYSTACK_FREE YYFREE
371 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
374 #if (! defined (yyoverflow) \
375 && (! defined (__cplusplus) \
376 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
378 /* A type that is properly aligned for any stack member. */
385 /* The size of the maximum gap between one aligned stack and the next. */
386 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
388 /* The size of an array large to enough to hold all stacks, each with
390 # define YYSTACK_BYTES(N) \
391 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
392 + YYSTACK_GAP_MAXIMUM)
394 /* Copy COUNT objects from FROM to TO. The source and destination do
397 # if defined (__GNUC__) && 1 < __GNUC__
398 # define YYCOPY(To, From, Count) \
399 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
401 # define YYCOPY(To, From, Count) \
404 register YYSIZE_T yyi; \
405 for (yyi = 0; yyi < (Count); yyi++) \
406 (To)[yyi] = (From)[yyi]; \
412 /* Relocate STACK from its old location to the new one. The
413 local variables YYSIZE and YYSTACKSIZE give the old and new number of
414 elements in the stack, and YYPTR gives the new location of the
415 stack. Advance YYPTR to a properly aligned location for the next
417 # define YYSTACK_RELOCATE(Stack) \
420 YYSIZE_T yynewbytes; \
421 YYCOPY (&yyptr->Stack, Stack, yysize); \
422 Stack = &yyptr->Stack; \
423 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
424 yyptr += yynewbytes / sizeof (*yyptr); \
430 #if defined (__STDC__) || defined (__cplusplus)
431 typedef signed char yysigned_char
;
433 typedef short yysigned_char
;
436 /* YYFINAL -- State number of the termination state. */
438 /* YYLAST -- Last index in YYTABLE. */
441 /* YYNTOKENS -- Number of terminals. */
443 /* YYNNTS -- Number of nonterminals. */
445 /* YYNRULES -- Number of rules. */
447 /* YYNRULES -- Number of states. */
450 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
452 #define YYMAXUTOK 276
454 #define YYTRANSLATE(YYX) \
455 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
457 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
458 static const unsigned char yytranslate
[] =
460 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
461 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
462 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
463 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
464 2, 2, 2, 2, 24, 2, 2, 25, 2, 2,
465 2, 2, 2, 2, 2, 2, 2, 2, 23, 2,
466 2, 2, 2, 2, 22, 2, 2, 2, 2, 2,
467 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
468 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
469 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
470 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
471 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
472 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
473 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
474 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
475 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
476 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
477 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
478 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
479 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
480 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
481 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
482 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
483 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
484 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
485 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
486 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
487 15, 16, 17, 18, 19, 20, 21
491 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
493 static const unsigned char yyprhs
[] =
495 0, 0, 3, 5, 7, 10, 11, 14, 16, 18,
496 20, 22, 24, 26, 28, 31, 36, 42, 49, 57,
497 59, 62, 64, 67, 71, 73, 76, 78, 81, 84,
498 87, 91, 97, 101, 105, 109, 112, 117, 120, 124,
499 127, 129, 132, 135, 137, 140, 143, 145, 148, 151,
500 153, 156, 159, 161, 164, 167, 169, 172, 175, 178,
501 181, 183, 185, 188, 191, 194, 197, 200, 203, 205,
502 207, 209, 211, 213, 215, 217, 218, 221, 222
505 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
506 static const yysigned_char yyrhs
[] =
508 27, 0, -1, 28, -1, 29, -1, 22, 39, -1,
509 -1, 29, 30, -1, 31, -1, 32, -1, 33, -1,
510 35, -1, 34, -1, 36, -1, 42, -1, 19, 10,
511 -1, 19, 23, 19, 44, -1, 19, 23, 19, 18,
512 43, -1, 19, 23, 19, 23, 41, 44, -1, 19,
513 23, 19, 23, 41, 18, 43, -1, 9, -1, 9,
514 4, -1, 17, -1, 17, 38, -1, 17, 18, 43,
515 -1, 7, -1, 17, 4, -1, 5, -1, 5, 24,
516 -1, 14, 5, -1, 19, 5, -1, 19, 25, 19,
517 -1, 19, 25, 19, 25, 19, -1, 19, 18, 18,
518 -1, 19, 12, 18, -1, 12, 18, 18, -1, 12,
519 19, -1, 12, 19, 24, 19, -1, 19, 12, -1,
520 19, 12, 19, -1, 37, 3, -1, 37, -1, 14,
521 16, -1, 19, 16, -1, 16, -1, 14, 13, -1,
522 19, 13, -1, 13, -1, 14, 6, -1, 19, 6,
523 -1, 6, -1, 14, 8, -1, 19, 8, -1, 8,
524 -1, 14, 11, -1, 19, 11, -1, 11, -1, 14,
525 15, -1, 19, 15, -1, 20, 15, -1, 21, 15,
526 -1, 15, -1, 38, -1, 18, 16, -1, 18, 13,
527 -1, 18, 6, -1, 18, 8, -1, 18, 11, -1,
528 18, 15, -1, 40, -1, 41, -1, 20, -1, 18,
529 -1, 21, -1, 19, -1, 19, -1, -1, 23, 19,
533 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
534 static const unsigned short yyrline
[] =
536 0, 230, 230, 231, 235, 242, 244, 248, 250, 252,
537 254, 256, 258, 260, 264, 272, 280, 290, 297, 309,
538 314, 322, 324, 326, 328, 330, 335, 340, 345, 350,
539 358, 363, 383, 390, 398, 406, 411, 417, 422, 431,
540 441, 445, 447, 449, 451, 453, 455, 457, 459, 461,
541 463, 465, 467, 469, 471, 473, 475, 477, 479, 481,
542 483, 485, 489, 491, 493, 495, 497, 499, 503, 503,
543 506, 507, 512, 513, 518, 556, 557, 563, 564
547 #if YYDEBUG || YYERROR_VERBOSE
548 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
549 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
550 static const char *const yytname
[] =
552 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
553 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
554 "tMONTH", "tMONTH_UNIT", "tORDINAL", "tSEC_UNIT", "tYEAR_UNIT", "tZONE",
555 "tSNUMBER", "tUNUMBER", "tSDECIMAL_NUMBER", "tUDECIMAL_NUMBER", "'@'",
556 "':'", "','", "'/'", "$accept", "spec", "timespec", "items", "item",
557 "time", "local_zone", "zone", "day", "date", "rel", "relunit",
558 "relunit_snumber", "seconds", "signed_seconds", "unsigned_seconds",
559 "number", "o_colon_minutes", "o_merid", 0
564 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
566 static const unsigned short yytoknum
[] =
568 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
569 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
570 275, 276, 64, 58, 44, 47
574 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
575 static const unsigned char yyr1
[] =
577 0, 26, 27, 27, 28, 29, 29, 30, 30, 30,
578 30, 30, 30, 30, 31, 31, 31, 31, 31, 32,
579 32, 33, 33, 33, 33, 33, 34, 34, 34, 34,
580 35, 35, 35, 35, 35, 35, 35, 35, 35, 36,
581 36, 37, 37, 37, 37, 37, 37, 37, 37, 37,
582 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
583 37, 37, 38, 38, 38, 38, 38, 38, 39, 39,
584 40, 40, 41, 41, 42, 43, 43, 44, 44
587 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
588 static const unsigned char yyr2
[] =
590 0, 2, 1, 1, 2, 0, 2, 1, 1, 1,
591 1, 1, 1, 1, 2, 4, 5, 6, 7, 1,
592 2, 1, 2, 3, 1, 2, 1, 2, 2, 2,
593 3, 5, 3, 3, 3, 2, 4, 2, 3, 2,
594 1, 2, 2, 1, 2, 2, 1, 2, 2, 1,
595 2, 2, 1, 2, 2, 1, 2, 2, 2, 2,
596 1, 1, 2, 2, 2, 2, 2, 2, 1, 1,
597 1, 1, 1, 1, 1, 0, 2, 0, 1
600 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
601 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
602 means the default is an error. */
603 static const unsigned char yydefact
[] =
605 5, 0, 0, 2, 3, 71, 73, 70, 72, 4,
606 68, 69, 1, 26, 49, 24, 52, 19, 55, 0,
607 46, 0, 60, 43, 21, 0, 74, 0, 0, 6,
608 7, 8, 9, 11, 10, 12, 40, 61, 13, 27,
609 20, 0, 35, 28, 47, 50, 53, 44, 56, 41,
610 25, 75, 22, 64, 65, 66, 63, 67, 62, 29,
611 48, 51, 14, 54, 37, 45, 57, 42, 0, 0,
612 0, 58, 59, 39, 34, 0, 0, 23, 33, 38,
613 32, 77, 30, 36, 76, 78, 75, 0, 15, 0,
614 16, 77, 31, 75, 17, 18
617 /* YYDEFGOTO[NTERM-NUM]. */
618 static const yysigned_char yydefgoto
[] =
620 -1, 2, 3, 4, 29, 30, 31, 32, 33, 34,
621 35, 36, 37, 9, 10, 11, 38, 77, 88
624 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
626 #define YYPACT_NINF -43
627 static const yysigned_char yypact
[] =
629 -18, 48, 9, -43, 19, -43, -43, -43, -43, -43,
630 -43, -43, -43, 32, -43, -43, -43, 54, -43, 28,
631 -43, 37, -43, -43, -2, 49, -5, 57, 58, -43,
632 -43, -43, -43, -43, -43, -43, 60, -43, -43, -43,
633 -43, 56, 51, -43, -43, -43, -43, -43, -43, -43,
634 -43, 6, -43, -43, -43, -43, -43, -43, -43, -43,
635 -43, -43, -43, -43, 52, -43, -43, -43, 59, 61,
636 62, -43, -43, -43, -43, 63, 64, -43, -43, -43,
637 -43, 31, 53, -43, -43, -43, 65, 40, -43, 66,
638 -43, 5, -43, 65, -43, -43
641 /* YYPGOTO[NTERM-NUM]. */
642 static const yysigned_char yypgoto
[] =
644 -43, -43, -43, -43, -43, -43, -43, -43, -43, -43,
645 -43, -43, 55, -43, -43, -11, -43, -42, -7
648 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
649 positive, shift that token. If negative, reduce the rule which
650 number is the opposite. If zero, do what YYDEFACT says.
651 If YYTABLE_NINF, syntax error. */
652 #define YYTABLE_NINF -1
653 static const unsigned char yytable
[] =
655 59, 60, 50, 61, 1, 62, 63, 64, 65, 12,
656 66, 67, 53, 68, 54, 85, 51, 55, 69, 56,
657 70, 57, 58, 93, 13, 14, 15, 16, 17, 76,
658 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
659 28, 85, 43, 44, 90, 45, 41, 42, 46, 86,
660 47, 95, 48, 49, 87, 53, 39, 54, 40, 6,
661 55, 8, 56, 73, 57, 58, 5, 6, 7, 8,
662 78, 79, 71, 72, 74, 75, 91, 80, 89, 52,
663 81, 82, 83, 84, 94, 92, 0, 0, 76
666 static const yysigned_char yycheck
[] =
668 5, 6, 4, 8, 22, 10, 11, 12, 13, 0,
669 15, 16, 6, 18, 8, 10, 18, 11, 23, 13,
670 25, 15, 16, 18, 5, 6, 7, 8, 9, 23,
671 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
672 21, 10, 5, 6, 86, 8, 18, 19, 11, 18,
673 13, 93, 15, 16, 23, 6, 24, 8, 4, 19,
674 11, 21, 13, 3, 15, 16, 18, 19, 20, 21,
675 18, 19, 15, 15, 18, 24, 87, 18, 25, 24,
676 19, 19, 19, 19, 91, 19, -1, -1, 23
679 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
680 symbol of state STATE-NUM. */
681 static const unsigned char yystos
[] =
683 0, 22, 27, 28, 29, 18, 19, 20, 21, 39,
684 40, 41, 0, 5, 6, 7, 8, 9, 11, 12,
685 13, 14, 15, 16, 17, 18, 19, 20, 21, 30,
686 31, 32, 33, 34, 35, 36, 37, 38, 42, 24,
687 4, 18, 19, 5, 6, 8, 11, 13, 15, 16,
688 4, 18, 38, 6, 8, 11, 13, 15, 16, 5,
689 6, 8, 10, 11, 12, 13, 15, 16, 18, 23,
690 25, 15, 15, 3, 18, 24, 23, 43, 18, 19,
691 18, 19, 19, 19, 19, 10, 18, 23, 44, 25,
692 43, 41, 19, 18, 44, 43
695 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
696 # define YYSIZE_T __SIZE_TYPE__
698 #if ! defined (YYSIZE_T) && defined (size_t)
699 # define YYSIZE_T size_t
701 #if ! defined (YYSIZE_T)
702 # if defined (__STDC__) || defined (__cplusplus)
703 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
704 # define YYSIZE_T size_t
707 #if ! defined (YYSIZE_T)
708 # define YYSIZE_T unsigned int
711 #define yyerrok (yyerrstatus = 0)
712 #define yyclearin (yychar = YYEMPTY)
716 #define YYACCEPT goto yyacceptlab
717 #define YYABORT goto yyabortlab
718 #define YYERROR goto yyerrorlab
721 /* Like YYERROR except do call yyerror. This remains here temporarily
722 to ease the transition to the new meaning of YYERROR, for GCC.
723 Once GCC version 2 has supplanted version 1, this can go. */
725 #define YYFAIL goto yyerrlab
727 #define YYRECOVERING() (!!yyerrstatus)
729 #define YYBACKUP(Token, Value) \
731 if (yychar == YYEMPTY && yylen == 1) \
735 yytoken = YYTRANSLATE (yychar); \
741 yyerror (pc, "syntax error: cannot back up");\
747 #define YYERRCODE 256
749 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
752 #ifndef YYLLOC_DEFAULT
753 # define YYLLOC_DEFAULT(Current, Rhs, N) \
754 ((Current).first_line = (Rhs)[1].first_line, \
755 (Current).first_column = (Rhs)[1].first_column, \
756 (Current).last_line = (Rhs)[N].last_line, \
757 (Current).last_column = (Rhs)[N].last_column)
760 /* YYLEX -- calling `yylex' with the right arguments. */
763 # define YYLEX yylex (&yylval, YYLEX_PARAM)
765 # define YYLEX yylex (&yylval, pc)
768 /* Enable debugging if requested. */
772 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
773 # define YYFPRINTF fprintf
776 # define YYDPRINTF(Args) \
782 # define YYDSYMPRINT(Args) \
788 # define YYDSYMPRINTF(Title, Token, Value, Location) \
792 YYFPRINTF (stderr, "%s ", Title); \
793 yysymprint (stderr, \
795 YYFPRINTF (stderr, "\n"); \
799 /*------------------------------------------------------------------.
800 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
802 `------------------------------------------------------------------*/
804 #if defined (__STDC__) || defined (__cplusplus)
806 yy_stack_print (short *bottom
, short *top
)
809 yy_stack_print (bottom
, top
)
814 YYFPRINTF (stderr
, "Stack now");
815 for (/* Nothing. */; bottom
<= top
; ++bottom
)
816 YYFPRINTF (stderr
, " %d", *bottom
);
817 YYFPRINTF (stderr
, "\n");
820 # define YY_STACK_PRINT(Bottom, Top) \
823 yy_stack_print ((Bottom), (Top)); \
827 /*------------------------------------------------.
828 | Report that the YYRULE is going to be reduced. |
829 `------------------------------------------------*/
831 #if defined (__STDC__) || defined (__cplusplus)
833 yy_reduce_print (int yyrule
)
836 yy_reduce_print (yyrule
)
841 unsigned int yylno
= yyrline
[yyrule
];
842 YYFPRINTF (stderr
, "Reducing stack by rule %d (line %u), ",
844 /* Print the symbols being reduced, and their result. */
845 for (yyi
= yyprhs
[yyrule
]; 0 <= yyrhs
[yyi
]; yyi
++)
846 YYFPRINTF (stderr
, "%s ", yytname
[yyrhs
[yyi
]]);
847 YYFPRINTF (stderr
, "-> %s\n", yytname
[yyr1
[yyrule
]]);
850 # define YY_REDUCE_PRINT(Rule) \
853 yy_reduce_print (Rule); \
856 /* Nonzero means print parse trace. It is left uninitialized so that
857 multiple parsers can coexist. */
860 # define YYDPRINTF(Args)
861 # define YYDSYMPRINT(Args)
862 # define YYDSYMPRINTF(Title, Token, Value, Location)
863 # define YY_STACK_PRINT(Bottom, Top)
864 # define YY_REDUCE_PRINT(Rule)
865 #endif /* !YYDEBUG */
868 /* YYINITDEPTH -- initial size of the parser's stacks. */
870 # define YYINITDEPTH 200
873 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
874 if the built-in stack extension method is used).
876 Do not make this value too large; the results are undefined if
877 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
878 evaluated with infinite-precision integer arithmetic. */
880 #if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
885 # define YYMAXDEPTH 10000
893 # if defined (__GLIBC__) && defined (_STRING_H)
894 # define yystrlen strlen
896 /* Return the length of YYSTR. */
898 # if defined (__STDC__) || defined (__cplusplus)
899 yystrlen (const char *yystr
)
905 register const char *yys
= yystr
;
907 while (*yys
++ != '\0')
910 return yys
- yystr
- 1;
916 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
917 # define yystpcpy stpcpy
919 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
922 # if defined (__STDC__) || defined (__cplusplus)
923 yystpcpy (char *yydest
, const char *yysrc
)
925 yystpcpy (yydest
, yysrc
)
930 register char *yyd
= yydest
;
931 register const char *yys
= yysrc
;
933 while ((*yyd
++ = *yys
++) != '\0')
941 #endif /* !YYERROR_VERBOSE */
946 /*--------------------------------.
947 | Print this symbol on YYOUTPUT. |
948 `--------------------------------*/
950 #if defined (__STDC__) || defined (__cplusplus)
952 yysymprint (FILE *yyoutput
, int yytype
, YYSTYPE
*yyvaluep
)
955 yysymprint (yyoutput
, yytype
, yyvaluep
)
961 /* Pacify ``unused variable'' warnings. */
964 if (yytype
< YYNTOKENS
)
966 YYFPRINTF (yyoutput
, "token %s (", yytname
[yytype
]);
968 YYPRINT (yyoutput
, yytoknum
[yytype
], *yyvaluep
);
972 YYFPRINTF (yyoutput
, "nterm %s (", yytname
[yytype
]);
979 YYFPRINTF (yyoutput
, ")");
982 #endif /* ! YYDEBUG */
983 /*-----------------------------------------------.
984 | Release the memory associated to this symbol. |
985 `-----------------------------------------------*/
987 #if defined (__STDC__) || defined (__cplusplus)
989 yydestruct (int yytype
, YYSTYPE
*yyvaluep
)
992 yydestruct (yytype
, yyvaluep
)
997 /* Pacify ``unused variable'' warnings. */
1009 /* Prevent warnings from -Wmissing-prototypes. */
1011 #ifdef YYPARSE_PARAM
1012 # if defined (__STDC__) || defined (__cplusplus)
1013 int yyparse (void *YYPARSE_PARAM
);
1017 #else /* ! YYPARSE_PARAM */
1018 #if defined (__STDC__) || defined (__cplusplus)
1019 int yyparse ( parser_control
*pc
);
1023 #endif /* ! YYPARSE_PARAM */
1034 #ifdef YYPARSE_PARAM
1035 # if defined (__STDC__) || defined (__cplusplus)
1036 int yyparse (void *YYPARSE_PARAM
)
1038 int yyparse (YYPARSE_PARAM
)
1039 void *YYPARSE_PARAM
;
1041 #else /* ! YYPARSE_PARAM */
1042 #if defined (__STDC__) || defined (__cplusplus)
1044 yyparse ( parser_control
*pc
)
1048 parser_control
*pc
;
1052 /* The lookahead symbol. */
1055 /* The semantic value of the lookahead symbol. */
1058 /* Number of syntax errors so far. */
1061 register int yystate
;
1064 /* Number of tokens to shift before error messages enabled. */
1066 /* Lookahead token as an internal (translated) token number. */
1069 /* Three stacks and their tools:
1070 `yyss': related to states,
1071 `yyvs': related to semantic values,
1072 `yyls': related to locations.
1074 Refer to the stacks thru separate pointers, to allow yyoverflow
1075 to reallocate them elsewhere. */
1077 /* The state stack. */
1078 short yyssa
[YYINITDEPTH
];
1079 short *yyss
= yyssa
;
1080 register short *yyssp
;
1082 /* The semantic value stack. */
1083 YYSTYPE yyvsa
[YYINITDEPTH
];
1084 YYSTYPE
*yyvs
= yyvsa
;
1085 register YYSTYPE
*yyvsp
;
1089 #define YYPOPSTACK (yyvsp--, yyssp--)
1091 YYSIZE_T yystacksize
= YYINITDEPTH
;
1093 /* The variables used to return semantic value and location from the
1098 /* When reducing, the number of symbols on the RHS of the reduced
1102 YYDPRINTF ((stderr
, "Starting parse\n"));
1107 yychar
= YYEMPTY
; /* Cause a token to be read. */
1109 /* Initialize stack pointers.
1110 Waste one element of value and location stack
1111 so that they stay on the same level as the state stack.
1112 The wasted elements are never initialized. */
1119 /*------------------------------------------------------------.
1120 | yynewstate -- Push a new state, which is found in yystate. |
1121 `------------------------------------------------------------*/
1123 /* In all cases, when you get here, the value and location stacks
1124 have just been pushed. so pushing a state here evens the stacks.
1131 if (yyss
+ yystacksize
- 1 <= yyssp
)
1133 /* Get the current used size of the three stacks, in elements. */
1134 YYSIZE_T yysize
= yyssp
- yyss
+ 1;
1138 /* Give user a chance to reallocate the stack. Use copies of
1139 these so that the &'s don't force the real ones into
1141 YYSTYPE
*yyvs1
= yyvs
;
1142 short *yyss1
= yyss
;
1145 /* Each stack pointer address is followed by the size of the
1146 data in use in that stack, in bytes. This used to be a
1147 conditional around just the two extra args, but that might
1148 be undefined if yyoverflow is a macro. */
1149 yyoverflow ("parser stack overflow",
1150 &yyss1
, yysize
* sizeof (*yyssp
),
1151 &yyvs1
, yysize
* sizeof (*yyvsp
),
1158 #else /* no yyoverflow */
1159 # ifndef YYSTACK_RELOCATE
1162 /* Extend the stack our own way. */
1163 if (YYMAXDEPTH
<= yystacksize
)
1166 if (YYMAXDEPTH
< yystacksize
)
1167 yystacksize
= YYMAXDEPTH
;
1170 short *yyss1
= yyss
;
1171 union yyalloc
*yyptr
=
1172 (union yyalloc
*) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize
));
1175 YYSTACK_RELOCATE (yyss
);
1176 YYSTACK_RELOCATE (yyvs
);
1178 # undef YYSTACK_RELOCATE
1180 YYSTACK_FREE (yyss1
);
1183 #endif /* no yyoverflow */
1185 yyssp
= yyss
+ yysize
- 1;
1186 yyvsp
= yyvs
+ yysize
- 1;
1189 YYDPRINTF ((stderr
, "Stack size increased to %lu\n",
1190 (unsigned long int) yystacksize
));
1192 if (yyss
+ yystacksize
- 1 <= yyssp
)
1196 YYDPRINTF ((stderr
, "Entering state %d\n", yystate
));
1205 /* Do appropriate processing given the current state. */
1206 /* Read a lookahead token if we need one and don't already have one. */
1209 /* First try to decide what to do without reference to lookahead token. */
1211 yyn
= yypact
[yystate
];
1212 if (yyn
== YYPACT_NINF
)
1215 /* Not known => get a lookahead token if don't already have one. */
1217 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1218 if (yychar
== YYEMPTY
)
1220 YYDPRINTF ((stderr
, "Reading a token: "));
1224 if (yychar
<= YYEOF
)
1226 yychar
= yytoken
= YYEOF
;
1227 YYDPRINTF ((stderr
, "Now at end of input.\n"));
1231 yytoken
= YYTRANSLATE (yychar
);
1232 YYDSYMPRINTF ("Next token is", yytoken
, &yylval
, &yylloc
);
1235 /* If the proper action on seeing token YYTOKEN is to reduce or to
1236 detect an error, take that action. */
1238 if (yyn
< 0 || YYLAST
< yyn
|| yycheck
[yyn
] != yytoken
)
1243 if (yyn
== 0 || yyn
== YYTABLE_NINF
)
1252 /* Shift the lookahead token. */
1253 YYDPRINTF ((stderr
, "Shifting token %s, ", yytname
[yytoken
]));
1255 /* Discard the token being shifted unless it is eof. */
1256 if (yychar
!= YYEOF
)
1262 /* Count tokens shifted since error; after three, turn off error
1271 /*-----------------------------------------------------------.
1272 | yydefault -- do the default action for the current state. |
1273 `-----------------------------------------------------------*/
1275 yyn
= yydefact
[yystate
];
1281 /*-----------------------------.
1282 | yyreduce -- Do a reduction. |
1283 `-----------------------------*/
1285 /* yyn is the number of a rule to reduce with. */
1288 /* If YYLEN is nonzero, implement the default value of the action:
1291 Otherwise, the following line sets YYVAL to garbage.
1292 This behavior is undocumented and Bison
1293 users should not rely upon it. Assigning to YYVAL
1294 unconditionally makes the parser a bit smaller, and it avoids a
1295 GCC warning that YYVAL may be used uninitialized. */
1296 yyval
= yyvsp
[1-yylen
];
1299 YY_REDUCE_PRINT (yyn
);
1303 #line 236 "getdate.y"
1305 pc
->seconds
= yyvsp
[0].timespec
;
1306 pc
->timespec_seen
= true;
1311 #line 249 "getdate.y"
1312 { pc
->times_seen
++; }
1316 #line 251 "getdate.y"
1317 { pc
->local_zones_seen
++; }
1321 #line 253 "getdate.y"
1322 { pc
->zones_seen
++; }
1326 #line 255 "getdate.y"
1327 { pc
->dates_seen
++; }
1331 #line 257 "getdate.y"
1332 { pc
->days_seen
++; }
1336 #line 259 "getdate.y"
1337 { pc
->rels_seen
= true; }
1341 #line 265 "getdate.y"
1343 pc
->hour
= yyvsp
[-1].textintval
.value
;
1345 pc
->seconds
.tv_sec
= 0;
1346 pc
->seconds
.tv_nsec
= 0;
1347 pc
->meridian
= yyvsp
[0].intval
;
1352 #line 273 "getdate.y"
1354 pc
->hour
= yyvsp
[-3].textintval
.value
;
1355 pc
->minutes
= yyvsp
[-1].textintval
.value
;
1356 pc
->seconds
.tv_sec
= 0;
1357 pc
->seconds
.tv_nsec
= 0;
1358 pc
->meridian
= yyvsp
[0].intval
;
1363 #line 281 "getdate.y"
1365 pc
->hour
= yyvsp
[-4].textintval
.value
;
1366 pc
->minutes
= yyvsp
[-2].textintval
.value
;
1367 pc
->seconds
.tv_sec
= 0;
1368 pc
->seconds
.tv_nsec
= 0;
1369 pc
->meridian
= MER24
;
1371 pc
->time_zone
= time_zone_hhmm (yyvsp
[-1].textintval
, yyvsp
[0].intval
);
1376 #line 291 "getdate.y"
1378 pc
->hour
= yyvsp
[-5].textintval
.value
;
1379 pc
->minutes
= yyvsp
[-3].textintval
.value
;
1380 pc
->seconds
= yyvsp
[-1].timespec
;
1381 pc
->meridian
= yyvsp
[0].intval
;
1386 #line 298 "getdate.y"
1388 pc
->hour
= yyvsp
[-6].textintval
.value
;
1389 pc
->minutes
= yyvsp
[-4].textintval
.value
;
1390 pc
->seconds
= yyvsp
[-2].timespec
;
1391 pc
->meridian
= MER24
;
1393 pc
->time_zone
= time_zone_hhmm (yyvsp
[-1].textintval
, yyvsp
[0].intval
);
1398 #line 310 "getdate.y"
1400 pc
->local_isdst
= yyvsp
[0].intval
;
1401 pc
->dsts_seen
+= (0 < yyvsp
[0].intval
);
1406 #line 315 "getdate.y"
1408 pc
->local_isdst
= 1;
1409 pc
->dsts_seen
+= (0 < yyvsp
[-1].intval
) + 1;
1414 #line 323 "getdate.y"
1415 { pc
->time_zone
= yyvsp
[0].intval
; }
1419 #line 325 "getdate.y"
1420 { pc
->time_zone
= yyvsp
[-1].intval
; pc
->rels_seen
= true; }
1424 #line 327 "getdate.y"
1425 { pc
->time_zone
= yyvsp
[-2].intval
+ time_zone_hhmm (yyvsp
[-1].textintval
, yyvsp
[0].intval
); }
1429 #line 329 "getdate.y"
1430 { pc
->time_zone
= yyvsp
[0].intval
+ 60; }
1434 #line 331 "getdate.y"
1435 { pc
->time_zone
= yyvsp
[-1].intval
+ 60; }
1439 #line 336 "getdate.y"
1441 pc
->day_ordinal
= 1;
1442 pc
->day_number
= yyvsp
[0].intval
;
1447 #line 341 "getdate.y"
1449 pc
->day_ordinal
= 1;
1450 pc
->day_number
= yyvsp
[-1].intval
;
1455 #line 346 "getdate.y"
1457 pc
->day_ordinal
= yyvsp
[-1].intval
;
1458 pc
->day_number
= yyvsp
[0].intval
;
1463 #line 351 "getdate.y"
1465 pc
->day_ordinal
= yyvsp
[-1].textintval
.value
;
1466 pc
->day_number
= yyvsp
[0].intval
;
1471 #line 359 "getdate.y"
1473 pc
->month
= yyvsp
[-2].textintval
.value
;
1474 pc
->day
= yyvsp
[0].textintval
.value
;
1479 #line 364 "getdate.y"
1481 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1482 otherwise as MM/DD/YY.
1483 The goal in recognizing YYYY/MM/DD is solely to support legacy
1484 machine-generated dates like those in an RCS log listing. If
1485 you want portability, use the ISO 8601 format. */
1486 if (4 <= yyvsp
[-4].textintval
.digits
)
1488 pc
->year
= yyvsp
[-4].textintval
;
1489 pc
->month
= yyvsp
[-2].textintval
.value
;
1490 pc
->day
= yyvsp
[0].textintval
.value
;
1494 pc
->month
= yyvsp
[-4].textintval
.value
;
1495 pc
->day
= yyvsp
[-2].textintval
.value
;
1496 pc
->year
= yyvsp
[0].textintval
;
1502 #line 384 "getdate.y"
1504 /* ISO 8601 format. YYYY-MM-DD. */
1505 pc
->year
= yyvsp
[-2].textintval
;
1506 pc
->month
= -yyvsp
[-1].textintval
.value
;
1507 pc
->day
= -yyvsp
[0].textintval
.value
;
1512 #line 391 "getdate.y"
1514 /* e.g. 17-JUN-1992. */
1515 pc
->day
= yyvsp
[-2].textintval
.value
;
1516 pc
->month
= yyvsp
[-1].intval
;
1517 pc
->year
.value
= -yyvsp
[0].textintval
.value
;
1518 pc
->year
.digits
= yyvsp
[0].textintval
.digits
;
1523 #line 399 "getdate.y"
1525 /* e.g. JUN-17-1992. */
1526 pc
->month
= yyvsp
[-2].intval
;
1527 pc
->day
= -yyvsp
[-1].textintval
.value
;
1528 pc
->year
.value
= -yyvsp
[0].textintval
.value
;
1529 pc
->year
.digits
= yyvsp
[0].textintval
.digits
;
1534 #line 407 "getdate.y"
1536 pc
->month
= yyvsp
[-1].intval
;
1537 pc
->day
= yyvsp
[0].textintval
.value
;
1542 #line 412 "getdate.y"
1544 pc
->month
= yyvsp
[-3].intval
;
1545 pc
->day
= yyvsp
[-2].textintval
.value
;
1546 pc
->year
= yyvsp
[0].textintval
;
1551 #line 418 "getdate.y"
1553 pc
->day
= yyvsp
[-1].textintval
.value
;
1554 pc
->month
= yyvsp
[0].intval
;
1559 #line 423 "getdate.y"
1561 pc
->day
= yyvsp
[-2].textintval
.value
;
1562 pc
->month
= yyvsp
[-1].intval
;
1563 pc
->year
= yyvsp
[0].textintval
;
1568 #line 432 "getdate.y"
1570 pc
->rel_ns
= -pc
->rel_ns
;
1571 pc
->rel_seconds
= -pc
->rel_seconds
;
1572 pc
->rel_minutes
= -pc
->rel_minutes
;
1573 pc
->rel_hour
= -pc
->rel_hour
;
1574 pc
->rel_day
= -pc
->rel_day
;
1575 pc
->rel_month
= -pc
->rel_month
;
1576 pc
->rel_year
= -pc
->rel_year
;
1581 #line 446 "getdate.y"
1582 { pc
->rel_year
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1586 #line 448 "getdate.y"
1587 { pc
->rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1591 #line 450 "getdate.y"
1592 { pc
->rel_year
+= yyvsp
[0].intval
; }
1596 #line 452 "getdate.y"
1597 { pc
->rel_month
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1601 #line 454 "getdate.y"
1602 { pc
->rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1606 #line 456 "getdate.y"
1607 { pc
->rel_month
+= yyvsp
[0].intval
; }
1611 #line 458 "getdate.y"
1612 { pc
->rel_day
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1616 #line 460 "getdate.y"
1617 { pc
->rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1621 #line 462 "getdate.y"
1622 { pc
->rel_day
+= yyvsp
[0].intval
; }
1626 #line 464 "getdate.y"
1627 { pc
->rel_hour
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1631 #line 466 "getdate.y"
1632 { pc
->rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1636 #line 468 "getdate.y"
1637 { pc
->rel_hour
+= yyvsp
[0].intval
; }
1641 #line 470 "getdate.y"
1642 { pc
->rel_minutes
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1646 #line 472 "getdate.y"
1647 { pc
->rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1651 #line 474 "getdate.y"
1652 { pc
->rel_minutes
+= yyvsp
[0].intval
; }
1656 #line 476 "getdate.y"
1657 { pc
->rel_seconds
+= yyvsp
[-1].intval
* yyvsp
[0].intval
; }
1661 #line 478 "getdate.y"
1662 { pc
->rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1666 #line 480 "getdate.y"
1667 { pc
->rel_seconds
+= yyvsp
[-1].timespec
.tv_sec
* yyvsp
[0].intval
; pc
->rel_ns
+= yyvsp
[-1].timespec
.tv_nsec
* yyvsp
[0].intval
; }
1671 #line 482 "getdate.y"
1672 { pc
->rel_seconds
+= yyvsp
[-1].timespec
.tv_sec
* yyvsp
[0].intval
; pc
->rel_ns
+= yyvsp
[-1].timespec
.tv_nsec
* yyvsp
[0].intval
; }
1676 #line 484 "getdate.y"
1677 { pc
->rel_seconds
+= yyvsp
[0].intval
; }
1681 #line 490 "getdate.y"
1682 { pc
->rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1686 #line 492 "getdate.y"
1687 { pc
->rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1691 #line 494 "getdate.y"
1692 { pc
->rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1696 #line 496 "getdate.y"
1697 { pc
->rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1701 #line 498 "getdate.y"
1702 { pc
->rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1706 #line 500 "getdate.y"
1707 { pc
->rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1711 #line 508 "getdate.y"
1712 { yyval
.timespec
.tv_sec
= yyvsp
[0].textintval
.value
; yyval
.timespec
.tv_nsec
= 0; }
1716 #line 514 "getdate.y"
1717 { yyval
.timespec
.tv_sec
= yyvsp
[0].textintval
.value
; yyval
.timespec
.tv_nsec
= 0; }
1721 #line 519 "getdate.y"
1723 if (pc
->dates_seen
&& ! pc
->year
.digits
1724 && ! pc
->rels_seen
&& (pc
->times_seen
|| 2 < yyvsp
[0].textintval
.digits
))
1725 pc
->year
= yyvsp
[0].textintval
;
1728 if (4 < yyvsp
[0].textintval
.digits
)
1731 pc
->day
= yyvsp
[0].textintval
.value
% 100;
1732 pc
->month
= (yyvsp
[0].textintval
.value
/ 100) % 100;
1733 pc
->year
.value
= yyvsp
[0].textintval
.value
/ 10000;
1734 pc
->year
.digits
= yyvsp
[0].textintval
.digits
- 4;
1739 if (yyvsp
[0].textintval
.digits
<= 2)
1741 pc
->hour
= yyvsp
[0].textintval
.value
;
1746 pc
->hour
= yyvsp
[0].textintval
.value
/ 100;
1747 pc
->minutes
= yyvsp
[0].textintval
.value
% 100;
1749 pc
->seconds
.tv_sec
= 0;
1750 pc
->seconds
.tv_nsec
= 0;
1751 pc
->meridian
= MER24
;
1758 #line 556 "getdate.y"
1759 { yyval
.intval
= -1; }
1763 #line 558 "getdate.y"
1764 { yyval
.intval
= yyvsp
[0].textintval
.value
; }
1768 #line 563 "getdate.y"
1769 { yyval
.intval
= MER24
; }
1773 #line 565 "getdate.y"
1774 { yyval
.intval
= yyvsp
[0].intval
; }
1780 /* Line 1000 of yacc.c. */
1781 #line 1782 "getdate.c"
1787 YY_STACK_PRINT (yyss
, yyssp
);
1792 /* Now `shift' the result of the reduction. Determine what state
1793 that goes to, based on the state we popped back to and the rule
1794 number reduced by. */
1798 yystate
= yypgoto
[yyn
- YYNTOKENS
] + *yyssp
;
1799 if (0 <= yystate
&& yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
1800 yystate
= yytable
[yystate
];
1802 yystate
= yydefgoto
[yyn
- YYNTOKENS
];
1807 /*------------------------------------.
1808 | yyerrlab -- here on detecting error |
1809 `------------------------------------*/
1811 /* If not already recovering from an error, report this error. */
1816 yyn
= yypact
[yystate
];
1818 if (YYPACT_NINF
< yyn
&& yyn
< YYLAST
)
1820 YYSIZE_T yysize
= 0;
1821 int yytype
= YYTRANSLATE (yychar
);
1822 const char* yyprefix
;
1826 /* Start YYX at -YYN if negative to avoid negative indexes in
1828 int yyxbegin
= yyn
< 0 ? -yyn
: 0;
1830 /* Stay within bounds of both yycheck and yytname. */
1831 int yychecklim
= YYLAST
- yyn
;
1832 int yyxend
= yychecklim
< YYNTOKENS
? yychecklim
: YYNTOKENS
;
1835 yyprefix
= ", expecting ";
1836 for (yyx
= yyxbegin
; yyx
< yyxend
; ++yyx
)
1837 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1839 yysize
+= yystrlen (yyprefix
) + yystrlen (yytname
[yyx
]);
1847 yysize
+= (sizeof ("syntax error, unexpected ")
1848 + yystrlen (yytname
[yytype
]));
1849 yymsg
= (char *) YYSTACK_ALLOC (yysize
);
1852 char *yyp
= yystpcpy (yymsg
, "syntax error, unexpected ");
1853 yyp
= yystpcpy (yyp
, yytname
[yytype
]);
1857 yyprefix
= ", expecting ";
1858 for (yyx
= yyxbegin
; yyx
< yyxend
; ++yyx
)
1859 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1861 yyp
= yystpcpy (yyp
, yyprefix
);
1862 yyp
= yystpcpy (yyp
, yytname
[yyx
]);
1866 yyerror (pc
, yymsg
);
1867 YYSTACK_FREE (yymsg
);
1870 yyerror (pc
, "syntax error; also virtual memory exhausted");
1873 #endif /* YYERROR_VERBOSE */
1874 yyerror (pc
, "syntax error");
1879 if (yyerrstatus
== 3)
1881 /* If just tried and failed to reuse lookahead token after an
1882 error, discard it. */
1884 if (yychar
<= YYEOF
)
1886 /* If at end of input, pop the error token,
1887 then the rest of the stack, then return failure. */
1888 if (yychar
== YYEOF
)
1894 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1895 yydestruct (yystos
[*yyssp
], yyvsp
);
1900 YYDSYMPRINTF ("Error: discarding", yytoken
, &yylval
, &yylloc
);
1901 yydestruct (yytoken
, &yylval
);
1907 /* Else will try to reuse lookahead token after shifting the error
1912 /*---------------------------------------------------.
1913 | yyerrorlab -- error raised explicitly by YYERROR. |
1914 `---------------------------------------------------*/
1918 /* Pacify GCC when the user code never invokes YYERROR and the label
1919 yyerrorlab therefore never appears in user code. */
1930 /*-------------------------------------------------------------.
1931 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1932 `-------------------------------------------------------------*/
1934 yyerrstatus
= 3; /* Each real token shifted decrements this. */
1938 yyn
= yypact
[yystate
];
1939 if (yyn
!= YYPACT_NINF
)
1942 if (0 <= yyn
&& yyn
<= YYLAST
&& yycheck
[yyn
] == YYTERROR
)
1950 /* Pop the current state because it cannot handle the error token. */
1954 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1955 yydestruct (yystos
[yystate
], yyvsp
);
1958 YY_STACK_PRINT (yyss
, yyssp
);
1964 YYDPRINTF ((stderr
, "Shifting error token, "));
1973 /*-------------------------------------.
1974 | yyacceptlab -- YYACCEPT comes here. |
1975 `-------------------------------------*/
1980 /*-----------------------------------.
1981 | yyabortlab -- YYABORT comes here. |
1982 `-----------------------------------*/
1988 /*----------------------------------------------.
1989 | yyoverflowlab -- parser overflow comes here. |
1990 `----------------------------------------------*/
1992 yyerror (pc
, "parser stack overflow");
2000 YYSTACK_FREE (yyss
);
2006 #line 568 "getdate.y"
2009 static table
const meridian_table
[] =
2011 { "AM", tMERIDIAN
, MERam
},
2012 { "A.M.", tMERIDIAN
, MERam
},
2013 { "PM", tMERIDIAN
, MERpm
},
2014 { "P.M.", tMERIDIAN
, MERpm
},
2018 static table
const dst_table
[] =
2023 static table
const month_and_day_table
[] =
2025 { "JANUARY", tMONTH
, 1 },
2026 { "FEBRUARY", tMONTH
, 2 },
2027 { "MARCH", tMONTH
, 3 },
2028 { "APRIL", tMONTH
, 4 },
2029 { "MAY", tMONTH
, 5 },
2030 { "JUNE", tMONTH
, 6 },
2031 { "JULY", tMONTH
, 7 },
2032 { "AUGUST", tMONTH
, 8 },
2033 { "SEPTEMBER",tMONTH
, 9 },
2034 { "SEPT", tMONTH
, 9 },
2035 { "OCTOBER", tMONTH
, 10 },
2036 { "NOVEMBER", tMONTH
, 11 },
2037 { "DECEMBER", tMONTH
, 12 },
2038 { "SUNDAY", tDAY
, 0 },
2039 { "MONDAY", tDAY
, 1 },
2040 { "TUESDAY", tDAY
, 2 },
2041 { "TUES", tDAY
, 2 },
2042 { "WEDNESDAY",tDAY
, 3 },
2043 { "WEDNES", tDAY
, 3 },
2044 { "THURSDAY", tDAY
, 4 },
2045 { "THUR", tDAY
, 4 },
2046 { "THURS", tDAY
, 4 },
2047 { "FRIDAY", tDAY
, 5 },
2048 { "SATURDAY", tDAY
, 6 },
2052 static table
const time_units_table
[] =
2054 { "YEAR", tYEAR_UNIT
, 1 },
2055 { "MONTH", tMONTH_UNIT
, 1 },
2056 { "FORTNIGHT",tDAY_UNIT
, 14 },
2057 { "WEEK", tDAY_UNIT
, 7 },
2058 { "DAY", tDAY_UNIT
, 1 },
2059 { "HOUR", tHOUR_UNIT
, 1 },
2060 { "MINUTE", tMINUTE_UNIT
, 1 },
2061 { "MIN", tMINUTE_UNIT
, 1 },
2062 { "SECOND", tSEC_UNIT
, 1 },
2063 { "SEC", tSEC_UNIT
, 1 },
2067 /* Assorted relative-time words. */
2068 static table
const relative_time_table
[] =
2070 { "TOMORROW", tDAY_UNIT
, 1 },
2071 { "YESTERDAY",tDAY_UNIT
, -1 },
2072 { "TODAY", tDAY_UNIT
, 0 },
2073 { "NOW", tDAY_UNIT
, 0 },
2074 { "LAST", tORDINAL
, -1 },
2075 { "THIS", tORDINAL
, 0 },
2076 { "NEXT", tORDINAL
, 1 },
2077 { "FIRST", tORDINAL
, 1 },
2078 /*{ "SECOND", tORDINAL, 2 }, */
2079 { "THIRD", tORDINAL
, 3 },
2080 { "FOURTH", tORDINAL
, 4 },
2081 { "FIFTH", tORDINAL
, 5 },
2082 { "SIXTH", tORDINAL
, 6 },
2083 { "SEVENTH", tORDINAL
, 7 },
2084 { "EIGHTH", tORDINAL
, 8 },
2085 { "NINTH", tORDINAL
, 9 },
2086 { "TENTH", tORDINAL
, 10 },
2087 { "ELEVENTH", tORDINAL
, 11 },
2088 { "TWELFTH", tORDINAL
, 12 },
2093 /* The universal time zone table. These labels can be used even for
2094 time stamps that would not otherwise be valid, e.g., GMT time
2095 stamps in London during summer. */
2096 static table
const universal_time_zone_table
[] =
2098 { "GMT", tZONE
, HOUR ( 0) }, /* Greenwich Mean */
2099 { "UT", tZONE
, HOUR ( 0) }, /* Universal (Coordinated) */
2100 { "UTC", tZONE
, HOUR ( 0) },
2104 /* The time zone table. This table is necessarily incomplete, as time
2105 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
2106 as Eastern time in Australia, not as US Eastern Standard Time.
2107 You cannot rely on getdate to handle arbitrary time zone
2108 abbreviations; use numeric abbreviations like `-0500' instead. */
2109 static table
const time_zone_table
[] =
2111 { "WET", tZONE
, HOUR ( 0) }, /* Western European */
2112 { "WEST", tDAYZONE
, HOUR ( 0) }, /* Western European Summer */
2113 { "BST", tDAYZONE
, HOUR ( 0) }, /* British Summer */
2114 { "ART", tZONE
, -HOUR ( 3) }, /* Argentina */
2115 { "BRT", tZONE
, -HOUR ( 3) }, /* Brazil */
2116 { "BRST", tDAYZONE
, -HOUR ( 3) }, /* Brazil Summer */
2117 { "NST", tZONE
, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
2118 { "NDT", tDAYZONE
,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
2119 { "AST", tZONE
, -HOUR ( 4) }, /* Atlantic Standard */
2120 { "ADT", tDAYZONE
, -HOUR ( 4) }, /* Atlantic Daylight */
2121 { "CLT", tZONE
, -HOUR ( 4) }, /* Chile */
2122 { "CLST", tDAYZONE
, -HOUR ( 4) }, /* Chile Summer */
2123 { "EST", tZONE
, -HOUR ( 5) }, /* Eastern Standard */
2124 { "EDT", tDAYZONE
, -HOUR ( 5) }, /* Eastern Daylight */
2125 { "CST", tZONE
, -HOUR ( 6) }, /* Central Standard */
2126 { "CDT", tDAYZONE
, -HOUR ( 6) }, /* Central Daylight */
2127 { "MST", tZONE
, -HOUR ( 7) }, /* Mountain Standard */
2128 { "MDT", tDAYZONE
, -HOUR ( 7) }, /* Mountain Daylight */
2129 { "PST", tZONE
, -HOUR ( 8) }, /* Pacific Standard */
2130 { "PDT", tDAYZONE
, -HOUR ( 8) }, /* Pacific Daylight */
2131 { "AKST", tZONE
, -HOUR ( 9) }, /* Alaska Standard */
2132 { "AKDT", tDAYZONE
, -HOUR ( 9) }, /* Alaska Daylight */
2133 { "HST", tZONE
, -HOUR (10) }, /* Hawaii Standard */
2134 { "HAST", tZONE
, -HOUR (10) }, /* Hawaii-Aleutian Standard */
2135 { "HADT", tDAYZONE
, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
2136 { "SST", tZONE
, -HOUR (12) }, /* Samoa Standard */
2137 { "WAT", tZONE
, HOUR ( 1) }, /* West Africa */
2138 { "CET", tZONE
, HOUR ( 1) }, /* Central European */
2139 { "CEST", tDAYZONE
, HOUR ( 1) }, /* Central European Summer */
2140 { "MET", tZONE
, HOUR ( 1) }, /* Middle European */
2141 { "MEZ", tZONE
, HOUR ( 1) }, /* Middle European */
2142 { "MEST", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
2143 { "MESZ", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
2144 { "EET", tZONE
, HOUR ( 2) }, /* Eastern European */
2145 { "EEST", tDAYZONE
, HOUR ( 2) }, /* Eastern European Summer */
2146 { "CAT", tZONE
, HOUR ( 2) }, /* Central Africa */
2147 { "SAST", tZONE
, HOUR ( 2) }, /* South Africa Standard */
2148 { "EAT", tZONE
, HOUR ( 3) }, /* East Africa */
2149 { "MSK", tZONE
, HOUR ( 3) }, /* Moscow */
2150 { "MSD", tDAYZONE
, HOUR ( 3) }, /* Moscow Daylight */
2151 { "IST", tZONE
, (HOUR ( 5) + 30) }, /* India Standard */
2152 { "SGT", tZONE
, HOUR ( 8) }, /* Singapore */
2153 { "KST", tZONE
, HOUR ( 9) }, /* Korea Standard */
2154 { "JST", tZONE
, HOUR ( 9) }, /* Japan Standard */
2155 { "GST", tZONE
, HOUR (10) }, /* Guam Standard */
2156 { "NZST", tZONE
, HOUR (12) }, /* New Zealand Standard */
2157 { "NZDT", tDAYZONE
, HOUR (12) }, /* New Zealand Daylight */
2161 /* Military time zone table. */
2162 static table
const military_table
[] =
2164 { "A", tZONE
, -HOUR ( 1) },
2165 { "B", tZONE
, -HOUR ( 2) },
2166 { "C", tZONE
, -HOUR ( 3) },
2167 { "D", tZONE
, -HOUR ( 4) },
2168 { "E", tZONE
, -HOUR ( 5) },
2169 { "F", tZONE
, -HOUR ( 6) },
2170 { "G", tZONE
, -HOUR ( 7) },
2171 { "H", tZONE
, -HOUR ( 8) },
2172 { "I", tZONE
, -HOUR ( 9) },
2173 { "K", tZONE
, -HOUR (10) },
2174 { "L", tZONE
, -HOUR (11) },
2175 { "M", tZONE
, -HOUR (12) },
2176 { "N", tZONE
, HOUR ( 1) },
2177 { "O", tZONE
, HOUR ( 2) },
2178 { "P", tZONE
, HOUR ( 3) },
2179 { "Q", tZONE
, HOUR ( 4) },
2180 { "R", tZONE
, HOUR ( 5) },
2181 { "S", tZONE
, HOUR ( 6) },
2182 { "T", tZONE
, HOUR ( 7) },
2183 { "U", tZONE
, HOUR ( 8) },
2184 { "V", tZONE
, HOUR ( 9) },
2185 { "W", tZONE
, HOUR (10) },
2186 { "X", tZONE
, HOUR (11) },
2187 { "Y", tZONE
, HOUR (12) },
2188 { "Z", tZONE
, HOUR ( 0) },
2194 /* Convert a time zone expressed as HH:MM into an integer count of
2195 minutes. If MM is negative, then S is of the form HHMM and needs
2196 to be picked apart; otherwise, S is of the form HH. */
2199 time_zone_hhmm (textint s
, long int mm
)
2202 return (s
.value
/ 100) * 60 + s
.value
% 100;
2204 return s
.value
* 60 + (s
.negative
? -mm
: mm
);
2208 to_hour (long int hours
, int meridian
)
2212 default: /* Pacify GCC. */
2214 return 0 <= hours
&& hours
< 24 ? hours
: -1;
2216 return 0 < hours
&& hours
< 12 ? hours
: hours
== 12 ? 0 : -1;
2218 return 0 < hours
&& hours
< 12 ? hours
+ 12 : hours
== 12 ? 12 : -1;
2223 to_year (textint textyear
)
2225 long int year
= textyear
.value
;
2230 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2231 years 69-99 map to 1969-1999. */
2232 else if (textyear
.digits
== 2)
2233 year
+= year
< 69 ? 2000 : 1900;
2238 static table
const *
2239 lookup_zone (parser_control
const *pc
, char const *name
)
2243 for (tp
= universal_time_zone_table
; tp
->name
; tp
++)
2244 if (strcmp (name
, tp
->name
) == 0)
2247 /* Try local zone abbreviations before those in time_zone_table, as
2248 the local ones are more likely to be right. */
2249 for (tp
= pc
->local_time_zone_table
; tp
->name
; tp
++)
2250 if (strcmp (name
, tp
->name
) == 0)
2253 for (tp
= time_zone_table
; tp
->name
; tp
++)
2254 if (strcmp (name
, tp
->name
) == 0)
2260 #if ! HAVE_TM_GMTOFF
2261 /* Yield the difference between *A and *B,
2262 measured in seconds, ignoring leap seconds.
2263 The body of this function is taken directly from the GNU C Library;
2264 see src/strftime.c. */
2266 tm_diff (struct tm
const *a
, struct tm
const *b
)
2268 /* Compute intervening leap days correctly even if year is negative.
2269 Take care to avoid int overflow in leap day calculations. */
2270 int a4
= SHR (a
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (a
->tm_year
& 3);
2271 int b4
= SHR (b
->tm_year
, 2) + SHR (TM_YEAR_BASE
, 2) - ! (b
->tm_year
& 3);
2272 int a100
= a4
/ 25 - (a4
% 25 < 0);
2273 int b100
= b4
/ 25 - (b4
% 25 < 0);
2274 int a400
= SHR (a100
, 2);
2275 int b400
= SHR (b100
, 2);
2276 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
2277 long int ayear
= a
->tm_year
;
2278 long int years
= ayear
- b
->tm_year
;
2279 long int days
= (365 * years
+ intervening_leap_days
2280 + (a
->tm_yday
- b
->tm_yday
));
2281 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
2282 + (a
->tm_min
- b
->tm_min
))
2283 + (a
->tm_sec
- b
->tm_sec
));
2285 #endif /* ! HAVE_TM_GMTOFF */
2287 static table
const *
2288 lookup_word (parser_control
const *pc
, char *word
)
2297 /* Make it uppercase. */
2298 for (p
= word
; *p
; p
++)
2300 unsigned char ch
= *p
;
2305 for (tp
= meridian_table
; tp
->name
; tp
++)
2306 if (strcmp (word
, tp
->name
) == 0)
2309 /* See if we have an abbreviation for a month. */
2310 wordlen
= strlen (word
);
2311 abbrev
= wordlen
== 3 || (wordlen
== 4 && word
[3] == '.');
2313 for (tp
= month_and_day_table
; tp
->name
; tp
++)
2314 if ((abbrev
? strncmp (word
, tp
->name
, 3) : strcmp (word
, tp
->name
)) == 0)
2317 if ((tp
= lookup_zone (pc
, word
)))
2320 if (strcmp (word
, dst_table
[0].name
) == 0)
2323 for (tp
= time_units_table
; tp
->name
; tp
++)
2324 if (strcmp (word
, tp
->name
) == 0)
2327 /* Strip off any plural and try the units table again. */
2328 if (word
[wordlen
- 1] == 'S')
2330 word
[wordlen
- 1] = '\0';
2331 for (tp
= time_units_table
; tp
->name
; tp
++)
2332 if (strcmp (word
, tp
->name
) == 0)
2334 word
[wordlen
- 1] = 'S'; /* For "this" in relative_time_table. */
2337 for (tp
= relative_time_table
; tp
->name
; tp
++)
2338 if (strcmp (word
, tp
->name
) == 0)
2341 /* Military time zones. */
2343 for (tp
= military_table
; tp
->name
; tp
++)
2344 if (word
[0] == tp
->name
[0])
2347 /* Drop out any periods and try the time zone table again. */
2348 for (period_found
= false, p
= q
= word
; (*p
= *q
); q
++)
2350 period_found
= true;
2353 if (period_found
&& (tp
= lookup_zone (pc
, word
)))
2360 yylex (YYSTYPE
*lvalp
, parser_control
*pc
)
2367 while (c
= *pc
->input
, ISSPACE (c
))
2370 if (ISDIGIT (c
) || c
== '-' || c
== '+')
2374 unsigned long int value
;
2375 if (c
== '-' || c
== '+')
2377 sign
= c
== '-' ? -1 : 1;
2378 while (c
= *++pc
->input
, ISSPACE (c
))
2381 /* skip the '-' sign */
2387 for (value
= 0; ; value
*= 10)
2389 unsigned long int value1
= value
+ (c
- '0');
2396 if (ULONG_MAX
/ 10 < value
)
2399 if ((c
== '.' || c
== ',') && ISDIGIT (p
[1]))
2404 unsigned long int value1
;
2406 /* Check for overflow when converting value to time_t. */
2421 if (value
!= value1
)
2424 /* Accumulate fraction, to ns precision. */
2427 for (digits
= 2; digits
<= LOG10_BILLION
; digits
++)
2434 /* Skip excess digits, truncating toward -Infinity. */
2436 for (; ISDIGIT (*p
); p
++)
2442 while (ISDIGIT (*p
))
2445 /* Adjust to the timespec convention, which is that
2446 tv_nsec is always a positive offset even if tv_sec is
2456 lvalp
->timespec
.tv_sec
= s
;
2457 lvalp
->timespec
.tv_nsec
= ns
;
2459 return sign
? tSDECIMAL_NUMBER
: tUDECIMAL_NUMBER
;
2463 lvalp
->textintval
.negative
= sign
< 0;
2466 lvalp
->textintval
.value
= - value
;
2467 if (0 < lvalp
->textintval
.value
)
2472 lvalp
->textintval
.value
= value
;
2473 if (lvalp
->textintval
.value
< 0)
2476 lvalp
->textintval
.digits
= p
- pc
->input
;
2478 return sign
? tSNUMBER
: tUNUMBER
;
2490 if (p
< buff
+ sizeof buff
- 1)
2494 while (ISALPHA (c
) || c
== '.');
2497 tp
= lookup_word (pc
, buff
);
2500 lvalp
->intval
= tp
->value
;
2505 return *pc
->input
++;
2521 /* Do nothing if the parser reports an error. */
2523 yyerror (parser_control
*pc ATTRIBUTE_UNUSED
, char *s ATTRIBUTE_UNUSED
)
2528 /* If *TM0 is the old and *TM1 is the new value of a struct tm after
2529 passing it to mktime, return true if it's OK that mktime returned T.
2530 It's not OK if *TM0 has out-of-range members. */
2533 mktime_ok (struct tm
const *tm0
, struct tm
const *tm1
, time_t t
)
2535 if (t
== (time_t) -1)
2537 /* Guard against falsely reporting an error when parsing a time
2538 stamp that happens to equal (time_t) -1, on a host that
2539 supports such a time stamp. */
2540 tm1
= localtime (&t
);
2545 return ! ((tm0
->tm_sec
^ tm1
->tm_sec
)
2546 | (tm0
->tm_min
^ tm1
->tm_min
)
2547 | (tm0
->tm_hour
^ tm1
->tm_hour
)
2548 | (tm0
->tm_mday
^ tm1
->tm_mday
)
2549 | (tm0
->tm_mon
^ tm1
->tm_mon
)
2550 | (tm0
->tm_year
^ tm1
->tm_year
));
2553 /* A reasonable upper bound for the size of ordinary TZ strings.
2554 Use heap allocation if TZ's length exceeds this. */
2555 enum { TZBUFSIZE
= 100 };
2557 /* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
2560 get_tz (char tzbuf
[TZBUFSIZE
])
2562 char *tz
= getenv ("TZ");
2565 size_t tzsize
= strlen (tz
) + 1;
2566 tz
= (tzsize
<= TZBUFSIZE
2567 ? memcpy (tzbuf
, tz
, tzsize
)
2568 : xmemdup (tz
, tzsize
));
2573 /* Parse a date/time string, storing the resulting time value into *RESULT.
2574 The string itself is pointed to by P. Return true if successful.
2575 P can be an incomplete or relative time specification; if so, use
2576 *NOW as the basis for the returned time. */
2578 get_date (struct timespec
*result
, char const *p
, struct timespec
const *now
)
2582 struct tm
const *tmp
;
2586 struct timespec gettime_buffer
;
2588 bool tz_was_altered
= false;
2590 char tz0buf
[TZBUFSIZE
];
2595 gettime (&gettime_buffer
);
2596 now
= &gettime_buffer
;
2599 Start
= now
->tv_sec
;
2600 Start_ns
= now
->tv_nsec
;
2602 tmp
= localtime (&now
->tv_sec
);
2606 while (c
= *p
, ISSPACE (c
))
2609 if (strncmp (p
, "TZ=\"", 4) == 0)
2611 char const *tzbase
= p
+ 4;
2615 for (s
= tzbase
; *s
; s
++, tzsize
++)
2619 if (! (*s
== '\\' || *s
== '"'))
2626 char tz1buf
[TZBUFSIZE
];
2627 bool large_tz
= TZBUFSIZE
< tzsize
;
2629 tz0
= get_tz (tz0buf
);
2630 z
= tz1
= large_tz
? xmalloc (tzsize
) : tz1buf
;
2631 for (s
= tzbase
; *s
!= '"'; s
++)
2632 *z
++ = *(s
+= *s
== '\\');
2634 setenv_ok
= setenv ("TZ", tz1
, 1) == 0;
2639 tz_was_altered
= true;
2645 pc
.year
.value
= tmp
->tm_year
;
2646 pc
.year
.value
+= TM_YEAR_BASE
;
2648 pc
.month
= tmp
->tm_mon
+ 1;
2649 pc
.day
= tmp
->tm_mday
;
2650 pc
.hour
= tmp
->tm_hour
;
2651 pc
.minutes
= tmp
->tm_min
;
2652 pc
.seconds
.tv_sec
= tmp
->tm_sec
;
2653 pc
.seconds
.tv_nsec
= Start_ns
;
2654 tm
.tm_isdst
= tmp
->tm_isdst
;
2656 pc
.meridian
= MER24
;
2664 pc
.timespec_seen
= false;
2665 pc
.rels_seen
= false;
2669 pc
.local_zones_seen
= 0;
2673 #if HAVE_STRUCT_TM_TM_ZONE
2674 pc
.local_time_zone_table
[0].name
= tmp
->tm_zone
;
2675 pc
.local_time_zone_table
[0].type
= tLOCAL_ZONE
;
2676 pc
.local_time_zone_table
[0].value
= tmp
->tm_isdst
;
2677 pc
.local_time_zone_table
[1].name
= NULL
;
2679 /* Probe the names used in the next three calendar quarters, looking
2680 for a tm_isdst different from the one we already have. */
2683 for (quarter
= 1; quarter
<= 3; quarter
++)
2685 time_t probe
= Start
+ quarter
* (90 * 24 * 60 * 60);
2686 struct tm
const *probe_tm
= localtime (&probe
);
2687 if (probe_tm
&& probe_tm
->tm_zone
2688 && probe_tm
->tm_isdst
!= pc
.local_time_zone_table
[0].value
)
2691 pc
.local_time_zone_table
[1].name
= probe_tm
->tm_zone
;
2692 pc
.local_time_zone_table
[1].type
= tLOCAL_ZONE
;
2693 pc
.local_time_zone_table
[1].value
= probe_tm
->tm_isdst
;
2694 pc
.local_time_zone_table
[2].name
= NULL
;
2704 extern char *tzname
[];
2707 for (i
= 0; i
< 2; i
++)
2709 pc
.local_time_zone_table
[i
].name
= tzname
[i
];
2710 pc
.local_time_zone_table
[i
].type
= tLOCAL_ZONE
;
2711 pc
.local_time_zone_table
[i
].value
= i
;
2713 pc
.local_time_zone_table
[i
].name
= NULL
;
2716 pc
.local_time_zone_table
[0].name
= NULL
;
2720 if (pc
.local_time_zone_table
[0].name
&& pc
.local_time_zone_table
[1].name
2721 && ! strcmp (pc
.local_time_zone_table
[0].name
,
2722 pc
.local_time_zone_table
[1].name
))
2724 /* This locale uses the same abbrevation for standard and
2725 daylight times. So if we see that abbreviation, we don't
2726 know whether it's daylight time. */
2727 pc
.local_time_zone_table
[0].value
= -1;
2728 pc
.local_time_zone_table
[1].name
= NULL
;
2731 if (yyparse (&pc
) != 0)
2734 if (pc
.timespec_seen
)
2735 *result
= pc
.seconds
;
2738 if (1 < (pc
.times_seen
| pc
.dates_seen
| pc
.days_seen
| pc
.dsts_seen
2739 | (pc
.local_zones_seen
+ pc
.zones_seen
)))
2742 tm
.tm_year
= to_year (pc
.year
) - TM_YEAR_BASE
;
2743 tm
.tm_mon
= pc
.month
- 1;
2744 tm
.tm_mday
= pc
.day
;
2745 if (pc
.times_seen
|| (pc
.rels_seen
&& ! pc
.dates_seen
&& ! pc
.days_seen
))
2747 tm
.tm_hour
= to_hour (pc
.hour
, pc
.meridian
);
2750 tm
.tm_min
= pc
.minutes
;
2751 tm
.tm_sec
= pc
.seconds
.tv_sec
;
2755 tm
.tm_hour
= tm
.tm_min
= tm
.tm_sec
= 0;
2756 pc
.seconds
.tv_nsec
= 0;
2759 /* Let mktime deduce tm_isdst if we have an absolute time stamp. */
2763 /* But if the input explicitly specifies local time with or without
2764 DST, give mktime that information. */
2765 if (pc
.local_zones_seen
)
2766 tm
.tm_isdst
= pc
.local_isdst
;
2770 Start
= mktime (&tm
);
2772 if (! mktime_ok (&tm0
, &tm
, Start
))
2774 if (! pc
.zones_seen
)
2778 /* Guard against falsely reporting errors near the time_t
2779 boundaries when parsing times in other time zones. For
2780 example, suppose the input string "1969-12-31 23:00:00 -0100",
2781 the current time zone is 8 hours ahead of UTC, and the min
2782 time_t value is 1970-01-01 00:00:00 UTC. Then the min
2783 localtime value is 1970-01-01 08:00:00, and mktime will
2784 therefore fail on 1969-12-31 23:00:00. To work around the
2785 problem, set the time zone to 1 hour behind UTC temporarily
2786 by setting TZ="XXX1:00" and try mktime again. */
2788 long int time_zone
= pc
.time_zone
;
2789 long int abs_time_zone
= time_zone
< 0 ? - time_zone
: time_zone
;
2790 long int abs_time_zone_hour
= abs_time_zone
/ 60;
2791 int abs_time_zone_min
= abs_time_zone
% 60;
2792 char tz1buf
[sizeof "XXX+0:00"
2793 + sizeof pc
.time_zone
* CHAR_BIT
/ 3];
2794 if (!tz_was_altered
)
2795 tz0
= get_tz (tz0buf
);
2796 sprintf (tz1buf
, "XXX%s%ld:%02d", "-" + (time_zone
< 0),
2797 abs_time_zone_hour
, abs_time_zone_min
);
2798 if (setenv ("TZ", tz1buf
, 1) != 0)
2800 tz_was_altered
= true;
2802 Start
= mktime (&tm
);
2803 if (! mktime_ok (&tm0
, &tm
, Start
))
2808 if (pc
.days_seen
&& ! pc
.dates_seen
)
2810 tm
.tm_mday
+= ((pc
.day_number
- tm
.tm_wday
+ 7) % 7
2811 + 7 * (pc
.day_ordinal
- (0 < pc
.day_ordinal
)));
2813 Start
= mktime (&tm
);
2814 if (Start
== (time_t) -1)
2820 long int delta
= pc
.time_zone
* 60;
2822 #ifdef HAVE_TM_GMTOFF
2823 delta
-= tm
.tm_gmtoff
;
2826 struct tm
const *gmt
= gmtime (&t
);
2829 delta
-= tm_diff (&tm
, gmt
);
2832 if ((Start
< t1
) != (delta
< 0))
2833 goto fail
; /* time_t overflow */
2837 /* Add relative date. */
2838 if (pc
.rel_year
| pc
.rel_month
| pc
.rel_day
)
2840 int year
= tm
.tm_year
+ pc
.rel_year
;
2841 int month
= tm
.tm_mon
+ pc
.rel_month
;
2842 int day
= tm
.tm_mday
+ pc
.rel_day
;
2843 if (((year
< tm
.tm_year
) ^ (pc
.rel_year
< 0))
2844 | ((month
< tm
.tm_mon
) ^ (pc
.rel_month
< 0))
2845 | ((day
< tm
.tm_mday
) ^ (pc
.rel_day
< 0)))
2850 Start
= mktime (&tm
);
2851 if (Start
== (time_t) -1)
2855 /* Add relative hours, minutes, and seconds. On hosts that support
2856 leap seconds, ignore the possibility of leap seconds; e.g.,
2857 "+ 10 minutes" adds 600 seconds, even if one of them is a
2858 leap second. Typically this is not what the user wants, but it's
2859 too hard to do it the other way, because the time zone indicator
2860 must be applied before relative times, and if mktime is applied
2861 again the time zone will be lost. */
2863 long int sum_ns
= pc
.seconds
.tv_nsec
+ pc
.rel_ns
;
2864 long int normalized_ns
= (sum_ns
% BILLION
+ BILLION
) % BILLION
;
2866 long int d1
= 60 * 60 * pc
.rel_hour
;
2867 time_t t1
= t0
+ d1
;
2868 long int d2
= 60 * pc
.rel_minutes
;
2869 time_t t2
= t1
+ d2
;
2870 long int d3
= pc
.rel_seconds
;
2871 time_t t3
= t2
+ d3
;
2872 long int d4
= (sum_ns
- normalized_ns
) / BILLION
;
2873 time_t t4
= t3
+ d4
;
2875 if ((d1
/ (60 * 60) ^ pc
.rel_hour
)
2876 | (d2
/ 60 ^ pc
.rel_minutes
)
2877 | ((t1
< t0
) ^ (d1
< 0))
2878 | ((t2
< t1
) ^ (d2
< 0))
2879 | ((t3
< t2
) ^ (d3
< 0))
2880 | ((t4
< t3
) ^ (d4
< 0)))
2883 result
->tv_sec
= t4
;
2884 result
->tv_nsec
= normalized_ns
;
2894 ok
&= (tz0
? setenv ("TZ", tz0
, 1) : unsetenv ("TZ")) == 0;
2903 main (int ac
, char **av
)
2907 printf ("Enter date, or blank line to exit.\n\t> ");
2910 buff
[BUFSIZ
- 1] = '\0';
2911 while (fgets (buff
, BUFSIZ
- 1, stdin
) && buff
[0])
2914 struct tm
const *tm
;
2915 if (! get_date (&d
, buff
, NULL
))
2916 printf ("Bad format - couldn't convert.\n");
2917 else if (! (tm
= localtime (&d
.tv_sec
)))
2919 long int sec
= d
.tv_sec
;
2920 printf ("localtime (%ld) failed\n", sec
);
2925 printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",
2926 tm
->tm_year
+ 1900L, tm
->tm_mon
+ 1, tm
->tm_mday
,
2927 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, ns
);