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. */
143 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
146 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
147 # define IN_CTYPE_DOMAIN(c) 1
149 # define IN_CTYPE_DOMAIN(c) isascii (c)
152 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
153 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
154 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
155 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
157 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
158 - Its arg may be any int or unsigned int; it need not be an unsigned char.
159 - It's guaranteed to evaluate its argument exactly once.
160 - It's typically faster.
161 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
162 ISDIGIT_LOCALE unless it's important to use the locale's definition
163 of `digit' even when the host does not conform to POSIX. */
164 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
166 #if STDC_HEADERS || HAVE_STRING_H
170 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
171 # define __attribute__(x)
174 #ifndef ATTRIBUTE_UNUSED
175 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
178 #define EPOCH_YEAR 1970
179 #define TM_YEAR_BASE 1900
181 #define HOUR(x) ((x) * 60)
183 /* An integer value, and the number of digits in its textual
191 /* An entry in the lexical lookup table. */
199 /* Meridian: am, pm, or 24-hour style. */
200 enum { MERam
, MERpm
, MER24
};
202 /* Information passed to and from the parser. */
205 /* The input string remaining to be parsed. */
208 /* N, if this is the Nth Tuesday. */
211 /* Day of week; Sunday is 0. */
214 /* tm_isdst flag for the local zone. */
217 /* Time zone, in minutes east of UTC. */
220 /* Style used for time. */
223 /* Gregorian year, month, day, hour, minutes, and seconds. */
231 /* Relative year, month, day, hour, minutes, and seconds. */
239 /* Counts of nonterminals of various flavors parsed so far. */
242 int local_zones_seen
;
247 /* Table of local time zone abbrevations, terminated by a null entry. */
248 table local_time_zone_table
[3];
251 #define PC (* (parser_control *) parm)
252 #define YYLEX_PARAM parm
253 #define YYPARSE_PARAM parm
255 static int yyerror ();
260 /* Enabling traces. */
265 /* Enabling verbose error messages. */
266 #ifdef YYERROR_VERBOSE
267 # undef YYERROR_VERBOSE
268 # define YYERROR_VERBOSE 1
270 # define YYERROR_VERBOSE 0
273 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
274 #line 172 "getdate.y"
275 typedef union YYSTYPE
{
279 /* Line 191 of yacc.c. */
280 #line 281 "getdate.c"
281 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
282 # define YYSTYPE_IS_DECLARED 1
283 # define YYSTYPE_IS_TRIVIAL 1
288 /* Copy the second part of user declarations. */
291 /* Line 214 of yacc.c. */
292 #line 293 "getdate.c"
294 #if ! defined (yyoverflow) || YYERROR_VERBOSE
296 /* The parser invokes alloca or malloc; define the necessary symbols. */
298 # if YYSTACK_USE_ALLOCA
299 # define YYSTACK_ALLOC alloca
301 # ifndef YYSTACK_USE_ALLOCA
302 # if defined (alloca) || defined (_ALLOCA_H)
303 # define YYSTACK_ALLOC alloca
306 # define YYSTACK_ALLOC __builtin_alloca
312 # ifdef YYSTACK_ALLOC
313 /* Pacify GCC's `empty if-body' warning. */
314 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
316 # if defined (__STDC__) || defined (__cplusplus)
317 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
318 # define YYSIZE_T size_t
320 # define YYSTACK_ALLOC malloc
321 # define YYSTACK_FREE free
323 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
326 #if (! defined (yyoverflow) \
327 && (! defined (__cplusplus) \
328 || (YYSTYPE_IS_TRIVIAL)))
330 /* A type that is properly aligned for any stack member. */
337 /* The size of the maximum gap between one aligned stack and the next. */
338 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
340 /* The size of an array large to enough to hold all stacks, each with
342 # define YYSTACK_BYTES(N) \
343 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
344 + YYSTACK_GAP_MAXIMUM)
346 /* Copy COUNT objects from FROM to TO. The source and destination do
350 # define YYCOPY(To, From, Count) \
351 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
353 # define YYCOPY(To, From, Count) \
356 register YYSIZE_T yyi; \
357 for (yyi = 0; yyi < (Count); yyi++) \
358 (To)[yyi] = (From)[yyi]; \
364 /* Relocate STACK from its old location to the new one. The
365 local variables YYSIZE and YYSTACKSIZE give the old and new number of
366 elements in the stack, and YYPTR gives the new location of the
367 stack. Advance YYPTR to a properly aligned location for the next
369 # define YYSTACK_RELOCATE(Stack) \
372 YYSIZE_T yynewbytes; \
373 YYCOPY (&yyptr->Stack, Stack, yysize); \
374 Stack = &yyptr->Stack; \
375 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
376 yyptr += yynewbytes / sizeof (*yyptr); \
382 #if defined (__STDC__) || defined (__cplusplus)
383 typedef signed char yysigned_char
;
385 typedef short yysigned_char
;
388 /* YYFINAL -- State number of the termination state. */
390 /* YYLAST -- Last index in YYTABLE. */
393 /* YYNTOKENS -- Number of terminals. */
395 /* YYNNTS -- Number of nonterminals. */
397 /* YYNRULES -- Number of rules. */
399 /* YYNRULES -- Number of states. */
402 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
404 #define YYMAXUTOK 273
406 #define YYTRANSLATE(YYX) \
407 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
409 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
410 static const unsigned char yytranslate
[] =
412 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
416 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
432 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
436 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
437 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
438 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
443 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
445 static const unsigned char yyprhs
[] =
447 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
448 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
449 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
450 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
451 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
452 149, 152, 154, 156, 157
455 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
456 static const yysigned_char yyrhs
[] =
458 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
459 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
460 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
461 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
462 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
463 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
464 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
465 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
466 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
467 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
468 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
469 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
470 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
471 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
472 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
473 14, -1, 14, -1, 18, -1, -1, 10, -1
476 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
477 static const unsigned short yyrline
[] =
479 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
480 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
481 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
482 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
483 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
484 395, 397, 402, 439, 440
488 #if YYDEBUG || YYERROR_VERBOSE
489 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
490 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
491 static const char *const yytname
[] =
493 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
494 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
495 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
496 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
497 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
503 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
505 static const unsigned short yytoknum
[] =
507 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
508 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
513 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
514 static const unsigned char yyr1
[] =
516 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
517 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
518 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
519 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
520 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
524 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
525 static const unsigned char yyr2
[] =
527 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
528 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
529 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
530 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
531 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
535 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
536 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
537 means the default is an error. */
538 static const unsigned char yydefact
[] =
540 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
541 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
542 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
543 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
544 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
545 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
549 /* YYDEFGOTO[NTERM-NUM]. */
550 static const yysigned_char yydefgoto
[] =
552 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
556 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
558 #define YYPACT_NINF -17
559 static const yysigned_char yypact
[] =
561 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
562 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
563 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
564 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
565 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
566 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
570 /* YYPGOTO[NTERM-NUM]. */
571 static const yysigned_char yypgoto
[] =
573 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
577 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
578 positive, shift that token. If negative, reduce the rule which
579 number is the opposite. If zero, do what YYDEFACT says.
580 If YYTABLE_NINF, syntax error. */
581 #define YYTABLE_NINF -1
582 static const unsigned char yytable
[] =
584 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
585 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
586 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
587 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
588 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
592 static const unsigned char yycheck
[] =
594 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
595 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
596 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
597 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
598 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
602 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
603 symbol of state STATE-NUM. */
604 static const unsigned char yystos
[] =
606 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
607 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
608 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
609 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
610 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
611 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
615 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
616 # define YYSIZE_T __SIZE_TYPE__
618 #if ! defined (YYSIZE_T) && defined (size_t)
619 # define YYSIZE_T size_t
621 #if ! defined (YYSIZE_T)
622 # if defined (__STDC__) || defined (__cplusplus)
623 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
624 # define YYSIZE_T size_t
627 #if ! defined (YYSIZE_T)
628 # define YYSIZE_T unsigned int
631 #define yyerrok (yyerrstatus = 0)
632 #define yyclearin (yychar = YYEMPTY)
636 #define YYACCEPT goto yyacceptlab
637 #define YYABORT goto yyabortlab
638 #define YYERROR goto yyerrlab1
641 /* Like YYERROR except do call yyerror. This remains here temporarily
642 to ease the transition to the new meaning of YYERROR, for GCC.
643 Once GCC version 2 has supplanted version 1, this can go. */
645 #define YYFAIL goto yyerrlab
647 #define YYRECOVERING() (!!yyerrstatus)
649 #define YYBACKUP(Token, Value) \
651 if (yychar == YYEMPTY && yylen == 1) \
655 yytoken = YYTRANSLATE (yychar); \
661 yyerror ("syntax error: cannot back up");\
667 #define YYERRCODE 256
669 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
672 #ifndef YYLLOC_DEFAULT
673 # define YYLLOC_DEFAULT(Current, Rhs, N) \
674 Current.first_line = Rhs[1].first_line; \
675 Current.first_column = Rhs[1].first_column; \
676 Current.last_line = Rhs[N].last_line; \
677 Current.last_column = Rhs[N].last_column;
680 /* YYLEX -- calling `yylex' with the right arguments. */
683 # define YYLEX yylex (&yylval, YYLEX_PARAM)
685 # define YYLEX yylex (&yylval)
688 /* Enable debugging if requested. */
692 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
693 # define YYFPRINTF fprintf
696 # define YYDPRINTF(Args) \
702 # define YYDSYMPRINT(Args) \
708 # define YYDSYMPRINTF(Title, Token, Value, Location) \
712 YYFPRINTF (stderr, "%s ", Title); \
713 yysymprint (stderr, \
715 YYFPRINTF (stderr, "\n"); \
719 /*------------------------------------------------------------------.
720 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
722 `------------------------------------------------------------------*/
724 #if defined (__STDC__) || defined (__cplusplus)
726 yy_stack_print (short *bottom
, short *top
)
729 yy_stack_print (bottom
, top
)
734 YYFPRINTF (stderr
, "Stack now");
735 for (/* Nothing. */; bottom
<= top
; ++bottom
)
736 YYFPRINTF (stderr
, " %d", *bottom
);
737 YYFPRINTF (stderr
, "\n");
740 # define YY_STACK_PRINT(Bottom, Top) \
743 yy_stack_print ((Bottom), (Top)); \
747 /*------------------------------------------------.
748 | Report that the YYRULE is going to be reduced. |
749 `------------------------------------------------*/
751 #if defined (__STDC__) || defined (__cplusplus)
753 yy_reduce_print (int yyrule
)
756 yy_reduce_print (yyrule
)
761 unsigned int yylineno
= yyrline
[yyrule
];
762 YYFPRINTF (stderr
, "Reducing stack by rule %d (line %u), ",
763 yyrule
- 1, yylineno
);
764 /* Print the symbols being reduced, and their result. */
765 for (yyi
= yyprhs
[yyrule
]; 0 <= yyrhs
[yyi
]; yyi
++)
766 YYFPRINTF (stderr
, "%s ", yytname
[yyrhs
[yyi
]]);
767 YYFPRINTF (stderr
, "-> %s\n", yytname
[yyr1
[yyrule
]]);
770 # define YY_REDUCE_PRINT(Rule) \
773 yy_reduce_print (Rule); \
776 /* Nonzero means print parse trace. It is left uninitialized so that
777 multiple parsers can coexist. */
780 # define YYDPRINTF(Args)
781 # define YYDSYMPRINT(Args)
782 # define YYDSYMPRINTF(Title, Token, Value, Location)
783 # define YY_STACK_PRINT(Bottom, Top)
784 # define YY_REDUCE_PRINT(Rule)
785 #endif /* !YYDEBUG */
788 /* YYINITDEPTH -- initial size of the parser's stacks. */
790 # define YYINITDEPTH 200
793 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
794 if the built-in stack extension method is used).
796 Do not make this value too large; the results are undefined if
797 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
798 evaluated with infinite-precision integer arithmetic. */
805 # define YYMAXDEPTH 10000
813 # if defined (__GLIBC__) && defined (_STRING_H)
814 # define yystrlen strlen
816 /* Return the length of YYSTR. */
818 # if defined (__STDC__) || defined (__cplusplus)
819 yystrlen (const char *yystr
)
825 register const char *yys
= yystr
;
827 while (*yys
++ != '\0')
830 return yys
- yystr
- 1;
836 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
837 # define yystpcpy stpcpy
839 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
842 # if defined (__STDC__) || defined (__cplusplus)
843 yystpcpy (char *yydest
, const char *yysrc
)
845 yystpcpy (yydest
, yysrc
)
850 register char *yyd
= yydest
;
851 register const char *yys
= yysrc
;
853 while ((*yyd
++ = *yys
++) != '\0')
861 #endif /* !YYERROR_VERBOSE */
866 /*--------------------------------.
867 | Print this symbol on YYOUTPUT. |
868 `--------------------------------*/
870 #if defined (__STDC__) || defined (__cplusplus)
872 yysymprint (FILE *yyoutput
, int yytype
, YYSTYPE
*yyvaluep
)
875 yysymprint (yyoutput
, yytype
, yyvaluep
)
881 /* Pacify ``unused variable'' warnings. */
884 if (yytype
< YYNTOKENS
)
886 YYFPRINTF (yyoutput
, "token %s (", yytname
[yytype
]);
888 YYPRINT (yyoutput
, yytoknum
[yytype
], *yyvaluep
);
892 YYFPRINTF (yyoutput
, "nterm %s (", yytname
[yytype
]);
899 YYFPRINTF (yyoutput
, ")");
902 #endif /* ! YYDEBUG */
903 /*-----------------------------------------------.
904 | Release the memory associated to this symbol. |
905 `-----------------------------------------------*/
907 #if defined (__STDC__) || defined (__cplusplus)
909 yydestruct (int yytype
, YYSTYPE
*yyvaluep
)
912 yydestruct (yytype
, yyvaluep
)
917 /* Pacify ``unused variable'' warnings. */
929 /* Prevent warnings from -Wmissing-prototypes. */
932 # if defined (__STDC__) || defined (__cplusplus)
933 int yyparse (void *YYPARSE_PARAM
);
937 #else /* ! YYPARSE_PARAM */
938 #if defined (__STDC__) || defined (__cplusplus)
943 #endif /* ! YYPARSE_PARAM */
955 # if defined (__STDC__) || defined (__cplusplus)
956 int yyparse (void *YYPARSE_PARAM
)
958 int yyparse (YYPARSE_PARAM
)
961 #else /* ! YYPARSE_PARAM */
962 #if defined (__STDC__) || defined (__cplusplus)
972 /* The lookahead symbol. */
975 /* The semantic value of the lookahead symbol. */
978 /* Number of syntax errors so far. */
981 register int yystate
;
984 /* Number of tokens to shift before error messages enabled. */
986 /* Lookahead token as an internal (translated) token number. */
989 /* Three stacks and their tools:
990 `yyss': related to states,
991 `yyvs': related to semantic values,
992 `yyls': related to locations.
994 Refer to the stacks thru separate pointers, to allow yyoverflow
995 to reallocate them elsewhere. */
997 /* The state stack. */
998 short yyssa
[YYINITDEPTH
];
1000 register short *yyssp
;
1002 /* The semantic value stack. */
1003 YYSTYPE yyvsa
[YYINITDEPTH
];
1004 YYSTYPE
*yyvs
= yyvsa
;
1005 register YYSTYPE
*yyvsp
;
1009 #define YYPOPSTACK (yyvsp--, yyssp--)
1011 YYSIZE_T yystacksize
= YYINITDEPTH
;
1013 /* The variables used to return semantic value and location from the
1018 /* When reducing, the number of symbols on the RHS of the reduced
1022 YYDPRINTF ((stderr
, "Starting parse\n"));
1027 yychar
= YYEMPTY
; /* Cause a token to be read. */
1029 /* Initialize stack pointers.
1030 Waste one element of value and location stack
1031 so that they stay on the same level as the state stack.
1032 The wasted elements are never initialized. */
1039 /*------------------------------------------------------------.
1040 | yynewstate -- Push a new state, which is found in yystate. |
1041 `------------------------------------------------------------*/
1043 /* In all cases, when you get here, the value and location stacks
1044 have just been pushed. so pushing a state here evens the stacks.
1051 if (yyss
+ yystacksize
- 1 <= yyssp
)
1053 /* Get the current used size of the three stacks, in elements. */
1054 YYSIZE_T yysize
= yyssp
- yyss
+ 1;
1058 /* Give user a chance to reallocate the stack. Use copies of
1059 these so that the &'s don't force the real ones into
1061 YYSTYPE
*yyvs1
= yyvs
;
1062 short *yyss1
= yyss
;
1065 /* Each stack pointer address is followed by the size of the
1066 data in use in that stack, in bytes. This used to be a
1067 conditional around just the two extra args, but that might
1068 be undefined if yyoverflow is a macro. */
1069 yyoverflow ("parser stack overflow",
1070 &yyss1
, yysize
* sizeof (*yyssp
),
1071 &yyvs1
, yysize
* sizeof (*yyvsp
),
1078 #else /* no yyoverflow */
1079 # ifndef YYSTACK_RELOCATE
1082 /* Extend the stack our own way. */
1083 if (YYMAXDEPTH
<= yystacksize
)
1086 if (YYMAXDEPTH
< yystacksize
)
1087 yystacksize
= YYMAXDEPTH
;
1090 short *yyss1
= yyss
;
1091 union yyalloc
*yyptr
=
1092 (union yyalloc
*) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize
));
1095 YYSTACK_RELOCATE (yyss
);
1096 YYSTACK_RELOCATE (yyvs
);
1098 # undef YYSTACK_RELOCATE
1100 YYSTACK_FREE (yyss1
);
1103 #endif /* no yyoverflow */
1105 yyssp
= yyss
+ yysize
- 1;
1106 yyvsp
= yyvs
+ yysize
- 1;
1109 YYDPRINTF ((stderr
, "Stack size increased to %lu\n",
1110 (unsigned long int) yystacksize
));
1112 if (yyss
+ yystacksize
- 1 <= yyssp
)
1116 YYDPRINTF ((stderr
, "Entering state %d\n", yystate
));
1125 /* Do appropriate processing given the current state. */
1126 /* Read a lookahead token if we need one and don't already have one. */
1129 /* First try to decide what to do without reference to lookahead token. */
1131 yyn
= yypact
[yystate
];
1132 if (yyn
== YYPACT_NINF
)
1135 /* Not known => get a lookahead token if don't already have one. */
1137 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1138 if (yychar
== YYEMPTY
)
1140 YYDPRINTF ((stderr
, "Reading a token: "));
1144 if (yychar
<= YYEOF
)
1146 yychar
= yytoken
= YYEOF
;
1147 YYDPRINTF ((stderr
, "Now at end of input.\n"));
1151 yytoken
= YYTRANSLATE (yychar
);
1152 YYDSYMPRINTF ("Next token is", yytoken
, &yylval
, &yylloc
);
1155 /* If the proper action on seeing token YYTOKEN is to reduce or to
1156 detect an error, take that action. */
1158 if (yyn
< 0 || YYLAST
< yyn
|| yycheck
[yyn
] != yytoken
)
1163 if (yyn
== 0 || yyn
== YYTABLE_NINF
)
1172 /* Shift the lookahead token. */
1173 YYDPRINTF ((stderr
, "Shifting token %s, ", yytname
[yytoken
]));
1175 /* Discard the token being shifted unless it is eof. */
1176 if (yychar
!= YYEOF
)
1182 /* Count tokens shifted since error; after three, turn off error
1191 /*-----------------------------------------------------------.
1192 | yydefault -- do the default action for the current state. |
1193 `-----------------------------------------------------------*/
1195 yyn
= yydefact
[yystate
];
1201 /*-----------------------------.
1202 | yyreduce -- Do a reduction. |
1203 `-----------------------------*/
1205 /* yyn is the number of a rule to reduce with. */
1208 /* If YYLEN is nonzero, implement the default value of the action:
1211 Otherwise, the following line sets YYVAL to garbage.
1212 This behavior is undocumented and Bison
1213 users should not rely upon it. Assigning to YYVAL
1214 unconditionally makes the parser a bit smaller, and it avoids a
1215 GCC warning that YYVAL may be used uninitialized. */
1216 yyval
= yyvsp
[1-yylen
];
1219 YY_REDUCE_PRINT (yyn
);
1223 #line 195 "getdate.y"
1224 { PC
.times_seen
++; }
1228 #line 197 "getdate.y"
1229 { PC
.local_zones_seen
++; }
1233 #line 199 "getdate.y"
1234 { PC
.zones_seen
++; }
1238 #line 201 "getdate.y"
1239 { PC
.dates_seen
++; }
1243 #line 203 "getdate.y"
1248 #line 205 "getdate.y"
1253 #line 211 "getdate.y"
1255 PC
.hour
= yyvsp
[-1].textintval
.value
;
1258 PC
.meridian
= yyvsp
[0].intval
;
1263 #line 218 "getdate.y"
1265 PC
.hour
= yyvsp
[-3].textintval
.value
;
1266 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1268 PC
.meridian
= yyvsp
[0].intval
;
1273 #line 225 "getdate.y"
1275 PC
.hour
= yyvsp
[-3].textintval
.value
;
1276 PC
.minutes
= yyvsp
[-1].textintval
.value
;
1277 PC
.meridian
= MER24
;
1279 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1284 #line 233 "getdate.y"
1286 PC
.hour
= yyvsp
[-5].textintval
.value
;
1287 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1288 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1289 PC
.meridian
= yyvsp
[0].intval
;
1294 #line 240 "getdate.y"
1296 PC
.hour
= yyvsp
[-5].textintval
.value
;
1297 PC
.minutes
= yyvsp
[-3].textintval
.value
;
1298 PC
.seconds
= yyvsp
[-1].textintval
.value
;
1299 PC
.meridian
= MER24
;
1301 PC
.time_zone
= yyvsp
[0].textintval
.value
% 100 + (yyvsp
[0].textintval
.value
/ 100) * 60;
1306 #line 252 "getdate.y"
1307 { PC
.local_isdst
= yyvsp
[0].intval
; }
1311 #line 254 "getdate.y"
1312 { PC
.local_isdst
= yyvsp
[-1].intval
< 0 ? 1 : yyvsp
[-1].intval
+ 1; }
1316 #line 259 "getdate.y"
1317 { PC
.time_zone
= yyvsp
[0].intval
; }
1321 #line 261 "getdate.y"
1322 { PC
.time_zone
= yyvsp
[0].intval
+ 60; }
1326 #line 263 "getdate.y"
1327 { PC
.time_zone
= yyvsp
[-1].intval
+ 60; }
1331 #line 268 "getdate.y"
1334 PC
.day_number
= yyvsp
[0].intval
;
1339 #line 273 "getdate.y"
1342 PC
.day_number
= yyvsp
[-1].intval
;
1347 #line 278 "getdate.y"
1349 PC
.day_ordinal
= yyvsp
[-1].textintval
.value
;
1350 PC
.day_number
= yyvsp
[0].intval
;
1355 #line 286 "getdate.y"
1357 PC
.month
= yyvsp
[-2].textintval
.value
;
1358 PC
.day
= yyvsp
[0].textintval
.value
;
1363 #line 291 "getdate.y"
1365 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1366 otherwise as MM/DD/YY.
1367 The goal in recognizing YYYY/MM/DD is solely to support legacy
1368 machine-generated dates like those in an RCS log listing. If
1369 you want portability, use the ISO 8601 format. */
1370 if (4 <= yyvsp
[-4].textintval
.digits
)
1372 PC
.year
= yyvsp
[-4].textintval
;
1373 PC
.month
= yyvsp
[-2].textintval
.value
;
1374 PC
.day
= yyvsp
[0].textintval
.value
;
1378 PC
.month
= yyvsp
[-4].textintval
.value
;
1379 PC
.day
= yyvsp
[-2].textintval
.value
;
1380 PC
.year
= yyvsp
[0].textintval
;
1386 #line 311 "getdate.y"
1388 /* ISO 8601 format. YYYY-MM-DD. */
1389 PC
.year
= yyvsp
[-2].textintval
;
1390 PC
.month
= -yyvsp
[-1].textintval
.value
;
1391 PC
.day
= -yyvsp
[0].textintval
.value
;
1396 #line 318 "getdate.y"
1398 /* e.g. 17-JUN-1992. */
1399 PC
.day
= yyvsp
[-2].textintval
.value
;
1400 PC
.month
= yyvsp
[-1].intval
;
1401 PC
.year
.value
= -yyvsp
[0].textintval
.value
;
1402 PC
.year
.digits
= yyvsp
[0].textintval
.digits
;
1407 #line 326 "getdate.y"
1409 PC
.month
= yyvsp
[-1].intval
;
1410 PC
.day
= yyvsp
[0].textintval
.value
;
1415 #line 331 "getdate.y"
1417 PC
.month
= yyvsp
[-3].intval
;
1418 PC
.day
= yyvsp
[-2].textintval
.value
;
1419 PC
.year
= yyvsp
[0].textintval
;
1424 #line 337 "getdate.y"
1426 PC
.day
= yyvsp
[-1].textintval
.value
;
1427 PC
.month
= yyvsp
[0].intval
;
1432 #line 342 "getdate.y"
1434 PC
.day
= yyvsp
[-2].textintval
.value
;
1435 PC
.month
= yyvsp
[-1].intval
;
1436 PC
.year
= yyvsp
[0].textintval
;
1441 #line 351 "getdate.y"
1443 PC
.rel_seconds
= -PC
.rel_seconds
;
1444 PC
.rel_minutes
= -PC
.rel_minutes
;
1445 PC
.rel_hour
= -PC
.rel_hour
;
1446 PC
.rel_day
= -PC
.rel_day
;
1447 PC
.rel_month
= -PC
.rel_month
;
1448 PC
.rel_year
= -PC
.rel_year
;
1453 #line 364 "getdate.y"
1454 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1458 #line 366 "getdate.y"
1459 { PC
.rel_year
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1463 #line 368 "getdate.y"
1464 { PC
.rel_year
+= yyvsp
[0].intval
; }
1468 #line 370 "getdate.y"
1469 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1473 #line 372 "getdate.y"
1474 { PC
.rel_month
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1478 #line 374 "getdate.y"
1479 { PC
.rel_month
+= yyvsp
[0].intval
; }
1483 #line 376 "getdate.y"
1484 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1488 #line 378 "getdate.y"
1489 { PC
.rel_day
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1493 #line 380 "getdate.y"
1494 { PC
.rel_day
+= yyvsp
[0].intval
; }
1498 #line 382 "getdate.y"
1499 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1503 #line 384 "getdate.y"
1504 { PC
.rel_hour
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1508 #line 386 "getdate.y"
1509 { PC
.rel_hour
+= yyvsp
[0].intval
; }
1513 #line 388 "getdate.y"
1514 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1518 #line 390 "getdate.y"
1519 { PC
.rel_minutes
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1523 #line 392 "getdate.y"
1524 { PC
.rel_minutes
+= yyvsp
[0].intval
; }
1528 #line 394 "getdate.y"
1529 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1533 #line 396 "getdate.y"
1534 { PC
.rel_seconds
+= yyvsp
[-1].textintval
.value
* yyvsp
[0].intval
; }
1538 #line 398 "getdate.y"
1539 { PC
.rel_seconds
+= yyvsp
[0].intval
; }
1543 #line 403 "getdate.y"
1546 && ! PC
.rels_seen
&& (PC
.times_seen
|| 2 < yyvsp
[0].textintval
.digits
))
1547 PC
.year
= yyvsp
[0].textintval
;
1550 if (4 < yyvsp
[0].textintval
.digits
)
1553 PC
.day
= yyvsp
[0].textintval
.value
% 100;
1554 PC
.month
= (yyvsp
[0].textintval
.value
/ 100) % 100;
1555 PC
.year
.value
= yyvsp
[0].textintval
.value
/ 10000;
1556 PC
.year
.digits
= yyvsp
[0].textintval
.digits
- 4;
1561 if (yyvsp
[0].textintval
.digits
<= 2)
1563 PC
.hour
= yyvsp
[0].textintval
.value
;
1568 PC
.hour
= yyvsp
[0].textintval
.value
/ 100;
1569 PC
.minutes
= yyvsp
[0].textintval
.value
% 100;
1572 PC
.meridian
= MER24
;
1579 #line 439 "getdate.y"
1580 { yyval
.intval
= MER24
; }
1584 #line 441 "getdate.y"
1585 { yyval
.intval
= yyvsp
[0].intval
; }
1591 /* Line 999 of yacc.c. */
1592 #line 1593 "getdate.c"
1598 YY_STACK_PRINT (yyss
, yyssp
);
1603 /* Now `shift' the result of the reduction. Determine what state
1604 that goes to, based on the state we popped back to and the rule
1605 number reduced by. */
1609 yystate
= yypgoto
[yyn
- YYNTOKENS
] + *yyssp
;
1610 if (0 <= yystate
&& yystate
<= YYLAST
&& yycheck
[yystate
] == *yyssp
)
1611 yystate
= yytable
[yystate
];
1613 yystate
= yydefgoto
[yyn
- YYNTOKENS
];
1618 /*------------------------------------.
1619 | yyerrlab -- here on detecting error |
1620 `------------------------------------*/
1622 /* If not already recovering from an error, report this error. */
1627 yyn
= yypact
[yystate
];
1629 if (YYPACT_NINF
< yyn
&& yyn
< YYLAST
)
1631 YYSIZE_T yysize
= 0;
1632 int yytype
= YYTRANSLATE (yychar
);
1637 /* Start YYX at -YYN if negative to avoid negative indexes in
1639 for (yyx
= yyn
< 0 ? -yyn
: 0;
1640 yyx
< (int) (sizeof (yytname
) / sizeof (char *)); yyx
++)
1641 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1642 yysize
+= yystrlen (yytname
[yyx
]) + 15, yycount
++;
1643 yysize
+= yystrlen ("syntax error, unexpected ") + 1;
1644 yysize
+= yystrlen (yytname
[yytype
]);
1645 yymsg
= (char *) YYSTACK_ALLOC (yysize
);
1648 char *yyp
= yystpcpy (yymsg
, "syntax error, unexpected ");
1649 yyp
= yystpcpy (yyp
, yytname
[yytype
]);
1654 for (yyx
= yyn
< 0 ? -yyn
: 0;
1655 yyx
< (int) (sizeof (yytname
) / sizeof (char *));
1657 if (yycheck
[yyx
+ yyn
] == yyx
&& yyx
!= YYTERROR
)
1659 const char *yyq
= ! yycount
? ", expecting " : " or ";
1660 yyp
= yystpcpy (yyp
, yyq
);
1661 yyp
= yystpcpy (yyp
, yytname
[yyx
]);
1666 YYSTACK_FREE (yymsg
);
1669 yyerror ("syntax error; also virtual memory exhausted");
1672 #endif /* YYERROR_VERBOSE */
1673 yyerror ("syntax error");
1678 if (yyerrstatus
== 3)
1680 /* If just tried and failed to reuse lookahead token after an
1681 error, discard it. */
1683 /* Return failure if at end of input. */
1684 if (yychar
== YYEOF
)
1686 /* Pop the error token. */
1688 /* Pop the rest of the stack. */
1689 while (yyss
< yyssp
)
1691 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1692 yydestruct (yystos
[*yyssp
], yyvsp
);
1698 YYDSYMPRINTF ("Error: discarding", yytoken
, &yylval
, &yylloc
);
1699 yydestruct (yytoken
, &yylval
);
1704 /* Else will try to reuse lookahead token after shifting the error
1709 /*----------------------------------------------------.
1710 | yyerrlab1 -- error raised explicitly by an action. |
1711 `----------------------------------------------------*/
1713 yyerrstatus
= 3; /* Each real token shifted decrements this. */
1717 yyn
= yypact
[yystate
];
1718 if (yyn
!= YYPACT_NINF
)
1721 if (0 <= yyn
&& yyn
<= YYLAST
&& yycheck
[yyn
] == YYTERROR
)
1729 /* Pop the current state because it cannot handle the error token. */
1733 YYDSYMPRINTF ("Error: popping", yystos
[*yyssp
], yyvsp
, yylsp
);
1734 yydestruct (yystos
[yystate
], yyvsp
);
1738 YY_STACK_PRINT (yyss
, yyssp
);
1744 YYDPRINTF ((stderr
, "Shifting error token, "));
1753 /*-------------------------------------.
1754 | yyacceptlab -- YYACCEPT comes here. |
1755 `-------------------------------------*/
1760 /*-----------------------------------.
1761 | yyabortlab -- YYABORT comes here. |
1762 `-----------------------------------*/
1768 /*----------------------------------------------.
1769 | yyoverflowlab -- parser overflow comes here. |
1770 `----------------------------------------------*/
1772 yyerror ("parser stack overflow");
1780 YYSTACK_FREE (yyss
);
1786 #line 444 "getdate.y"
1789 /* Include this file down here because bison inserts code above which
1790 may define-away `const'. We want the prototype for get_date to have
1791 the same signature as the function definition. */
1792 #include "modules/getdate.h"
1795 struct tm
*gmtime ();
1798 struct tm
*localtime ();
1804 static table
const meridian_table
[] =
1806 { "AM", tMERIDIAN
, MERam
},
1807 { "A.M.", tMERIDIAN
, MERam
},
1808 { "PM", tMERIDIAN
, MERpm
},
1809 { "P.M.", tMERIDIAN
, MERpm
},
1813 static table
const dst_table
[] =
1818 static table
const month_and_day_table
[] =
1820 { "JANUARY", tMONTH
, 1 },
1821 { "FEBRUARY", tMONTH
, 2 },
1822 { "MARCH", tMONTH
, 3 },
1823 { "APRIL", tMONTH
, 4 },
1824 { "MAY", tMONTH
, 5 },
1825 { "JUNE", tMONTH
, 6 },
1826 { "JULY", tMONTH
, 7 },
1827 { "AUGUST", tMONTH
, 8 },
1828 { "SEPTEMBER",tMONTH
, 9 },
1829 { "SEPT", tMONTH
, 9 },
1830 { "OCTOBER", tMONTH
, 10 },
1831 { "NOVEMBER", tMONTH
, 11 },
1832 { "DECEMBER", tMONTH
, 12 },
1833 { "SUNDAY", tDAY
, 0 },
1834 { "MONDAY", tDAY
, 1 },
1835 { "TUESDAY", tDAY
, 2 },
1836 { "TUES", tDAY
, 2 },
1837 { "WEDNESDAY",tDAY
, 3 },
1838 { "WEDNES", tDAY
, 3 },
1839 { "THURSDAY", tDAY
, 4 },
1840 { "THUR", tDAY
, 4 },
1841 { "THURS", tDAY
, 4 },
1842 { "FRIDAY", tDAY
, 5 },
1843 { "SATURDAY", tDAY
, 6 },
1847 static table
const time_units_table
[] =
1849 { "YEAR", tYEAR_UNIT
, 1 },
1850 { "MONTH", tMONTH_UNIT
, 1 },
1851 { "FORTNIGHT",tDAY_UNIT
, 14 },
1852 { "WEEK", tDAY_UNIT
, 7 },
1853 { "DAY", tDAY_UNIT
, 1 },
1854 { "HOUR", tHOUR_UNIT
, 1 },
1855 { "MINUTE", tMINUTE_UNIT
, 1 },
1856 { "MIN", tMINUTE_UNIT
, 1 },
1857 { "SECOND", tSEC_UNIT
, 1 },
1858 { "SEC", tSEC_UNIT
, 1 },
1862 /* Assorted relative-time words. */
1863 static table
const relative_time_table
[] =
1865 { "TOMORROW", tMINUTE_UNIT
, 24 * 60 },
1866 { "YESTERDAY",tMINUTE_UNIT
, - (24 * 60) },
1867 { "TODAY", tMINUTE_UNIT
, 0 },
1868 { "NOW", tMINUTE_UNIT
, 0 },
1869 { "LAST", tUNUMBER
, -1 },
1870 { "THIS", tUNUMBER
, 0 },
1871 { "NEXT", tUNUMBER
, 1 },
1872 { "FIRST", tUNUMBER
, 1 },
1873 /*{ "SECOND", tUNUMBER, 2 }, */
1874 { "THIRD", tUNUMBER
, 3 },
1875 { "FOURTH", tUNUMBER
, 4 },
1876 { "FIFTH", tUNUMBER
, 5 },
1877 { "SIXTH", tUNUMBER
, 6 },
1878 { "SEVENTH", tUNUMBER
, 7 },
1879 { "EIGHTH", tUNUMBER
, 8 },
1880 { "NINTH", tUNUMBER
, 9 },
1881 { "TENTH", tUNUMBER
, 10 },
1882 { "ELEVENTH", tUNUMBER
, 11 },
1883 { "TWELFTH", tUNUMBER
, 12 },
1888 /* The time zone table. This table is necessarily incomplete, as time
1889 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1890 as Eastern time in Australia, not as US Eastern Standard Time.
1891 You cannot rely on getdate to handle arbitrary time zone
1892 abbreviations; use numeric abbreviations like `-0500' instead. */
1893 static table
const time_zone_table
[] =
1895 { "GMT", tZONE
, HOUR ( 0) }, /* Greenwich Mean */
1896 { "UT", tZONE
, HOUR ( 0) }, /* Universal (Coordinated) */
1897 { "UTC", tZONE
, HOUR ( 0) },
1898 { "WET", tZONE
, HOUR ( 0) }, /* Western European */
1899 { "WEST", tDAYZONE
, HOUR ( 0) }, /* Western European Summer */
1900 { "BST", tDAYZONE
, HOUR ( 0) }, /* British Summer */
1901 { "ART", tZONE
, -HOUR ( 3) }, /* Argentina */
1902 { "BRT", tZONE
, -HOUR ( 3) }, /* Brazil */
1903 { "BRST", tDAYZONE
, -HOUR ( 3) }, /* Brazil Summer */
1904 { "NST", tZONE
, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1905 { "NDT", tDAYZONE
,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1906 { "AST", tZONE
, -HOUR ( 4) }, /* Atlantic Standard */
1907 { "ADT", tDAYZONE
, -HOUR ( 4) }, /* Atlantic Daylight */
1908 { "CLT", tZONE
, -HOUR ( 4) }, /* Chile */
1909 { "CLST", tDAYZONE
, -HOUR ( 4) }, /* Chile Summer */
1910 { "EST", tZONE
, -HOUR ( 5) }, /* Eastern Standard */
1911 { "EDT", tDAYZONE
, -HOUR ( 5) }, /* Eastern Daylight */
1912 { "CST", tZONE
, -HOUR ( 6) }, /* Central Standard */
1913 { "CDT", tDAYZONE
, -HOUR ( 6) }, /* Central Daylight */
1914 { "MST", tZONE
, -HOUR ( 7) }, /* Mountain Standard */
1915 { "MDT", tDAYZONE
, -HOUR ( 7) }, /* Mountain Daylight */
1916 { "PST", tZONE
, -HOUR ( 8) }, /* Pacific Standard */
1917 { "PDT", tDAYZONE
, -HOUR ( 8) }, /* Pacific Daylight */
1918 { "AKST", tZONE
, -HOUR ( 9) }, /* Alaska Standard */
1919 { "AKDT", tDAYZONE
, -HOUR ( 9) }, /* Alaska Daylight */
1920 { "HST", tZONE
, -HOUR (10) }, /* Hawaii Standard */
1921 { "HAST", tZONE
, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1922 { "HADT", tDAYZONE
, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1923 { "SST", tZONE
, -HOUR (12) }, /* Samoa Standard */
1924 { "WAT", tZONE
, HOUR ( 1) }, /* West Africa */
1925 { "CET", tZONE
, HOUR ( 1) }, /* Central European */
1926 { "CEST", tDAYZONE
, HOUR ( 1) }, /* Central European Summer */
1927 { "MET", tZONE
, HOUR ( 1) }, /* Middle European */
1928 { "MEZ", tZONE
, HOUR ( 1) }, /* Middle European */
1929 { "MEST", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1930 { "MESZ", tDAYZONE
, HOUR ( 1) }, /* Middle European Summer */
1931 { "EET", tZONE
, HOUR ( 2) }, /* Eastern European */
1932 { "EEST", tDAYZONE
, HOUR ( 2) }, /* Eastern European Summer */
1933 { "CAT", tZONE
, HOUR ( 2) }, /* Central Africa */
1934 { "SAST", tZONE
, HOUR ( 2) }, /* South Africa Standard */
1935 { "EAT", tZONE
, HOUR ( 3) }, /* East Africa */
1936 { "MSK", tZONE
, HOUR ( 3) }, /* Moscow */
1937 { "MSD", tDAYZONE
, HOUR ( 3) }, /* Moscow Daylight */
1938 { "IST", tZONE
, (HOUR ( 5) + 30) }, /* India Standard */
1939 { "SGT", tZONE
, HOUR ( 8) }, /* Singapore */
1940 { "KST", tZONE
, HOUR ( 9) }, /* Korea Standard */
1941 { "JST", tZONE
, HOUR ( 9) }, /* Japan Standard */
1942 { "GST", tZONE
, HOUR (10) }, /* Guam Standard */
1943 { "NZST", tZONE
, HOUR (12) }, /* New Zealand Standard */
1944 { "NZDT", tDAYZONE
, HOUR (12) }, /* New Zealand Daylight */
1948 /* Military time zone table. */
1949 static table
const military_table
[] =
1951 { "A", tZONE
, -HOUR ( 1) },
1952 { "B", tZONE
, -HOUR ( 2) },
1953 { "C", tZONE
, -HOUR ( 3) },
1954 { "D", tZONE
, -HOUR ( 4) },
1955 { "E", tZONE
, -HOUR ( 5) },
1956 { "F", tZONE
, -HOUR ( 6) },
1957 { "G", tZONE
, -HOUR ( 7) },
1958 { "H", tZONE
, -HOUR ( 8) },
1959 { "I", tZONE
, -HOUR ( 9) },
1960 { "K", tZONE
, -HOUR (10) },
1961 { "L", tZONE
, -HOUR (11) },
1962 { "M", tZONE
, -HOUR (12) },
1963 { "N", tZONE
, HOUR ( 1) },
1964 { "O", tZONE
, HOUR ( 2) },
1965 { "P", tZONE
, HOUR ( 3) },
1966 { "Q", tZONE
, HOUR ( 4) },
1967 { "R", tZONE
, HOUR ( 5) },
1968 { "S", tZONE
, HOUR ( 6) },
1969 { "T", tZONE
, HOUR ( 7) },
1970 { "U", tZONE
, HOUR ( 8) },
1971 { "V", tZONE
, HOUR ( 9) },
1972 { "W", tZONE
, HOUR (10) },
1973 { "X", tZONE
, HOUR (11) },
1974 { "Y", tZONE
, HOUR (12) },
1975 { "Z", tZONE
, HOUR ( 0) },
1982 to_hour (int hours
, int meridian
)
1987 return 0 <= hours
&& hours
< 24 ? hours
: -1;
1989 return 0 < hours
&& hours
< 12 ? hours
: hours
== 12 ? 0 : -1;
1991 return 0 < hours
&& hours
< 12 ? hours
+ 12 : hours
== 12 ? 12 : -1;
2000 to_year (textint textyear
)
2002 int year
= textyear
.value
;
2007 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2008 years 69-99 map to 1969-1999. */
2009 if (textyear
.digits
== 2)
2010 year
+= year
< 69 ? 2000 : 1900;
2015 static table
const *
2016 lookup_zone (parser_control
const *pc
, char const *name
)
2020 /* Try local zone abbreviations first; they're more likely to be right. */
2021 for (tp
= pc
->local_time_zone_table
; tp
->name
; tp
++)
2022 if (strcmp (name
, tp
->name
) == 0)
2025 for (tp
= time_zone_table
; tp
->name
; tp
++)
2026 if (strcmp (name
, tp
->name
) == 0)
2032 #if ! HAVE_TM_GMTOFF
2033 /* Yield the difference between *A and *B,
2034 measured in seconds, ignoring leap seconds.
2035 The body of this function is taken directly from the GNU C Library;
2036 see src/strftime.c. */
2038 tm_diff (struct tm
const *a
, struct tm
const *b
)
2040 /* Compute intervening leap days correctly even if year is negative.
2041 Take care to avoid int overflow in leap day calculations,
2042 but it's OK to assume that A and B are close to each other. */
2043 int a4
= (a
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (a
->tm_year
& 3);
2044 int b4
= (b
->tm_year
>> 2) + (TM_YEAR_BASE
>> 2) - ! (b
->tm_year
& 3);
2045 int a100
= a4
/ 25 - (a4
% 25 < 0);
2046 int b100
= b4
/ 25 - (b4
% 25 < 0);
2047 int a400
= a100
>> 2;
2048 int b400
= b100
>> 2;
2049 int intervening_leap_days
= (a4
- b4
) - (a100
- b100
) + (a400
- b400
);
2050 int years
= a
->tm_year
- b
->tm_year
;
2051 int days
= (365 * years
+ intervening_leap_days
2052 + (a
->tm_yday
- b
->tm_yday
));
2053 return (60 * (60 * (24 * days
+ (a
->tm_hour
- b
->tm_hour
))
2054 + (a
->tm_min
- b
->tm_min
))
2055 + (a
->tm_sec
- b
->tm_sec
));
2057 #endif /* ! HAVE_TM_GMTOFF */
2059 static table
const *
2060 lookup_word (parser_control
const *pc
, char *word
)
2069 /* Make it uppercase. */
2070 for (p
= word
; *p
; p
++)
2071 if (ISLOWER ((unsigned char) *p
))
2072 *p
= toupper ((unsigned char) *p
);
2074 for (tp
= meridian_table
; tp
->name
; tp
++)
2075 if (strcmp (word
, tp
->name
) == 0)
2078 /* See if we have an abbreviation for a month. */
2079 wordlen
= strlen (word
);
2080 abbrev
= wordlen
== 3 || (wordlen
== 4 && word
[3] == '.');
2082 for (tp
= month_and_day_table
; tp
->name
; tp
++)
2083 if ((abbrev
? strncmp (word
, tp
->name
, 3) : strcmp (word
, tp
->name
)) == 0)
2086 if ((tp
= lookup_zone (pc
, word
)))
2089 if (strcmp (word
, dst_table
[0].name
) == 0)
2092 for (tp
= time_units_table
; tp
->name
; tp
++)
2093 if (strcmp (word
, tp
->name
) == 0)
2096 /* Strip off any plural and try the units table again. */
2097 if (word
[wordlen
- 1] == 'S')
2099 word
[wordlen
- 1] = '\0';
2100 for (tp
= time_units_table
; tp
->name
; tp
++)
2101 if (strcmp (word
, tp
->name
) == 0)
2103 word
[wordlen
- 1] = 'S'; /* For "this" in relative_time_table. */
2106 for (tp
= relative_time_table
; tp
->name
; tp
++)
2107 if (strcmp (word
, tp
->name
) == 0)
2110 /* Military time zones. */
2112 for (tp
= military_table
; tp
->name
; tp
++)
2113 if (word
[0] == tp
->name
[0])
2116 /* Drop out any periods and try the time zone table again. */
2117 for (i
= 0, p
= q
= word
; (*p
= *q
); q
++)
2122 if (i
&& (tp
= lookup_zone (pc
, word
)))
2129 yylex (YYSTYPE
*lvalp
, parser_control
*pc
)
2136 while (c
= *pc
->input
, ISSPACE (c
))
2139 if (ISDIGIT (c
) || c
== '-' || c
== '+')
2144 if (c
== '-' || c
== '+')
2146 sign
= c
== '-' ? -1 : 1;
2149 /* skip the '-' sign */
2158 value
= 10 * value
+ c
- '0';
2161 while (ISDIGIT (c
));
2162 lvalp
->textintval
.value
= sign
< 0 ? -value
: value
;
2163 lvalp
->textintval
.digits
= p
- pc
->input
;
2165 return sign
? tSNUMBER
: tUNUMBER
;
2176 if (p
< buff
+ sizeof buff
- 1)
2180 while (ISALPHA (c
) || c
== '.');
2183 tp
= lookup_word (pc
, buff
);
2186 lvalp
->intval
= tp
->value
;
2191 return *pc
->input
++;
2207 /* Do nothing if the parser reports an error. */
2209 yyerror (char *s ATTRIBUTE_UNUSED
)
2214 /* Parse a date/time string P. Return the corresponding time_t value,
2215 or (time_t) -1 if there is an error. P can be an incomplete or
2216 relative time specification; if so, use *NOW as the basis for the
2219 get_date (const char *p
, const time_t *now
)
2221 time_t Start
= now
? *now
: time (0);
2222 struct tm
*tmp
= localtime (&Start
);
2231 pc
.year
.value
= tmp
->tm_year
+ TM_YEAR_BASE
;
2233 pc
.month
= tmp
->tm_mon
+ 1;
2234 pc
.day
= tmp
->tm_mday
;
2235 pc
.hour
= tmp
->tm_hour
;
2236 pc
.minutes
= tmp
->tm_min
;
2237 pc
.seconds
= tmp
->tm_sec
;
2238 tm
.tm_isdst
= tmp
->tm_isdst
;
2240 pc
.meridian
= MER24
;
2251 pc
.local_zones_seen
= 0;
2254 #if HAVE_STRUCT_TM_TM_ZONE
2255 pc
.local_time_zone_table
[0].name
= tmp
->tm_zone
;
2256 pc
.local_time_zone_table
[0].type
= tLOCAL_ZONE
;
2257 pc
.local_time_zone_table
[0].value
= tmp
->tm_isdst
;
2258 pc
.local_time_zone_table
[1].name
= 0;
2260 /* Probe the names used in the next three calendar quarters, looking
2261 for a tm_isdst different from the one we already have. */
2264 for (quarter
= 1; quarter
<= 3; quarter
++)
2266 time_t probe
= Start
+ quarter
* (90 * 24 * 60 * 60);
2267 struct tm
*probe_tm
= localtime (&probe
);
2268 if (probe_tm
&& probe_tm
->tm_zone
2269 && probe_tm
->tm_isdst
!= pc
.local_time_zone_table
[0].value
)
2272 pc
.local_time_zone_table
[1].name
= probe_tm
->tm_zone
;
2273 pc
.local_time_zone_table
[1].type
= tLOCAL_ZONE
;
2274 pc
.local_time_zone_table
[1].value
= probe_tm
->tm_isdst
;
2275 pc
.local_time_zone_table
[2].name
= 0;
2285 extern char *tzname
[];
2288 for (i
= 0; i
< 2; i
++)
2290 pc
.local_time_zone_table
[i
].name
= tzname
[i
];
2291 pc
.local_time_zone_table
[i
].type
= tLOCAL_ZONE
;
2292 pc
.local_time_zone_table
[i
].value
= i
;
2294 pc
.local_time_zone_table
[i
].name
= 0;
2297 pc
.local_time_zone_table
[0].name
= 0;
2301 if (pc
.local_time_zone_table
[0].name
&& pc
.local_time_zone_table
[1].name
2302 && ! strcmp (pc
.local_time_zone_table
[0].name
,
2303 pc
.local_time_zone_table
[1].name
))
2305 /* This locale uses the same abbrevation for standard and
2306 daylight times. So if we see that abbreviation, we don't
2307 know whether it's daylight time. */
2308 pc
.local_time_zone_table
[0].value
= -1;
2309 pc
.local_time_zone_table
[1].name
= 0;
2312 if (yyparse (&pc
) != 0
2313 || 1 < pc
.times_seen
|| 1 < pc
.dates_seen
|| 1 < pc
.days_seen
2314 || 1 < (pc
.local_zones_seen
+ pc
.zones_seen
)
2315 || (pc
.local_zones_seen
&& 1 < pc
.local_isdst
))
2318 tm
.tm_year
= to_year (pc
.year
) - TM_YEAR_BASE
+ pc
.rel_year
;
2319 tm
.tm_mon
= pc
.month
- 1 + pc
.rel_month
;
2320 tm
.tm_mday
= pc
.day
+ pc
.rel_day
;
2321 if (pc
.times_seen
|| (pc
.rels_seen
&& ! pc
.dates_seen
&& ! pc
.days_seen
))
2323 tm
.tm_hour
= to_hour (pc
.hour
, pc
.meridian
);
2326 tm
.tm_min
= pc
.minutes
;
2327 tm
.tm_sec
= pc
.seconds
;
2331 tm
.tm_hour
= tm
.tm_min
= tm
.tm_sec
= 0;
2334 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2335 or if the relative time stamp mentions days, months, or years. */
2336 if (pc
.dates_seen
| pc
.days_seen
| pc
.times_seen
| pc
.rel_day
2337 | pc
.rel_month
| pc
.rel_year
)
2340 /* But if the input explicitly specifies local time with or without
2341 DST, give mktime that information. */
2342 if (pc
.local_zones_seen
)
2343 tm
.tm_isdst
= pc
.local_isdst
;
2347 Start
= mktime (&tm
);
2349 if (Start
== (time_t) -1)
2352 /* Guard against falsely reporting errors near the time_t boundaries
2353 when parsing times in other time zones. For example, if the min
2354 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2355 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2356 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2357 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2358 zone by 24 hours to compensate. This algorithm assumes that
2359 there is no DST transition within a day of the time_t boundaries. */
2363 if (tm
.tm_year
<= EPOCH_YEAR
- TM_YEAR_BASE
)
2366 pc
.time_zone
+= 24 * 60;
2371 pc
.time_zone
-= 24 * 60;
2373 Start
= mktime (&tm
);
2376 if (Start
== (time_t) -1)
2380 if (pc
.days_seen
&& ! pc
.dates_seen
)
2382 tm
.tm_mday
+= ((pc
.day_number
- tm
.tm_wday
+ 7) % 7
2383 + 7 * (pc
.day_ordinal
- (0 < pc
.day_ordinal
)));
2385 Start
= mktime (&tm
);
2386 if (Start
== (time_t) -1)
2392 int delta
= pc
.time_zone
* 60;
2393 #ifdef HAVE_TM_GMTOFF
2394 delta
-= tm
.tm_gmtoff
;
2396 struct tm
*gmt
= gmtime (&Start
);
2399 delta
-= tm_diff (&tm
, gmt
);
2401 if ((Start
< Start
- delta
) != (delta
< 0))
2402 return -1; /* time_t overflow */
2406 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2407 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2408 leap second. Typically this is not what the user wants, but it's
2409 too hard to do it the other way, because the time zone indicator
2410 must be applied before relative times, and if mktime is applied
2411 again the time zone will be lost. */
2414 long d1
= 60 * 60 * (long) pc
.rel_hour
;
2415 time_t t1
= t0
+ d1
;
2416 long d2
= 60 * (long) pc
.rel_minutes
;
2417 time_t t2
= t1
+ d2
;
2418 int d3
= pc
.rel_seconds
;
2419 time_t t3
= t2
+ d3
;
2420 if ((d1
/ (60 * 60) ^ pc
.rel_hour
)
2421 | (d2
/ 60 ^ pc
.rel_minutes
)
2422 | ((t0
+ d1
< t0
) ^ (d1
< 0))
2423 | ((t1
+ d2
< t1
) ^ (d2
< 0))
2424 | ((t2
+ d3
< t2
) ^ (d3
< 0)))
2437 main (int ac
, char **av
)
2442 printf ("Enter date, or blank line to exit.\n\t> ");
2445 buff
[BUFSIZ
- 1] = 0;
2446 while (fgets (buff
, BUFSIZ
- 1, stdin
) && buff
[0])
2448 d
= get_date (buff
, 0);
2449 if (d
== (time_t) -1)
2450 printf ("Bad format - couldn't convert.\n");
2452 printf ("%s", ctime (&d
));
2458 #endif /* defined TEST */