1 /* A Bison parser, made by GNU Bison 1.875a. */
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
79 #define tHOUR_UNIT 263
80 #define tLOCAL_ZONE 264
82 #define tMINUTE_UNIT 266
84 #define tMONTH_UNIT 268
86 #define tYEAR_UNIT 270
94 /* Copy the first part of user declarations. */
97 /* Parse a string into an internal time stamp.
98 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
100 This program is free software; you can redistribute it and/or modify
101 it under the terms of the GNU General Public License as published by
102 the Free Software Foundation; either version 2, or (at your option)
105 This program is distributed in the hope that it will be useful,
106 but WITHOUT ANY WARRANTY; without even the implied warranty of
107 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108 GNU General Public License for more details.
110 You should have received a copy of the GNU General Public License
111 along with this program; if not, write to the Free Software Foundation,
112 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
114 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
115 at the University of North Carolina at Chapel Hill. Later tweaked by
116 a couple of people on Usenet. Completely overhauled by Rich $alz
117 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
119 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
120 the right thing about local DST. Unlike previous versions, this
121 version is reentrant. */
129 /* Since the code of getdate.y is not included in the Emacs executable
130 itself, there is no need to #define static in this file. Even if
131 the code were included in the Emacs executable, it probably
132 wouldn't do any harm to #undef it here; this will only cause
133 problems if we try to write to a static variable, which I don't
134 think this code needs to do. */
142 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
145 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
146 # define IN_CTYPE_DOMAIN(c) 1
148 # define IN_CTYPE_DOMAIN(c) isascii (c)
151 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
152 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
153 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
154 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
156 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
157 - Its arg may be any int or unsigned int; it need not be an unsigned char.
158 - It's guaranteed to evaluate its argument exactly once.
159 - It's typically faster.
160 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
161 ISDIGIT_LOCALE unless it's important to use the locale's definition
162 of `digit' even when the host does not conform to POSIX. */
163 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
165 #if STDC_HEADERS || HAVE_STRING_H
169 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
170 # define __attribute__(x)
173 #ifndef ATTRIBUTE_UNUSED
174 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
177 #define EPOCH_YEAR 1970
178 #define TM_YEAR_BASE 1900
180 #define HOUR(x) ((x) * 60)
182 /* An integer value, and the number of digits in its textual
190 /* An entry in the lexical lookup table. */
198 /* Meridian: am, pm, or 24-hour style. */
199 enum { MERam, MERpm, MER24 };
201 /* Information passed to and from the parser. */
204 /* The input string remaining to be parsed. */
207 /* N, if this is the Nth Tuesday. */
210 /* Day of week; Sunday is 0. */
213 /* tm_isdst flag for the local zone. */
216 /* Time zone, in minutes east of UTC. */
219 /* Style used for time. */
222 /* Gregorian year, month, day, hour, minutes, and seconds. */
230 /* Relative year, month, day, hour, minutes, and seconds. */
238 /* Counts of nonterminals of various flavors parsed so far. */
241 int local_zones_seen;
246 /* Table of local time zone abbrevations, terminated by a null entry. */
247 table local_time_zone_table[3];
250 #define PC (* (parser_control *) parm)
251 #define YYLEX_PARAM parm
252 #define YYPARSE_PARAM parm
254 static int yyerror ();
259 /* Enabling traces. */
264 /* Enabling verbose error messages. */
265 #ifdef YYERROR_VERBOSE
266 # undef YYERROR_VERBOSE
267 # define YYERROR_VERBOSE 1
269 # define YYERROR_VERBOSE 0
272 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
273 #line 172 "getdate.y"
274 typedef union YYSTYPE {
278 /* Line 191 of yacc.c. */
279 #line 281 "getdate.c"
280 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
281 # define YYSTYPE_IS_DECLARED 1
282 # define YYSTYPE_IS_TRIVIAL 1
287 /* Copy the second part of user declarations. */
290 /* Line 214 of yacc.c. */
291 #line 293 "getdate.c"
293 #if ! defined (yyoverflow) || YYERROR_VERBOSE
295 /* The parser invokes alloca or malloc; define the necessary symbols. */
297 # if YYSTACK_USE_ALLOCA
298 # define YYSTACK_ALLOC alloca
300 # ifndef YYSTACK_USE_ALLOCA
301 # if defined (alloca) || defined (_ALLOCA_H)
302 # define YYSTACK_ALLOC alloca
305 # define YYSTACK_ALLOC __builtin_alloca
311 # ifdef YYSTACK_ALLOC
312 /* Pacify GCC's `empty if-body' warning. */
313 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
315 # if defined (__STDC__) || defined (__cplusplus)
316 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
317 # define YYSIZE_T size_t
319 # define YYSTACK_ALLOC malloc
320 # define YYSTACK_FREE free
322 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
325 #if (! defined (yyoverflow) \
326 && (! defined (__cplusplus) \
327 || (YYSTYPE_IS_TRIVIAL)))
329 /* A type that is properly aligned for any stack member. */
336 /* The size of the maximum gap between one aligned stack and the next. */
337 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
339 /* The size of an array large to enough to hold all stacks, each with
341 # define YYSTACK_BYTES(N) \
342 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
343 + YYSTACK_GAP_MAXIMUM)
345 /* Copy COUNT objects from FROM to TO. The source and destination do
349 # define YYCOPY(To, From, Count) \
350 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
352 # define YYCOPY(To, From, Count) \
355 register YYSIZE_T yyi; \
356 for (yyi = 0; yyi < (Count); yyi++) \
357 (To)[yyi] = (From)[yyi]; \
363 /* Relocate STACK from its old location to the new one. The
364 local variables YYSIZE and YYSTACKSIZE give the old and new number of
365 elements in the stack, and YYPTR gives the new location of the
366 stack. Advance YYPTR to a properly aligned location for the next
368 # define YYSTACK_RELOCATE(Stack) \
371 YYSIZE_T yynewbytes; \
372 YYCOPY (&yyptr->Stack, Stack, yysize); \
373 Stack = &yyptr->Stack; \
374 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
375 yyptr += yynewbytes / sizeof (*yyptr); \
381 #if defined (__STDC__) || defined (__cplusplus)
382 typedef signed char yysigned_char;
384 typedef short yysigned_char;
387 /* YYFINAL -- State number of the termination state. */
389 /* YYLAST -- Last index in YYTABLE. */
392 /* YYNTOKENS -- Number of terminals. */
394 /* YYNNTS -- Number of nonterminals. */
396 /* YYNRULES -- Number of rules. */
398 /* YYNRULES -- Number of states. */
401 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
403 #define YYMAXUTOK 273
405 #define YYTRANSLATE(YYX) \
406 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
408 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
409 static const unsigned char yytranslate[] =
411 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
415 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
416 2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
432 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
436 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
437 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
442 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
444 static const unsigned char yyprhs[] =
446 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
447 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
448 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
449 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
450 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
451 149, 152, 154, 156, 157
454 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
455 static const yysigned_char yyrhs[] =
457 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
458 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
459 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
460 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
461 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
462 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
463 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
464 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
465 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
466 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
467 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
468 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
469 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
470 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
471 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
472 14, -1, 14, -1, 18, -1, -1, 10, -1
475 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
476 static const unsigned short yyrline[] =
478 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
479 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
480 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
481 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
482 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
483 395, 397, 402, 439, 440
487 #if YYDEBUG || YYERROR_VERBOSE
488 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
489 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
490 static const char *const yytname[] =
492 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
493 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
494 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
495 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
496 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
502 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
504 static const unsigned short yytoknum[] =
506 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
507 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
512 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
513 static const unsigned char yyr1[] =
515 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
516 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
517 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
518 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
519 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
523 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
524 static const unsigned char yyr2[] =
526 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
527 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
528 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
529 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
530 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
534 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
535 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
536 means the default is an error. */
537 static const unsigned char yydefact[] =
539 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
540 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
541 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
542 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
543 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
544 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
548 /* YYDEFGOTO[NTERM-NUM]. */
549 static const yysigned_char yydefgoto[] =
551 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
555 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
557 #define YYPACT_NINF -17
558 static const yysigned_char yypact[] =
560 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
561 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
562 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
563 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
564 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
565 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
569 /* YYPGOTO[NTERM-NUM]. */
570 static const yysigned_char yypgoto[] =
572 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
576 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
577 positive, shift that token. If negative, reduce the rule which
578 number is the opposite. If zero, do what YYDEFACT says.
579 If YYTABLE_NINF, syntax error. */
580 #define YYTABLE_NINF -1
581 static const unsigned char yytable[] =
583 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
584 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
585 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
586 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
587 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
591 static const unsigned char yycheck[] =
593 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
594 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
595 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
596 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
597 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
601 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
602 symbol of state STATE-NUM. */
603 static const unsigned char yystos[] =
605 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
606 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
607 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
608 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
609 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
610 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
614 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
615 # define YYSIZE_T __SIZE_TYPE__
617 #if ! defined (YYSIZE_T) && defined (size_t)
618 # define YYSIZE_T size_t
620 #if ! defined (YYSIZE_T)
621 # if defined (__STDC__) || defined (__cplusplus)
622 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
623 # define YYSIZE_T size_t
626 #if ! defined (YYSIZE_T)
627 # define YYSIZE_T unsigned int
630 #define yyerrok (yyerrstatus = 0)
631 #define yyclearin (yychar = YYEMPTY)
635 #define YYACCEPT goto yyacceptlab
636 #define YYABORT goto yyabortlab
637 #define YYERROR goto yyerrlab1
640 /* Like YYERROR except do call yyerror. This remains here temporarily
641 to ease the transition to the new meaning of YYERROR, for GCC.
642 Once GCC version 2 has supplanted version 1, this can go. */
644 #define YYFAIL goto yyerrlab
646 #define YYRECOVERING() (!!yyerrstatus)
648 #define YYBACKUP(Token, Value) \
650 if (yychar == YYEMPTY && yylen == 1) \
654 yytoken = YYTRANSLATE (yychar); \
660 yyerror ("syntax error: cannot back up");\
666 #define YYERRCODE 256
668 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
671 #ifndef YYLLOC_DEFAULT
672 # define YYLLOC_DEFAULT(Current, Rhs, N) \
673 Current.first_line = Rhs[1].first_line; \
674 Current.first_column = Rhs[1].first_column; \
675 Current.last_line = Rhs[N].last_line; \
676 Current.last_column = Rhs[N].last_column;
679 /* YYLEX -- calling `yylex' with the right arguments. */
682 # define YYLEX yylex (&yylval, YYLEX_PARAM)
684 # define YYLEX yylex (&yylval)
687 /* Enable debugging if requested. */
691 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
692 # define YYFPRINTF fprintf
695 # define YYDPRINTF(Args) \
701 # define YYDSYMPRINT(Args) \
707 # define YYDSYMPRINTF(Title, Token, Value, Location) \
711 YYFPRINTF (stderr, "%s ", Title); \
712 yysymprint (stderr, \
714 YYFPRINTF (stderr, "\n"); \
718 /*------------------------------------------------------------------.
719 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
721 `------------------------------------------------------------------*/
723 #if defined (__STDC__) || defined (__cplusplus)
725 yy_stack_print (short *bottom, short *top)
728 yy_stack_print (bottom, top)
733 YYFPRINTF (stderr, "Stack now");
734 for (/* Nothing. */; bottom <= top; ++bottom)
735 YYFPRINTF (stderr, " %d", *bottom);
736 YYFPRINTF (stderr, "\n");
739 # define YY_STACK_PRINT(Bottom, Top) \
742 yy_stack_print ((Bottom), (Top)); \
746 /*------------------------------------------------.
747 | Report that the YYRULE is going to be reduced. |
748 `------------------------------------------------*/
750 #if defined (__STDC__) || defined (__cplusplus)
752 yy_reduce_print (int yyrule)
755 yy_reduce_print (yyrule)
760 unsigned int yylineno = yyrline[yyrule];
761 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
762 yyrule - 1, yylineno);
763 /* Print the symbols being reduced, and their result. */
764 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
765 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
766 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
769 # define YY_REDUCE_PRINT(Rule) \
772 yy_reduce_print (Rule); \
775 /* Nonzero means print parse trace. It is left uninitialized so that
776 multiple parsers can coexist. */
779 # define YYDPRINTF(Args)
780 # define YYDSYMPRINT(Args)
781 # define YYDSYMPRINTF(Title, Token, Value, Location)
782 # define YY_STACK_PRINT(Bottom, Top)
783 # define YY_REDUCE_PRINT(Rule)
784 #endif /* !YYDEBUG */
787 /* YYINITDEPTH -- initial size of the parser's stacks. */
789 # define YYINITDEPTH 200
792 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
793 if the built-in stack extension method is used).
795 Do not make this value too large; the results are undefined if
796 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
797 evaluated with infinite-precision integer arithmetic. */
804 # define YYMAXDEPTH 10000
812 # if defined (__GLIBC__) && defined (_STRING_H)
813 # define yystrlen strlen
815 /* Return the length of YYSTR. */
817 # if defined (__STDC__) || defined (__cplusplus)
818 yystrlen (const char *yystr)
824 register const char *yys = yystr;
826 while (*yys++ != '\0')
829 return yys - yystr - 1;
835 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
836 # define yystpcpy stpcpy
838 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
841 # if defined (__STDC__) || defined (__cplusplus)
842 yystpcpy (char *yydest, const char *yysrc)
844 yystpcpy (yydest, yysrc)
849 register char *yyd = yydest;
850 register const char *yys = yysrc;
852 while ((*yyd++ = *yys++) != '\0')
860 #endif /* !YYERROR_VERBOSE */
865 /*--------------------------------.
866 | Print this symbol on YYOUTPUT. |
867 `--------------------------------*/
869 #if defined (__STDC__) || defined (__cplusplus)
871 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
874 yysymprint (yyoutput, yytype, yyvaluep)
880 /* Pacify ``unused variable'' warnings. */
883 if (yytype < YYNTOKENS)
885 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
887 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
891 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
898 YYFPRINTF (yyoutput, ")");
901 #endif /* ! YYDEBUG */
902 /*-----------------------------------------------.
903 | Release the memory associated to this symbol. |
904 `-----------------------------------------------*/
906 #if defined (__STDC__) || defined (__cplusplus)
908 yydestruct (int yytype, YYSTYPE *yyvaluep)
911 yydestruct (yytype, yyvaluep)
916 /* Pacify ``unused variable'' warnings. */
928 /* Prevent warnings from -Wmissing-prototypes. */
931 # if defined (__STDC__) || defined (__cplusplus)
932 int yyparse (void *YYPARSE_PARAM);
936 #else /* ! YYPARSE_PARAM */
937 #if defined (__STDC__) || defined (__cplusplus)
942 #endif /* ! YYPARSE_PARAM */
954 # if defined (__STDC__) || defined (__cplusplus)
955 int yyparse (void *YYPARSE_PARAM)
957 int yyparse (YYPARSE_PARAM)
960 #else /* ! YYPARSE_PARAM */
961 #if defined (__STDC__) || defined (__cplusplus)
971 /* The lookahead symbol. */
974 /* The semantic value of the lookahead symbol. */
977 /* Number of syntax errors so far. */
980 register int yystate;
983 /* Number of tokens to shift before error messages enabled. */
985 /* Lookahead token as an internal (translated) token number. */
988 /* Three stacks and their tools:
989 `yyss': related to states,
990 `yyvs': related to semantic values,
991 `yyls': related to locations.
993 Refer to the stacks thru separate pointers, to allow yyoverflow
994 to reallocate them elsewhere. */
996 /* The state stack. */
997 short yyssa[YYINITDEPTH];
999 register short *yyssp;
1001 /* The semantic value stack. */
1002 YYSTYPE yyvsa[YYINITDEPTH];
1003 YYSTYPE *yyvs = yyvsa;
1004 register YYSTYPE *yyvsp;
1008 #define YYPOPSTACK (yyvsp--, yyssp--)
1010 YYSIZE_T yystacksize = YYINITDEPTH;
1012 /* The variables used to return semantic value and location from the
1017 /* When reducing, the number of symbols on the RHS of the reduced
1021 YYDPRINTF ((stderr, "Starting parse\n"));
1026 yychar = YYEMPTY; /* Cause a token to be read. */
1028 /* Initialize stack pointers.
1029 Waste one element of value and location stack
1030 so that they stay on the same level as the state stack.
1031 The wasted elements are never initialized. */
1038 /*------------------------------------------------------------.
1039 | yynewstate -- Push a new state, which is found in yystate. |
1040 `------------------------------------------------------------*/
1042 /* In all cases, when you get here, the value and location stacks
1043 have just been pushed. so pushing a state here evens the stacks.
1050 if (yyss + yystacksize - 1 <= yyssp)
1052 /* Get the current used size of the three stacks, in elements. */
1053 YYSIZE_T yysize = yyssp - yyss + 1;
1057 /* Give user a chance to reallocate the stack. Use copies of
1058 these so that the &'s don't force the real ones into
1060 YYSTYPE *yyvs1 = yyvs;
1061 short *yyss1 = yyss;
1064 /* Each stack pointer address is followed by the size of the
1065 data in use in that stack, in bytes. This used to be a
1066 conditional around just the two extra args, but that might
1067 be undefined if yyoverflow is a macro. */
1068 yyoverflow ("parser stack overflow",
1069 &yyss1, yysize * sizeof (*yyssp),
1070 &yyvs1, yysize * sizeof (*yyvsp),
1077 #else /* no yyoverflow */
1078 # ifndef YYSTACK_RELOCATE
1081 /* Extend the stack our own way. */
1082 if (YYMAXDEPTH <= yystacksize)
1085 if (YYMAXDEPTH < yystacksize)
1086 yystacksize = YYMAXDEPTH;
1089 short *yyss1 = yyss;
1090 union yyalloc *yyptr =
1091 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1094 YYSTACK_RELOCATE (yyss);
1095 YYSTACK_RELOCATE (yyvs);
1097 # undef YYSTACK_RELOCATE
1099 YYSTACK_FREE (yyss1);
1102 #endif /* no yyoverflow */
1104 yyssp = yyss + yysize - 1;
1105 yyvsp = yyvs + yysize - 1;
1108 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1109 (unsigned long int) yystacksize));
1111 if (yyss + yystacksize - 1 <= yyssp)
1115 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1124 /* Do appropriate processing given the current state. */
1125 /* Read a lookahead token if we need one and don't already have one. */
1128 /* First try to decide what to do without reference to lookahead token. */
1130 yyn = yypact[yystate];
1131 if (yyn == YYPACT_NINF)
1134 /* Not known => get a lookahead token if don't already have one. */
1136 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1137 if (yychar == YYEMPTY)
1139 YYDPRINTF ((stderr, "Reading a token: "));
1143 if (yychar <= YYEOF)
1145 yychar = yytoken = YYEOF;
1146 YYDPRINTF ((stderr, "Now at end of input.\n"));
1150 yytoken = YYTRANSLATE (yychar);
1151 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1154 /* If the proper action on seeing token YYTOKEN is to reduce or to
1155 detect an error, take that action. */
1157 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1162 if (yyn == 0 || yyn == YYTABLE_NINF)
1171 /* Shift the lookahead token. */
1172 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1174 /* Discard the token being shifted unless it is eof. */
1175 if (yychar != YYEOF)
1181 /* Count tokens shifted since error; after three, turn off error
1190 /*-----------------------------------------------------------.
1191 | yydefault -- do the default action for the current state. |
1192 `-----------------------------------------------------------*/
1194 yyn = yydefact[yystate];
1200 /*-----------------------------.
1201 | yyreduce -- Do a reduction. |
1202 `-----------------------------*/
1204 /* yyn is the number of a rule to reduce with. */
1207 /* If YYLEN is nonzero, implement the default value of the action:
1210 Otherwise, the following line sets YYVAL to garbage.
1211 This behavior is undocumented and Bison
1212 users should not rely upon it. Assigning to YYVAL
1213 unconditionally makes the parser a bit smaller, and it avoids a
1214 GCC warning that YYVAL may be used uninitialized. */
1215 yyval = yyvsp[1-yylen];
1218 YY_REDUCE_PRINT (yyn);
1222 #line 195 "getdate.y"
1223 { PC.times_seen++; }
1227 #line 197 "getdate.y"
1228 { PC.local_zones_seen++; }
1232 #line 199 "getdate.y"
1233 { PC.zones_seen++; }
1237 #line 201 "getdate.y"
1238 { PC.dates_seen++; }
1242 #line 203 "getdate.y"
1247 #line 205 "getdate.y"
1252 #line 211 "getdate.y"
1254 PC.hour = yyvsp[-1].textintval.value;
1257 PC.meridian = yyvsp[0].intval;
1262 #line 218 "getdate.y"
1264 PC.hour = yyvsp[-3].textintval.value;
1265 PC.minutes = yyvsp[-1].textintval.value;
1267 PC.meridian = yyvsp[0].intval;
1272 #line 225 "getdate.y"
1274 PC.hour = yyvsp[-3].textintval.value;
1275 PC.minutes = yyvsp[-1].textintval.value;
1276 PC.meridian = MER24;
1278 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1283 #line 233 "getdate.y"
1285 PC.hour = yyvsp[-5].textintval.value;
1286 PC.minutes = yyvsp[-3].textintval.value;
1287 PC.seconds = yyvsp[-1].textintval.value;
1288 PC.meridian = yyvsp[0].intval;
1293 #line 240 "getdate.y"
1295 PC.hour = yyvsp[-5].textintval.value;
1296 PC.minutes = yyvsp[-3].textintval.value;
1297 PC.seconds = yyvsp[-1].textintval.value;
1298 PC.meridian = MER24;
1300 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1305 #line 252 "getdate.y"
1306 { PC.local_isdst = yyvsp[0].intval; }
1310 #line 254 "getdate.y"
1311 { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1315 #line 259 "getdate.y"
1316 { PC.time_zone = yyvsp[0].intval; }
1320 #line 261 "getdate.y"
1321 { PC.time_zone = yyvsp[0].intval + 60; }
1325 #line 263 "getdate.y"
1326 { PC.time_zone = yyvsp[-1].intval + 60; }
1330 #line 268 "getdate.y"
1333 PC.day_number = yyvsp[0].intval;
1338 #line 273 "getdate.y"
1341 PC.day_number = yyvsp[-1].intval;
1346 #line 278 "getdate.y"
1348 PC.day_ordinal = yyvsp[-1].textintval.value;
1349 PC.day_number = yyvsp[0].intval;
1354 #line 286 "getdate.y"
1356 PC.month = yyvsp[-2].textintval.value;
1357 PC.day = yyvsp[0].textintval.value;
1362 #line 291 "getdate.y"
1364 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1365 otherwise as MM/DD/YY.
1366 The goal in recognizing YYYY/MM/DD is solely to support legacy
1367 machine-generated dates like those in an RCS log listing. If
1368 you want portability, use the ISO 8601 format. */
1369 if (4 <= yyvsp[-4].textintval.digits)
1371 PC.year = yyvsp[-4].textintval;
1372 PC.month = yyvsp[-2].textintval.value;
1373 PC.day = yyvsp[0].textintval.value;
1377 PC.month = yyvsp[-4].textintval.value;
1378 PC.day = yyvsp[-2].textintval.value;
1379 PC.year = yyvsp[0].textintval;
1385 #line 311 "getdate.y"
1387 /* ISO 8601 format. YYYY-MM-DD. */
1388 PC.year = yyvsp[-2].textintval;
1389 PC.month = -yyvsp[-1].textintval.value;
1390 PC.day = -yyvsp[0].textintval.value;
1395 #line 318 "getdate.y"
1397 /* e.g. 17-JUN-1992. */
1398 PC.day = yyvsp[-2].textintval.value;
1399 PC.month = yyvsp[-1].intval;
1400 PC.year.value = -yyvsp[0].textintval.value;
1401 PC.year.digits = yyvsp[0].textintval.digits;
1406 #line 326 "getdate.y"
1408 PC.month = yyvsp[-1].intval;
1409 PC.day = yyvsp[0].textintval.value;
1414 #line 331 "getdate.y"
1416 PC.month = yyvsp[-3].intval;
1417 PC.day = yyvsp[-2].textintval.value;
1418 PC.year = yyvsp[0].textintval;
1423 #line 337 "getdate.y"
1425 PC.day = yyvsp[-1].textintval.value;
1426 PC.month = yyvsp[0].intval;
1431 #line 342 "getdate.y"
1433 PC.day = yyvsp[-2].textintval.value;
1434 PC.month = yyvsp[-1].intval;
1435 PC.year = yyvsp[0].textintval;
1440 #line 351 "getdate.y"
1442 PC.rel_seconds = -PC.rel_seconds;
1443 PC.rel_minutes = -PC.rel_minutes;
1444 PC.rel_hour = -PC.rel_hour;
1445 PC.rel_day = -PC.rel_day;
1446 PC.rel_month = -PC.rel_month;
1447 PC.rel_year = -PC.rel_year;
1452 #line 364 "getdate.y"
1453 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1457 #line 366 "getdate.y"
1458 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1462 #line 368 "getdate.y"
1463 { PC.rel_year += yyvsp[0].intval; }
1467 #line 370 "getdate.y"
1468 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1472 #line 372 "getdate.y"
1473 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1477 #line 374 "getdate.y"
1478 { PC.rel_month += yyvsp[0].intval; }
1482 #line 376 "getdate.y"
1483 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1487 #line 378 "getdate.y"
1488 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1492 #line 380 "getdate.y"
1493 { PC.rel_day += yyvsp[0].intval; }
1497 #line 382 "getdate.y"
1498 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1502 #line 384 "getdate.y"
1503 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1507 #line 386 "getdate.y"
1508 { PC.rel_hour += yyvsp[0].intval; }
1512 #line 388 "getdate.y"
1513 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1517 #line 390 "getdate.y"
1518 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1522 #line 392 "getdate.y"
1523 { PC.rel_minutes += yyvsp[0].intval; }
1527 #line 394 "getdate.y"
1528 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1532 #line 396 "getdate.y"
1533 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1537 #line 398 "getdate.y"
1538 { PC.rel_seconds += yyvsp[0].intval; }
1542 #line 403 "getdate.y"
1545 && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
1546 PC.year = yyvsp[0].textintval;
1549 if (4 < yyvsp[0].textintval.digits)
1552 PC.day = yyvsp[0].textintval.value % 100;
1553 PC.month = (yyvsp[0].textintval.value / 100) % 100;
1554 PC.year.value = yyvsp[0].textintval.value / 10000;
1555 PC.year.digits = yyvsp[0].textintval.digits - 4;
1560 if (yyvsp[0].textintval.digits <= 2)
1562 PC.hour = yyvsp[0].textintval.value;
1567 PC.hour = yyvsp[0].textintval.value / 100;
1568 PC.minutes = yyvsp[0].textintval.value % 100;
1571 PC.meridian = MER24;
1578 #line 439 "getdate.y"
1579 { yyval.intval = MER24; }
1583 #line 441 "getdate.y"
1584 { yyval.intval = yyvsp[0].intval; }
1590 /* Line 999 of yacc.c. */
1591 #line 1593 "getdate.c"
1597 YY_STACK_PRINT (yyss, yyssp);
1602 /* Now `shift' the result of the reduction. Determine what state
1603 that goes to, based on the state we popped back to and the rule
1604 number reduced by. */
1608 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1609 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1610 yystate = yytable[yystate];
1612 yystate = yydefgoto[yyn - YYNTOKENS];
1617 /*------------------------------------.
1618 | yyerrlab -- here on detecting error |
1619 `------------------------------------*/
1621 /* If not already recovering from an error, report this error. */
1626 yyn = yypact[yystate];
1628 if (YYPACT_NINF < yyn && yyn < YYLAST)
1630 YYSIZE_T yysize = 0;
1631 int yytype = YYTRANSLATE (yychar);
1636 /* Start YYX at -YYN if negative to avoid negative indexes in
1638 for (yyx = yyn < 0 ? -yyn : 0;
1639 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1640 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1641 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1642 yysize += yystrlen ("syntax error, unexpected ") + 1;
1643 yysize += yystrlen (yytname[yytype]);
1644 yymsg = (char *) YYSTACK_ALLOC (yysize);
1647 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1648 yyp = yystpcpy (yyp, yytname[yytype]);
1653 for (yyx = yyn < 0 ? -yyn : 0;
1654 yyx < (int) (sizeof (yytname) / sizeof (char *));
1656 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1658 const char *yyq = ! yycount ? ", expecting " : " or ";
1659 yyp = yystpcpy (yyp, yyq);
1660 yyp = yystpcpy (yyp, yytname[yyx]);
1665 YYSTACK_FREE (yymsg);
1668 yyerror ("syntax error; also virtual memory exhausted");
1671 #endif /* YYERROR_VERBOSE */
1672 yyerror ("syntax error");
1677 if (yyerrstatus == 3)
1679 /* If just tried and failed to reuse lookahead token after an
1680 error, discard it. */
1682 /* Return failure if at end of input. */
1683 if (yychar == YYEOF)
1685 /* Pop the error token. */
1687 /* Pop the rest of the stack. */
1688 while (yyss < yyssp)
1690 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1691 yydestruct (yystos[*yyssp], yyvsp);
1697 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1698 yydestruct (yytoken, &yylval);
1703 /* Else will try to reuse lookahead token after shifting the error
1708 /*----------------------------------------------------.
1709 | yyerrlab1 -- error raised explicitly by an action. |
1710 `----------------------------------------------------*/
1712 yyerrstatus = 3; /* Each real token shifted decrements this. */
1716 yyn = yypact[yystate];
1717 if (yyn != YYPACT_NINF)
1720 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1728 /* Pop the current state because it cannot handle the error token. */
1732 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1733 yydestruct (yystos[yystate], yyvsp);
1737 YY_STACK_PRINT (yyss, yyssp);
1743 YYDPRINTF ((stderr, "Shifting error token, "));
1752 /*-------------------------------------.
1753 | yyacceptlab -- YYACCEPT comes here. |
1754 `-------------------------------------*/
1759 /*-----------------------------------.
1760 | yyabortlab -- YYABORT comes here. |
1761 `-----------------------------------*/
1767 /*----------------------------------------------.
1768 | yyoverflowlab -- parser overflow comes here. |
1769 `----------------------------------------------*/
1771 yyerror ("parser stack overflow");
1779 YYSTACK_FREE (yyss);
1785 #line 444 "getdate.y"
1788 /* Include this file down here because bison inserts code above which
1789 may define-away `const'. We want the prototype for get_date to have
1790 the same signature as the function definition. */
1791 #include "modules/getdate.h"
1794 struct tm *gmtime ();
1797 struct tm *localtime ();
1803 static table const meridian_table[] =
1805 { "AM", tMERIDIAN, MERam },
1806 { "A.M.", tMERIDIAN, MERam },
1807 { "PM", tMERIDIAN, MERpm },
1808 { "P.M.", tMERIDIAN, MERpm },
1812 static table const dst_table[] =
1817 static table const month_and_day_table[] =
1819 { "JANUARY", tMONTH, 1 },
1820 { "FEBRUARY", tMONTH, 2 },
1821 { "MARCH", tMONTH, 3 },
1822 { "APRIL", tMONTH, 4 },
1823 { "MAY", tMONTH, 5 },
1824 { "JUNE", tMONTH, 6 },
1825 { "JULY", tMONTH, 7 },
1826 { "AUGUST", tMONTH, 8 },
1827 { "SEPTEMBER",tMONTH, 9 },
1828 { "SEPT", tMONTH, 9 },
1829 { "OCTOBER", tMONTH, 10 },
1830 { "NOVEMBER", tMONTH, 11 },
1831 { "DECEMBER", tMONTH, 12 },
1832 { "SUNDAY", tDAY, 0 },
1833 { "MONDAY", tDAY, 1 },
1834 { "TUESDAY", tDAY, 2 },
1835 { "TUES", tDAY, 2 },
1836 { "WEDNESDAY",tDAY, 3 },
1837 { "WEDNES", tDAY, 3 },
1838 { "THURSDAY", tDAY, 4 },
1839 { "THUR", tDAY, 4 },
1840 { "THURS", tDAY, 4 },
1841 { "FRIDAY", tDAY, 5 },
1842 { "SATURDAY", tDAY, 6 },
1846 static table const time_units_table[] =
1848 { "YEAR", tYEAR_UNIT, 1 },
1849 { "MONTH", tMONTH_UNIT, 1 },
1850 { "FORTNIGHT",tDAY_UNIT, 14 },
1851 { "WEEK", tDAY_UNIT, 7 },
1852 { "DAY", tDAY_UNIT, 1 },
1853 { "HOUR", tHOUR_UNIT, 1 },
1854 { "MINUTE", tMINUTE_UNIT, 1 },
1855 { "MIN", tMINUTE_UNIT, 1 },
1856 { "SECOND", tSEC_UNIT, 1 },
1857 { "SEC", tSEC_UNIT, 1 },
1861 /* Assorted relative-time words. */
1862 static table const relative_time_table[] =
1864 { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
1865 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
1866 { "TODAY", tMINUTE_UNIT, 0 },
1867 { "NOW", tMINUTE_UNIT, 0 },
1868 { "LAST", tUNUMBER, -1 },
1869 { "THIS", tUNUMBER, 0 },
1870 { "NEXT", tUNUMBER, 1 },
1871 { "FIRST", tUNUMBER, 1 },
1872 /*{ "SECOND", tUNUMBER, 2 }, */
1873 { "THIRD", tUNUMBER, 3 },
1874 { "FOURTH", tUNUMBER, 4 },
1875 { "FIFTH", tUNUMBER, 5 },
1876 { "SIXTH", tUNUMBER, 6 },
1877 { "SEVENTH", tUNUMBER, 7 },
1878 { "EIGHTH", tUNUMBER, 8 },
1879 { "NINTH", tUNUMBER, 9 },
1880 { "TENTH", tUNUMBER, 10 },
1881 { "ELEVENTH", tUNUMBER, 11 },
1882 { "TWELFTH", tUNUMBER, 12 },
1887 /* The time zone table. This table is necessarily incomplete, as time
1888 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1889 as Eastern time in Australia, not as US Eastern Standard Time.
1890 You cannot rely on getdate to handle arbitrary time zone
1891 abbreviations; use numeric abbreviations like `-0500' instead. */
1892 static table const time_zone_table[] =
1894 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1895 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1896 { "UTC", tZONE, HOUR ( 0) },
1897 { "WET", tZONE, HOUR ( 0) }, /* Western European */
1898 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
1899 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
1900 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
1901 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
1902 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1903 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1904 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1905 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
1906 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1907 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
1908 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1909 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
1910 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1911 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
1912 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1913 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
1914 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1915 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
1916 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1917 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
1918 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1919 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
1920 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1921 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1922 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
1923 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
1924 { "CET", tZONE, HOUR ( 1) }, /* Central European */
1925 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
1926 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
1927 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
1928 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1929 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1930 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
1931 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
1932 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
1933 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
1934 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
1935 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
1936 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
1937 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
1938 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
1939 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
1940 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
1941 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
1942 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
1943 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
1947 /* Military time zone table. */
1948 static table const military_table[] =
1950 { "A", tZONE, -HOUR ( 1) },
1951 { "B", tZONE, -HOUR ( 2) },
1952 { "C", tZONE, -HOUR ( 3) },
1953 { "D", tZONE, -HOUR ( 4) },
1954 { "E", tZONE, -HOUR ( 5) },
1955 { "F", tZONE, -HOUR ( 6) },
1956 { "G", tZONE, -HOUR ( 7) },
1957 { "H", tZONE, -HOUR ( 8) },
1958 { "I", tZONE, -HOUR ( 9) },
1959 { "K", tZONE, -HOUR (10) },
1960 { "L", tZONE, -HOUR (11) },
1961 { "M", tZONE, -HOUR (12) },
1962 { "N", tZONE, HOUR ( 1) },
1963 { "O", tZONE, HOUR ( 2) },
1964 { "P", tZONE, HOUR ( 3) },
1965 { "Q", tZONE, HOUR ( 4) },
1966 { "R", tZONE, HOUR ( 5) },
1967 { "S", tZONE, HOUR ( 6) },
1968 { "T", tZONE, HOUR ( 7) },
1969 { "U", tZONE, HOUR ( 8) },
1970 { "V", tZONE, HOUR ( 9) },
1971 { "W", tZONE, HOUR (10) },
1972 { "X", tZONE, HOUR (11) },
1973 { "Y", tZONE, HOUR (12) },
1974 { "Z", tZONE, HOUR ( 0) },
1981 to_hour (int hours, int meridian)
1986 return 0 <= hours && hours < 24 ? hours : -1;
1988 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1990 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
1999 to_year (textint textyear)
2001 int year = textyear.value;
2006 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2007 years 69-99 map to 1969-1999. */
2008 if (textyear.digits == 2)
2009 year += year < 69 ? 2000 : 1900;
2014 static table const *
2015 lookup_zone (parser_control const *pc, char const *name)
2019 /* Try local zone abbreviations first; they're more likely to be right. */
2020 for (tp = pc->local_time_zone_table; tp->name; tp++)
2021 if (strcmp (name, tp->name) == 0)
2024 for (tp = time_zone_table; tp->name; tp++)
2025 if (strcmp (name, tp->name) == 0)
2031 #if ! HAVE_TM_GMTOFF
2032 /* Yield the difference between *A and *B,
2033 measured in seconds, ignoring leap seconds.
2034 The body of this function is taken directly from the GNU C Library;
2035 see src/strftime.c. */
2037 tm_diff (struct tm const *a, struct tm const *b)
2039 /* Compute intervening leap days correctly even if year is negative.
2040 Take care to avoid int overflow in leap day calculations,
2041 but it's OK to assume that A and B are close to each other. */
2042 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2043 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2044 int a100 = a4 / 25 - (a4 % 25 < 0);
2045 int b100 = b4 / 25 - (b4 % 25 < 0);
2046 int a400 = a100 >> 2;
2047 int b400 = b100 >> 2;
2048 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2049 int years = a->tm_year - b->tm_year;
2050 int days = (365 * years + intervening_leap_days
2051 + (a->tm_yday - b->tm_yday));
2052 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2053 + (a->tm_min - b->tm_min))
2054 + (a->tm_sec - b->tm_sec));
2056 #endif /* ! HAVE_TM_GMTOFF */
2058 static table const *
2059 lookup_word (parser_control const *pc, char *word)
2068 /* Make it uppercase. */
2069 for (p = word; *p; p++)
2070 if (ISLOWER ((unsigned char) *p))
2071 *p = toupper ((unsigned char) *p);
2073 for (tp = meridian_table; tp->name; tp++)
2074 if (strcmp (word, tp->name) == 0)
2077 /* See if we have an abbreviation for a month. */
2078 wordlen = strlen (word);
2079 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2081 for (tp = month_and_day_table; tp->name; tp++)
2082 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2085 if ((tp = lookup_zone (pc, word)))
2088 if (strcmp (word, dst_table[0].name) == 0)
2091 for (tp = time_units_table; tp->name; tp++)
2092 if (strcmp (word, tp->name) == 0)
2095 /* Strip off any plural and try the units table again. */
2096 if (word[wordlen - 1] == 'S')
2098 word[wordlen - 1] = '\0';
2099 for (tp = time_units_table; tp->name; tp++)
2100 if (strcmp (word, tp->name) == 0)
2102 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2105 for (tp = relative_time_table; tp->name; tp++)
2106 if (strcmp (word, tp->name) == 0)
2109 /* Military time zones. */
2111 for (tp = military_table; tp->name; tp++)
2112 if (word[0] == tp->name[0])
2115 /* Drop out any periods and try the time zone table again. */
2116 for (i = 0, p = q = word; (*p = *q); q++)
2121 if (i && (tp = lookup_zone (pc, word)))
2128 yylex (YYSTYPE *lvalp, parser_control *pc)
2135 while (c = *pc->input, ISSPACE (c))
2138 if (ISDIGIT (c) || c == '-' || c == '+')
2143 if (c == '-' || c == '+')
2145 sign = c == '-' ? -1 : 1;
2148 /* skip the '-' sign */
2157 value = 10 * value + c - '0';
2160 while (ISDIGIT (c));
2161 lvalp->textintval.value = sign < 0 ? -value : value;
2162 lvalp->textintval.digits = p - pc->input;
2164 return sign ? tSNUMBER : tUNUMBER;
2175 if (p < buff + sizeof buff - 1)
2179 while (ISALPHA (c) || c == '.');
2182 tp = lookup_word (pc, buff);
2185 lvalp->intval = tp->value;
2190 return *pc->input++;
2206 /* Do nothing if the parser reports an error. */
2208 yyerror (char *s ATTRIBUTE_UNUSED)
2213 /* Parse a date/time string P. Return the corresponding time_t value,
2214 or (time_t) -1 if there is an error. P can be an incomplete or
2215 relative time specification; if so, use *NOW as the basis for the
2218 get_date (const char *p, const time_t *now)
2220 time_t Start = now ? *now : time (0);
2221 struct tm *tmp = localtime (&Start);
2230 pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2232 pc.month = tmp->tm_mon + 1;
2233 pc.day = tmp->tm_mday;
2234 pc.hour = tmp->tm_hour;
2235 pc.minutes = tmp->tm_min;
2236 pc.seconds = tmp->tm_sec;
2237 tm.tm_isdst = tmp->tm_isdst;
2239 pc.meridian = MER24;
2250 pc.local_zones_seen = 0;
2253 #if HAVE_STRUCT_TM_TM_ZONE
2254 pc.local_time_zone_table[0].name = tmp->tm_zone;
2255 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2256 pc.local_time_zone_table[0].value = tmp->tm_isdst;
2257 pc.local_time_zone_table[1].name = 0;
2259 /* Probe the names used in the next three calendar quarters, looking
2260 for a tm_isdst different from the one we already have. */
2263 for (quarter = 1; quarter <= 3; quarter++)
2265 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2266 struct tm *probe_tm = localtime (&probe);
2267 if (probe_tm && probe_tm->tm_zone
2268 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2271 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2272 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2273 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2274 pc.local_time_zone_table[2].name = 0;
2284 extern char *tzname[];
2287 for (i = 0; i < 2; i++)
2289 pc.local_time_zone_table[i].name = tzname[i];
2290 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2291 pc.local_time_zone_table[i].value = i;
2293 pc.local_time_zone_table[i].name = 0;
2296 pc.local_time_zone_table[0].name = 0;
2300 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2301 && ! strcmp (pc.local_time_zone_table[0].name,
2302 pc.local_time_zone_table[1].name))
2304 /* This locale uses the same abbrevation for standard and
2305 daylight times. So if we see that abbreviation, we don't
2306 know whether it's daylight time. */
2307 pc.local_time_zone_table[0].value = -1;
2308 pc.local_time_zone_table[1].name = 0;
2311 if (yyparse (&pc) != 0
2312 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2313 || 1 < (pc.local_zones_seen + pc.zones_seen)
2314 || (pc.local_zones_seen && 1 < pc.local_isdst))
2317 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2318 tm.tm_mon = pc.month - 1 + pc.rel_month;
2319 tm.tm_mday = pc.day + pc.rel_day;
2320 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2322 tm.tm_hour = to_hour (pc.hour, pc.meridian);
2325 tm.tm_min = pc.minutes;
2326 tm.tm_sec = pc.seconds;
2330 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2333 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2334 or if the relative time stamp mentions days, months, or years. */
2335 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2336 | pc.rel_month | pc.rel_year)
2339 /* But if the input explicitly specifies local time with or without
2340 DST, give mktime that information. */
2341 if (pc.local_zones_seen)
2342 tm.tm_isdst = pc.local_isdst;
2346 Start = mktime (&tm);
2348 if (Start == (time_t) -1)
2351 /* Guard against falsely reporting errors near the time_t boundaries
2352 when parsing times in other time zones. For example, if the min
2353 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2354 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2355 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2356 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2357 zone by 24 hours to compensate. This algorithm assumes that
2358 there is no DST transition within a day of the time_t boundaries. */
2362 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2365 pc.time_zone += 24 * 60;
2370 pc.time_zone -= 24 * 60;
2372 Start = mktime (&tm);
2375 if (Start == (time_t) -1)
2379 if (pc.days_seen && ! pc.dates_seen)
2381 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2382 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2384 Start = mktime (&tm);
2385 if (Start == (time_t) -1)
2391 int delta = pc.time_zone * 60;
2392 #ifdef HAVE_TM_GMTOFF
2393 delta -= tm.tm_gmtoff;
2395 struct tm *gmt = gmtime (&Start);
2398 delta -= tm_diff (&tm, gmt);
2400 if ((Start < Start - delta) != (delta < 0))
2401 return -1; /* time_t overflow */
2405 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2406 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2407 leap second. Typically this is not what the user wants, but it's
2408 too hard to do it the other way, because the time zone indicator
2409 must be applied before relative times, and if mktime is applied
2410 again the time zone will be lost. */
2413 long d1 = 60 * 60 * (long) pc.rel_hour;
2414 time_t t1 = t0 + d1;
2415 long d2 = 60 * (long) pc.rel_minutes;
2416 time_t t2 = t1 + d2;
2417 int d3 = pc.rel_seconds;
2418 time_t t3 = t2 + d3;
2419 if ((d1 / (60 * 60) ^ pc.rel_hour)
2420 | (d2 / 60 ^ pc.rel_minutes)
2421 | ((t0 + d1 < t0) ^ (d1 < 0))
2422 | ((t1 + d2 < t1) ^ (d2 < 0))
2423 | ((t2 + d3 < t2) ^ (d3 < 0)))
2436 main (int ac, char **av)
2441 printf ("Enter date, or blank line to exit.\n\t> ");
2444 buff[BUFSIZ - 1] = 0;
2445 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2447 d = get_date (buff, 0);
2448 if (d == (time_t) -1)
2449 printf ("Bad format - couldn't convert.\n");
2451 printf ("%s", ctime (&d));
2457 #endif /* defined TEST */