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. */
125 # ifdef HAVE_ALLOCA_H
130 /* Since the code of getdate.y is not included in the Emacs executable
131 itself, there is no need to #define static in this file. Even if
132 the code were included in the Emacs executable, it probably
133 wouldn't do any harm to #undef it here; this will only cause
134 problems if we try to write to a static variable, which I don't
135 think this code needs to do. */
144 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
147 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
148 # define IN_CTYPE_DOMAIN(c) 1
150 # define IN_CTYPE_DOMAIN(c) isascii (c)
153 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
154 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
155 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
156 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
158 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
159 - Its arg may be any int or unsigned int; it need not be an unsigned char.
160 - It's guaranteed to evaluate its argument exactly once.
161 - It's typically faster.
162 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
163 ISDIGIT_LOCALE unless it's important to use the locale's definition
164 of `digit' even when the host does not conform to POSIX. */
165 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
167 #if STDC_HEADERS || HAVE_STRING_H
171 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
172 # define __attribute__(x)
175 #ifndef ATTRIBUTE_UNUSED
176 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
179 #define EPOCH_YEAR 1970
180 #define TM_YEAR_BASE 1900
182 #define HOUR(x) ((x) * 60)
184 /* An integer value, and the number of digits in its textual
192 /* An entry in the lexical lookup table. */
200 /* Meridian: am, pm, or 24-hour style. */
201 enum { MERam
, MERpm
, MER24
};
203 /* Information passed to and from the parser. */
206 /* The input string remaining to be parsed. */
209 /* N, if this is the Nth Tuesday. */
212 /* Day of week; Sunday is 0. */
215 /* tm_isdst flag for the local zone. */
218 /* Time zone, in minutes east of UTC. */
221 /* Style used for time. */
224 /* Gregorian year, month, day, hour, minutes, and seconds. */
232 /* Relative year, month, day, hour, minutes, and seconds. */
240 /* Counts of nonterminals of various flavors parsed so far. */
243 int local_zones_seen
;
248 /* Table of local time zone abbrevations, terminated by a null entry. */
249 table local_time_zone_table
[3];
252 #define PC (* (parser_control *) parm)
253 #define YYLEX_PARAM parm
254 #define YYPARSE_PARAM parm
256 static int yyerror ();
261 /* Enabling traces. */
266 /* Enabling verbose error messages. */
267 #ifdef YYERROR_VERBOSE
268 # undef YYERROR_VERBOSE
269 # define YYERROR_VERBOSE 1
271 # define YYERROR_VERBOSE 0
274 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
275 #line 172 "getdate.y"
276 typedef union YYSTYPE
{
280 /* Line 191 of yacc.c. */
281 #line 281 "getdate.c"
282 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
283 # define YYSTYPE_IS_DECLARED 1
284 # define YYSTYPE_IS_TRIVIAL 1
289 /* Copy the second part of user declarations. */
292 /* Line 214 of yacc.c. */
293 #line 293 "getdate.c"
295 #if ! defined (yyoverflow) || YYERROR_VERBOSE
297 /* The parser invokes alloca or malloc; define the necessary symbols. */
299 # if YYSTACK_USE_ALLOCA
300 # define YYSTACK_ALLOC alloca
302 # ifndef YYSTACK_USE_ALLOCA
303 # if defined (alloca) || defined (_ALLOCA_H)
304 # define YYSTACK_ALLOC alloca
307 # define YYSTACK_ALLOC __builtin_alloca
313 # ifdef YYSTACK_ALLOC
314 /* Pacify GCC's `empty if-body' warning. */
315 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
317 # if defined (__STDC__) || defined (__cplusplus)
318 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
319 # define YYSIZE_T size_t
321 # define YYSTACK_ALLOC malloc
322 # define YYSTACK_FREE free
324 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
327 #if (! defined (yyoverflow) \
328 && (! defined (__cplusplus) \
329 || (YYSTYPE_IS_TRIVIAL)))
331 /* A type that is properly aligned for any stack member. */
338 /* The size of the maximum gap between one aligned stack and the next. */
339 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
341 /* The size of an array large to enough to hold all stacks, each with
343 # define YYSTACK_BYTES(N) \
344 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
345 + YYSTACK_GAP_MAXIMUM)
347 /* Copy COUNT objects from FROM to TO. The source and destination do
351 # define YYCOPY(To, From, Count) \
352 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
354 # define YYCOPY(To, From, Count) \
357 register YYSIZE_T yyi; \
358 for (yyi = 0; yyi < (Count); yyi++) \
359 (To)[yyi] = (From)[yyi]; \
365 /* Relocate STACK from its old location to the new one. The
366 local variables YYSIZE and YYSTACKSIZE give the old and new number of
367 elements in the stack, and YYPTR gives the new location of the
368 stack. Advance YYPTR to a properly aligned location for the next
370 # define YYSTACK_RELOCATE(Stack) \
373 YYSIZE_T yynewbytes; \
374 YYCOPY (&yyptr->Stack, Stack, yysize); \
375 Stack = &yyptr->Stack; \
376 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
377 yyptr += yynewbytes / sizeof (*yyptr); \
383 #if defined (__STDC__) || defined (__cplusplus)
384 typedef signed char yysigned_char
;
386 typedef short yysigned_char
;
389 /* YYFINAL -- State number of the termination state. */
391 /* YYLAST -- Last index in YYTABLE. */
394 /* YYNTOKENS -- Number of terminals. */
396 /* YYNNTS -- Number of nonterminals. */
398 /* YYNRULES -- Number of rules. */
400 /* YYNRULES -- Number of states. */
403 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
405 #define YYMAXUTOK 273
407 #define YYTRANSLATE(YYX) \
408 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
410 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
411 static const unsigned char yytranslate
[] =
413 0, 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, 2, 2, 2, 2, 2, 2,
416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 19, 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, 2, 2, 2, 2,
437 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
438 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
439 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
444 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
446 static const unsigned char yyprhs
[] =
448 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
449 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
450 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
451 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
452 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
453 149, 152, 154, 156, 157
456 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
457 static const yysigned_char yyrhs
[] =
459 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
460 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
461 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
462 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
463 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
464 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
465 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
466 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
467 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
468 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
469 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
470 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
471 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
472 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
473 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
474 14, -1, 14, -1, 18, -1, -1, 10, -1
477 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
478 static const unsigned short yyrline
[] =
480 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
481 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
482 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
483 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
484 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
485 395, 397, 402, 439, 440
489 #if YYDEBUG || YYERROR_VERBOSE
490 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
491 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
492 static const char *const yytname
[] =
494 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
495 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
496 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
497 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
498 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
504 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
506 static const unsigned short yytoknum
[] =
508 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
509 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
514 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
515 static const unsigned char yyr1
[] =
517 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
518 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
519 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
520 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
521 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
525 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
526 static const unsigned char yyr2
[] =
528 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
529 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
530 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
531 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
532 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
536 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
537 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
538 means the default is an error. */
539 static const unsigned char yydefact
[] =
541 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
542 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
543 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
544 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
545 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
546 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
550 /* YYDEFGOTO[NTERM-NUM]. */
551 static const yysigned_char yydefgoto
[] =
553 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
557 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
559 #define YYPACT_NINF -17
560 static const yysigned_char yypact
[] =
562 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
563 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
564 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
565 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
566 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
567 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
571 /* YYPGOTO[NTERM-NUM]. */
572 static const yysigned_char yypgoto
[] =
574 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
578 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
579 positive, shift that token. If negative, reduce the rule which
580 number is the opposite. If zero, do what YYDEFACT says.
581 If YYTABLE_NINF, syntax error. */
582 #define YYTABLE_NINF -1
583 static const unsigned char yytable
[] =
585 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
586 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
587 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
588 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
589 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
593 static const unsigned char yycheck
[] =
595 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
596 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
597 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
598 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
599 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
603 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
604 symbol of state STATE-NUM. */
605 static const unsigned char yystos
[] =
607 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
608 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
609 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
610 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
611 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
612 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
616 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
617 # define YYSIZE_T __SIZE_TYPE__
619 #if ! defined (YYSIZE_T) && defined (size_t)
620 # define YYSIZE_T size_t
622 #if ! defined (YYSIZE_T)
623 # if defined (__STDC__) || defined (__cplusplus)
624 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
625 # define YYSIZE_T size_t
628 #if ! defined (YYSIZE_T)
629 # define YYSIZE_T unsigned int
632 #define yyerrok (yyerrstatus = 0)
633 #define yyclearin (yychar = YYEMPTY)
637 #define YYACCEPT goto yyacceptlab
638 #define YYABORT goto yyabortlab
639 #define YYERROR goto yyerrlab1
642 /* Like YYERROR except do call yyerror. This remains here temporarily
643 to ease the transition to the new meaning of YYERROR, for GCC.
644 Once GCC version 2 has supplanted version 1, this can go. */
646 #define YYFAIL goto yyerrlab
648 #define YYRECOVERING() (!!yyerrstatus)
650 #define YYBACKUP(Token, Value) \
652 if (yychar == YYEMPTY && yylen == 1) \
656 yytoken = YYTRANSLATE (yychar); \
662 yyerror ("syntax error: cannot back up");\
668 #define YYERRCODE 256
670 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
673 #ifndef YYLLOC_DEFAULT
674 # define YYLLOC_DEFAULT(Current, Rhs, N) \
675 Current.first_line = Rhs[1].first_line; \
676 Current.first_column = Rhs[1].first_column; \
677 Current.last_line = Rhs[N].last_line; \
678 Current.last_column = Rhs[N].last_column;
681 /* YYLEX -- calling `yylex' with the right arguments. */
684 # define YYLEX yylex (&yylval, YYLEX_PARAM)
686 # define YYLEX yylex (&yylval)
689 /* Enable debugging if requested. */
693 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
694 # define YYFPRINTF fprintf
697 # define YYDPRINTF(Args) \
703 # define YYDSYMPRINT(Args) \
709 # define YYDSYMPRINTF(Title, Token, Value, Location) \
713 YYFPRINTF (stderr, "%s ", Title); \
714 yysymprint (stderr, \
716 YYFPRINTF (stderr, "\n"); \
720 /*------------------------------------------------------------------.
721 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
723 `------------------------------------------------------------------*/
725 #if defined (__STDC__) || defined (__cplusplus)
727 yy_stack_print (short *bottom
, short *top
)
730 yy_stack_print (bottom
, top
)
735 YYFPRINTF (stderr
, "Stack now");
736 for (/* Nothing. */; bottom
<= top
; ++bottom
)
737 YYFPRINTF (stderr
, " %d", *bottom
);
738 YYFPRINTF (stderr
, "\n");
741 # define YY_STACK_PRINT(Bottom, Top) \
744 yy_stack_print ((Bottom), (Top)); \
748 /*------------------------------------------------.
749 | Report that the YYRULE is going to be reduced. |
750 `------------------------------------------------*/
752 #if defined (__STDC__) || defined (__cplusplus)
754 yy_reduce_print (int yyrule
)
757 yy_reduce_print (yyrule
)
762 unsigned int yylineno
= yyrline
[yyrule
];
763 YYFPRINTF (stderr
, "Reducing stack by rule %d (line %u), ",
764 yyrule
- 1, yylineno
);
765 /* Print the symbols being reduced, and their result. */
766 for (yyi
= yyprhs
[yyrule
]; 0 <= yyrhs
[yyi
]; yyi
++)
767 YYFPRINTF (stderr
, "%s ", yytname
[yyrhs
[yyi
]]);
768 YYFPRINTF (stderr
, "-> %s\n", yytname
[yyr1
[yyrule
]]);
771 # define YY_REDUCE_PRINT(Rule) \
774 yy_reduce_print (Rule); \
777 /* Nonzero means print parse trace. It is left uninitialized so that
778 multiple parsers can coexist. */
781 # define YYDPRINTF(Args)
782 # define YYDSYMPRINT(Args)
783 # define YYDSYMPRINTF(Title, Token, Value, Location)
784 # define YY_STACK_PRINT(Bottom, Top)
785 # define YY_REDUCE_PRINT(Rule)
786 #endif /* !YYDEBUG */
789 /* YYINITDEPTH -- initial size of the parser's stacks. */
791 # define YYINITDEPTH 200
794 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
795 if the built-in stack extension method is used).
797 Do not make this value too large; the results are undefined if
798 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
799 evaluated with infinite-precision integer arithmetic. */
806 # define YYMAXDEPTH 10000
814 # if defined (__GLIBC__) && defined (_STRING_H)
815 # define yystrlen strlen
817 /* Return the length of YYSTR. */
819 # if defined (__STDC__) || defined (__cplusplus)
820 yystrlen (const char *yystr
)
826 register const char *yys
= yystr
;
828 while (*yys
++ != '\0')
831 return yys
- yystr
- 1;
837 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
838 # define yystpcpy stpcpy
840 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
843 # if defined (__STDC__) || defined (__cplusplus)
844 yystpcpy (char *yydest
, const char *yysrc
)
846 yystpcpy (yydest
, yysrc
)
851 register char *yyd
= yydest
;
852 register const char *yys
= yysrc
;
854 while ((*yyd
++ = *yys
++) != '\0')
862 #endif /* !YYERROR_VERBOSE */
867 /*--------------------------------.
868 | Print this symbol on YYOUTPUT. |
869 `--------------------------------*/
871 #if defined (__STDC__) || defined (__cplusplus)
873 yysymprint (FILE *yyoutput
, int yytype
, YYSTYPE
*yyvaluep
)
876 yysymprint (yyoutput
, yytype
, yyvaluep
)
882 /* Pacify ``unused variable'' warnings. */
885 if (yytype
< YYNTOKENS
)
887 YYFPRINTF (yyoutput
, "token %s (", yytname
[yytype
]);
889 YYPRINT (yyoutput
, yytoknum
[yytype
], *yyvaluep
);
893 YYFPRINTF (yyoutput
, "nterm %s (", yytname
[yytype
]);
900 YYFPRINTF (yyoutput
, ")");
903 #endif /* ! YYDEBUG */
904 /*-----------------------------------------------.
905 | Release the memory associated to this symbol. |
906 `-----------------------------------------------*/
908 #if defined (__STDC__) || defined (__cplusplus)
910 yydestruct (int yytype
, YYSTYPE
*yyvaluep
)
913 yydestruct (yytype
, yyvaluep
)
918 /* Pacify ``unused variable'' warnings. */
930 /* Prevent warnings from -Wmissing-prototypes. */
933 # if defined (__STDC__) || defined (__cplusplus)
934 int yyparse (void *YYPARSE_PARAM
);
938 #else /* ! YYPARSE_PARAM */
939 #if defined (__STDC__) || defined (__cplusplus)
944 #endif /* ! YYPARSE_PARAM */
956 # if defined (__STDC__) || defined (__cplusplus)
957 int yyparse (void *YYPARSE_PARAM
)
959 int yyparse (YYPARSE_PARAM
)
962 #else /* ! YYPARSE_PARAM */
963 #if defined (__STDC__) || defined (__cplusplus)
973 /* The lookahead symbol. */
976 /* The semantic value of the lookahead symbol. */
979 /* Number of syntax errors so far. */
982 register int yystate
;
985 /* Number of tokens to shift before error messages enabled. */
987 /* Lookahead token as an internal (translated) token number. */
990 /* Three stacks and their tools:
991 `yyss': related to states,
992 `yyvs': related to semantic values,
993 `yyls': related to locations.
995 Refer to the stacks thru separate pointers, to allow yyoverflow
996 to reallocate them elsewhere. */
998 /* The state stack. */
999 short yyssa
[YYINITDEPTH
];
1000 short *yyss
= yyssa
;
1001 register short *yyssp
;
1003 /* The semantic value stack. */
1004 YYSTYPE yyvsa
[YYINITDEPTH
];
1005 YYSTYPE
*yyvs
= yyvsa
;
1006 register YYSTYPE
*yyvsp
;
1010 #define YYPOPSTACK (yyvsp--, yyssp--)
1012 YYSIZE_T yystacksize
= YYINITDEPTH
;
1014 /* The variables used to return semantic value and location from the
1019 /* When reducing, the number of symbols on the RHS of the reduced
1023 YYDPRINTF ((stderr
, "Starting parse\n"));
1028 yychar
= YYEMPTY
; /* Cause a token to be read. */
1030 /* Initialize stack pointers.
1031 Waste one element of value and location stack
1032 so that they stay on the same level as the state stack.
1033 The wasted elements are never initialized. */
1040 /*------------------------------------------------------------.
1041 | yynewstate -- Push a new state, which is found in yystate. |
1042 `------------------------------------------------------------*/
1044 /* In all cases, when you get here, the value and location stacks
1045 have just been pushed. so pushing a state here evens the stacks.
1052 if (yyss
+ yystacksize
- 1 <= yyssp
)
1054 /* Get the current used size of the three stacks, in elements. */
1055 YYSIZE_T yysize
= yyssp
- yyss
+ 1;
1059 /* Give user a chance to reallocate the stack. Use copies of
1060 these so that the &'s don't force the real ones into
1062 YYSTYPE
*yyvs1
= yyvs
;
1063 short *yyss1
= yyss
;
1066 /* Each stack pointer address is followed by the size of the
1067 data in use in that stack, in bytes. This used to be a
1068 conditional around just the two extra args, but that might
1069 be undefined if yyoverflow is a macro. */
1070 yyoverflow ("parser stack overflow",
1071 &yyss1
, yysize
* sizeof (*yyssp
),
1072 &yyvs1
, yysize
* sizeof (*yyvsp
),
1079 #else /* no yyoverflow */
1080 # ifndef YYSTACK_RELOCATE
1083 /* Extend the stack our own way. */
1084 if (YYMAXDEPTH
<= yystacksize
)
1087 if (YYMAXDEPTH
< yystacksize
)
1088 yystacksize
= YYMAXDEPTH
;
1091 short *yyss1
= yyss
;
1092 union yyalloc
*yyptr
=
1093 (union yyalloc
*) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize
));
1096 YYSTACK_RELOCATE (yyss
);
1097 YYSTACK_RELOCATE (yyvs
);
1099 # undef YYSTACK_RELOCATE
1101 YYSTACK_FREE (yyss1
);
1104 #endif /* no yyoverflow */
1106 yyssp
= yyss
+ yysize
- 1;
1107 yyvsp
= yyvs
+ yysize
- 1;
1110 YYDPRINTF ((stderr
, "Stack size increased to %lu\n",
1111 (unsigned long int) yystacksize
));
1113 if (yyss
+ yystacksize
- 1 <= yyssp
)
1117 YYDPRINTF ((stderr
, "Entering state %d\n", yystate
));
1126 /* Do appropriate processing given the current state. */
1127 /* Read a lookahead token if we need one and don't already have one. */
1130 /* First try to decide what to do without reference to lookahead token. */
1132 yyn
= yypact
[yystate
];
1133 if (yyn
== YYPACT_NINF
)
1136 /* Not known => get a lookahead token if don't already have one. */
1138 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1139 if (yychar
== YYEMPTY
)
1141 YYDPRINTF ((stderr
, "Reading a token: "));
1145 if (yychar
<= YYEOF
)
1147 yychar
= yytoken
= YYEOF
;
1148 YYDPRINTF ((stderr
, "Now at end of input.\n"));
1152 yytoken
= YYTRANSLATE (yychar
);
1153 YYDSYMPRINTF ("Next token is", yytoken
, &yylval
, &yylloc
);
1156 /* If the proper action on seeing token YYTOKEN is to reduce or to
1157 detect an error, take that action. */
1159 if (yyn
< 0 || YYLAST
< yyn
|| yycheck
[yyn
] != yytoken
)
1164 if (yyn
== 0 || yyn
== YYTABLE_NINF
)
1173 /* Shift the lookahead token. */
1174 YYDPRINTF ((stderr
, "Shifting token %s, ", yytname
[yytoken
]));
1176 /* Discard the token being shifted unless it is eof. */
1177 if (yychar
!= YYEOF
)
1183 /* Count tokens shifted since error; after three, turn off error
1192 /*-----------------------------------------------------------.
1193 | yydefault -- do the default action for the current state. |
1194 `-----------------------------------------------------------*/
1196 yyn
= yydefact
[yystate
];
1202 /*-----------------------------.
1203 | yyreduce -- Do a reduction. |
1204 `-----------------------------*/
1206 /* yyn is the number of a rule to reduce with. */
1209 /* If YYLEN is nonzero, implement the default value of the action:
1212 Otherwise, the following line sets YYVAL to garbage.
1213 This behavior is undocumented and Bison
1214 users should not rely upon it. Assigning to YYVAL
1215 unconditionally makes the parser a bit smaller, and it avoids a
1216 GCC warning that YYVAL may be used uninitialized. */
1217 yyval
= yyvsp
[1-yylen
];
1220 YY_REDUCE_PRINT (yyn
);
1224 #line 195 "getdate.y"
1225 { PC
.times_seen
++; }
1229 #line 197 "getdate.y"
1230 { PC
.local_zones_seen
++; }
1234 #line 199 "getdate.y"
1235 { PC
.zones_seen
++; }
1239 #line 201 "getdate.y"
1240 { PC
.dates_seen
++; }
1244 #line 203 "getdate.y"
1249 #line 205 "getdate.y"
1254 #line 211 "getdate.y"
1256 PC
.hour
= yyvsp
[-1].textintval
.value
;
1259 PC
.meridian
= yyvsp
[0].intval
;
1264 #line 218 "getdate.y"
1266 PC
.hour
= yyvsp
[-3].textintval
.value
;
1267 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1269 PC
.meridian
= yyvsp
[0].intval
;
1274 #line 225 "getdate.y"
1276 PC
.hour
= yyvsp
[-3].textintval
.value
;
1277 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1278 PC
.meridian
= MER24
;
1280 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1285 #line 233 "getdate.y"
1287 PC
.hour
= yyvsp
[-5].textintval
.value
;
1288 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1289 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1290 PC
.meridian
= yyvsp
[0].intval
;
1295 #line 240 "getdate.y"
1297 PC
.hour
= yyvsp
[-5].textintval
.value
;
1298 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1299 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1300 PC
.meridian
= MER24
;
1302 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1307 #line 252 "getdate.y"
1308 { PC
.local_isdst
= yyvsp
[0].intval
; }
1312 #line 254 "getdate.y"
1313 { PC
.local_isdst
= yyvsp
[-1].intval
< 0 ? 1 : yyvsp
[-1].intval
+ 1; }
1317 #line 259 "getdate.y"
1318 { PC
.time_zone
= yyvsp
[0].intval
; }
1322 #line 261 "getdate.y"
1323 { PC
.time_zone
= yyvsp
[0].intval
+ 60; }
1327 #line 263 "getdate.y"
1328 { PC
.time_zone
= yyvsp
[-1].intval
+ 60; }
1332 #line 268 "getdate.y"
1335 PC
.day_number
= yyvsp
[0].intval
;
1340 #line 273 "getdate.y"
1343 PC
.day_number
= yyvsp
[-1].intval
;
1348 #line 278 "getdate.y"
1350 PC
.day_ordinal
= yyvsp
[-1].textintval
.value
;
1351 PC
.day_number
= yyvsp
[0].intval
;
1356 #line 286 "getdate.y"
1358 PC
.month
= yyvsp
[-2].textintval
.value
;
1359 PC
.day
= yyvsp
[0].textintval
.value
;
1364 #line 291 "getdate.y"
1366 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1367 otherwise as MM/DD/YY.
1368 The goal in recognizing YYYY/MM/DD is solely to support legacy
1369 machine-generated dates like those in an RCS log listing. If
1370 you want portability, use the ISO 8601 format. */
1371 if (4 <= yyvsp
[-4].textintval
.digits
)
1373 PC
.year
= yyvsp
[-4].textintval
;
1374 PC
.month
= yyvsp
[-2].textintval
.value
;
1375 PC
.day
= yyvsp
[0].textintval
.value
;
1379 PC
.month
= yyvsp
[-4].textintval
.value
;
1380 PC
.day
= yyvsp
[-2].textintval
.value
;
1381 PC
.year
= yyvsp
[0].textintval
;
1387 #line 311 "getdate.y"
1389 /* ISO 8601 format. YYYY-MM-DD. */
1390 PC
.year
= yyvsp
[-2].textintval
;
1391 PC
.month
= -yyvsp
[-1].textintval
.value
;
1392 PC
.day
= -yyvsp
[0].textintval
.value
;
1397 #line 318 "getdate.y"
1399 /* e.g. 17-JUN-1992. */
1400 PC
.day
= yyvsp
[-2].textintval
.value
;
1401 PC
.month
= yyvsp
[-1].intval
;
1402 PC
.year
.value
= -yyvsp
[0].textintval
.value
;
1403 PC
.year
.digits
= yyvsp
[0].textintval
.digits
;
1408 #line 326 "getdate.y"
1410 PC
.month
= yyvsp
[-1].intval
;
1411 PC
.day
= yyvsp
[0].textintval
.value
;
1416 #line 331 "getdate.y"
1418 PC
.month
= yyvsp
[-3].intval
;
1419 PC
.day
= yyvsp
[-2].textintval
.value
;
1420 PC
.year
= yyvsp
[0].textintval
;
1425 #line 337 "getdate.y"
1427 PC
.day
= yyvsp
[-1].textintval
.value
;
1428 PC
.month
= yyvsp
[0].intval
;
1433 #line 342 "getdate.y"
1435 PC
.day
= yyvsp
[-2].textintval
.value
;
1436 PC
.month
= yyvsp
[-1].intval
;
1437 PC
.year
= yyvsp
[0].textintval
;
1442 #line 351 "getdate.y"
1444 PC
.rel_seconds
= -PC
.rel_seconds
;
1445 PC
.rel_minutes
= -PC
.rel_minutes
;
1446 PC
.rel_hour
= -PC
.rel_hour
;
1447 PC
.rel_day
= -PC
.rel_day
;
1448 PC
.rel_month
= -PC
.rel_month
;
1449 PC
.rel_year
= -PC
.rel_year
;
1454 #line 364 "getdate.y"
1455 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1459 #line 366 "getdate.y"
1460 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1464 #line 368 "getdate.y"
1465 { PC
.rel_year
+= yyvsp
[0].intval
; }
1469 #line 370 "getdate.y"
1470 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1474 #line 372 "getdate.y"
1475 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1479 #line 374 "getdate.y"
1480 { PC
.rel_month
+= yyvsp
[0].intval
; }
1484 #line 376 "getdate.y"
1485 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1489 #line 378 "getdate.y"
1490 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1494 #line 380 "getdate.y"
1495 { PC
.rel_day
+= yyvsp
[0].intval
; }
1499 #line 382 "getdate.y"
1500 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1504 #line 384 "getdate.y"
1505 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1509 #line 386 "getdate.y"
1510 { PC
.rel_hour
+= yyvsp
[0].intval
; }
1514 #line 388 "getdate.y"
1515 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1519 #line 390 "getdate.y"
1520 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1524 #line 392 "getdate.y"
1525 { PC
.rel_minutes
+= yyvsp
[0].intval
; }
1529 #line 394 "getdate.y"
1530 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1534 #line 396 "getdate.y"
1535 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1539 #line 398 "getdate.y"
1540 { PC
.rel_seconds
+= yyvsp
[0].intval
; }
1544 #line 403 "getdate.y"
1547 && ! PC
.rels_seen
&& (PC
.times_seen
|| 2 < yyvsp
[0].textintval
.digits
))
1548 PC
.year
= yyvsp
[0].textintval
;
1551 if (4 < yyvsp
[0].textintval
.digits
)
1554 PC
.day
= yyvsp
[0].textintval
.value
% 100;
1555 PC
.month
= (yyvsp
[0].textintval
.value
/ 100) % 100;
1556 PC
.year
.value
= yyvsp
[0].textintval
.value
/ 10000;
1557 PC
.year
.digits
= yyvsp
[0].textintval
.digits
- 4;
1562 if (yyvsp
[0].textintval
.digits
<= 2)
1564 PC
.hour
= yyvsp
[0].textintval
.value
;
1569 PC
.hour
= yyvsp
[0].textintval
.value
/ 100;
1570 PC
.minutes
= yyvsp
[0].textintval
.value
% 100;
1573 PC
.meridian
= MER24
;
1580 #line 439 "getdate.y"
1581 { yyval
.intval
= MER24
; }
1585 #line 441 "getdate.y"
1586 { yyval
.intval
= yyvsp
[0].intval
; }
1592 /* Line 999 of yacc.c. */
1593 #line 1593 "getdate.c"
1599 YY_STACK_PRINT (yyss
, yyssp
);
1604 /* Now `shift' the result of the reduction. Determine what state
1605 that goes to, based on the state we popped back to and the rule
1606 number reduced by. */
1610 yystate
= yypgoto
[yyn
- YYNTOKENS
] + *yyssp
;
1611 if (0 <= yystate
&& yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
1612 yystate
= yytable
[yystate
];
1614 yystate
= yydefgoto
[yyn
- YYNTOKENS
];
1619 /*------------------------------------.
1620 | yyerrlab -- here on detecting error |
1621 `------------------------------------*/
1623 /* If not already recovering from an error, report this error. */
1628 yyn
= yypact
[yystate
];
1630 if (YYPACT_NINF
< yyn
&& yyn
< YYLAST
)
1632 YYSIZE_T yysize
= 0;
1633 int yytype
= YYTRANSLATE (yychar
);
1638 /* Start YYX at -YYN if negative to avoid negative indexes in
1640 for (yyx
= yyn
< 0 ? -yyn
: 0;
1641 yyx
< (int) (sizeof (yytname
) / sizeof (char *)); yyx
++)
1642 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1643 yysize
+= yystrlen (yytname
[yyx
]) + 15, yycount
++;
1644 yysize
+= yystrlen ("syntax error, unexpected ") + 1;
1645 yysize
+= yystrlen (yytname
[yytype
]);
1646 yymsg
= (char *) YYSTACK_ALLOC (yysize
);
1649 char *yyp
= yystpcpy (yymsg
, "syntax error, unexpected ");
1650 yyp
= yystpcpy (yyp
, yytname
[yytype
]);
1655 for (yyx
= yyn
< 0 ? -yyn
: 0;
1656 yyx
< (int) (sizeof (yytname
) / sizeof (char *));
1658 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1660 const char *yyq
= ! yycount
? ", expecting " : " or ";
1661 yyp
= yystpcpy (yyp
, yyq
);
1662 yyp
= yystpcpy (yyp
, yytname
[yyx
]);
1667 YYSTACK_FREE (yymsg
);
1670 yyerror ("syntax error; also virtual memory exhausted");
1673 #endif /* YYERROR_VERBOSE */
1674 yyerror ("syntax error");
1679 if (yyerrstatus
== 3)
1681 /* If just tried and failed to reuse lookahead token after an
1682 error, discard it. */
1684 /* Return failure if at end of input. */
1685 if (yychar
== YYEOF
)
1687 /* Pop the error token. */
1689 /* Pop the rest of the stack. */
1690 while (yyss
< yyssp
)
1692 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1693 yydestruct (yystos
[*yyssp
], yyvsp
);
1699 YYDSYMPRINTF ("Error: discarding", yytoken
, &yylval
, &yylloc
);
1700 yydestruct (yytoken
, &yylval
);
1705 /* Else will try to reuse lookahead token after shifting the error
1710 /*----------------------------------------------------.
1711 | yyerrlab1 -- error raised explicitly by an action. |
1712 `----------------------------------------------------*/
1714 yyerrstatus
= 3; /* Each real token shifted decrements this. */
1718 yyn
= yypact
[yystate
];
1719 if (yyn
!= YYPACT_NINF
)
1722 if (0 <= yyn
&& yyn
<= YYLAST
&& yycheck
[yyn
] == YYTERROR
)
1730 /* Pop the current state because it cannot handle the error token. */
1734 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1735 yydestruct (yystos
[yystate
], yyvsp
);
1739 YY_STACK_PRINT (yyss
, yyssp
);
1745 YYDPRINTF ((stderr
, "Shifting error token, "));
1754 /*-------------------------------------.
1755 | yyacceptlab -- YYACCEPT comes here. |
1756 `-------------------------------------*/
1761 /*-----------------------------------.
1762 | yyabortlab -- YYABORT comes here. |
1763 `-----------------------------------*/
1769 /*----------------------------------------------.
1770 | yyoverflowlab -- parser overflow comes here. |
1771 `----------------------------------------------*/
1773 yyerror ("parser stack overflow");
1781 YYSTACK_FREE (yyss
);
1787 #line 444 "getdate.y"
1790 /* Include this file down here because bison inserts code above which
1791 may define-away `const'. We want the prototype for get_date to have
1792 the same signature as the function definition. */
1793 #include "modules/getdate.h"
1796 struct tm
*gmtime ();
1799 struct tm
*localtime ();
1805 static table
const meridian_table
[] =
1807 { "AM", tMERIDIAN
, MERam
},
1808 { "A.M.", tMERIDIAN
, MERam
},
1809 { "PM", tMERIDIAN
, MERpm
},
1810 { "P.M.", tMERIDIAN
, MERpm
},
1814 static table
const dst_table
[] =
1819 static table
const month_and_day_table
[] =
1821 { "JANUARY", tMONTH
, 1 },
1822 { "FEBRUARY", tMONTH
, 2 },
1823 { "MARCH", tMONTH
, 3 },
1824 { "APRIL", tMONTH
, 4 },
1825 { "MAY", tMONTH
, 5 },
1826 { "JUNE", tMONTH
, 6 },
1827 { "JULY", tMONTH
, 7 },
1828 { "AUGUST", tMONTH
, 8 },
1829 { "SEPTEMBER",tMONTH
, 9 },
1830 { "SEPT", tMONTH
, 9 },
1831 { "OCTOBER", tMONTH
, 10 },
1832 { "NOVEMBER", tMONTH
, 11 },
1833 { "DECEMBER", tMONTH
, 12 },
1834 { "SUNDAY", tDAY
, 0 },
1835 { "MONDAY", tDAY
, 1 },
1836 { "TUESDAY", tDAY
, 2 },
1837 { "TUES", tDAY
, 2 },
1838 { "WEDNESDAY",tDAY
, 3 },
1839 { "WEDNES", tDAY
, 3 },
1840 { "THURSDAY", tDAY
, 4 },
1841 { "THUR", tDAY
, 4 },
1842 { "THURS", tDAY
, 4 },
1843 { "FRIDAY", tDAY
, 5 },
1844 { "SATURDAY", tDAY
, 6 },
1848 static table
const time_units_table
[] =
1850 { "YEAR", tYEAR_UNIT
, 1 },
1851 { "MONTH", tMONTH_UNIT
, 1 },
1852 { "FORTNIGHT",tDAY_UNIT
, 14 },
1853 { "WEEK", tDAY_UNIT
, 7 },
1854 { "DAY", tDAY_UNIT
, 1 },
1855 { "HOUR", tHOUR_UNIT
, 1 },
1856 { "MINUTE", tMINUTE_UNIT
, 1 },
1857 { "MIN", tMINUTE_UNIT
, 1 },
1858 { "SECOND", tSEC_UNIT
, 1 },
1859 { "SEC", tSEC_UNIT
, 1 },
1863 /* Assorted relative-time words. */
1864 static table
const relative_time_table
[] =
1866 { "TOMORROW", tMINUTE_UNIT
, 24 * 60 },
1867 { "YESTERDAY",tMINUTE_UNIT
, - (24 * 60) },
1868 { "TODAY", tMINUTE_UNIT
, 0 },
1869 { "NOW", tMINUTE_UNIT
, 0 },
1870 { "LAST", tUNUMBER
, -1 },
1871 { "THIS", tUNUMBER
, 0 },
1872 { "NEXT", tUNUMBER
, 1 },
1873 { "FIRST", tUNUMBER
, 1 },
1874 /*{ "SECOND", tUNUMBER, 2 }, */
1875 { "THIRD", tUNUMBER
, 3 },
1876 { "FOURTH", tUNUMBER
, 4 },
1877 { "FIFTH", tUNUMBER
, 5 },
1878 { "SIXTH", tUNUMBER
, 6 },
1879 { "SEVENTH", tUNUMBER
, 7 },
1880 { "EIGHTH", tUNUMBER
, 8 },
1881 { "NINTH", tUNUMBER
, 9 },
1882 { "TENTH", tUNUMBER
, 10 },
1883 { "ELEVENTH", tUNUMBER
, 11 },
1884 { "TWELFTH", tUNUMBER
, 12 },
1889 /* The time zone table. This table is necessarily incomplete, as time
1890 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1891 as Eastern time in Australia, not as US Eastern Standard Time.
1892 You cannot rely on getdate to handle arbitrary time zone
1893 abbreviations; use numeric abbreviations like `-0500' instead. */
1894 static table
const time_zone_table
[] =
1896 { "GMT", tZONE
, HOUR ( 0) }, /* Greenwich Mean */
1897 { "UT", tZONE
, HOUR ( 0) }, /* Universal (Coordinated) */
1898 { "UTC", tZONE
, HOUR ( 0) },
1899 { "WET", tZONE
, HOUR ( 0) }, /* Western European */
1900 { "WEST", tDAYZONE
, HOUR ( 0) }, /* Western European Summer */
1901 { "BST", tDAYZONE
, HOUR ( 0) }, /* British Summer */
1902 { "ART", tZONE
, -HOUR ( 3) }, /* Argentina */
1903 { "BRT", tZONE
, -HOUR ( 3) }, /* Brazil */
1904 { "BRST", tDAYZONE
, -HOUR ( 3) }, /* Brazil Summer */
1905 { "NST", tZONE
, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1906 { "NDT", tDAYZONE
,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1907 { "AST", tZONE
, -HOUR ( 4) }, /* Atlantic Standard */
1908 { "ADT", tDAYZONE
, -HOUR ( 4) }, /* Atlantic Daylight */
1909 { "CLT", tZONE
, -HOUR ( 4) }, /* Chile */
1910 { "CLST", tDAYZONE
, -HOUR ( 4) }, /* Chile Summer */
1911 { "EST", tZONE
, -HOUR ( 5) }, /* Eastern Standard */
1912 { "EDT", tDAYZONE
, -HOUR ( 5) }, /* Eastern Daylight */
1913 { "CST", tZONE
, -HOUR ( 6) }, /* Central Standard */
1914 { "CDT", tDAYZONE
, -HOUR ( 6) }, /* Central Daylight */
1915 { "MST", tZONE
, -HOUR ( 7) }, /* Mountain Standard */
1916 { "MDT", tDAYZONE
, -HOUR ( 7) }, /* Mountain Daylight */
1917 { "PST", tZONE
, -HOUR ( 8) }, /* Pacific Standard */
1918 { "PDT", tDAYZONE
, -HOUR ( 8) }, /* Pacific Daylight */
1919 { "AKST", tZONE
, -HOUR ( 9) }, /* Alaska Standard */
1920 { "AKDT", tDAYZONE
, -HOUR ( 9) }, /* Alaska Daylight */
1921 { "HST", tZONE
, -HOUR (10) }, /* Hawaii Standard */
1922 { "HAST", tZONE
, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1923 { "HADT", tDAYZONE
, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1924 { "SST", tZONE
, -HOUR (12) }, /* Samoa Standard */
1925 { "WAT", tZONE
, HOUR ( 1) }, /* West Africa */
1926 { "CET", tZONE
, HOUR ( 1) }, /* Central European */
1927 { "CEST", tDAYZONE
, HOUR ( 1) }, /* Central European Summer */
1928 { "MET", tZONE
, HOUR ( 1) }, /* Middle European */
1929 { "MEZ", tZONE
, HOUR ( 1) }, /* Middle European */
1930 { "MEST", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1931 { "MESZ", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1932 { "EET", tZONE
, HOUR ( 2) }, /* Eastern European */
1933 { "EEST", tDAYZONE
, HOUR ( 2) }, /* Eastern European Summer */
1934 { "CAT", tZONE
, HOUR ( 2) }, /* Central Africa */
1935 { "SAST", tZONE
, HOUR ( 2) }, /* South Africa Standard */
1936 { "EAT", tZONE
, HOUR ( 3) }, /* East Africa */
1937 { "MSK", tZONE
, HOUR ( 3) }, /* Moscow */
1938 { "MSD", tDAYZONE
, HOUR ( 3) }, /* Moscow Daylight */
1939 { "IST", tZONE
, (HOUR ( 5) + 30) }, /* India Standard */
1940 { "SGT", tZONE
, HOUR ( 8) }, /* Singapore */
1941 { "KST", tZONE
, HOUR ( 9) }, /* Korea Standard */
1942 { "JST", tZONE
, HOUR ( 9) }, /* Japan Standard */
1943 { "GST", tZONE
, HOUR (10) }, /* Guam Standard */
1944 { "NZST", tZONE
, HOUR (12) }, /* New Zealand Standard */
1945 { "NZDT", tDAYZONE
, HOUR (12) }, /* New Zealand Daylight */
1949 /* Military time zone table. */
1950 static table
const military_table
[] =
1952 { "A", tZONE
, -HOUR ( 1) },
1953 { "B", tZONE
, -HOUR ( 2) },
1954 { "C", tZONE
, -HOUR ( 3) },
1955 { "D", tZONE
, -HOUR ( 4) },
1956 { "E", tZONE
, -HOUR ( 5) },
1957 { "F", tZONE
, -HOUR ( 6) },
1958 { "G", tZONE
, -HOUR ( 7) },
1959 { "H", tZONE
, -HOUR ( 8) },
1960 { "I", tZONE
, -HOUR ( 9) },
1961 { "K", tZONE
, -HOUR (10) },
1962 { "L", tZONE
, -HOUR (11) },
1963 { "M", tZONE
, -HOUR (12) },
1964 { "N", tZONE
, HOUR ( 1) },
1965 { "O", tZONE
, HOUR ( 2) },
1966 { "P", tZONE
, HOUR ( 3) },
1967 { "Q", tZONE
, HOUR ( 4) },
1968 { "R", tZONE
, HOUR ( 5) },
1969 { "S", tZONE
, HOUR ( 6) },
1970 { "T", tZONE
, HOUR ( 7) },
1971 { "U", tZONE
, HOUR ( 8) },
1972 { "V", tZONE
, HOUR ( 9) },
1973 { "W", tZONE
, HOUR (10) },
1974 { "X", tZONE
, HOUR (11) },
1975 { "Y", tZONE
, HOUR (12) },
1976 { "Z", tZONE
, HOUR ( 0) },
1983 to_hour (int hours
, int meridian
)
1988 return 0 <= hours
&& hours
< 24 ? hours
: -1;
1990 return 0 < hours
&& hours
< 12 ? hours
: hours
== 12 ? 0 : -1;
1992 return 0 < hours
&& hours
< 12 ? hours
+ 12 : hours
== 12 ? 12 : -1;
2001 to_year (textint textyear
)
2003 int year
= textyear
.value
;
2008 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2009 years 69-99 map to 1969-1999. */
2010 if (textyear
.digits
== 2)
2011 year
+= year
< 69 ? 2000 : 1900;
2016 static table
const *
2017 lookup_zone (parser_control
const *pc
, char const *name
)
2021 /* Try local zone abbreviations first; they're more likely to be right. */
2022 for (tp
= pc
->local_time_zone_table
; tp
->name
; tp
++)
2023 if (strcmp (name
, tp
->name
) == 0)
2026 for (tp
= time_zone_table
; tp
->name
; tp
++)
2027 if (strcmp (name
, tp
->name
) == 0)
2033 #if ! HAVE_TM_GMTOFF
2034 /* Yield the difference between *A and *B,
2035 measured in seconds, ignoring leap seconds.
2036 The body of this function is taken directly from the GNU C Library;
2037 see src/strftime.c. */
2039 tm_diff (struct tm
const *a
, struct tm
const *b
)
2041 /* Compute intervening leap days correctly even if year is negative.
2042 Take care to avoid int overflow in leap day calculations,
2043 but it's OK to assume that A and B are close to each other. */
2044 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
2045 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
2046 int a100
= a4
/ 25 - (a4
% 25 < 0);
2047 int b100
= b4
/ 25 - (b4
% 25 < 0);
2048 int a400
= a100
>> 2;
2049 int b400
= b100
>> 2;
2050 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
2051 int years
= a
->tm_year
- b
->tm_year
;
2052 int days
= (365 * years
+ intervening_leap_days
2053 + (a
->tm_yday
- b
->tm_yday
));
2054 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
2055 + (a
->tm_min
- b
->tm_min
))
2056 + (a
->tm_sec
- b
->tm_sec
));
2058 #endif /* ! HAVE_TM_GMTOFF */
2060 static table
const *
2061 lookup_word (parser_control
const *pc
, char *word
)
2070 /* Make it uppercase. */
2071 for (p
= word
; *p
; p
++)
2072 if (ISLOWER ((unsigned char) *p
))
2073 *p
= toupper ((unsigned char) *p
);
2075 for (tp
= meridian_table
; tp
->name
; tp
++)
2076 if (strcmp (word
, tp
->name
) == 0)
2079 /* See if we have an abbreviation for a month. */
2080 wordlen
= strlen (word
);
2081 abbrev
= wordlen
== 3 || (wordlen
== 4 && word
[3] == '.');
2083 for (tp
= month_and_day_table
; tp
->name
; tp
++)
2084 if ((abbrev
? strncmp (word
, tp
->name
, 3) : strcmp (word
, tp
->name
)) == 0)
2087 if ((tp
= lookup_zone (pc
, word
)))
2090 if (strcmp (word
, dst_table
[0].name
) == 0)
2093 for (tp
= time_units_table
; tp
->name
; tp
++)
2094 if (strcmp (word
, tp
->name
) == 0)
2097 /* Strip off any plural and try the units table again. */
2098 if (word
[wordlen
- 1] == 'S')
2100 word
[wordlen
- 1] = '\0';
2101 for (tp
= time_units_table
; tp
->name
; tp
++)
2102 if (strcmp (word
, tp
->name
) == 0)
2104 word
[wordlen
- 1] = 'S'; /* For "this" in relative_time_table. */
2107 for (tp
= relative_time_table
; tp
->name
; tp
++)
2108 if (strcmp (word
, tp
->name
) == 0)
2111 /* Military time zones. */
2113 for (tp
= military_table
; tp
->name
; tp
++)
2114 if (word
[0] == tp
->name
[0])
2117 /* Drop out any periods and try the time zone table again. */
2118 for (i
= 0, p
= q
= word
; (*p
= *q
); q
++)
2123 if (i
&& (tp
= lookup_zone (pc
, word
)))
2130 yylex (YYSTYPE
*lvalp
, parser_control
*pc
)
2137 while (c
= *pc
->input
, ISSPACE (c
))
2140 if (ISDIGIT (c
) || c
== '-' || c
== '+')
2145 if (c
== '-' || c
== '+')
2147 sign
= c
== '-' ? -1 : 1;
2150 /* skip the '-' sign */
2159 value
= 10 * value
+ c
- '0';
2162 while (ISDIGIT (c
));
2163 lvalp
->textintval
.value
= sign
< 0 ? -value
: value
;
2164 lvalp
->textintval
.digits
= p
- pc
->input
;
2166 return sign
? tSNUMBER
: tUNUMBER
;
2177 if (p
< buff
+ sizeof buff
- 1)
2181 while (ISALPHA (c
) || c
== '.');
2184 tp
= lookup_word (pc
, buff
);
2187 lvalp
->intval
= tp
->value
;
2192 return *pc
->input
++;
2208 /* Do nothing if the parser reports an error. */
2210 yyerror (char *s ATTRIBUTE_UNUSED
)
2215 /* Parse a date/time string P. Return the corresponding time_t value,
2216 or (time_t) -1 if there is an error. P can be an incomplete or
2217 relative time specification; if so, use *NOW as the basis for the
2220 get_date (const char *p
, const time_t *now
)
2222 time_t Start
= now
? *now
: time (0);
2223 struct tm
*tmp
= localtime (&Start
);
2232 pc
.year
.value
= tmp
->tm_year
+ TM_YEAR_BASE
;
2234 pc
.month
= tmp
->tm_mon
+ 1;
2235 pc
.day
= tmp
->tm_mday
;
2236 pc
.hour
= tmp
->tm_hour
;
2237 pc
.minutes
= tmp
->tm_min
;
2238 pc
.seconds
= tmp
->tm_sec
;
2239 tm
.tm_isdst
= tmp
->tm_isdst
;
2241 pc
.meridian
= MER24
;
2252 pc
.local_zones_seen
= 0;
2255 #if HAVE_STRUCT_TM_TM_ZONE
2256 pc
.local_time_zone_table
[0].name
= tmp
->tm_zone
;
2257 pc
.local_time_zone_table
[0].type
= tLOCAL_ZONE
;
2258 pc
.local_time_zone_table
[0].value
= tmp
->tm_isdst
;
2259 pc
.local_time_zone_table
[1].name
= 0;
2261 /* Probe the names used in the next three calendar quarters, looking
2262 for a tm_isdst different from the one we already have. */
2265 for (quarter
= 1; quarter
<= 3; quarter
++)
2267 time_t probe
= Start
+ quarter
* (90 * 24 * 60 * 60);
2268 struct tm
*probe_tm
= localtime (&probe
);
2269 if (probe_tm
&& probe_tm
->tm_zone
2270 && probe_tm
->tm_isdst
!= pc
.local_time_zone_table
[0].value
)
2273 pc
.local_time_zone_table
[1].name
= probe_tm
->tm_zone
;
2274 pc
.local_time_zone_table
[1].type
= tLOCAL_ZONE
;
2275 pc
.local_time_zone_table
[1].value
= probe_tm
->tm_isdst
;
2276 pc
.local_time_zone_table
[2].name
= 0;
2286 extern char *tzname
[];
2289 for (i
= 0; i
< 2; i
++)
2291 pc
.local_time_zone_table
[i
].name
= tzname
[i
];
2292 pc
.local_time_zone_table
[i
].type
= tLOCAL_ZONE
;
2293 pc
.local_time_zone_table
[i
].value
= i
;
2295 pc
.local_time_zone_table
[i
].name
= 0;
2298 pc
.local_time_zone_table
[0].name
= 0;
2302 if (pc
.local_time_zone_table
[0].name
&& pc
.local_time_zone_table
[1].name
2303 && ! strcmp (pc
.local_time_zone_table
[0].name
,
2304 pc
.local_time_zone_table
[1].name
))
2306 /* This locale uses the same abbrevation for standard and
2307 daylight times. So if we see that abbreviation, we don't
2308 know whether it's daylight time. */
2309 pc
.local_time_zone_table
[0].value
= -1;
2310 pc
.local_time_zone_table
[1].name
= 0;
2313 if (yyparse (&pc
) != 0
2314 || 1 < pc
.times_seen
|| 1 < pc
.dates_seen
|| 1 < pc
.days_seen
2315 || 1 < (pc
.local_zones_seen
+ pc
.zones_seen
)
2316 || (pc
.local_zones_seen
&& 1 < pc
.local_isdst
))
2319 tm
.tm_year
= to_year (pc
.year
) - TM_YEAR_BASE
+ pc
.rel_year
;
2320 tm
.tm_mon
= pc
.month
- 1 + pc
.rel_month
;
2321 tm
.tm_mday
= pc
.day
+ pc
.rel_day
;
2322 if (pc
.times_seen
|| (pc
.rels_seen
&& ! pc
.dates_seen
&& ! pc
.days_seen
))
2324 tm
.tm_hour
= to_hour (pc
.hour
, pc
.meridian
);
2327 tm
.tm_min
= pc
.minutes
;
2328 tm
.tm_sec
= pc
.seconds
;
2332 tm
.tm_hour
= tm
.tm_min
= tm
.tm_sec
= 0;
2335 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2336 or if the relative time stamp mentions days, months, or years. */
2337 if (pc
.dates_seen
| pc
.days_seen
| pc
.times_seen
| pc
.rel_day
2338 | pc
.rel_month
| pc
.rel_year
)
2341 /* But if the input explicitly specifies local time with or without
2342 DST, give mktime that information. */
2343 if (pc
.local_zones_seen
)
2344 tm
.tm_isdst
= pc
.local_isdst
;
2348 Start
= mktime (&tm
);
2350 if (Start
== (time_t) -1)
2353 /* Guard against falsely reporting errors near the time_t boundaries
2354 when parsing times in other time zones. For example, if the min
2355 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2356 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2357 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2358 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2359 zone by 24 hours to compensate. This algorithm assumes that
2360 there is no DST transition within a day of the time_t boundaries. */
2364 if (tm
.tm_year
<= EPOCH_YEAR
- TM_YEAR_BASE
)
2367 pc
.time_zone
+= 24 * 60;
2372 pc
.time_zone
-= 24 * 60;
2374 Start
= mktime (&tm
);
2377 if (Start
== (time_t) -1)
2381 if (pc
.days_seen
&& ! pc
.dates_seen
)
2383 tm
.tm_mday
+= ((pc
.day_number
- tm
.tm_wday
+ 7) % 7
2384 + 7 * (pc
.day_ordinal
- (0 < pc
.day_ordinal
)));
2386 Start
= mktime (&tm
);
2387 if (Start
== (time_t) -1)
2393 int delta
= pc
.time_zone
* 60;
2394 #ifdef HAVE_TM_GMTOFF
2395 delta
-= tm
.tm_gmtoff
;
2397 struct tm
*gmt
= gmtime (&Start
);
2400 delta
-= tm_diff (&tm
, gmt
);
2402 if ((Start
< Start
- delta
) != (delta
< 0))
2403 return -1; /* time_t overflow */
2407 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2408 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2409 leap second. Typically this is not what the user wants, but it's
2410 too hard to do it the other way, because the time zone indicator
2411 must be applied before relative times, and if mktime is applied
2412 again the time zone will be lost. */
2415 long d1
= 60 * 60 * (long) pc
.rel_hour
;
2416 time_t t1
= t0
+ d1
;
2417 long d2
= 60 * (long) pc
.rel_minutes
;
2418 time_t t2
= t1
+ d2
;
2419 int d3
= pc
.rel_seconds
;
2420 time_t t3
= t2
+ d3
;
2421 if ((d1
/ (60 * 60) ^ pc
.rel_hour
)
2422 | (d2
/ 60 ^ pc
.rel_minutes
)
2423 | ((t0
+ d1
< t0
) ^ (d1
< 0))
2424 | ((t1
+ d2
< t1
) ^ (d2
< 0))
2425 | ((t2
+ d3
< t2
) ^ (d3
< 0)))
2438 main (int ac
, char **av
)
2443 printf ("Enter date, or blank line to exit.\n\t> ");
2446 buff
[BUFSIZ
- 1] = 0;
2447 while (fgets (buff
, BUFSIZ
- 1, stdin
) && buff
[0])
2449 d
= get_date (buff
, 0);
2450 if (d
== (time_t) -1)
2451 printf ("Bad format - couldn't convert.\n");
2453 printf ("%s", ctime (&d
));
2459 #endif /* defined TEST */