1 /* A Bison parser, made by GNU Bison 1.875c. */
3 /* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
26 /* Written by Richard Stallman by simplifying the original so called
27 ``semantic'' parser. */
29 /* All symbols defined below should begin with yy or YY, to avoid
30 infringing on user name space. This should be done even for local
31 variables, as they might otherwise be expanded by user macros.
32 There are some unavoidable exceptions within include files to
33 define necessary library symbols; they are noted "INFRINGES ON
34 USER NAME SPACE" below. */
36 /* Identify Bison output. */
40 #define YYSKELETON_NAME "yacc.c"
45 /* Using locations. */
46 #define YYLSP_NEEDED 0
53 /* Put the tokens into the symbol table, so that GDB and other debuggers
71 #define tMONTH_UNIT 262
80 /* Copy the first part of user declarations. */
85 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
86 ** at the University of North Carolina at Chapel Hill. Later tweaked by
87 ** a couple of people on Usenet. Completely overhauled by Rich $alz
88 ** <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990.
89 ** Further revised (removed obsolete constructs and cleaned up timezone
90 ** names) in August, 1991, by Rich. Paul Eggert <eggert@twinsun.com>
91 ** helped in September, 1992. Art Cancro <ajc@uncensored.citadel.org> cleaned
92 ** it up for ANSI C in December, 1999.
94 ** This grammar has six shift/reduce conflicts.
96 ** This code is in the public domain and has no copyright.
98 /* SUPPRESS 530 *//* Empty body for statement */
99 /* SUPPRESS 593 on yyerrlab *//* Label was not used */
100 /* SUPPRESS 593 on yynewstate *//* Label was not used */
101 /* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */
107 #include <sys/types.h>
110 #if TIME_WITH_SYS_TIME
111 # include <sys/time.h>
115 # include <sys/time.h>
122 # if !STDC_HEADERS && HAVE_MEMORY_H
128 # include <strings.h>
131 #include "parsedate.h"
135 #define yyparse date_parse
136 #define yylex date_lex
137 #define yyerror date_error
140 /* See the LeapYears table in Convert. */
142 #define END_OF_TIME 2038
143 /* Constants for general time calculations. */
145 #define SECSPERDAY (24L * 60L * 60L)
146 /* Readability for TABLE stuff. */
147 #define HOUR(x) (x * 60)
151 #define IS7BIT(x) ((unsigned int)(x) < 0200)
153 #define SIZEOF(array) ((int)(sizeof array / sizeof array[0]))
154 #define ENDOF(array) (&array[SIZEOF(array)])
158 ** An entry in the lexical lookup table.
160 typedef struct _TABLE {
167 ** Daylight-savings mode: on, off, or not yet known.
169 typedef enum _DSTMODE {
170 DSTon, DSToff, DSTmaybe
174 ** Meridian: am, pm, or 24-hour style.
176 typedef enum _MERIDIAN {
182 ** Global variables. We could get rid of most of them by using a yacc
183 ** union, but this is more efficient. (This routine predates the
184 ** yacc %union construct.)
186 static char *yyInput;
187 static DSTMODE yyDSTmode;
188 static int yyHaveDate;
189 static int yyHaveRel;
190 static int yyHaveTime;
191 static time_t yyTimezone;
193 static time_t yyHour;
194 static time_t yyMinutes;
195 static time_t yyMonth;
196 static time_t yySeconds;
197 static time_t yyYear;
198 static MERIDIAN yyMeridian;
199 static time_t yyRelMonth;
200 static time_t yyRelSeconds;
203 static void date_error(char *);
206 /* Enabling traces. */
211 /* Enabling verbose error messages. */
212 #ifdef YYERROR_VERBOSE
213 # undef YYERROR_VERBOSE
214 # define YYERROR_VERBOSE 1
216 # define YYERROR_VERBOSE 0
219 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
220 #line 125 "parsedate.y"
221 typedef union YYSTYPE {
223 enum _MERIDIAN Meridian;
225 /* Line 191 of yacc.c. */
227 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
228 # define YYSTYPE_IS_DECLARED 1
229 # define YYSTYPE_IS_TRIVIAL 1
234 /* Copy the second part of user declarations. */
237 /* Line 214 of yacc.c. */
240 #if ! defined (yyoverflow) || YYERROR_VERBOSE
246 # define YYMALLOC malloc
249 /* The parser invokes alloca or malloc; define the necessary symbols. */
251 # ifdef YYSTACK_USE_ALLOCA
252 # if YYSTACK_USE_ALLOCA
253 # define YYSTACK_ALLOC alloca
256 # if defined (alloca) || defined (_ALLOCA_H)
257 # define YYSTACK_ALLOC alloca
260 # define YYSTACK_ALLOC __builtin_alloca
265 # ifdef YYSTACK_ALLOC
266 /* Pacify GCC's `empty if-body' warning. */
267 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
269 # if defined (__STDC__) || defined (__cplusplus)
270 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
271 # define YYSIZE_T size_t
273 # define YYSTACK_ALLOC YYMALLOC
274 # define YYSTACK_FREE YYFREE
276 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
279 #if (! defined (yyoverflow) \
280 && (! defined (__cplusplus) \
281 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
283 /* A type that is properly aligned for any stack member. */
290 /* The size of the maximum gap between one aligned stack and the next. */
291 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
293 /* The size of an array large to enough to hold all stacks, each with
295 # define YYSTACK_BYTES(N) \
296 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
297 + YYSTACK_GAP_MAXIMUM)
299 /* Copy COUNT objects from FROM to TO. The source and destination do
302 # if defined (__GNUC__) && 1 < __GNUC__
303 # define YYCOPY(To, From, Count) \
304 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
306 # define YYCOPY(To, From, Count) \
309 register YYSIZE_T yyi; \
310 for (yyi = 0; yyi < (Count); yyi++) \
311 (To)[yyi] = (From)[yyi]; \
317 /* Relocate STACK from its old location to the new one. The
318 local variables YYSIZE and YYSTACKSIZE give the old and new number of
319 elements in the stack, and YYPTR gives the new location of the
320 stack. Advance YYPTR to a properly aligned location for the next
322 # define YYSTACK_RELOCATE(Stack) \
325 YYSIZE_T yynewbytes; \
326 YYCOPY (&yyptr->Stack, Stack, yysize); \
327 Stack = &yyptr->Stack; \
328 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
329 yyptr += yynewbytes / sizeof (*yyptr); \
335 #if defined (__STDC__) || defined (__cplusplus)
336 typedef signed char yysigned_char;
338 typedef short yysigned_char;
341 /* YYFINAL -- State number of the termination state. */
343 /* YYLAST -- Last index in YYTABLE. */
346 /* YYNTOKENS -- Number of terminals. */
348 /* YYNNTS -- Number of nonterminals. */
350 /* YYNRULES -- Number of rules. */
352 /* YYNRULES -- Number of states. */
355 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
357 #define YYMAXUTOK 266
359 #define YYTRANSLATE(YYX) \
360 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
362 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
363 static const unsigned char yytranslate[] =
365 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
366 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
367 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
368 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
369 2, 2, 2, 2, 14, 2, 2, 13, 2, 2,
370 2, 2, 2, 2, 2, 2, 2, 2, 12, 2,
371 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
372 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
373 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
374 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
375 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
376 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
377 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
378 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
379 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
380 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
381 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
382 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
383 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
384 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
385 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
386 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
387 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
388 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
389 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
390 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
391 5, 6, 7, 8, 9, 10, 11
395 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
397 static const unsigned char yyprhs[] =
399 0, 0, 3, 4, 7, 9, 12, 14, 16, 19,
400 24, 29, 36, 43, 45, 47, 50, 52, 54, 58,
401 64, 67, 72, 75, 79, 85, 88, 91, 94, 97,
405 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
406 static const yysigned_char yyrhs[] =
408 16, 0, -1, -1, 16, 17, -1, 18, -1, 18,
409 19, -1, 21, -1, 22, -1, 10, 23, -1, 10,
410 12, 10, 23, -1, 10, 12, 10, 20, -1, 10,
411 12, 10, 12, 10, 23, -1, 10, 12, 10, 12,
412 10, 20, -1, 11, -1, 4, -1, 11, 20, -1,
413 20, -1, 9, -1, 10, 13, 10, -1, 10, 13,
414 10, 13, 10, -1, 6, 10, -1, 6, 10, 14,
415 10, -1, 10, 6, -1, 10, 6, 10, -1, 3,
416 14, 10, 6, 10, -1, 9, 8, -1, 10, 8,
417 -1, 9, 7, -1, 10, 7, -1, -1, 5, -1
420 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
421 static const unsigned short yyrline[] =
423 0, 139, 139, 140, 143, 152, 156, 159, 164, 176,
424 182, 189, 195, 205, 209, 213, 221, 227, 248, 252,
425 264, 268, 273, 277, 282, 289, 292, 295, 298, 303,
430 #if YYDEBUG || YYERROR_VERBOSE
431 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
432 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
433 static const char *const yytname[] =
435 "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN",
436 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE",
437 "':'", "'/'", "','", "$accept", "spec", "item", "time", "zone",
438 "numzone", "date", "rel", "o_merid", 0
443 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
445 static const unsigned short yytoknum[] =
447 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
452 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
453 static const unsigned char yyr1[] =
455 0, 15, 16, 16, 17, 17, 17, 17, 18, 18,
456 18, 18, 18, 19, 19, 19, 19, 20, 21, 21,
457 21, 21, 21, 21, 21, 22, 22, 22, 22, 23,
461 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
462 static const unsigned char yyr2[] =
464 0, 2, 0, 2, 1, 2, 1, 1, 2, 4,
465 4, 6, 6, 1, 1, 2, 1, 1, 3, 5,
466 2, 4, 2, 3, 5, 2, 2, 2, 2, 0,
470 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
471 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
472 means the default is an error. */
473 static const unsigned char yydefact[] =
475 2, 0, 1, 0, 0, 0, 29, 3, 4, 6,
476 7, 0, 20, 27, 25, 30, 22, 28, 26, 0,
477 0, 8, 14, 17, 13, 5, 16, 0, 0, 23,
478 29, 18, 15, 0, 21, 0, 10, 9, 0, 24,
482 /* YYDEFGOTO[NTERM-NUM]. */
483 static const yysigned_char yydefgoto[] =
485 -1, 1, 7, 8, 25, 26, 9, 10, 21
488 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
490 #define YYPACT_NINF -29
491 static const yysigned_char yypact[] =
493 -29, 1, -29, -11, 11, 20, 12, -29, 4, -29,
494 -29, 13, 16, -29, -29, -29, 21, -29, -29, 22,
495 23, -29, -29, -29, 5, -29, -29, 28, 25, -29,
496 17, 24, -29, 26, -29, 29, -29, -29, 30, -29,
500 /* YYPGOTO[NTERM-NUM]. */
501 static const yysigned_char yypgoto[] =
503 -29, -29, -29, -29, -29, -24, -29, -29, -28
506 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
507 positive, shift that token. If negative, reduce the rule which
508 number is the opposite. If zero, do what YYDEFACT says.
509 If YYTABLE_NINF, syntax error. */
510 #define YYTABLE_NINF -1
511 static const unsigned char yytable[] =
513 32, 2, 37, 11, 3, 15, 36, 4, 22, 23,
514 5, 6, 43, 23, 23, 24, 42, 15, 16, 17,
515 18, 12, 15, 27, 19, 20, 23, 13, 14, 35,
516 28, 29, 30, 31, 33, 34, 39, 38, 0, 40,
520 static const yysigned_char yycheck[] =
522 24, 0, 30, 14, 3, 5, 30, 6, 4, 9,
523 9, 10, 40, 9, 9, 11, 40, 5, 6, 7,
524 8, 10, 5, 10, 12, 13, 9, 7, 8, 12,
525 14, 10, 10, 10, 6, 10, 10, 13, -1, 10,
529 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
530 symbol of state STATE-NUM. */
531 static const unsigned char yystos[] =
533 0, 16, 0, 3, 6, 9, 10, 17, 18, 21,
534 22, 14, 10, 7, 8, 5, 6, 7, 8, 12,
535 13, 23, 4, 9, 11, 19, 20, 10, 14, 10,
536 10, 10, 20, 6, 10, 12, 20, 23, 13, 10,
540 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
541 # define YYSIZE_T __SIZE_TYPE__
543 #if ! defined (YYSIZE_T) && defined (size_t)
544 # define YYSIZE_T size_t
546 #if ! defined (YYSIZE_T)
547 # if defined (__STDC__) || defined (__cplusplus)
548 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
549 # define YYSIZE_T size_t
552 #if ! defined (YYSIZE_T)
553 # define YYSIZE_T unsigned int
556 #define yyerrok (yyerrstatus = 0)
557 #define yyclearin (yychar = YYEMPTY)
561 #define YYACCEPT goto yyacceptlab
562 #define YYABORT goto yyabortlab
563 #define YYERROR goto yyerrorlab
566 /* Like YYERROR except do call yyerror. This remains here temporarily
567 to ease the transition to the new meaning of YYERROR, for GCC.
568 Once GCC version 2 has supplanted version 1, this can go. */
570 #define YYFAIL goto yyerrlab
572 #define YYRECOVERING() (!!yyerrstatus)
574 #define YYBACKUP(Token, Value) \
576 if (yychar == YYEMPTY && yylen == 1) \
580 yytoken = YYTRANSLATE (yychar); \
586 yyerror ("syntax error: cannot back up");\
592 #define YYERRCODE 256
594 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
597 #ifndef YYLLOC_DEFAULT
598 # define YYLLOC_DEFAULT(Current, Rhs, N) \
599 ((Current).first_line = (Rhs)[1].first_line, \
600 (Current).first_column = (Rhs)[1].first_column, \
601 (Current).last_line = (Rhs)[N].last_line, \
602 (Current).last_column = (Rhs)[N].last_column)
605 /* YYLEX -- calling `yylex' with the right arguments. */
608 # define YYLEX yylex (YYLEX_PARAM)
610 # define YYLEX yylex ()
613 /* Enable debugging if requested. */
617 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
618 # define YYFPRINTF fprintf
621 # define YYDPRINTF(Args) \
627 # define YYDSYMPRINT(Args) \
633 # define YYDSYMPRINTF(Title, Token, Value, Location) \
637 YYFPRINTF (stderr, "%s ", Title); \
638 yysymprint (stderr, \
640 YYFPRINTF (stderr, "\n"); \
644 /*------------------------------------------------------------------.
645 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
647 `------------------------------------------------------------------*/
649 #if defined (__STDC__) || defined (__cplusplus)
651 yy_stack_print (short *bottom, short *top)
654 yy_stack_print (bottom, top)
659 YYFPRINTF (stderr, "Stack now");
660 for (/* Nothing. */; bottom <= top; ++bottom)
661 YYFPRINTF (stderr, " %d", *bottom);
662 YYFPRINTF (stderr, "\n");
665 # define YY_STACK_PRINT(Bottom, Top) \
668 yy_stack_print ((Bottom), (Top)); \
672 /*------------------------------------------------.
673 | Report that the YYRULE is going to be reduced. |
674 `------------------------------------------------*/
676 #if defined (__STDC__) || defined (__cplusplus)
678 yy_reduce_print (int yyrule)
681 yy_reduce_print (yyrule)
686 unsigned int yylno = yyrline[yyrule];
687 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
689 /* Print the symbols being reduced, and their result. */
690 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
691 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
692 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
695 # define YY_REDUCE_PRINT(Rule) \
698 yy_reduce_print (Rule); \
701 /* Nonzero means print parse trace. It is left uninitialized so that
702 multiple parsers can coexist. */
705 # define YYDPRINTF(Args)
706 # define YYDSYMPRINT(Args)
707 # define YYDSYMPRINTF(Title, Token, Value, Location)
708 # define YY_STACK_PRINT(Bottom, Top)
709 # define YY_REDUCE_PRINT(Rule)
710 #endif /* !YYDEBUG */
713 /* YYINITDEPTH -- initial size of the parser's stacks. */
715 # define YYINITDEPTH 200
718 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
719 if the built-in stack extension method is used).
721 Do not make this value too large; the results are undefined if
722 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
723 evaluated with infinite-precision integer arithmetic. */
725 #if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
730 # define YYMAXDEPTH 10000
738 # if defined (__GLIBC__) && defined (_STRING_H)
739 # define yystrlen strlen
741 /* Return the length of YYSTR. */
743 # if defined (__STDC__) || defined (__cplusplus)
744 yystrlen (const char *yystr)
750 register const char *yys = yystr;
752 while (*yys++ != '\0')
755 return yys - yystr - 1;
761 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
762 # define yystpcpy stpcpy
764 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
767 # if defined (__STDC__) || defined (__cplusplus)
768 yystpcpy (char *yydest, const char *yysrc)
770 yystpcpy (yydest, yysrc)
775 register char *yyd = yydest;
776 register const char *yys = yysrc;
778 while ((*yyd++ = *yys++) != '\0')
786 #endif /* !YYERROR_VERBOSE */
791 /*--------------------------------.
792 | Print this symbol on YYOUTPUT. |
793 `--------------------------------*/
795 #if defined (__STDC__) || defined (__cplusplus)
797 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
800 yysymprint (yyoutput, yytype, yyvaluep)
806 /* Pacify ``unused variable'' warnings. */
809 if (yytype < YYNTOKENS)
811 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
813 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
817 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
824 YYFPRINTF (yyoutput, ")");
827 #endif /* ! YYDEBUG */
828 /*-----------------------------------------------.
829 | Release the memory associated to this symbol. |
830 `-----------------------------------------------*/
832 #if defined (__STDC__) || defined (__cplusplus)
834 yydestruct (int yytype, YYSTYPE *yyvaluep)
837 yydestruct (yytype, yyvaluep)
842 /* Pacify ``unused variable'' warnings. */
854 /* Prevent warnings from -Wmissing-prototypes. */
857 # if defined (__STDC__) || defined (__cplusplus)
858 int yyparse (void *YYPARSE_PARAM);
862 #else /* ! YYPARSE_PARAM */
863 #if defined (__STDC__) || defined (__cplusplus)
868 #endif /* ! YYPARSE_PARAM */
872 /* The lookahead symbol. */
875 /* The semantic value of the lookahead symbol. */
878 /* Number of syntax errors so far. */
888 # if defined (__STDC__) || defined (__cplusplus)
889 int yyparse (void *YYPARSE_PARAM)
891 int yyparse (YYPARSE_PARAM)
894 #else /* ! YYPARSE_PARAM */
895 #if defined (__STDC__) || defined (__cplusplus)
906 register int yystate;
909 /* Number of tokens to shift before error messages enabled. */
911 /* Lookahead token as an internal (translated) token number. */
914 /* Three stacks and their tools:
915 `yyss': related to states,
916 `yyvs': related to semantic values,
917 `yyls': related to locations.
919 Refer to the stacks thru separate pointers, to allow yyoverflow
920 to reallocate them elsewhere. */
922 /* The state stack. */
923 short yyssa[YYINITDEPTH];
925 register short *yyssp;
927 /* The semantic value stack. */
928 YYSTYPE yyvsa[YYINITDEPTH];
929 YYSTYPE *yyvs = yyvsa;
930 register YYSTYPE *yyvsp;
934 #define YYPOPSTACK (yyvsp--, yyssp--)
936 YYSIZE_T yystacksize = YYINITDEPTH;
938 /* The variables used to return semantic value and location from the
943 /* When reducing, the number of symbols on the RHS of the reduced
947 YYDPRINTF ((stderr, "Starting parse\n"));
952 yychar = YYEMPTY; /* Cause a token to be read. */
954 /* Initialize stack pointers.
955 Waste one element of value and location stack
956 so that they stay on the same level as the state stack.
957 The wasted elements are never initialized. */
964 /*------------------------------------------------------------.
965 | yynewstate -- Push a new state, which is found in yystate. |
966 `------------------------------------------------------------*/
968 /* In all cases, when you get here, the value and location stacks
969 have just been pushed. so pushing a state here evens the stacks.
976 if (yyss + yystacksize - 1 <= yyssp)
978 /* Get the current used size of the three stacks, in elements. */
979 YYSIZE_T yysize = yyssp - yyss + 1;
983 /* Give user a chance to reallocate the stack. Use copies of
984 these so that the &'s don't force the real ones into
986 YYSTYPE *yyvs1 = yyvs;
990 /* Each stack pointer address is followed by the size of the
991 data in use in that stack, in bytes. This used to be a
992 conditional around just the two extra args, but that might
993 be undefined if yyoverflow is a macro. */
994 yyoverflow ("parser stack overflow",
995 &yyss1, yysize * sizeof (*yyssp),
996 &yyvs1, yysize * sizeof (*yyvsp),
1003 #else /* no yyoverflow */
1004 # ifndef YYSTACK_RELOCATE
1007 /* Extend the stack our own way. */
1008 if (YYMAXDEPTH <= yystacksize)
1011 if (YYMAXDEPTH < yystacksize)
1012 yystacksize = YYMAXDEPTH;
1015 short *yyss1 = yyss;
1016 union yyalloc *yyptr =
1017 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1020 YYSTACK_RELOCATE (yyss);
1021 YYSTACK_RELOCATE (yyvs);
1023 # undef YYSTACK_RELOCATE
1025 YYSTACK_FREE (yyss1);
1028 #endif /* no yyoverflow */
1030 yyssp = yyss + yysize - 1;
1031 yyvsp = yyvs + yysize - 1;
1034 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1035 (unsigned long int) yystacksize));
1037 if (yyss + yystacksize - 1 <= yyssp)
1041 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1050 /* Do appropriate processing given the current state. */
1051 /* Read a lookahead token if we need one and don't already have one. */
1054 /* First try to decide what to do without reference to lookahead token. */
1056 yyn = yypact[yystate];
1057 if (yyn == YYPACT_NINF)
1060 /* Not known => get a lookahead token if don't already have one. */
1062 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1063 if (yychar == YYEMPTY)
1065 YYDPRINTF ((stderr, "Reading a token: "));
1069 if (yychar <= YYEOF)
1071 yychar = yytoken = YYEOF;
1072 YYDPRINTF ((stderr, "Now at end of input.\n"));
1076 yytoken = YYTRANSLATE (yychar);
1077 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1080 /* If the proper action on seeing token YYTOKEN is to reduce or to
1081 detect an error, take that action. */
1083 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1088 if (yyn == 0 || yyn == YYTABLE_NINF)
1097 /* Shift the lookahead token. */
1098 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1100 /* Discard the token being shifted unless it is eof. */
1101 if (yychar != YYEOF)
1107 /* Count tokens shifted since error; after three, turn off error
1116 /*-----------------------------------------------------------.
1117 | yydefault -- do the default action for the current state. |
1118 `-----------------------------------------------------------*/
1120 yyn = yydefact[yystate];
1126 /*-----------------------------.
1127 | yyreduce -- Do a reduction. |
1128 `-----------------------------*/
1130 /* yyn is the number of a rule to reduce with. */
1133 /* If YYLEN is nonzero, implement the default value of the action:
1136 Otherwise, the following line sets YYVAL to garbage.
1137 This behavior is undocumented and Bison
1138 users should not rely upon it. Assigning to YYVAL
1139 unconditionally makes the parser a bit smaller, and it avoids a
1140 GCC warning that YYVAL may be used uninitialized. */
1141 yyval = yyvsp[1-yylen];
1144 YY_REDUCE_PRINT (yyn);
1148 #line 143 "parsedate.y"
1152 /* I am compulsive about lint natterings... */
1153 if (yyHaveTime == -1) {
1161 #line 152 "parsedate.y"
1164 yyTimezone = yyvsp[0].Number;
1169 #line 156 "parsedate.y"
1176 #line 159 "parsedate.y"
1183 #line 164 "parsedate.y"
1185 if (yyvsp[-1].Number < 100) {
1186 yyHour = yyvsp[-1].Number;
1190 yyHour = yyvsp[-1].Number / 100;
1191 yyMinutes = yyvsp[-1].Number % 100;
1194 yyMeridian = yyvsp[0].Meridian;
1199 #line 176 "parsedate.y"
1201 yyHour = yyvsp[-3].Number;
1202 yyMinutes = yyvsp[-1].Number;
1204 yyMeridian = yyvsp[0].Meridian;
1209 #line 182 "parsedate.y"
1211 yyHour = yyvsp[-3].Number;
1212 yyMinutes = yyvsp[-1].Number;
1213 yyTimezone = yyvsp[0].Number;
1220 #line 189 "parsedate.y"
1222 yyHour = yyvsp[-5].Number;
1223 yyMinutes = yyvsp[-3].Number;
1224 yySeconds = yyvsp[-1].Number;
1225 yyMeridian = yyvsp[0].Meridian;
1230 #line 195 "parsedate.y"
1232 yyHour = yyvsp[-5].Number;
1233 yyMinutes = yyvsp[-3].Number;
1234 yySeconds = yyvsp[-1].Number;
1235 yyTimezone = yyvsp[0].Number;
1242 #line 205 "parsedate.y"
1244 yyval.Number = yyvsp[0].Number;
1250 #line 209 "parsedate.y"
1252 yyval.Number = yyvsp[0].Number;
1258 #line 213 "parsedate.y"
1260 /* Only allow "GMT+300" and "GMT-0800" */
1261 if (yyvsp[-1].Number != 0) {
1264 yyval.Number = yyvsp[0].Number;
1270 #line 221 "parsedate.y"
1272 yyval.Number = yyvsp[0].Number;
1278 #line 227 "parsedate.y"
1282 /* Unix and GMT and numeric timezones -- a little confusing. */
1283 if (yyvsp[0].Number < 0) {
1284 /* Don't work with negative modulus. */
1285 yyvsp[0].Number = -yyvsp[0].Number;
1286 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1289 yyval.Number = (yyvsp[0].Number / 100) * 60 + i;
1292 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1295 yyval.Number = -((yyvsp[0].Number / 100) * 60 + i);
1301 #line 248 "parsedate.y"
1303 yyMonth = yyvsp[-2].Number;
1304 yyDay = yyvsp[0].Number;
1309 #line 252 "parsedate.y"
1311 if (yyvsp[-4].Number > 100) {
1312 yyYear = yyvsp[-4].Number;
1313 yyMonth = yyvsp[-2].Number;
1314 yyDay = yyvsp[0].Number;
1317 yyMonth = yyvsp[-4].Number;
1318 yyDay = yyvsp[-2].Number;
1319 yyYear = yyvsp[0].Number;
1325 #line 264 "parsedate.y"
1327 yyMonth = yyvsp[-1].Number;
1328 yyDay = yyvsp[0].Number;
1333 #line 268 "parsedate.y"
1335 yyMonth = yyvsp[-3].Number;
1336 yyDay = yyvsp[-2].Number;
1337 yyYear = yyvsp[0].Number;
1342 #line 273 "parsedate.y"
1344 yyDay = yyvsp[-1].Number;
1345 yyMonth = yyvsp[0].Number;
1350 #line 277 "parsedate.y"
1352 yyDay = yyvsp[-2].Number;
1353 yyMonth = yyvsp[-1].Number;
1354 yyYear = yyvsp[0].Number;
1359 #line 282 "parsedate.y"
1361 yyDay = yyvsp[-2].Number;
1362 yyMonth = yyvsp[-1].Number;
1363 yyYear = yyvsp[0].Number;
1368 #line 289 "parsedate.y"
1370 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1375 #line 292 "parsedate.y"
1377 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1382 #line 295 "parsedate.y"
1384 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1389 #line 298 "parsedate.y"
1391 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1396 #line 303 "parsedate.y"
1398 yyval.Meridian = MER24;
1403 #line 306 "parsedate.y"
1405 yyval.Meridian = yyvsp[0].Meridian;
1412 /* Line 1000 of yacc.c. */
1413 #line 1414 "y.tab.c"
1419 YY_STACK_PRINT (yyss, yyssp);
1424 /* Now `shift' the result of the reduction. Determine what state
1425 that goes to, based on the state we popped back to and the rule
1426 number reduced by. */
1430 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1431 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1432 yystate = yytable[yystate];
1434 yystate = yydefgoto[yyn - YYNTOKENS];
1439 /*------------------------------------.
1440 | yyerrlab -- here on detecting error |
1441 `------------------------------------*/
1443 /* If not already recovering from an error, report this error. */
1448 yyn = yypact[yystate];
1450 if (YYPACT_NINF < yyn && yyn < YYLAST)
1452 YYSIZE_T yysize = 0;
1453 int yytype = YYTRANSLATE (yychar);
1454 const char* yyprefix;
1458 /* Start YYX at -YYN if negative to avoid negative indexes in
1460 int yyxbegin = yyn < 0 ? -yyn : 0;
1462 /* Stay within bounds of both yycheck and yytname. */
1463 int yychecklim = YYLAST - yyn;
1464 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1467 yyprefix = ", expecting ";
1468 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1469 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1471 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1479 yysize += (sizeof ("syntax error, unexpected ")
1480 + yystrlen (yytname[yytype]));
1481 yymsg = (char *) YYSTACK_ALLOC (yysize);
1484 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1485 yyp = yystpcpy (yyp, yytname[yytype]);
1489 yyprefix = ", expecting ";
1490 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1491 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1493 yyp = yystpcpy (yyp, yyprefix);
1494 yyp = yystpcpy (yyp, yytname[yyx]);
1499 YYSTACK_FREE (yymsg);
1502 yyerror ("syntax error; also virtual memory exhausted");
1505 #endif /* YYERROR_VERBOSE */
1506 yyerror ("syntax error");
1511 if (yyerrstatus == 3)
1513 /* If just tried and failed to reuse lookahead token after an
1514 error, discard it. */
1516 if (yychar <= YYEOF)
1518 /* If at end of input, pop the error token,
1519 then the rest of the stack, then return failure. */
1520 if (yychar == YYEOF)
1526 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1527 yydestruct (yystos[*yyssp], yyvsp);
1532 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1533 yydestruct (yytoken, &yylval);
1539 /* Else will try to reuse lookahead token after shifting the error
1544 /*---------------------------------------------------.
1545 | yyerrorlab -- error raised explicitly by YYERROR. |
1546 `---------------------------------------------------*/
1550 /* Pacify GCC when the user code never invokes YYERROR and the label
1551 yyerrorlab therefore never appears in user code. */
1562 /*-------------------------------------------------------------.
1563 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1564 `-------------------------------------------------------------*/
1566 yyerrstatus = 3; /* Each real token shifted decrements this. */
1570 yyn = yypact[yystate];
1571 if (yyn != YYPACT_NINF)
1574 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1582 /* Pop the current state because it cannot handle the error token. */
1586 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1587 yydestruct (yystos[yystate], yyvsp);
1590 YY_STACK_PRINT (yyss, yyssp);
1596 YYDPRINTF ((stderr, "Shifting error token, "));
1605 /*-------------------------------------.
1606 | yyacceptlab -- YYACCEPT comes here. |
1607 `-------------------------------------*/
1612 /*-----------------------------------.
1613 | yyabortlab -- YYABORT comes here. |
1614 `-----------------------------------*/
1620 /*----------------------------------------------.
1621 | yyoverflowlab -- parser overflow comes here. |
1622 `----------------------------------------------*/
1624 yyerror ("parser stack overflow");
1632 YYSTACK_FREE (yyss);
1638 #line 311 "parsedate.y"
1641 /* Month and day table. */
1642 static TABLE MonthDayTable[] = {
1643 { "january", tMONTH, 1 },
1644 { "february", tMONTH, 2 },
1645 { "march", tMONTH, 3 },
1646 { "april", tMONTH, 4 },
1647 { "may", tMONTH, 5 },
1648 { "june", tMONTH, 6 },
1649 { "july", tMONTH, 7 },
1650 { "august", tMONTH, 8 },
1651 { "september", tMONTH, 9 },
1652 { "october", tMONTH, 10 },
1653 { "november", tMONTH, 11 },
1654 { "december", tMONTH, 12 },
1655 /* The value of the day isn't used... */
1656 { "sunday", tDAY, 0 },
1657 { "monday", tDAY, 0 },
1658 { "tuesday", tDAY, 0 },
1659 { "wednesday", tDAY, 0 },
1660 { "thursday", tDAY, 0 },
1661 { "friday", tDAY, 0 },
1662 { "saturday", tDAY, 0 },
1665 /* Time units table. */
1666 static TABLE UnitsTable[] = {
1667 { "year", tMONTH_UNIT, 12 },
1668 { "month", tMONTH_UNIT, 1 },
1669 { "week", tSEC_UNIT, 7L * 24 * 60 * 60 },
1670 { "day", tSEC_UNIT, 1L * 24 * 60 * 60 },
1671 { "hour", tSEC_UNIT, 60 * 60 },
1672 { "minute", tSEC_UNIT, 60 },
1673 { "min", tSEC_UNIT, 60 },
1674 { "second", tSEC_UNIT, 1 },
1675 { "sec", tSEC_UNIT, 1 },
1678 /* Timezone table. */
1679 static TABLE TimezoneTable[] = {
1680 { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
1681 { "ut", tZONE, HOUR( 0) }, /* Universal */
1682 { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */
1683 { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */
1684 { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */
1685 { "wet", tZONE, HOUR( 0) }, /* Western European */
1686 { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
1687 { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */
1688 { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */
1689 { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
1690 { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
1691 { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
1692 { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
1693 { "cst", tZONE, HOUR( 6) }, /* Central Standard */
1694 { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
1695 { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
1696 { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
1697 { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
1698 { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
1699 { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
1700 { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
1701 { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */
1702 { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */
1703 { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
1704 { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */
1705 { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */
1706 { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */
1707 { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */
1708 { "mez", tZONE, -HOUR(1) }, /* Middle European */
1709 { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
1710 { "cet", tZONE, -HOUR(1) }, /* Central European */
1711 { "met", tZONE, -HOUR(1) }, /* Middle European */
1712 { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */
1713 { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */
1714 { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */
1715 { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */
1716 { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */
1717 { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */
1718 { "cct", tZONE, -HOUR(8) }, /* China Coast */
1719 { "jst", tZONE, -HOUR(9) }, /* Japan Standard */
1720 { "kst", tZONE, -HOUR(9) }, /* Korean Standard */
1721 { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */
1722 { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */
1723 { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */
1724 { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
1725 { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
1726 { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
1727 { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
1729 /* For completeness we include the following entries. */
1732 /* Duplicate names. Either they conflict with a zone listed above
1733 * (which is either more likely to be seen or just been in circulation
1734 * longer), or they conflict with another zone in this section and
1735 * we could not reasonably choose one over the other. */
1736 { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */
1737 { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */
1738 { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
1739 { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */
1740 { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */
1741 { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */
1742 { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */
1743 { "cst", tZONE, HOUR( 5) }, /* Chile Standard */
1744 { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */
1745 { "ast", tZONE, HOUR( 5) }, /* Acre Standard */
1746 { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */
1747 { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */
1748 { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */
1749 { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */
1750 { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */
1751 { "sst", tZONE, HOUR(11) }, /* Samoa Standard */
1752 { "ist", tZONE, -HOUR(2) }, /* Israel Standard */
1753 { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */
1754 { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */
1755 { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */
1756 { "cst", tZONE, -HOUR(8) }, /* China Standard */
1757 { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */
1758 { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */
1760 /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
1761 { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
1762 { "wat", tZONE, -HOUR(1) }, /* West Africa */
1763 { "at", tZONE, HOUR( 2) }, /* Azores */
1764 { "gst", tZONE, -HOUR(10) }, /* Guam Standard */
1765 { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */
1766 { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
1767 { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
1768 { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
1769 { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
1770 { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
1771 { "fwt", tZONE, -HOUR(1) }, /* French Winter */
1772 { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
1773 { "bt", tZONE, -HOUR(3) }, /* Baghdad */
1774 { "it", tZONE, -(HOUR(3)+30) }, /* Iran */
1775 { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
1776 { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
1777 { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */
1778 { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
1779 { "nst", tZONE, -HOUR(7) }, /* North Sumatra */
1780 { "sst", tZONE, -HOUR(7) }, /* South Sumatra */
1781 { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
1782 { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
1783 { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
1784 { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */
1785 { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */
1786 { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */
1787 { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */
1801 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1803 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
1805 if (Meridian == MER24) {
1806 if (Hours < 0 || Hours > 23)
1810 if (Hours < 1 || Hours > 12)
1814 if (Meridian == MERpm)
1817 return (Hours * 60L + Minutes) * 60L + Seconds;
1822 Convert(time_t Month, time_t Day, time_t Year,
1823 time_t Hours, time_t Minutes, time_t Seconds,
1824 MERIDIAN Meridian, DSTMODE dst)
1826 static int DaysNormal[13] = {
1827 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1829 static int DaysLeap[13] = {
1830 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1832 static int LeapYears[] = {
1833 1972, 1976, 1980, 1984, 1988, 1992, 1996,
1834 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
1838 register time_t Julian;
1848 for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
1853 if (Year < EPOCH || Year > END_OF_TIME
1854 || Month < 1 || Month > 12
1855 /* NOSTRICT *//* conversion from long may lose accuracy */
1856 || Day < 1 || Day > mp[(int)Month])
1859 Julian = Day - 1 + (Year - EPOCH) * 365;
1860 for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
1863 for (i = 1; i < Month; i++)
1865 Julian *= SECSPERDAY;
1866 Julian += yyTimezone * 60L;
1867 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1871 if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
1872 Julian -= DST_OFFSET * 60L * 60L;
1878 DSTcorrect(time_t Start, time_t Future)
1883 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
1884 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
1885 return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L;
1890 RelativeMonth(time_t Start, time_t RelMonth)
1896 tm = localtime(&Start);
1897 Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
1899 Month = Month % 12 + 1;
1900 return DSTcorrect(Start,
1901 Convert(Month, (time_t)tm->tm_mday, Year,
1902 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
1908 LookupWord(char *buff, register int length)
1918 /* See if we have an abbreviation for a month. */
1919 if (length == 3 || (length == 4 && p[3] == '.'))
1920 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
1922 if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
1923 yylval.Number = tp->value;
1928 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
1929 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1930 yylval.Number = tp->value;
1934 /* Try for a timezone. */
1935 for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1936 if (c == tp->name[0] && p[1] == tp->name[1]
1937 && strcmp(p, tp->name) == 0) {
1938 yylval.Number = tp->value;
1942 /* Try the units table. */
1943 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1944 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1945 yylval.Number = tp->value;
1949 /* Strip off any plural and try the units table again. */
1950 if (--length > 0 && p[length] == 's') {
1952 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1953 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1955 yylval.Number = tp->value;
1962 /* Drop out any periods. */
1963 for (p = buff, q = (char*)buff; *q; q++)
1968 /* Try the meridians. */
1969 if (buff[1] == 'm' && buff[2] == '\0') {
1970 if (buff[0] == 'a') {
1971 yylval.Meridian = MERam;
1974 if (buff[0] == 'p') {
1975 yylval.Meridian = MERpm;
1980 /* If we saw any periods, try the timezones again. */
1981 if (p - buff != length) {
1983 for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1984 if (c == tp->name[0] && p[1] == tp->name[1]
1985 && strcmp(p, tp->name) == 0) {
1986 yylval.Number = tp->value;
1991 /* Unknown word -- assume GMT timezone. */
2005 register int nesting;
2008 /* Get first character after the whitespace. */
2010 while (isspace(*yyInput))
2014 /* Ignore RFC 822 comments, typically time zone names. */
2017 for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
2020 else if (!IS7BIT(c) || c == '\0' || c == '\r'
2021 || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
2022 /* Lexical error: bad comment. */
2028 if (isdigit(c) || c == '-' || c == '+') {
2029 if (c == '-' || c == '+') {
2030 sign = c == '-' ? -1 : 1;
2032 if (!isdigit(*yyInput))
2033 /* Skip the plus or minus sign. */
2038 for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
2039 i = 10 * i + c - '0';
2041 yylval.Number = sign < 0 ? -i : i;
2042 return sign ? tSNUMBER : tUNUMBER;
2047 for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
2048 if (p < &buff[sizeof buff - 1])
2049 *p++ = isupper(c) ? tolower(c) : c;
2052 return LookupWord(buff, p - buff);
2063 extern int date_parse(void);
2072 yyDSTmode = DSTmaybe;
2083 if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
2086 if (yyHaveDate || yyHaveTime) {
2087 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2088 yyMeridian, yyDSTmode);
2095 Start += yyRelSeconds;
2097 Start += RelativeMonth(Start, yyRelMonth);
2099 /* Have to do *something* with a legitimate -1 so it's distinguishable
2100 * from the error return value. (Alternately could set errno on error.) */
2101 return Start == -1 ? 0 : Start;
2109 #endif /* YYDEBUG */
2113 main(int ac, char *av[])
2120 #endif /* YYDEBUG */
2122 (void)printf("Enter date, or blank line to exit.\n\t> ");
2124 (void)printf("\t> ");
2125 (void)fflush(stdout);
2126 if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2129 if (strcmp(buff, "yydebug") == 0) {
2131 printf("yydebug = %s\n", yydebug ? "on" : "off");
2134 #endif /* YYDEBUG */
2135 d = parsedate(buff, (TIMEINFO *)NULL);
2137 (void)printf("Bad format - couldn't convert.\n");
2139 (void)printf("%s", ctime(&d));