1 /* A Bison parser, made by GNU Bison 1.875d. */
3 /* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 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 int) + 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 int 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 int 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 int 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 int *bottom, short int *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 int yyssa[YYINITDEPTH];
924 short int *yyss = yyssa;
925 register short int *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. */
965 /*------------------------------------------------------------.
966 | yynewstate -- Push a new state, which is found in yystate. |
967 `------------------------------------------------------------*/
969 /* In all cases, when you get here, the value and location stacks
970 have just been pushed. so pushing a state here evens the stacks.
977 if (yyss + yystacksize - 1 <= yyssp)
979 /* Get the current used size of the three stacks, in elements. */
980 YYSIZE_T yysize = yyssp - yyss + 1;
984 /* Give user a chance to reallocate the stack. Use copies of
985 these so that the &'s don't force the real ones into
987 YYSTYPE *yyvs1 = yyvs;
988 short int *yyss1 = yyss;
991 /* Each stack pointer address is followed by the size of the
992 data in use in that stack, in bytes. This used to be a
993 conditional around just the two extra args, but that might
994 be undefined if yyoverflow is a macro. */
995 yyoverflow ("parser stack overflow",
996 &yyss1, yysize * sizeof (*yyssp),
997 &yyvs1, yysize * sizeof (*yyvsp),
1004 #else /* no yyoverflow */
1005 # ifndef YYSTACK_RELOCATE
1008 /* Extend the stack our own way. */
1009 if (YYMAXDEPTH <= yystacksize)
1012 if (YYMAXDEPTH < yystacksize)
1013 yystacksize = YYMAXDEPTH;
1016 short int *yyss1 = yyss;
1017 union yyalloc *yyptr =
1018 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1021 YYSTACK_RELOCATE (yyss);
1022 YYSTACK_RELOCATE (yyvs);
1024 # undef YYSTACK_RELOCATE
1026 YYSTACK_FREE (yyss1);
1029 #endif /* no yyoverflow */
1031 yyssp = yyss + yysize - 1;
1032 yyvsp = yyvs + yysize - 1;
1035 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1036 (unsigned long int) yystacksize));
1038 if (yyss + yystacksize - 1 <= yyssp)
1042 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1051 /* Do appropriate processing given the current state. */
1052 /* Read a lookahead token if we need one and don't already have one. */
1055 /* First try to decide what to do without reference to lookahead token. */
1057 yyn = yypact[yystate];
1058 if (yyn == YYPACT_NINF)
1061 /* Not known => get a lookahead token if don't already have one. */
1063 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1064 if (yychar == YYEMPTY)
1066 YYDPRINTF ((stderr, "Reading a token: "));
1070 if (yychar <= YYEOF)
1072 yychar = yytoken = YYEOF;
1073 YYDPRINTF ((stderr, "Now at end of input.\n"));
1077 yytoken = YYTRANSLATE (yychar);
1078 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1081 /* If the proper action on seeing token YYTOKEN is to reduce or to
1082 detect an error, take that action. */
1084 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1089 if (yyn == 0 || yyn == YYTABLE_NINF)
1098 /* Shift the lookahead token. */
1099 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1101 /* Discard the token being shifted unless it is eof. */
1102 if (yychar != YYEOF)
1108 /* Count tokens shifted since error; after three, turn off error
1117 /*-----------------------------------------------------------.
1118 | yydefault -- do the default action for the current state. |
1119 `-----------------------------------------------------------*/
1121 yyn = yydefact[yystate];
1127 /*-----------------------------.
1128 | yyreduce -- Do a reduction. |
1129 `-----------------------------*/
1131 /* yyn is the number of a rule to reduce with. */
1134 /* If YYLEN is nonzero, implement the default value of the action:
1137 Otherwise, the following line sets YYVAL to garbage.
1138 This behavior is undocumented and Bison
1139 users should not rely upon it. Assigning to YYVAL
1140 unconditionally makes the parser a bit smaller, and it avoids a
1141 GCC warning that YYVAL may be used uninitialized. */
1142 yyval = yyvsp[1-yylen];
1145 YY_REDUCE_PRINT (yyn);
1149 #line 143 "parsedate.y"
1153 /* I am compulsive about lint natterings... */
1154 if (yyHaveTime == -1) {
1162 #line 152 "parsedate.y"
1165 yyTimezone = yyvsp[0].Number;
1170 #line 156 "parsedate.y"
1177 #line 159 "parsedate.y"
1184 #line 164 "parsedate.y"
1186 if (yyvsp[-1].Number < 100) {
1187 yyHour = yyvsp[-1].Number;
1191 yyHour = yyvsp[-1].Number / 100;
1192 yyMinutes = yyvsp[-1].Number % 100;
1195 yyMeridian = yyvsp[0].Meridian;
1200 #line 176 "parsedate.y"
1202 yyHour = yyvsp[-3].Number;
1203 yyMinutes = yyvsp[-1].Number;
1205 yyMeridian = yyvsp[0].Meridian;
1210 #line 182 "parsedate.y"
1212 yyHour = yyvsp[-3].Number;
1213 yyMinutes = yyvsp[-1].Number;
1214 yyTimezone = yyvsp[0].Number;
1221 #line 189 "parsedate.y"
1223 yyHour = yyvsp[-5].Number;
1224 yyMinutes = yyvsp[-3].Number;
1225 yySeconds = yyvsp[-1].Number;
1226 yyMeridian = yyvsp[0].Meridian;
1231 #line 195 "parsedate.y"
1233 yyHour = yyvsp[-5].Number;
1234 yyMinutes = yyvsp[-3].Number;
1235 yySeconds = yyvsp[-1].Number;
1236 yyTimezone = yyvsp[0].Number;
1243 #line 205 "parsedate.y"
1245 yyval.Number = yyvsp[0].Number;
1251 #line 209 "parsedate.y"
1253 yyval.Number = yyvsp[0].Number;
1259 #line 213 "parsedate.y"
1261 /* Only allow "GMT+300" and "GMT-0800" */
1262 if (yyvsp[-1].Number != 0) {
1265 yyval.Number = yyvsp[0].Number;
1271 #line 221 "parsedate.y"
1273 yyval.Number = yyvsp[0].Number;
1279 #line 227 "parsedate.y"
1283 /* Unix and GMT and numeric timezones -- a little confusing. */
1284 if (yyvsp[0].Number < 0) {
1285 /* Don't work with negative modulus. */
1286 yyvsp[0].Number = -yyvsp[0].Number;
1287 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1290 yyval.Number = (yyvsp[0].Number / 100) * 60 + i;
1293 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1296 yyval.Number = -((yyvsp[0].Number / 100) * 60 + i);
1302 #line 248 "parsedate.y"
1304 yyMonth = yyvsp[-2].Number;
1305 yyDay = yyvsp[0].Number;
1310 #line 252 "parsedate.y"
1312 if (yyvsp[-4].Number > 100) {
1313 yyYear = yyvsp[-4].Number;
1314 yyMonth = yyvsp[-2].Number;
1315 yyDay = yyvsp[0].Number;
1318 yyMonth = yyvsp[-4].Number;
1319 yyDay = yyvsp[-2].Number;
1320 yyYear = yyvsp[0].Number;
1326 #line 264 "parsedate.y"
1328 yyMonth = yyvsp[-1].Number;
1329 yyDay = yyvsp[0].Number;
1334 #line 268 "parsedate.y"
1336 yyMonth = yyvsp[-3].Number;
1337 yyDay = yyvsp[-2].Number;
1338 yyYear = yyvsp[0].Number;
1343 #line 273 "parsedate.y"
1345 yyDay = yyvsp[-1].Number;
1346 yyMonth = yyvsp[0].Number;
1351 #line 277 "parsedate.y"
1353 yyDay = yyvsp[-2].Number;
1354 yyMonth = yyvsp[-1].Number;
1355 yyYear = yyvsp[0].Number;
1360 #line 282 "parsedate.y"
1362 yyDay = yyvsp[-2].Number;
1363 yyMonth = yyvsp[-1].Number;
1364 yyYear = yyvsp[0].Number;
1369 #line 289 "parsedate.y"
1371 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1376 #line 292 "parsedate.y"
1378 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1383 #line 295 "parsedate.y"
1385 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1390 #line 298 "parsedate.y"
1392 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1397 #line 303 "parsedate.y"
1399 yyval.Meridian = MER24;
1404 #line 306 "parsedate.y"
1406 yyval.Meridian = yyvsp[0].Meridian;
1413 /* Line 1010 of yacc.c. */
1414 #line 1415 "y.tab.c"
1420 YY_STACK_PRINT (yyss, yyssp);
1425 /* Now `shift' the result of the reduction. Determine what state
1426 that goes to, based on the state we popped back to and the rule
1427 number reduced by. */
1431 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1432 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1433 yystate = yytable[yystate];
1435 yystate = yydefgoto[yyn - YYNTOKENS];
1440 /*------------------------------------.
1441 | yyerrlab -- here on detecting error |
1442 `------------------------------------*/
1444 /* If not already recovering from an error, report this error. */
1449 yyn = yypact[yystate];
1451 if (YYPACT_NINF < yyn && yyn < YYLAST)
1453 YYSIZE_T yysize = 0;
1454 int yytype = YYTRANSLATE (yychar);
1455 const char* yyprefix;
1459 /* Start YYX at -YYN if negative to avoid negative indexes in
1461 int yyxbegin = yyn < 0 ? -yyn : 0;
1463 /* Stay within bounds of both yycheck and yytname. */
1464 int yychecklim = YYLAST - yyn;
1465 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1468 yyprefix = ", expecting ";
1469 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1470 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1472 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1480 yysize += (sizeof ("syntax error, unexpected ")
1481 + yystrlen (yytname[yytype]));
1482 yymsg = (char *) YYSTACK_ALLOC (yysize);
1485 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1486 yyp = yystpcpy (yyp, yytname[yytype]);
1490 yyprefix = ", expecting ";
1491 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1492 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1494 yyp = yystpcpy (yyp, yyprefix);
1495 yyp = yystpcpy (yyp, yytname[yyx]);
1500 YYSTACK_FREE (yymsg);
1503 yyerror ("syntax error; also virtual memory exhausted");
1506 #endif /* YYERROR_VERBOSE */
1507 yyerror ("syntax error");
1512 if (yyerrstatus == 3)
1514 /* If just tried and failed to reuse lookahead token after an
1515 error, discard it. */
1517 if (yychar <= YYEOF)
1519 /* If at end of input, pop the error token,
1520 then the rest of the stack, then return failure. */
1521 if (yychar == YYEOF)
1527 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1528 yydestruct (yystos[*yyssp], yyvsp);
1533 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1534 yydestruct (yytoken, &yylval);
1540 /* Else will try to reuse lookahead token after shifting the error
1545 /*---------------------------------------------------.
1546 | yyerrorlab -- error raised explicitly by YYERROR. |
1547 `---------------------------------------------------*/
1551 /* Pacify GCC when the user code never invokes YYERROR and the label
1552 yyerrorlab therefore never appears in user code. */
1563 /*-------------------------------------------------------------.
1564 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1565 `-------------------------------------------------------------*/
1567 yyerrstatus = 3; /* Each real token shifted decrements this. */
1571 yyn = yypact[yystate];
1572 if (yyn != YYPACT_NINF)
1575 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1583 /* Pop the current state because it cannot handle the error token. */
1587 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1588 yydestruct (yystos[yystate], yyvsp);
1591 YY_STACK_PRINT (yyss, yyssp);
1597 YYDPRINTF ((stderr, "Shifting error token, "));
1606 /*-------------------------------------.
1607 | yyacceptlab -- YYACCEPT comes here. |
1608 `-------------------------------------*/
1613 /*-----------------------------------.
1614 | yyabortlab -- YYABORT comes here. |
1615 `-----------------------------------*/
1621 /*----------------------------------------------.
1622 | yyoverflowlab -- parser overflow comes here. |
1623 `----------------------------------------------*/
1625 yyerror ("parser stack overflow");
1633 YYSTACK_FREE (yyss);
1639 #line 311 "parsedate.y"
1642 /* Month and day table. */
1643 static TABLE MonthDayTable[] = {
1644 { "january", tMONTH, 1 },
1645 { "february", tMONTH, 2 },
1646 { "march", tMONTH, 3 },
1647 { "april", tMONTH, 4 },
1648 { "may", tMONTH, 5 },
1649 { "june", tMONTH, 6 },
1650 { "july", tMONTH, 7 },
1651 { "august", tMONTH, 8 },
1652 { "september", tMONTH, 9 },
1653 { "october", tMONTH, 10 },
1654 { "november", tMONTH, 11 },
1655 { "december", tMONTH, 12 },
1656 /* The value of the day isn't used... */
1657 { "sunday", tDAY, 0 },
1658 { "monday", tDAY, 0 },
1659 { "tuesday", tDAY, 0 },
1660 { "wednesday", tDAY, 0 },
1661 { "thursday", tDAY, 0 },
1662 { "friday", tDAY, 0 },
1663 { "saturday", tDAY, 0 },
1666 /* Time units table. */
1667 static TABLE UnitsTable[] = {
1668 { "year", tMONTH_UNIT, 12 },
1669 { "month", tMONTH_UNIT, 1 },
1670 { "week", tSEC_UNIT, 7L * 24 * 60 * 60 },
1671 { "day", tSEC_UNIT, 1L * 24 * 60 * 60 },
1672 { "hour", tSEC_UNIT, 60 * 60 },
1673 { "minute", tSEC_UNIT, 60 },
1674 { "min", tSEC_UNIT, 60 },
1675 { "second", tSEC_UNIT, 1 },
1676 { "sec", tSEC_UNIT, 1 },
1679 /* Timezone table. */
1680 static TABLE TimezoneTable[] = {
1681 { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
1682 { "ut", tZONE, HOUR( 0) }, /* Universal */
1683 { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */
1684 { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */
1685 { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */
1686 { "wet", tZONE, HOUR( 0) }, /* Western European */
1687 { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
1688 { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */
1689 { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */
1690 { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
1691 { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
1692 { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
1693 { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
1694 { "cst", tZONE, HOUR( 6) }, /* Central Standard */
1695 { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
1696 { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
1697 { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
1698 { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
1699 { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
1700 { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
1701 { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
1702 { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */
1703 { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */
1704 { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
1705 { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */
1706 { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */
1707 { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */
1708 { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */
1709 { "mez", tZONE, -HOUR(1) }, /* Middle European */
1710 { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
1711 { "cet", tZONE, -HOUR(1) }, /* Central European */
1712 { "met", tZONE, -HOUR(1) }, /* Middle European */
1713 { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */
1714 { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */
1715 { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */
1716 { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */
1717 { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */
1718 { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */
1719 { "cct", tZONE, -HOUR(8) }, /* China Coast */
1720 { "jst", tZONE, -HOUR(9) }, /* Japan Standard */
1721 { "kst", tZONE, -HOUR(9) }, /* Korean Standard */
1722 { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */
1723 { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */
1724 { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */
1725 { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
1726 { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
1727 { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
1728 { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
1730 /* For completeness we include the following entries. */
1733 /* Duplicate names. Either they conflict with a zone listed above
1734 * (which is either more likely to be seen or just been in circulation
1735 * longer), or they conflict with another zone in this section and
1736 * we could not reasonably choose one over the other. */
1737 { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */
1738 { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */
1739 { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
1740 { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */
1741 { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */
1742 { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */
1743 { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */
1744 { "cst", tZONE, HOUR( 5) }, /* Chile Standard */
1745 { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */
1746 { "ast", tZONE, HOUR( 5) }, /* Acre Standard */
1747 { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */
1748 { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */
1749 { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */
1750 { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */
1751 { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */
1752 { "sst", tZONE, HOUR(11) }, /* Samoa Standard */
1753 { "ist", tZONE, -HOUR(2) }, /* Israel Standard */
1754 { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */
1755 { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */
1756 { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */
1757 { "cst", tZONE, -HOUR(8) }, /* China Standard */
1758 { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */
1759 { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */
1761 /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
1762 { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
1763 { "wat", tZONE, -HOUR(1) }, /* West Africa */
1764 { "at", tZONE, HOUR( 2) }, /* Azores */
1765 { "gst", tZONE, -HOUR(10) }, /* Guam Standard */
1766 { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */
1767 { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
1768 { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
1769 { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
1770 { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
1771 { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
1772 { "fwt", tZONE, -HOUR(1) }, /* French Winter */
1773 { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
1774 { "bt", tZONE, -HOUR(3) }, /* Baghdad */
1775 { "it", tZONE, -(HOUR(3)+30) }, /* Iran */
1776 { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
1777 { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
1778 { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */
1779 { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
1780 { "nst", tZONE, -HOUR(7) }, /* North Sumatra */
1781 { "sst", tZONE, -HOUR(7) }, /* South Sumatra */
1782 { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
1783 { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
1784 { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
1785 { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */
1786 { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */
1787 { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */
1788 { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */
1802 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1804 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
1806 if (Meridian == MER24) {
1807 if (Hours < 0 || Hours > 23)
1811 if (Hours < 1 || Hours > 12)
1815 if (Meridian == MERpm)
1818 return (Hours * 60L + Minutes) * 60L + Seconds;
1823 Convert(time_t Month, time_t Day, time_t Year,
1824 time_t Hours, time_t Minutes, time_t Seconds,
1825 MERIDIAN Meridian, DSTMODE dst)
1827 static int DaysNormal[13] = {
1828 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1830 static int DaysLeap[13] = {
1831 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1833 static int LeapYears[] = {
1834 1972, 1976, 1980, 1984, 1988, 1992, 1996,
1835 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
1839 register time_t Julian;
1849 for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
1854 if (Year < EPOCH || Year > END_OF_TIME
1855 || Month < 1 || Month > 12
1856 /* NOSTRICT *//* conversion from long may lose accuracy */
1857 || Day < 1 || Day > mp[(int)Month])
1860 Julian = Day - 1 + (Year - EPOCH) * 365;
1861 for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
1864 for (i = 1; i < Month; i++)
1866 Julian *= SECSPERDAY;
1867 Julian += yyTimezone * 60L;
1868 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1872 if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
1873 Julian -= DST_OFFSET * 60L * 60L;
1879 DSTcorrect(time_t Start, time_t Future)
1884 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
1885 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
1886 return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L;
1891 RelativeMonth(time_t Start, time_t RelMonth)
1897 tm = localtime(&Start);
1898 Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
1900 Month = Month % 12 + 1;
1901 return DSTcorrect(Start,
1902 Convert(Month, (time_t)tm->tm_mday, Year,
1903 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
1909 LookupWord(char *buff, register int length)
1919 /* See if we have an abbreviation for a month. */
1920 if (length == 3 || (length == 4 && p[3] == '.'))
1921 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
1923 if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
1924 yylval.Number = tp->value;
1929 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
1930 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1931 yylval.Number = tp->value;
1935 /* Try for a timezone. */
1936 for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1937 if (c == tp->name[0] && p[1] == tp->name[1]
1938 && strcmp(p, tp->name) == 0) {
1939 yylval.Number = tp->value;
1943 /* Try the units table. */
1944 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1945 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1946 yylval.Number = tp->value;
1950 /* Strip off any plural and try the units table again. */
1951 if (--length > 0 && p[length] == 's') {
1953 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1954 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1956 yylval.Number = tp->value;
1963 /* Drop out any periods. */
1964 for (p = buff, q = (char*)buff; *q; q++)
1969 /* Try the meridians. */
1970 if (buff[1] == 'm' && buff[2] == '\0') {
1971 if (buff[0] == 'a') {
1972 yylval.Meridian = MERam;
1975 if (buff[0] == 'p') {
1976 yylval.Meridian = MERpm;
1981 /* If we saw any periods, try the timezones again. */
1982 if (p - buff != length) {
1984 for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1985 if (c == tp->name[0] && p[1] == tp->name[1]
1986 && strcmp(p, tp->name) == 0) {
1987 yylval.Number = tp->value;
1992 /* Unknown word -- assume GMT timezone. */
2006 register int nesting;
2009 /* Get first character after the whitespace. */
2011 while (isspace(*yyInput))
2015 /* Ignore RFC 822 comments, typically time zone names. */
2018 for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
2021 else if (!IS7BIT(c) || c == '\0' || c == '\r'
2022 || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
2023 /* Lexical error: bad comment. */
2029 if (isdigit(c) || c == '-' || c == '+') {
2030 if (c == '-' || c == '+') {
2031 sign = c == '-' ? -1 : 1;
2033 if (!isdigit(*yyInput))
2034 /* Skip the plus or minus sign. */
2039 for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
2040 i = 10 * i + c - '0';
2042 yylval.Number = sign < 0 ? -i : i;
2043 return sign ? tSNUMBER : tUNUMBER;
2048 for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
2049 if (p < &buff[sizeof buff - 1])
2050 *p++ = isupper(c) ? tolower(c) : c;
2053 return LookupWord(buff, p - buff);
2064 extern int date_parse(void);
2073 yyDSTmode = DSTmaybe;
2084 if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
2087 if (yyHaveDate || yyHaveTime) {
2088 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2089 yyMeridian, yyDSTmode);
2096 Start += yyRelSeconds;
2098 Start += RelativeMonth(Start, yyRelMonth);
2100 /* Have to do *something* with a legitimate -1 so it's distinguishable
2101 * from the error return value. (Alternately could set errno on error.) */
2102 return Start == -1 ? 0 : Start;
2110 #endif /* YYDEBUG */
2114 main(int ac, char *av[])
2121 #endif /* YYDEBUG */
2123 (void)printf("Enter date, or blank line to exit.\n\t> ");
2125 (void)printf("\t> ");
2126 (void)fflush(stdout);
2127 if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2130 if (strcmp(buff, "yydebug") == 0) {
2132 printf("yydebug = %s\n", yydebug ? "on" : "off");
2135 #endif /* YYDEBUG */
2136 d = parsedate(buff, (TIMEINFO *)NULL);
2138 (void)printf("Bad format - couldn't convert.\n");
2140 (void)printf("%s", ctime(&d));