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, see <http://www.gnu.org/licenses/>. */
19 /* As a special exception, when this file is copied by Bison into a
20 Bison output file, you may use that output file without restriction.
21 This special exception was added by the Free Software Foundation
22 in version 1.24 of Bison. */
24 /* Written by Richard Stallman by simplifying the original so called
25 ``semantic'' parser. */
27 /* All symbols defined below should begin with yy or YY, to avoid
28 infringing on user name space. This should be done even for local
29 variables, as they might otherwise be expanded by user macros.
30 There are some unavoidable exceptions within include files to
31 define necessary library symbols; they are noted "INFRINGES ON
32 USER NAME SPACE" below. */
34 /* Identify Bison output. */
38 #define YYSKELETON_NAME "yacc.c"
43 /* Using locations. */
44 #define YYLSP_NEEDED 0
51 /* Put the tokens into the symbol table, so that GDB and other debuggers
77 #define tHOUR_UNIT 263
78 #define tLOCAL_ZONE 264
80 #define tMINUTE_UNIT 266
82 #define tMONTH_UNIT 268
84 #define tYEAR_UNIT 270
92 /* Copy the first part of user declarations. */
95 /* Parse a string into an internal time stamp.
96 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
98 This program is free software; you can redistribute it and/or modify
99 it under the terms of the GNU General Public License as published by
100 the Free Software Foundation; either version 2, or (at your option)
103 This program is distributed in the hope that it will be useful,
104 but WITHOUT ANY WARRANTY; without even the implied warranty of
105 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
106 GNU General Public License for more details.
108 You should have received a copy of the GNU General Public License
109 along with this program; if not, see <http://www.gnu.org/licenses/>. */
111 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
112 at the University of North Carolina at Chapel Hill. Later tweaked by
113 a couple of people on Usenet. Completely overhauled by Rich $alz
114 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
116 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
117 the right thing about local DST. Unlike previous versions, this
118 version is reentrant. */
122 # ifdef HAVE_ALLOCA_H
127 /* Since the code of getdate.y is not included in the Emacs executable
128 itself, there is no need to #define static in this file. Even if
129 the code were included in the Emacs executable, it probably
130 wouldn't do any harm to #undef it here; this will only cause
131 problems if we try to write to a static variable, which I don't
132 think this code needs to do. */
141 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
144 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
145 # define IN_CTYPE_DOMAIN(c) 1
147 # define IN_CTYPE_DOMAIN(c) isascii (c)
150 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
151 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
152 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
153 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
155 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
156 - Its arg may be any int or unsigned int; it need not be an unsigned char.
157 - It's guaranteed to evaluate its argument exactly once.
158 - It's typically faster.
159 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
160 ISDIGIT_LOCALE unless it's important to use the locale's definition
161 of `digit' even when the host does not conform to POSIX. */
162 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
164 #if STDC_HEADERS || HAVE_STRING_H
168 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
169 # define __attribute__(x)
172 #ifndef ATTRIBUTE_UNUSED
173 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
176 #define EPOCH_YEAR 1970
177 #define TM_YEAR_BASE 1900
179 #define HOUR(x) ((x) * 60)
181 /* An integer value, and the number of digits in its textual
189 /* An entry in the lexical lookup table. */
197 /* Meridian: am, pm, or 24-hour style. */
198 enum { MERam
, MERpm
, MER24
};
200 /* Information passed to and from the parser. */
203 /* The input string remaining to be parsed. */
206 /* N, if this is the Nth Tuesday. */
209 /* Day of week; Sunday is 0. */
212 /* tm_isdst flag for the local zone. */
215 /* Time zone, in minutes east of UTC. */
218 /* Style used for time. */
221 /* Gregorian year, month, day, hour, minutes, and seconds. */
229 /* Relative year, month, day, hour, minutes, and seconds. */
237 /* Counts of nonterminals of various flavors parsed so far. */
240 int local_zones_seen
;
245 /* Table of local time zone abbrevations, terminated by a null entry. */
246 table local_time_zone_table
[3];
249 #define PC (* (parser_control *) parm)
250 #define YYLEX_PARAM parm
251 #define YYPARSE_PARAM parm
253 static int yyerror ();
258 /* Enabling traces. */
263 /* Enabling verbose error messages. */
264 #ifdef YYERROR_VERBOSE
265 # undef YYERROR_VERBOSE
266 # define YYERROR_VERBOSE 1
268 # define YYERROR_VERBOSE 0
271 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
272 #line 172 "getdate.y"
273 typedef union YYSTYPE
{
277 /* Line 191 of yacc.c. */
278 #line 281 "getdate.c"
279 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
280 # define YYSTYPE_IS_DECLARED 1
281 # define YYSTYPE_IS_TRIVIAL 1
286 /* Copy the second part of user declarations. */
289 /* Line 214 of yacc.c. */
290 #line 293 "getdate.c"
292 #if ! defined (yyoverflow) || YYERROR_VERBOSE
294 /* The parser invokes alloca or malloc; define the necessary symbols. */
296 # if YYSTACK_USE_ALLOCA
297 # define YYSTACK_ALLOC alloca
299 # ifndef YYSTACK_USE_ALLOCA
300 # if defined (alloca) || defined (_ALLOCA_H)
301 # define YYSTACK_ALLOC alloca
304 # define YYSTACK_ALLOC __builtin_alloca
310 # ifdef YYSTACK_ALLOC
311 /* Pacify GCC's `empty if-body' warning. */
312 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
314 # if defined (__STDC__) || defined (__cplusplus)
315 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
316 # define YYSIZE_T size_t
318 # define YYSTACK_ALLOC malloc
319 # define YYSTACK_FREE free
321 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
324 #if (! defined (yyoverflow) \
325 && (! defined (__cplusplus) \
326 || (YYSTYPE_IS_TRIVIAL)))
328 /* A type that is properly aligned for any stack member. */
335 /* The size of the maximum gap between one aligned stack and the next. */
336 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
338 /* The size of an array large to enough to hold all stacks, each with
340 # define YYSTACK_BYTES(N) \
341 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
342 + YYSTACK_GAP_MAXIMUM)
344 /* Copy COUNT objects from FROM to TO. The source and destination do
348 # define YYCOPY(To, From, Count) \
349 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
351 # define YYCOPY(To, From, Count) \
354 register YYSIZE_T yyi; \
355 for (yyi = 0; yyi < (Count); yyi++) \
356 (To)[yyi] = (From)[yyi]; \
362 /* Relocate STACK from its old location to the new one. The
363 local variables YYSIZE and YYSTACKSIZE give the old and new number of
364 elements in the stack, and YYPTR gives the new location of the
365 stack. Advance YYPTR to a properly aligned location for the next
367 # define YYSTACK_RELOCATE(Stack) \
370 YYSIZE_T yynewbytes; \
371 YYCOPY (&yyptr->Stack, Stack, yysize); \
372 Stack = &yyptr->Stack; \
373 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
374 yyptr += yynewbytes / sizeof (*yyptr); \
380 #if defined (__STDC__) || defined (__cplusplus)
381 typedef signed char yysigned_char
;
383 typedef short yysigned_char
;
386 /* YYFINAL -- State number of the termination state. */
388 /* YYLAST -- Last index in YYTABLE. */
391 /* YYNTOKENS -- Number of terminals. */
393 /* YYNNTS -- Number of nonterminals. */
395 /* YYNRULES -- Number of rules. */
397 /* YYNRULES -- Number of states. */
400 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
402 #define YYMAXUTOK 273
404 #define YYTRANSLATE(YYX) \
405 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
407 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
408 static const unsigned char yytranslate
[] =
410 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
411 2, 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, 20, 2, 2, 21, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
416 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 1, 2, 3, 4,
436 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
441 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
443 static const unsigned char yyprhs
[] =
445 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
446 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
447 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
448 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
449 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
450 149, 152, 154, 156, 157
453 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
454 static const yysigned_char yyrhs
[] =
456 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
457 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
458 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
459 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
460 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
461 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
462 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
463 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
464 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
465 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
466 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
467 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
468 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
469 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
470 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
471 14, -1, 14, -1, 18, -1, -1, 10, -1
474 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
475 static const unsigned short yyrline
[] =
477 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
478 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
479 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
480 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
481 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
482 395, 397, 402, 439, 440
486 #if YYDEBUG || YYERROR_VERBOSE
487 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
488 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
489 static const char *const yytname
[] =
491 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
492 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
493 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
494 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
495 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
501 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
503 static const unsigned short yytoknum
[] =
505 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
506 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
511 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
512 static const unsigned char yyr1
[] =
514 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
515 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
516 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
517 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
518 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
522 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
523 static const unsigned char yyr2
[] =
525 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
526 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
527 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
528 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
529 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
533 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
534 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
535 means the default is an error. */
536 static const unsigned char yydefact
[] =
538 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
539 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
540 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
541 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
542 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
543 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
547 /* YYDEFGOTO[NTERM-NUM]. */
548 static const yysigned_char yydefgoto
[] =
550 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
554 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
556 #define YYPACT_NINF -17
557 static const yysigned_char yypact
[] =
559 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
560 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
561 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
562 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
563 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
564 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
568 /* YYPGOTO[NTERM-NUM]. */
569 static const yysigned_char yypgoto
[] =
571 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
575 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
576 positive, shift that token. If negative, reduce the rule which
577 number is the opposite. If zero, do what YYDEFACT says.
578 If YYTABLE_NINF, syntax error. */
579 #define YYTABLE_NINF -1
580 static const unsigned char yytable
[] =
582 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
583 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
584 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
585 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
586 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
590 static const unsigned char yycheck
[] =
592 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
593 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
594 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
595 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
596 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
600 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
601 symbol of state STATE-NUM. */
602 static const unsigned char yystos
[] =
604 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
605 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
606 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
607 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
608 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
609 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
613 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
614 # define YYSIZE_T __SIZE_TYPE__
616 #if ! defined (YYSIZE_T) && defined (size_t)
617 # define YYSIZE_T size_t
619 #if ! defined (YYSIZE_T)
620 # if defined (__STDC__) || defined (__cplusplus)
621 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
622 # define YYSIZE_T size_t
625 #if ! defined (YYSIZE_T)
626 # define YYSIZE_T unsigned int
629 #define yyerrok (yyerrstatus = 0)
630 #define yyclearin (yychar = YYEMPTY)
634 #define YYACCEPT goto yyacceptlab
635 #define YYABORT goto yyabortlab
636 #define YYERROR goto yyerrlab1
639 /* Like YYERROR except do call yyerror. This remains here temporarily
640 to ease the transition to the new meaning of YYERROR, for GCC.
641 Once GCC version 2 has supplanted version 1, this can go. */
643 #define YYFAIL goto yyerrlab
645 #define YYRECOVERING() (!!yyerrstatus)
647 #define YYBACKUP(Token, Value) \
649 if (yychar == YYEMPTY && yylen == 1) \
653 yytoken = YYTRANSLATE (yychar); \
659 yyerror ("syntax error: cannot back up");\
665 #define YYERRCODE 256
667 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
670 #ifndef YYLLOC_DEFAULT
671 # define YYLLOC_DEFAULT(Current, Rhs, N) \
672 Current.first_line = Rhs[1].first_line; \
673 Current.first_column = Rhs[1].first_column; \
674 Current.last_line = Rhs[N].last_line; \
675 Current.last_column = Rhs[N].last_column;
678 /* YYLEX -- calling `yylex' with the right arguments. */
681 # define YYLEX yylex (&yylval, YYLEX_PARAM)
683 # define YYLEX yylex (&yylval)
686 /* Enable debugging if requested. */
690 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
691 # define YYFPRINTF fprintf
694 # define YYDPRINTF(Args) \
700 # define YYDSYMPRINT(Args) \
706 # define YYDSYMPRINTF(Title, Token, Value, Location) \
710 YYFPRINTF (stderr, "%s ", Title); \
711 yysymprint (stderr, \
713 YYFPRINTF (stderr, "\n"); \
717 /*------------------------------------------------------------------.
718 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
720 `------------------------------------------------------------------*/
722 #if defined (__STDC__) || defined (__cplusplus)
724 yy_stack_print (short *bottom
, short *top
)
727 yy_stack_print (bottom
, top
)
732 YYFPRINTF (stderr
, "Stack now");
733 for (/* Nothing. */; bottom
<= top
; ++bottom
)
734 YYFPRINTF (stderr
, " %d", *bottom
);
735 YYFPRINTF (stderr
, "\n");
738 # define YY_STACK_PRINT(Bottom, Top) \
741 yy_stack_print ((Bottom), (Top)); \
745 /*------------------------------------------------.
746 | Report that the YYRULE is going to be reduced. |
747 `------------------------------------------------*/
749 #if defined (__STDC__) || defined (__cplusplus)
751 yy_reduce_print (int yyrule
)
754 yy_reduce_print (yyrule
)
759 unsigned int yylineno
= yyrline
[yyrule
];
760 YYFPRINTF (stderr
, "Reducing stack by rule %d (line %u), ",
761 yyrule
- 1, yylineno
);
762 /* Print the symbols being reduced, and their result. */
763 for (yyi
= yyprhs
[yyrule
]; 0 <= yyrhs
[yyi
]; yyi
++)
764 YYFPRINTF (stderr
, "%s ", yytname
[yyrhs
[yyi
]]);
765 YYFPRINTF (stderr
, "-> %s\n", yytname
[yyr1
[yyrule
]]);
768 # define YY_REDUCE_PRINT(Rule) \
771 yy_reduce_print (Rule); \
774 /* Nonzero means print parse trace. It is left uninitialized so that
775 multiple parsers can coexist. */
778 # define YYDPRINTF(Args)
779 # define YYDSYMPRINT(Args)
780 # define YYDSYMPRINTF(Title, Token, Value, Location)
781 # define YY_STACK_PRINT(Bottom, Top)
782 # define YY_REDUCE_PRINT(Rule)
783 #endif /* !YYDEBUG */
786 /* YYINITDEPTH -- initial size of the parser's stacks. */
788 # define YYINITDEPTH 200
791 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
792 if the built-in stack extension method is used).
794 Do not make this value too large; the results are undefined if
795 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
796 evaluated with infinite-precision integer arithmetic. */
803 # define YYMAXDEPTH 10000
811 # if defined (__GLIBC__) && defined (_STRING_H)
812 # define yystrlen strlen
814 /* Return the length of YYSTR. */
816 # if defined (__STDC__) || defined (__cplusplus)
817 yystrlen (const char *yystr
)
823 register const char *yys
= yystr
;
825 while (*yys
++ != '\0')
828 return yys
- yystr
- 1;
834 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
835 # define yystpcpy stpcpy
837 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
840 # if defined (__STDC__) || defined (__cplusplus)
841 yystpcpy (char *yydest
, const char *yysrc
)
843 yystpcpy (yydest
, yysrc
)
848 register char *yyd
= yydest
;
849 register const char *yys
= yysrc
;
851 while ((*yyd
++ = *yys
++) != '\0')
859 #endif /* !YYERROR_VERBOSE */
864 /*--------------------------------.
865 | Print this symbol on YYOUTPUT. |
866 `--------------------------------*/
868 #if defined (__STDC__) || defined (__cplusplus)
870 yysymprint (FILE *yyoutput
, int yytype
, YYSTYPE
*yyvaluep
)
873 yysymprint (yyoutput
, yytype
, yyvaluep
)
879 /* Pacify ``unused variable'' warnings. */
882 if (yytype
< YYNTOKENS
)
884 YYFPRINTF (yyoutput
, "token %s (", yytname
[yytype
]);
886 YYPRINT (yyoutput
, yytoknum
[yytype
], *yyvaluep
);
890 YYFPRINTF (yyoutput
, "nterm %s (", yytname
[yytype
]);
897 YYFPRINTF (yyoutput
, ")");
900 #endif /* ! YYDEBUG */
901 /*-----------------------------------------------.
902 | Release the memory associated to this symbol. |
903 `-----------------------------------------------*/
905 #if defined (__STDC__) || defined (__cplusplus)
907 yydestruct (int yytype
, YYSTYPE
*yyvaluep
)
910 yydestruct (yytype
, yyvaluep
)
915 /* Pacify ``unused variable'' warnings. */
927 /* Prevent warnings from -Wmissing-prototypes. */
930 # if defined (__STDC__) || defined (__cplusplus)
931 int yyparse (void *YYPARSE_PARAM
);
935 #else /* ! YYPARSE_PARAM */
936 #if defined (__STDC__) || defined (__cplusplus)
941 #endif /* ! YYPARSE_PARAM */
953 # if defined (__STDC__) || defined (__cplusplus)
954 int yyparse (void *YYPARSE_PARAM
)
956 int yyparse (YYPARSE_PARAM
)
959 #else /* ! YYPARSE_PARAM */
960 #if defined (__STDC__) || defined (__cplusplus)
970 /* The lookahead symbol. */
973 /* The semantic value of the lookahead symbol. */
976 /* Number of syntax errors so far. */
979 register int yystate
;
982 /* Number of tokens to shift before error messages enabled. */
984 /* Lookahead token as an internal (translated) token number. */
987 /* Three stacks and their tools:
988 `yyss': related to states,
989 `yyvs': related to semantic values,
990 `yyls': related to locations.
992 Refer to the stacks thru separate pointers, to allow yyoverflow
993 to reallocate them elsewhere. */
995 /* The state stack. */
996 short yyssa
[YYINITDEPTH
];
998 register short *yyssp
;
1000 /* The semantic value stack. */
1001 YYSTYPE yyvsa
[YYINITDEPTH
];
1002 YYSTYPE
*yyvs
= yyvsa
;
1003 register YYSTYPE
*yyvsp
;
1007 #define YYPOPSTACK (yyvsp--, yyssp--)
1009 YYSIZE_T yystacksize
= YYINITDEPTH
;
1011 /* The variables used to return semantic value and location from the
1016 /* When reducing, the number of symbols on the RHS of the reduced
1020 YYDPRINTF ((stderr
, "Starting parse\n"));
1025 yychar
= YYEMPTY
; /* Cause a token to be read. */
1027 /* Initialize stack pointers.
1028 Waste one element of value and location stack
1029 so that they stay on the same level as the state stack.
1030 The wasted elements are never initialized. */
1037 /*------------------------------------------------------------.
1038 | yynewstate -- Push a new state, which is found in yystate. |
1039 `------------------------------------------------------------*/
1041 /* In all cases, when you get here, the value and location stacks
1042 have just been pushed. so pushing a state here evens the stacks.
1049 if (yyss
+ yystacksize
- 1 <= yyssp
)
1051 /* Get the current used size of the three stacks, in elements. */
1052 YYSIZE_T yysize
= yyssp
- yyss
+ 1;
1056 /* Give user a chance to reallocate the stack. Use copies of
1057 these so that the &'s don't force the real ones into
1059 YYSTYPE
*yyvs1
= yyvs
;
1060 short *yyss1
= yyss
;
1063 /* Each stack pointer address is followed by the size of the
1064 data in use in that stack, in bytes. This used to be a
1065 conditional around just the two extra args, but that might
1066 be undefined if yyoverflow is a macro. */
1067 yyoverflow ("parser stack overflow",
1068 &yyss1
, yysize
* sizeof (*yyssp
),
1069 &yyvs1
, yysize
* sizeof (*yyvsp
),
1076 #else /* no yyoverflow */
1077 # ifndef YYSTACK_RELOCATE
1080 /* Extend the stack our own way. */
1081 if (YYMAXDEPTH
<= yystacksize
)
1084 if (YYMAXDEPTH
< yystacksize
)
1085 yystacksize
= YYMAXDEPTH
;
1088 short *yyss1
= yyss
;
1089 union yyalloc
*yyptr
=
1090 (union yyalloc
*) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize
));
1093 YYSTACK_RELOCATE (yyss
);
1094 YYSTACK_RELOCATE (yyvs
);
1096 # undef YYSTACK_RELOCATE
1098 YYSTACK_FREE (yyss1
);
1101 #endif /* no yyoverflow */
1103 yyssp
= yyss
+ yysize
- 1;
1104 yyvsp
= yyvs
+ yysize
- 1;
1107 YYDPRINTF ((stderr
, "Stack size increased to %lu\n",
1108 (unsigned long int) yystacksize
));
1110 if (yyss
+ yystacksize
- 1 <= yyssp
)
1114 YYDPRINTF ((stderr
, "Entering state %d\n", yystate
));
1123 /* Do appropriate processing given the current state. */
1124 /* Read a lookahead token if we need one and don't already have one. */
1127 /* First try to decide what to do without reference to lookahead token. */
1129 yyn
= yypact
[yystate
];
1130 if (yyn
== YYPACT_NINF
)
1133 /* Not known => get a lookahead token if don't already have one. */
1135 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1136 if (yychar
== YYEMPTY
)
1138 YYDPRINTF ((stderr
, "Reading a token: "));
1142 if (yychar
<= YYEOF
)
1144 yychar
= yytoken
= YYEOF
;
1145 YYDPRINTF ((stderr
, "Now at end of input.\n"));
1149 yytoken
= YYTRANSLATE (yychar
);
1150 YYDSYMPRINTF ("Next token is", yytoken
, &yylval
, &yylloc
);
1153 /* If the proper action on seeing token YYTOKEN is to reduce or to
1154 detect an error, take that action. */
1156 if (yyn
< 0 || YYLAST
< yyn
|| yycheck
[yyn
] != yytoken
)
1161 if (yyn
== 0 || yyn
== YYTABLE_NINF
)
1170 /* Shift the lookahead token. */
1171 YYDPRINTF ((stderr
, "Shifting token %s, ", yytname
[yytoken
]));
1173 /* Discard the token being shifted unless it is eof. */
1174 if (yychar
!= YYEOF
)
1180 /* Count tokens shifted since error; after three, turn off error
1189 /*-----------------------------------------------------------.
1190 | yydefault -- do the default action for the current state. |
1191 `-----------------------------------------------------------*/
1193 yyn
= yydefact
[yystate
];
1199 /*-----------------------------.
1200 | yyreduce -- Do a reduction. |
1201 `-----------------------------*/
1203 /* yyn is the number of a rule to reduce with. */
1206 /* If YYLEN is nonzero, implement the default value of the action:
1209 Otherwise, the following line sets YYVAL to garbage.
1210 This behavior is undocumented and Bison
1211 users should not rely upon it. Assigning to YYVAL
1212 unconditionally makes the parser a bit smaller, and it avoids a
1213 GCC warning that YYVAL may be used uninitialized. */
1214 yyval
= yyvsp
[1-yylen
];
1217 YY_REDUCE_PRINT (yyn
);
1221 #line 195 "getdate.y"
1222 { PC
.times_seen
++; }
1226 #line 197 "getdate.y"
1227 { PC
.local_zones_seen
++; }
1231 #line 199 "getdate.y"
1232 { PC
.zones_seen
++; }
1236 #line 201 "getdate.y"
1237 { PC
.dates_seen
++; }
1241 #line 203 "getdate.y"
1246 #line 205 "getdate.y"
1251 #line 211 "getdate.y"
1253 PC
.hour
= yyvsp
[-1].textintval
.value
;
1256 PC
.meridian
= yyvsp
[0].intval
;
1261 #line 218 "getdate.y"
1263 PC
.hour
= yyvsp
[-3].textintval
.value
;
1264 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1266 PC
.meridian
= yyvsp
[0].intval
;
1271 #line 225 "getdate.y"
1273 PC
.hour
= yyvsp
[-3].textintval
.value
;
1274 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1275 PC
.meridian
= MER24
;
1277 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1282 #line 233 "getdate.y"
1284 PC
.hour
= yyvsp
[-5].textintval
.value
;
1285 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1286 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1287 PC
.meridian
= yyvsp
[0].intval
;
1292 #line 240 "getdate.y"
1294 PC
.hour
= yyvsp
[-5].textintval
.value
;
1295 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1296 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1297 PC
.meridian
= MER24
;
1299 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1304 #line 252 "getdate.y"
1305 { PC
.local_isdst
= yyvsp
[0].intval
; }
1309 #line 254 "getdate.y"
1310 { PC
.local_isdst
= yyvsp
[-1].intval
< 0 ? 1 : yyvsp
[-1].intval
+ 1; }
1314 #line 259 "getdate.y"
1315 { PC
.time_zone
= yyvsp
[0].intval
; }
1319 #line 261 "getdate.y"
1320 { PC
.time_zone
= yyvsp
[0].intval
+ 60; }
1324 #line 263 "getdate.y"
1325 { PC
.time_zone
= yyvsp
[-1].intval
+ 60; }
1329 #line 268 "getdate.y"
1332 PC
.day_number
= yyvsp
[0].intval
;
1337 #line 273 "getdate.y"
1340 PC
.day_number
= yyvsp
[-1].intval
;
1345 #line 278 "getdate.y"
1347 PC
.day_ordinal
= yyvsp
[-1].textintval
.value
;
1348 PC
.day_number
= yyvsp
[0].intval
;
1353 #line 286 "getdate.y"
1355 PC
.month
= yyvsp
[-2].textintval
.value
;
1356 PC
.day
= yyvsp
[0].textintval
.value
;
1361 #line 291 "getdate.y"
1363 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1364 otherwise as MM/DD/YY.
1365 The goal in recognizing YYYY/MM/DD is solely to support legacy
1366 machine-generated dates like those in an RCS log listing. If
1367 you want portability, use the ISO 8601 format. */
1368 if (4 <= yyvsp
[-4].textintval
.digits
)
1370 PC
.year
= yyvsp
[-4].textintval
;
1371 PC
.month
= yyvsp
[-2].textintval
.value
;
1372 PC
.day
= yyvsp
[0].textintval
.value
;
1376 PC
.month
= yyvsp
[-4].textintval
.value
;
1377 PC
.day
= yyvsp
[-2].textintval
.value
;
1378 PC
.year
= yyvsp
[0].textintval
;
1384 #line 311 "getdate.y"
1386 /* ISO 8601 format. YYYY-MM-DD. */
1387 PC
.year
= yyvsp
[-2].textintval
;
1388 PC
.month
= -yyvsp
[-1].textintval
.value
;
1389 PC
.day
= -yyvsp
[0].textintval
.value
;
1394 #line 318 "getdate.y"
1396 /* e.g. 17-JUN-1992. */
1397 PC
.day
= yyvsp
[-2].textintval
.value
;
1398 PC
.month
= yyvsp
[-1].intval
;
1399 PC
.year
.value
= -yyvsp
[0].textintval
.value
;
1400 PC
.year
.digits
= yyvsp
[0].textintval
.digits
;
1405 #line 326 "getdate.y"
1407 PC
.month
= yyvsp
[-1].intval
;
1408 PC
.day
= yyvsp
[0].textintval
.value
;
1413 #line 331 "getdate.y"
1415 PC
.month
= yyvsp
[-3].intval
;
1416 PC
.day
= yyvsp
[-2].textintval
.value
;
1417 PC
.year
= yyvsp
[0].textintval
;
1422 #line 337 "getdate.y"
1424 PC
.day
= yyvsp
[-1].textintval
.value
;
1425 PC
.month
= yyvsp
[0].intval
;
1430 #line 342 "getdate.y"
1432 PC
.day
= yyvsp
[-2].textintval
.value
;
1433 PC
.month
= yyvsp
[-1].intval
;
1434 PC
.year
= yyvsp
[0].textintval
;
1439 #line 351 "getdate.y"
1441 PC
.rel_seconds
= -PC
.rel_seconds
;
1442 PC
.rel_minutes
= -PC
.rel_minutes
;
1443 PC
.rel_hour
= -PC
.rel_hour
;
1444 PC
.rel_day
= -PC
.rel_day
;
1445 PC
.rel_month
= -PC
.rel_month
;
1446 PC
.rel_year
= -PC
.rel_year
;
1451 #line 364 "getdate.y"
1452 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1456 #line 366 "getdate.y"
1457 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1461 #line 368 "getdate.y"
1462 { PC
.rel_year
+= yyvsp
[0].intval
; }
1466 #line 370 "getdate.y"
1467 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1471 #line 372 "getdate.y"
1472 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1476 #line 374 "getdate.y"
1477 { PC
.rel_month
+= yyvsp
[0].intval
; }
1481 #line 376 "getdate.y"
1482 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1486 #line 378 "getdate.y"
1487 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1491 #line 380 "getdate.y"
1492 { PC
.rel_day
+= yyvsp
[0].intval
; }
1496 #line 382 "getdate.y"
1497 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1501 #line 384 "getdate.y"
1502 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1506 #line 386 "getdate.y"
1507 { PC
.rel_hour
+= yyvsp
[0].intval
; }
1511 #line 388 "getdate.y"
1512 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1516 #line 390 "getdate.y"
1517 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1521 #line 392 "getdate.y"
1522 { PC
.rel_minutes
+= yyvsp
[0].intval
; }
1526 #line 394 "getdate.y"
1527 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1531 #line 396 "getdate.y"
1532 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1536 #line 398 "getdate.y"
1537 { PC
.rel_seconds
+= yyvsp
[0].intval
; }
1541 #line 403 "getdate.y"
1544 && ! PC
.rels_seen
&& (PC
.times_seen
|| 2 < yyvsp
[0].textintval
.digits
))
1545 PC
.year
= yyvsp
[0].textintval
;
1548 if (4 < yyvsp
[0].textintval
.digits
)
1551 PC
.day
= yyvsp
[0].textintval
.value
% 100;
1552 PC
.month
= (yyvsp
[0].textintval
.value
/ 100) % 100;
1553 PC
.year
.value
= yyvsp
[0].textintval
.value
/ 10000;
1554 PC
.year
.digits
= yyvsp
[0].textintval
.digits
- 4;
1559 if (yyvsp
[0].textintval
.digits
<= 2)
1561 PC
.hour
= yyvsp
[0].textintval
.value
;
1566 PC
.hour
= yyvsp
[0].textintval
.value
/ 100;
1567 PC
.minutes
= yyvsp
[0].textintval
.value
% 100;
1570 PC
.meridian
= MER24
;
1577 #line 439 "getdate.y"
1578 { yyval
.intval
= MER24
; }
1582 #line 441 "getdate.y"
1583 { yyval
.intval
= yyvsp
[0].intval
; }
1589 /* Line 999 of yacc.c. */
1590 #line 1593 "getdate.c"
1596 YY_STACK_PRINT (yyss
, yyssp
);
1601 /* Now `shift' the result of the reduction. Determine what state
1602 that goes to, based on the state we popped back to and the rule
1603 number reduced by. */
1607 yystate
= yypgoto
[yyn
- YYNTOKENS
] + *yyssp
;
1608 if (0 <= yystate
&& yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
1609 yystate
= yytable
[yystate
];
1611 yystate
= yydefgoto
[yyn
- YYNTOKENS
];
1616 /*------------------------------------.
1617 | yyerrlab -- here on detecting error |
1618 `------------------------------------*/
1620 /* If not already recovering from an error, report this error. */
1625 yyn
= yypact
[yystate
];
1627 if (YYPACT_NINF
< yyn
&& yyn
< YYLAST
)
1629 YYSIZE_T yysize
= 0;
1630 int yytype
= YYTRANSLATE (yychar
);
1635 /* Start YYX at -YYN if negative to avoid negative indexes in
1637 for (yyx
= yyn
< 0 ? -yyn
: 0;
1638 yyx
< (int) (sizeof (yytname
) / sizeof (char *)); yyx
++)
1639 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1640 yysize
+= yystrlen (yytname
[yyx
]) + 15, yycount
++;
1641 yysize
+= yystrlen ("syntax error, unexpected ") + 1;
1642 yysize
+= yystrlen (yytname
[yytype
]);
1643 yymsg
= (char *) YYSTACK_ALLOC (yysize
);
1646 char *yyp
= yystpcpy (yymsg
, "syntax error, unexpected ");
1647 yyp
= yystpcpy (yyp
, yytname
[yytype
]);
1652 for (yyx
= yyn
< 0 ? -yyn
: 0;
1653 yyx
< (int) (sizeof (yytname
) / sizeof (char *));
1655 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1657 const char *yyq
= ! yycount
? ", expecting " : " or ";
1658 yyp
= yystpcpy (yyp
, yyq
);
1659 yyp
= yystpcpy (yyp
, yytname
[yyx
]);
1664 YYSTACK_FREE (yymsg
);
1667 yyerror ("syntax error; also virtual memory exhausted");
1670 #endif /* YYERROR_VERBOSE */
1671 yyerror ("syntax error");
1676 if (yyerrstatus
== 3)
1678 /* If just tried and failed to reuse lookahead token after an
1679 error, discard it. */
1681 /* Return failure if at end of input. */
1682 if (yychar
== YYEOF
)
1684 /* Pop the error token. */
1686 /* Pop the rest of the stack. */
1687 while (yyss
< yyssp
)
1689 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1690 yydestruct (yystos
[*yyssp
], yyvsp
);
1696 YYDSYMPRINTF ("Error: discarding", yytoken
, &yylval
, &yylloc
);
1697 yydestruct (yytoken
, &yylval
);
1702 /* Else will try to reuse lookahead token after shifting the error
1707 /*----------------------------------------------------.
1708 | yyerrlab1 -- error raised explicitly by an action. |
1709 `----------------------------------------------------*/
1711 yyerrstatus
= 3; /* Each real token shifted decrements this. */
1715 yyn
= yypact
[yystate
];
1716 if (yyn
!= YYPACT_NINF
)
1719 if (0 <= yyn
&& yyn
<= YYLAST
&& yycheck
[yyn
] == YYTERROR
)
1727 /* Pop the current state because it cannot handle the error token. */
1731 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1732 yydestruct (yystos
[yystate
], yyvsp
);
1736 YY_STACK_PRINT (yyss
, yyssp
);
1742 YYDPRINTF ((stderr
, "Shifting error token, "));
1751 /*-------------------------------------.
1752 | yyacceptlab -- YYACCEPT comes here. |
1753 `-------------------------------------*/
1758 /*-----------------------------------.
1759 | yyabortlab -- YYABORT comes here. |
1760 `-----------------------------------*/
1766 /*----------------------------------------------.
1767 | yyoverflowlab -- parser overflow comes here. |
1768 `----------------------------------------------*/
1770 yyerror ("parser stack overflow");
1778 YYSTACK_FREE (yyss
);
1784 #line 444 "getdate.y"
1787 /* Include this file down here because bison inserts code above which
1788 may define-away `const'. We want the prototype for get_date to have
1789 the same signature as the function definition. */
1790 #include "modules/getdate.h"
1793 struct tm
*gmtime ();
1796 struct tm
*localtime ();
1802 static table
const meridian_table
[] =
1804 { "AM", tMERIDIAN
, MERam
},
1805 { "A.M.", tMERIDIAN
, MERam
},
1806 { "PM", tMERIDIAN
, MERpm
},
1807 { "P.M.", tMERIDIAN
, MERpm
},
1811 static table
const dst_table
[] =
1816 static table
const month_and_day_table
[] =
1818 { "JANUARY", tMONTH
, 1 },
1819 { "FEBRUARY", tMONTH
, 2 },
1820 { "MARCH", tMONTH
, 3 },
1821 { "APRIL", tMONTH
, 4 },
1822 { "MAY", tMONTH
, 5 },
1823 { "JUNE", tMONTH
, 6 },
1824 { "JULY", tMONTH
, 7 },
1825 { "AUGUST", tMONTH
, 8 },
1826 { "SEPTEMBER",tMONTH
, 9 },
1827 { "SEPT", tMONTH
, 9 },
1828 { "OCTOBER", tMONTH
, 10 },
1829 { "NOVEMBER", tMONTH
, 11 },
1830 { "DECEMBER", tMONTH
, 12 },
1831 { "SUNDAY", tDAY
, 0 },
1832 { "MONDAY", tDAY
, 1 },
1833 { "TUESDAY", tDAY
, 2 },
1834 { "TUES", tDAY
, 2 },
1835 { "WEDNESDAY",tDAY
, 3 },
1836 { "WEDNES", tDAY
, 3 },
1837 { "THURSDAY", tDAY
, 4 },
1838 { "THUR", tDAY
, 4 },
1839 { "THURS", tDAY
, 4 },
1840 { "FRIDAY", tDAY
, 5 },
1841 { "SATURDAY", tDAY
, 6 },
1845 static table
const time_units_table
[] =
1847 { "YEAR", tYEAR_UNIT
, 1 },
1848 { "MONTH", tMONTH_UNIT
, 1 },
1849 { "FORTNIGHT",tDAY_UNIT
, 14 },
1850 { "WEEK", tDAY_UNIT
, 7 },
1851 { "DAY", tDAY_UNIT
, 1 },
1852 { "HOUR", tHOUR_UNIT
, 1 },
1853 { "MINUTE", tMINUTE_UNIT
, 1 },
1854 { "MIN", tMINUTE_UNIT
, 1 },
1855 { "SECOND", tSEC_UNIT
, 1 },
1856 { "SEC", tSEC_UNIT
, 1 },
1860 /* Assorted relative-time words. */
1861 static table
const relative_time_table
[] =
1863 { "TOMORROW", tMINUTE_UNIT
, 24 * 60 },
1864 { "YESTERDAY",tMINUTE_UNIT
, - (24 * 60) },
1865 { "TODAY", tMINUTE_UNIT
, 0 },
1866 { "NOW", tMINUTE_UNIT
, 0 },
1867 { "LAST", tUNUMBER
, -1 },
1868 { "THIS", tUNUMBER
, 0 },
1869 { "NEXT", tUNUMBER
, 1 },
1870 { "FIRST", tUNUMBER
, 1 },
1871 /*{ "SECOND", tUNUMBER, 2 }, */
1872 { "THIRD", tUNUMBER
, 3 },
1873 { "FOURTH", tUNUMBER
, 4 },
1874 { "FIFTH", tUNUMBER
, 5 },
1875 { "SIXTH", tUNUMBER
, 6 },
1876 { "SEVENTH", tUNUMBER
, 7 },
1877 { "EIGHTH", tUNUMBER
, 8 },
1878 { "NINTH", tUNUMBER
, 9 },
1879 { "TENTH", tUNUMBER
, 10 },
1880 { "ELEVENTH", tUNUMBER
, 11 },
1881 { "TWELFTH", tUNUMBER
, 12 },
1886 /* The time zone table. This table is necessarily incomplete, as time
1887 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1888 as Eastern time in Australia, not as US Eastern Standard Time.
1889 You cannot rely on getdate to handle arbitrary time zone
1890 abbreviations; use numeric abbreviations like `-0500' instead. */
1891 static table
const time_zone_table
[] =
1893 { "GMT", tZONE
, HOUR ( 0) }, /* Greenwich Mean */
1894 { "UT", tZONE
, HOUR ( 0) }, /* Universal (Coordinated) */
1895 { "UTC", tZONE
, HOUR ( 0) },
1896 { "WET", tZONE
, HOUR ( 0) }, /* Western European */
1897 { "WEST", tDAYZONE
, HOUR ( 0) }, /* Western European Summer */
1898 { "BST", tDAYZONE
, HOUR ( 0) }, /* British Summer */
1899 { "ART", tZONE
, -HOUR ( 3) }, /* Argentina */
1900 { "BRT", tZONE
, -HOUR ( 3) }, /* Brazil */
1901 { "BRST", tDAYZONE
, -HOUR ( 3) }, /* Brazil Summer */
1902 { "NST", tZONE
, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1903 { "NDT", tDAYZONE
,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1904 { "AST", tZONE
, -HOUR ( 4) }, /* Atlantic Standard */
1905 { "ADT", tDAYZONE
, -HOUR ( 4) }, /* Atlantic Daylight */
1906 { "CLT", tZONE
, -HOUR ( 4) }, /* Chile */
1907 { "CLST", tDAYZONE
, -HOUR ( 4) }, /* Chile Summer */
1908 { "EST", tZONE
, -HOUR ( 5) }, /* Eastern Standard */
1909 { "EDT", tDAYZONE
, -HOUR ( 5) }, /* Eastern Daylight */
1910 { "CST", tZONE
, -HOUR ( 6) }, /* Central Standard */
1911 { "CDT", tDAYZONE
, -HOUR ( 6) }, /* Central Daylight */
1912 { "MST", tZONE
, -HOUR ( 7) }, /* Mountain Standard */
1913 { "MDT", tDAYZONE
, -HOUR ( 7) }, /* Mountain Daylight */
1914 { "PST", tZONE
, -HOUR ( 8) }, /* Pacific Standard */
1915 { "PDT", tDAYZONE
, -HOUR ( 8) }, /* Pacific Daylight */
1916 { "AKST", tZONE
, -HOUR ( 9) }, /* Alaska Standard */
1917 { "AKDT", tDAYZONE
, -HOUR ( 9) }, /* Alaska Daylight */
1918 { "HST", tZONE
, -HOUR (10) }, /* Hawaii Standard */
1919 { "HAST", tZONE
, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1920 { "HADT", tDAYZONE
, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1921 { "SST", tZONE
, -HOUR (12) }, /* Samoa Standard */
1922 { "WAT", tZONE
, HOUR ( 1) }, /* West Africa */
1923 { "CET", tZONE
, HOUR ( 1) }, /* Central European */
1924 { "CEST", tDAYZONE
, HOUR ( 1) }, /* Central European Summer */
1925 { "MET", tZONE
, HOUR ( 1) }, /* Middle European */
1926 { "MEZ", tZONE
, HOUR ( 1) }, /* Middle European */
1927 { "MEST", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1928 { "MESZ", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1929 { "EET", tZONE
, HOUR ( 2) }, /* Eastern European */
1930 { "EEST", tDAYZONE
, HOUR ( 2) }, /* Eastern European Summer */
1931 { "CAT", tZONE
, HOUR ( 2) }, /* Central Africa */
1932 { "SAST", tZONE
, HOUR ( 2) }, /* South Africa Standard */
1933 { "EAT", tZONE
, HOUR ( 3) }, /* East Africa */
1934 { "MSK", tZONE
, HOUR ( 3) }, /* Moscow */
1935 { "MSD", tDAYZONE
, HOUR ( 3) }, /* Moscow Daylight */
1936 { "IST", tZONE
, (HOUR ( 5) + 30) }, /* India Standard */
1937 { "SGT", tZONE
, HOUR ( 8) }, /* Singapore */
1938 { "KST", tZONE
, HOUR ( 9) }, /* Korea Standard */
1939 { "JST", tZONE
, HOUR ( 9) }, /* Japan Standard */
1940 { "GST", tZONE
, HOUR (10) }, /* Guam Standard */
1941 { "NZST", tZONE
, HOUR (12) }, /* New Zealand Standard */
1942 { "NZDT", tDAYZONE
, HOUR (12) }, /* New Zealand Daylight */
1946 /* Military time zone table. */
1947 static table
const military_table
[] =
1949 { "A", tZONE
, -HOUR ( 1) },
1950 { "B", tZONE
, -HOUR ( 2) },
1951 { "C", tZONE
, -HOUR ( 3) },
1952 { "D", tZONE
, -HOUR ( 4) },
1953 { "E", tZONE
, -HOUR ( 5) },
1954 { "F", tZONE
, -HOUR ( 6) },
1955 { "G", tZONE
, -HOUR ( 7) },
1956 { "H", tZONE
, -HOUR ( 8) },
1957 { "I", tZONE
, -HOUR ( 9) },
1958 { "K", tZONE
, -HOUR (10) },
1959 { "L", tZONE
, -HOUR (11) },
1960 { "M", tZONE
, -HOUR (12) },
1961 { "N", tZONE
, HOUR ( 1) },
1962 { "O", tZONE
, HOUR ( 2) },
1963 { "P", tZONE
, HOUR ( 3) },
1964 { "Q", tZONE
, HOUR ( 4) },
1965 { "R", tZONE
, HOUR ( 5) },
1966 { "S", tZONE
, HOUR ( 6) },
1967 { "T", tZONE
, HOUR ( 7) },
1968 { "U", tZONE
, HOUR ( 8) },
1969 { "V", tZONE
, HOUR ( 9) },
1970 { "W", tZONE
, HOUR (10) },
1971 { "X", tZONE
, HOUR (11) },
1972 { "Y", tZONE
, HOUR (12) },
1973 { "Z", tZONE
, HOUR ( 0) },
1980 to_hour (int hours
, int meridian
)
1985 return 0 <= hours
&& hours
< 24 ? hours
: -1;
1987 return 0 < hours
&& hours
< 12 ? hours
: hours
== 12 ? 0 : -1;
1989 return 0 < hours
&& hours
< 12 ? hours
+ 12 : hours
== 12 ? 12 : -1;
1998 to_year (textint textyear
)
2000 int year
= textyear
.value
;
2005 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2006 years 69-99 map to 1969-1999. */
2007 if (textyear
.digits
== 2)
2008 year
+= year
< 69 ? 2000 : 1900;
2013 static table
const *
2014 lookup_zone (parser_control
const *pc
, char const *name
)
2018 /* Try local zone abbreviations first; they're more likely to be right. */
2019 for (tp
= pc
->local_time_zone_table
; tp
->name
; tp
++)
2020 if (strcmp (name
, tp
->name
) == 0)
2023 for (tp
= time_zone_table
; tp
->name
; tp
++)
2024 if (strcmp (name
, tp
->name
) == 0)
2030 #if ! HAVE_TM_GMTOFF
2031 /* Yield the difference between *A and *B,
2032 measured in seconds, ignoring leap seconds.
2033 The body of this function is taken directly from the GNU C Library;
2034 see src/strftime.c. */
2036 tm_diff (struct tm
const *a
, struct tm
const *b
)
2038 /* Compute intervening leap days correctly even if year is negative.
2039 Take care to avoid int overflow in leap day calculations,
2040 but it's OK to assume that A and B are close to each other. */
2041 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
2042 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
2043 int a100
= a4
/ 25 - (a4
% 25 < 0);
2044 int b100
= b4
/ 25 - (b4
% 25 < 0);
2045 int a400
= a100
>> 2;
2046 int b400
= b100
>> 2;
2047 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
2048 int years
= a
->tm_year
- b
->tm_year
;
2049 int days
= (365 * years
+ intervening_leap_days
2050 + (a
->tm_yday
- b
->tm_yday
));
2051 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
2052 + (a
->tm_min
- b
->tm_min
))
2053 + (a
->tm_sec
- b
->tm_sec
));
2055 #endif /* ! HAVE_TM_GMTOFF */
2057 static table
const *
2058 lookup_word (parser_control
const *pc
, char *word
)
2067 /* Make it uppercase. */
2068 for (p
= word
; *p
; p
++)
2069 if (ISLOWER ((unsigned char) *p
))
2070 *p
= toupper ((unsigned char) *p
);
2072 for (tp
= meridian_table
; tp
->name
; tp
++)
2073 if (strcmp (word
, tp
->name
) == 0)
2076 /* See if we have an abbreviation for a month. */
2077 wordlen
= strlen (word
);
2078 abbrev
= wordlen
== 3 || (wordlen
== 4 && word
[3] == '.');
2080 for (tp
= month_and_day_table
; tp
->name
; tp
++)
2081 if ((abbrev
? strncmp (word
, tp
->name
, 3) : strcmp (word
, tp
->name
)) == 0)
2084 if ((tp
= lookup_zone (pc
, word
)))
2087 if (strcmp (word
, dst_table
[0].name
) == 0)
2090 for (tp
= time_units_table
; tp
->name
; tp
++)
2091 if (strcmp (word
, tp
->name
) == 0)
2094 /* Strip off any plural and try the units table again. */
2095 if (word
[wordlen
- 1] == 'S')
2097 word
[wordlen
- 1] = '\0';
2098 for (tp
= time_units_table
; tp
->name
; tp
++)
2099 if (strcmp (word
, tp
->name
) == 0)
2101 word
[wordlen
- 1] = 'S'; /* For "this" in relative_time_table. */
2104 for (tp
= relative_time_table
; tp
->name
; tp
++)
2105 if (strcmp (word
, tp
->name
) == 0)
2108 /* Military time zones. */
2110 for (tp
= military_table
; tp
->name
; tp
++)
2111 if (word
[0] == tp
->name
[0])
2114 /* Drop out any periods and try the time zone table again. */
2115 for (i
= 0, p
= q
= word
; (*p
= *q
); q
++)
2120 if (i
&& (tp
= lookup_zone (pc
, word
)))
2127 yylex (YYSTYPE
*lvalp
, parser_control
*pc
)
2134 while (c
= *pc
->input
, ISSPACE (c
))
2137 if (ISDIGIT (c
) || c
== '-' || c
== '+')
2142 if (c
== '-' || c
== '+')
2144 sign
= c
== '-' ? -1 : 1;
2147 /* skip the '-' sign */
2156 value
= 10 * value
+ c
- '0';
2159 while (ISDIGIT (c
));
2160 lvalp
->textintval
.value
= sign
< 0 ? -value
: value
;
2161 lvalp
->textintval
.digits
= p
- pc
->input
;
2163 return sign
? tSNUMBER
: tUNUMBER
;
2174 if (p
< buff
+ sizeof buff
- 1)
2178 while (ISALPHA (c
) || c
== '.');
2181 tp
= lookup_word (pc
, buff
);
2184 lvalp
->intval
= tp
->value
;
2189 return *pc
->input
++;
2205 /* Do nothing if the parser reports an error. */
2207 yyerror (char *s ATTRIBUTE_UNUSED
)
2212 /* Parse a date/time string P. Return the corresponding time_t value,
2213 or (time_t) -1 if there is an error. P can be an incomplete or
2214 relative time specification; if so, use *NOW as the basis for the
2217 get_date (const char *p
, const time_t *now
)
2219 time_t Start
= now
? *now
: time (0);
2220 struct tm
*tmp
= localtime (&Start
);
2229 pc
.year
.value
= tmp
->tm_year
+ TM_YEAR_BASE
;
2231 pc
.month
= tmp
->tm_mon
+ 1;
2232 pc
.day
= tmp
->tm_mday
;
2233 pc
.hour
= tmp
->tm_hour
;
2234 pc
.minutes
= tmp
->tm_min
;
2235 pc
.seconds
= tmp
->tm_sec
;
2236 tm
.tm_isdst
= tmp
->tm_isdst
;
2238 pc
.meridian
= MER24
;
2249 pc
.local_zones_seen
= 0;
2252 #if HAVE_STRUCT_TM_TM_ZONE
2253 pc
.local_time_zone_table
[0].name
= tmp
->tm_zone
;
2254 pc
.local_time_zone_table
[0].type
= tLOCAL_ZONE
;
2255 pc
.local_time_zone_table
[0].value
= tmp
->tm_isdst
;
2256 pc
.local_time_zone_table
[1].name
= 0;
2258 /* Probe the names used in the next three calendar quarters, looking
2259 for a tm_isdst different from the one we already have. */
2262 for (quarter
= 1; quarter
<= 3; quarter
++)
2264 time_t probe
= Start
+ quarter
* (90 * 24 * 60 * 60);
2265 struct tm
*probe_tm
= localtime (&probe
);
2266 if (probe_tm
&& probe_tm
->tm_zone
2267 && probe_tm
->tm_isdst
!= pc
.local_time_zone_table
[0].value
)
2270 pc
.local_time_zone_table
[1].name
= probe_tm
->tm_zone
;
2271 pc
.local_time_zone_table
[1].type
= tLOCAL_ZONE
;
2272 pc
.local_time_zone_table
[1].value
= probe_tm
->tm_isdst
;
2273 pc
.local_time_zone_table
[2].name
= 0;
2283 extern char *tzname
[];
2286 for (i
= 0; i
< 2; i
++)
2288 pc
.local_time_zone_table
[i
].name
= tzname
[i
];
2289 pc
.local_time_zone_table
[i
].type
= tLOCAL_ZONE
;
2290 pc
.local_time_zone_table
[i
].value
= i
;
2292 pc
.local_time_zone_table
[i
].name
= 0;
2295 pc
.local_time_zone_table
[0].name
= 0;
2299 if (pc
.local_time_zone_table
[0].name
&& pc
.local_time_zone_table
[1].name
2300 && ! strcmp (pc
.local_time_zone_table
[0].name
,
2301 pc
.local_time_zone_table
[1].name
))
2303 /* This locale uses the same abbrevation for standard and
2304 daylight times. So if we see that abbreviation, we don't
2305 know whether it's daylight time. */
2306 pc
.local_time_zone_table
[0].value
= -1;
2307 pc
.local_time_zone_table
[1].name
= 0;
2310 if (yyparse (&pc
) != 0
2311 || 1 < pc
.times_seen
|| 1 < pc
.dates_seen
|| 1 < pc
.days_seen
2312 || 1 < (pc
.local_zones_seen
+ pc
.zones_seen
)
2313 || (pc
.local_zones_seen
&& 1 < pc
.local_isdst
))
2316 tm
.tm_year
= to_year (pc
.year
) - TM_YEAR_BASE
+ pc
.rel_year
;
2317 tm
.tm_mon
= pc
.month
- 1 + pc
.rel_month
;
2318 tm
.tm_mday
= pc
.day
+ pc
.rel_day
;
2319 if (pc
.times_seen
|| (pc
.rels_seen
&& ! pc
.dates_seen
&& ! pc
.days_seen
))
2321 tm
.tm_hour
= to_hour (pc
.hour
, pc
.meridian
);
2324 tm
.tm_min
= pc
.minutes
;
2325 tm
.tm_sec
= pc
.seconds
;
2329 tm
.tm_hour
= tm
.tm_min
= tm
.tm_sec
= 0;
2332 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2333 or if the relative time stamp mentions days, months, or years. */
2334 if (pc
.dates_seen
| pc
.days_seen
| pc
.times_seen
| pc
.rel_day
2335 | pc
.rel_month
| pc
.rel_year
)
2338 /* But if the input explicitly specifies local time with or without
2339 DST, give mktime that information. */
2340 if (pc
.local_zones_seen
)
2341 tm
.tm_isdst
= pc
.local_isdst
;
2345 Start
= mktime (&tm
);
2347 if (Start
== (time_t) -1)
2350 /* Guard against falsely reporting errors near the time_t boundaries
2351 when parsing times in other time zones. For example, if the min
2352 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2353 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2354 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2355 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2356 zone by 24 hours to compensate. This algorithm assumes that
2357 there is no DST transition within a day of the time_t boundaries. */
2361 if (tm
.tm_year
<= EPOCH_YEAR
- TM_YEAR_BASE
)
2364 pc
.time_zone
+= 24 * 60;
2369 pc
.time_zone
-= 24 * 60;
2371 Start
= mktime (&tm
);
2374 if (Start
== (time_t) -1)
2378 if (pc
.days_seen
&& ! pc
.dates_seen
)
2380 tm
.tm_mday
+= ((pc
.day_number
- tm
.tm_wday
+ 7) % 7
2381 + 7 * (pc
.day_ordinal
- (0 < pc
.day_ordinal
)));
2383 Start
= mktime (&tm
);
2384 if (Start
== (time_t) -1)
2390 int delta
= pc
.time_zone
* 60;
2391 #ifdef HAVE_TM_GMTOFF
2392 delta
-= tm
.tm_gmtoff
;
2394 struct tm
*gmt
= gmtime (&Start
);
2397 delta
-= tm_diff (&tm
, gmt
);
2399 if ((Start
< Start
- delta
) != (delta
< 0))
2400 return -1; /* time_t overflow */
2404 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2405 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2406 leap second. Typically this is not what the user wants, but it's
2407 too hard to do it the other way, because the time zone indicator
2408 must be applied before relative times, and if mktime is applied
2409 again the time zone will be lost. */
2412 long d1
= 60 * 60 * (long) pc
.rel_hour
;
2413 time_t t1
= t0
+ d1
;
2414 long d2
= 60 * (long) pc
.rel_minutes
;
2415 time_t t2
= t1
+ d2
;
2416 int d3
= pc
.rel_seconds
;
2417 time_t t3
= t2
+ d3
;
2418 if ((d1
/ (60 * 60) ^ pc
.rel_hour
)
2419 | (d2
/ 60 ^ pc
.rel_minutes
)
2420 | ((t0
+ d1
< t0
) ^ (d1
< 0))
2421 | ((t1
+ d2
< t1
) ^ (d2
< 0))
2422 | ((t2
+ d3
< t2
) ^ (d3
< 0)))
2435 main (int ac
, char **av
)
2440 printf ("Enter date, or blank line to exit.\n\t> ");
2443 buff
[BUFSIZ
- 1] = 0;
2444 while (fgets (buff
, BUFSIZ
- 1, stdin
) && buff
[0])
2446 d
= get_date (buff
, 0);
2447 if (d
== (time_t) -1)
2448 printf ("Bad format - couldn't convert.\n");
2450 printf ("%s", ctime (&d
));
2456 #endif /* defined TEST */