Replaced extract_token() with a completely new
[citadel.git] / citadel / parsedate.c
1 /* A Bison parser, made by GNU Bison 1.875c.  */
2
3 /* Skeleton parser for Yacc-like parsing with Bison,
4    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5
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)
9    any later version.
10
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.
15
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.  */
20
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.  */
25
26 /* Written by Richard Stallman by simplifying the original so called
27    ``semantic'' parser.  */
28
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.  */
35
36 /* Identify Bison output.  */
37 #define YYBISON 1
38
39 /* Skeleton name.  */
40 #define YYSKELETON_NAME "yacc.c"
41
42 /* Pure parsers.  */
43 #define YYPURE 0
44
45 /* Using locations.  */
46 #define YYLSP_NEEDED 0
47
48
49
50 /* Tokens.  */
51 #ifndef YYTOKENTYPE
52 # define YYTOKENTYPE
53    /* Put the tokens into the symbol table, so that GDB and other debuggers
54       know about them.  */
55    enum yytokentype {
56      tDAY = 258,
57      tDAYZONE = 259,
58      tMERIDIAN = 260,
59      tMONTH = 261,
60      tMONTH_UNIT = 262,
61      tSEC_UNIT = 263,
62      tSNUMBER = 264,
63      tUNUMBER = 265,
64      tZONE = 266
65    };
66 #endif
67 #define tDAY 258
68 #define tDAYZONE 259
69 #define tMERIDIAN 260
70 #define tMONTH 261
71 #define tMONTH_UNIT 262
72 #define tSEC_UNIT 263
73 #define tSNUMBER 264
74 #define tUNUMBER 265
75 #define tZONE 266
76
77
78
79
80 /* Copy the first part of user declarations.  */
81 #line 1 "parsedate.y"
82
83 /* $Revision: 4003 $
84 **
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.
93 **
94 **  This grammar has six shift/reduce conflicts.
95 **
96 **  This code is in the public domain and has no copyright.
97 */
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 */
102
103 #include "sysdep.h"
104
105 #include <stdio.h>
106 #include <stdlib.h>
107 #include <sys/types.h>
108 #include <ctype.h>
109
110 #if TIME_WITH_SYS_TIME
111 # include <sys/time.h>
112 # include <time.h>
113 #else
114 # if HAVE_SYS_TIME_H
115 #  include <sys/time.h>
116 # else
117 #  include <time.h>
118 # endif
119 #endif
120
121 #if HAVE_STRING_H
122 # if !STDC_HEADERS && HAVE_MEMORY_H
123 #  include <memory.h>
124 # endif
125 # include <string.h>
126 #endif
127 #if HAVE_STRINGS_H
128 # include <strings.h>
129 #endif
130
131 #include "parsedate.h"
132
133 int date_lex(void);
134
135 #define yyparse         date_parse
136 #define yylex           date_lex
137 #define yyerror         date_error
138
139
140     /* See the LeapYears table in Convert. */
141 #define EPOCH           1970
142 #define END_OF_TIME     2038
143     /* Constants for general time calculations. */
144 #define DST_OFFSET      1
145 #define SECSPERDAY      (24L * 60L * 60L)
146     /* Readability for TABLE stuff. */
147 #define HOUR(x)         (x * 60)
148
149 #define LPAREN          '('
150 #define RPAREN          ')'
151 #define IS7BIT(x)       ((unsigned int)(x) < 0200)
152
153 #define SIZEOF(array)   ((int)(sizeof array / sizeof array[0]))
154 #define ENDOF(array)    (&array[SIZEOF(array)])
155
156
157 /*
158 **  An entry in the lexical lookup table.
159 */
160 typedef struct _TABLE {
161     char        *name;
162     int         type;
163     time_t      value;
164 } TABLE;
165
166 /*
167 **  Daylight-savings mode:  on, off, or not yet known.
168 */
169 typedef enum _DSTMODE {
170     DSTon, DSToff, DSTmaybe
171 } DSTMODE;
172
173 /*
174 **  Meridian:  am, pm, or 24-hour style.
175 */
176 typedef enum _MERIDIAN {
177     MERam, MERpm, MER24
178 } MERIDIAN;
179
180
181 /*
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.)
185 */
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;
192 static time_t   yyDay;
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;
201
202
203 static void             date_error(char *);
204
205
206 /* Enabling traces.  */
207 #ifndef YYDEBUG
208 # define YYDEBUG 0
209 #endif
210
211 /* Enabling verbose error messages.  */
212 #ifdef YYERROR_VERBOSE
213 # undef YYERROR_VERBOSE
214 # define YYERROR_VERBOSE 1
215 #else
216 # define YYERROR_VERBOSE 0
217 #endif
218
219 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
220 #line 125 "parsedate.y"
221 typedef union YYSTYPE {
222     time_t              Number;
223     enum _MERIDIAN      Meridian;
224 } YYSTYPE;
225 /* Line 191 of yacc.c.  */
226 #line 227 "y.tab.c"
227 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
228 # define YYSTYPE_IS_DECLARED 1
229 # define YYSTYPE_IS_TRIVIAL 1
230 #endif
231
232
233
234 /* Copy the second part of user declarations.  */
235
236
237 /* Line 214 of yacc.c.  */
238 #line 239 "y.tab.c"
239
240 #if ! defined (yyoverflow) || YYERROR_VERBOSE
241
242 # ifndef YYFREE
243 #  define YYFREE free
244 # endif
245 # ifndef YYMALLOC
246 #  define YYMALLOC malloc
247 # endif
248
249 /* The parser invokes alloca or malloc; define the necessary symbols.  */
250
251 # ifdef YYSTACK_USE_ALLOCA
252 #  if YYSTACK_USE_ALLOCA
253 #   define YYSTACK_ALLOC alloca
254 #  endif
255 # else
256 #  if defined (alloca) || defined (_ALLOCA_H)
257 #   define YYSTACK_ALLOC alloca
258 #  else
259 #   ifdef __GNUC__
260 #    define YYSTACK_ALLOC __builtin_alloca
261 #   endif
262 #  endif
263 # endif
264
265 # ifdef YYSTACK_ALLOC
266    /* Pacify GCC's `empty if-body' warning. */
267 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
268 # else
269 #  if defined (__STDC__) || defined (__cplusplus)
270 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
271 #   define YYSIZE_T size_t
272 #  endif
273 #  define YYSTACK_ALLOC YYMALLOC
274 #  define YYSTACK_FREE YYFREE
275 # endif
276 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
277
278
279 #if (! defined (yyoverflow) \
280      && (! defined (__cplusplus) \
281          || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
282
283 /* A type that is properly aligned for any stack member.  */
284 union yyalloc
285 {
286   short yyss;
287   YYSTYPE yyvs;
288   };
289
290 /* The size of the maximum gap between one aligned stack and the next.  */
291 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
292
293 /* The size of an array large to enough to hold all stacks, each with
294    N elements.  */
295 # define YYSTACK_BYTES(N) \
296      ((N) * (sizeof (short) + sizeof (YYSTYPE))                         \
297       + YYSTACK_GAP_MAXIMUM)
298
299 /* Copy COUNT objects from FROM to TO.  The source and destination do
300    not overlap.  */
301 # ifndef YYCOPY
302 #  if defined (__GNUC__) && 1 < __GNUC__
303 #   define YYCOPY(To, From, Count) \
304       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
305 #  else
306 #   define YYCOPY(To, From, Count)              \
307       do                                        \
308         {                                       \
309           register YYSIZE_T yyi;                \
310           for (yyi = 0; yyi < (Count); yyi++)   \
311             (To)[yyi] = (From)[yyi];            \
312         }                                       \
313       while (0)
314 #  endif
315 # endif
316
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
321    stack.  */
322 # define YYSTACK_RELOCATE(Stack)                                        \
323     do                                                                  \
324       {                                                                 \
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);                          \
330       }                                                                 \
331     while (0)
332
333 #endif
334
335 #if defined (__STDC__) || defined (__cplusplus)
336    typedef signed char yysigned_char;
337 #else
338    typedef short yysigned_char;
339 #endif
340
341 /* YYFINAL -- State number of the termination state. */
342 #define YYFINAL  2
343 /* YYLAST -- Last index in YYTABLE.  */
344 #define YYLAST   40
345
346 /* YYNTOKENS -- Number of terminals. */
347 #define YYNTOKENS  15
348 /* YYNNTS -- Number of nonterminals. */
349 #define YYNNTS  9
350 /* YYNRULES -- Number of rules. */
351 #define YYNRULES  30
352 /* YYNRULES -- Number of states. */
353 #define YYNSTATES  44
354
355 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
356 #define YYUNDEFTOK  2
357 #define YYMAXUTOK   266
358
359 #define YYTRANSLATE(YYX)                                                \
360   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
361
362 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
363 static const unsigned char yytranslate[] =
364 {
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
392 };
393
394 #if YYDEBUG
395 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
396    YYRHS.  */
397 static const unsigned char yyprhs[] =
398 {
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,
402       98
403 };
404
405 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
406 static const yysigned_char yyrhs[] =
407 {
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
418 };
419
420 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
421 static const unsigned short yyrline[] =
422 {
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,
426      306
427 };
428 #endif
429
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[] =
434 {
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
439 };
440 #endif
441
442 # ifdef YYPRINT
443 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
444    token YYLEX-NUM.  */
445 static const unsigned short yytoknum[] =
446 {
447        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
448      265,   266,    58,    47,    44
449 };
450 # endif
451
452 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
453 static const unsigned char yyr1[] =
454 {
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,
458       23
459 };
460
461 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
462 static const unsigned char yyr2[] =
463 {
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,
467        1
468 };
469
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[] =
474 {
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,
479       29,    19,    12,    11
480 };
481
482 /* YYDEFGOTO[NTERM-NUM]. */
483 static const yysigned_char yydefgoto[] =
484 {
485       -1,     1,     7,     8,    25,    26,     9,    10,    21
486 };
487
488 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
489    STATE-NUM.  */
490 #define YYPACT_NINF -29
491 static const yysigned_char yypact[] =
492 {
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,
497        0,   -29,   -29,   -29
498 };
499
500 /* YYPGOTO[NTERM-NUM].  */
501 static const yysigned_char yypgoto[] =
502 {
503      -29,   -29,   -29,   -29,   -29,   -24,   -29,   -29,   -28
504 };
505
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[] =
512 {
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,
517       41
518 };
519
520 static const yysigned_char yycheck[] =
521 {
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,
526       10
527 };
528
529 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
530    symbol of state STATE-NUM.  */
531 static const unsigned char yystos[] =
532 {
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,
537       10,    10,    20,    23
538 };
539
540 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
541 # define YYSIZE_T __SIZE_TYPE__
542 #endif
543 #if ! defined (YYSIZE_T) && defined (size_t)
544 # define YYSIZE_T size_t
545 #endif
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
550 # endif
551 #endif
552 #if ! defined (YYSIZE_T)
553 # define YYSIZE_T unsigned int
554 #endif
555
556 #define yyerrok         (yyerrstatus = 0)
557 #define yyclearin       (yychar = YYEMPTY)
558 #define YYEMPTY         (-2)
559 #define YYEOF           0
560
561 #define YYACCEPT        goto yyacceptlab
562 #define YYABORT         goto yyabortlab
563 #define YYERROR         goto yyerrorlab
564
565
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.  */
569
570 #define YYFAIL          goto yyerrlab
571
572 #define YYRECOVERING()  (!!yyerrstatus)
573
574 #define YYBACKUP(Token, Value)                                  \
575 do                                                              \
576   if (yychar == YYEMPTY && yylen == 1)                          \
577     {                                                           \
578       yychar = (Token);                                         \
579       yylval = (Value);                                         \
580       yytoken = YYTRANSLATE (yychar);                           \
581       YYPOPSTACK;                                               \
582       goto yybackup;                                            \
583     }                                                           \
584   else                                                          \
585     {                                                           \
586       yyerror ("syntax error: cannot back up");\
587       YYERROR;                                                  \
588     }                                                           \
589 while (0)
590
591 #define YYTERROR        1
592 #define YYERRCODE       256
593
594 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
595    are run).  */
596
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)
603 #endif
604
605 /* YYLEX -- calling `yylex' with the right arguments.  */
606
607 #ifdef YYLEX_PARAM
608 # define YYLEX yylex (YYLEX_PARAM)
609 #else
610 # define YYLEX yylex ()
611 #endif
612
613 /* Enable debugging if requested.  */
614 #if YYDEBUG
615
616 # ifndef YYFPRINTF
617 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
618 #  define YYFPRINTF fprintf
619 # endif
620
621 # define YYDPRINTF(Args)                        \
622 do {                                            \
623   if (yydebug)                                  \
624     YYFPRINTF Args;                             \
625 } while (0)
626
627 # define YYDSYMPRINT(Args)                      \
628 do {                                            \
629   if (yydebug)                                  \
630     yysymprint Args;                            \
631 } while (0)
632
633 # define YYDSYMPRINTF(Title, Token, Value, Location)            \
634 do {                                                            \
635   if (yydebug)                                                  \
636     {                                                           \
637       YYFPRINTF (stderr, "%s ", Title);                         \
638       yysymprint (stderr,                                       \
639                   Token, Value);        \
640       YYFPRINTF (stderr, "\n");                                 \
641     }                                                           \
642 } while (0)
643
644 /*------------------------------------------------------------------.
645 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
646 | TOP (included).                                                   |
647 `------------------------------------------------------------------*/
648
649 #if defined (__STDC__) || defined (__cplusplus)
650 static void
651 yy_stack_print (short *bottom, short *top)
652 #else
653 static void
654 yy_stack_print (bottom, top)
655     short *bottom;
656     short *top;
657 #endif
658 {
659   YYFPRINTF (stderr, "Stack now");
660   for (/* Nothing. */; bottom <= top; ++bottom)
661     YYFPRINTF (stderr, " %d", *bottom);
662   YYFPRINTF (stderr, "\n");
663 }
664
665 # define YY_STACK_PRINT(Bottom, Top)                            \
666 do {                                                            \
667   if (yydebug)                                                  \
668     yy_stack_print ((Bottom), (Top));                           \
669 } while (0)
670
671
672 /*------------------------------------------------.
673 | Report that the YYRULE is going to be reduced.  |
674 `------------------------------------------------*/
675
676 #if defined (__STDC__) || defined (__cplusplus)
677 static void
678 yy_reduce_print (int yyrule)
679 #else
680 static void
681 yy_reduce_print (yyrule)
682     int yyrule;
683 #endif
684 {
685   int yyi;
686   unsigned int yylno = yyrline[yyrule];
687   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
688              yyrule - 1, yylno);
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]]);
693 }
694
695 # define YY_REDUCE_PRINT(Rule)          \
696 do {                                    \
697   if (yydebug)                          \
698     yy_reduce_print (Rule);             \
699 } while (0)
700
701 /* Nonzero means print parse trace.  It is left uninitialized so that
702    multiple parsers can coexist.  */
703 int yydebug;
704 #else /* !YYDEBUG */
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 */
711
712
713 /* YYINITDEPTH -- initial size of the parser's stacks.  */
714 #ifndef YYINITDEPTH
715 # define YYINITDEPTH 200
716 #endif
717
718 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
719    if the built-in stack extension method is used).
720
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.  */
724
725 #if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
726 # undef YYMAXDEPTH
727 #endif
728
729 #ifndef YYMAXDEPTH
730 # define YYMAXDEPTH 10000
731 #endif
732
733 \f
734
735 #if YYERROR_VERBOSE
736
737 # ifndef yystrlen
738 #  if defined (__GLIBC__) && defined (_STRING_H)
739 #   define yystrlen strlen
740 #  else
741 /* Return the length of YYSTR.  */
742 static YYSIZE_T
743 #   if defined (__STDC__) || defined (__cplusplus)
744 yystrlen (const char *yystr)
745 #   else
746 yystrlen (yystr)
747      const char *yystr;
748 #   endif
749 {
750   register const char *yys = yystr;
751
752   while (*yys++ != '\0')
753     continue;
754
755   return yys - yystr - 1;
756 }
757 #  endif
758 # endif
759
760 # ifndef yystpcpy
761 #  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
762 #   define yystpcpy stpcpy
763 #  else
764 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
765    YYDEST.  */
766 static char *
767 #   if defined (__STDC__) || defined (__cplusplus)
768 yystpcpy (char *yydest, const char *yysrc)
769 #   else
770 yystpcpy (yydest, yysrc)
771      char *yydest;
772      const char *yysrc;
773 #   endif
774 {
775   register char *yyd = yydest;
776   register const char *yys = yysrc;
777
778   while ((*yyd++ = *yys++) != '\0')
779     continue;
780
781   return yyd - 1;
782 }
783 #  endif
784 # endif
785
786 #endif /* !YYERROR_VERBOSE */
787
788 \f
789
790 #if YYDEBUG
791 /*--------------------------------.
792 | Print this symbol on YYOUTPUT.  |
793 `--------------------------------*/
794
795 #if defined (__STDC__) || defined (__cplusplus)
796 static void
797 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
798 #else
799 static void
800 yysymprint (yyoutput, yytype, yyvaluep)
801     FILE *yyoutput;
802     int yytype;
803     YYSTYPE *yyvaluep;
804 #endif
805 {
806   /* Pacify ``unused variable'' warnings.  */
807   (void) yyvaluep;
808
809   if (yytype < YYNTOKENS)
810     {
811       YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
812 # ifdef YYPRINT
813       YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
814 # endif
815     }
816   else
817     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
818
819   switch (yytype)
820     {
821       default:
822         break;
823     }
824   YYFPRINTF (yyoutput, ")");
825 }
826
827 #endif /* ! YYDEBUG */
828 /*-----------------------------------------------.
829 | Release the memory associated to this symbol.  |
830 `-----------------------------------------------*/
831
832 #if defined (__STDC__) || defined (__cplusplus)
833 static void
834 yydestruct (int yytype, YYSTYPE *yyvaluep)
835 #else
836 static void
837 yydestruct (yytype, yyvaluep)
838     int yytype;
839     YYSTYPE *yyvaluep;
840 #endif
841 {
842   /* Pacify ``unused variable'' warnings.  */
843   (void) yyvaluep;
844
845   switch (yytype)
846     {
847
848       default:
849         break;
850     }
851 }
852 \f
853
854 /* Prevent warnings from -Wmissing-prototypes.  */
855
856 #ifdef YYPARSE_PARAM
857 # if defined (__STDC__) || defined (__cplusplus)
858 int yyparse (void *YYPARSE_PARAM);
859 # else
860 int yyparse ();
861 # endif
862 #else /* ! YYPARSE_PARAM */
863 #if defined (__STDC__) || defined (__cplusplus)
864 int yyparse (void);
865 #else
866 int yyparse ();
867 #endif
868 #endif /* ! YYPARSE_PARAM */
869
870
871
872 /* The lookahead symbol.  */
873 int yychar;
874
875 /* The semantic value of the lookahead symbol.  */
876 YYSTYPE yylval;
877
878 /* Number of syntax errors so far.  */
879 int yynerrs;
880
881
882
883 /*----------.
884 | yyparse.  |
885 `----------*/
886
887 #ifdef YYPARSE_PARAM
888 # if defined (__STDC__) || defined (__cplusplus)
889 int yyparse (void *YYPARSE_PARAM)
890 # else
891 int yyparse (YYPARSE_PARAM)
892   void *YYPARSE_PARAM;
893 # endif
894 #else /* ! YYPARSE_PARAM */
895 #if defined (__STDC__) || defined (__cplusplus)
896 int
897 yyparse (void)
898 #else
899 int
900 yyparse ()
901
902 #endif
903 #endif
904 {
905   
906   register int yystate;
907   register int yyn;
908   int yyresult;
909   /* Number of tokens to shift before error messages enabled.  */
910   int yyerrstatus;
911   /* Lookahead token as an internal (translated) token number.  */
912   int yytoken = 0;
913
914   /* Three stacks and their tools:
915      `yyss': related to states,
916      `yyvs': related to semantic values,
917      `yyls': related to locations.
918
919      Refer to the stacks thru separate pointers, to allow yyoverflow
920      to reallocate them elsewhere.  */
921
922   /* The state stack.  */
923   short yyssa[YYINITDEPTH];
924   short *yyss = yyssa;
925   register short *yyssp;
926
927   /* The semantic value stack.  */
928   YYSTYPE yyvsa[YYINITDEPTH];
929   YYSTYPE *yyvs = yyvsa;
930   register YYSTYPE *yyvsp;
931
932
933
934 #define YYPOPSTACK   (yyvsp--, yyssp--)
935
936   YYSIZE_T yystacksize = YYINITDEPTH;
937
938   /* The variables used to return semantic value and location from the
939      action routines.  */
940   YYSTYPE yyval;
941
942
943   /* When reducing, the number of symbols on the RHS of the reduced
944      rule.  */
945   int yylen;
946
947   YYDPRINTF ((stderr, "Starting parse\n"));
948
949   yystate = 0;
950   yyerrstatus = 0;
951   yynerrs = 0;
952   yychar = YYEMPTY;             /* Cause a token to be read.  */
953
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.  */
958
959   yyssp = yyss;
960   yyvsp = yyvs;
961
962   goto yysetstate;
963
964 /*------------------------------------------------------------.
965 | yynewstate -- Push a new state, which is found in yystate.  |
966 `------------------------------------------------------------*/
967  yynewstate:
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.
970      */
971   yyssp++;
972
973  yysetstate:
974   *yyssp = yystate;
975
976   if (yyss + yystacksize - 1 <= yyssp)
977     {
978       /* Get the current used size of the three stacks, in elements.  */
979       YYSIZE_T yysize = yyssp - yyss + 1;
980
981 #ifdef yyoverflow
982       {
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
985            memory.  */
986         YYSTYPE *yyvs1 = yyvs;
987         short *yyss1 = yyss;
988
989
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),
997
998                     &yystacksize);
999
1000         yyss = yyss1;
1001         yyvs = yyvs1;
1002       }
1003 #else /* no yyoverflow */
1004 # ifndef YYSTACK_RELOCATE
1005       goto yyoverflowlab;
1006 # else
1007       /* Extend the stack our own way.  */
1008       if (YYMAXDEPTH <= yystacksize)
1009         goto yyoverflowlab;
1010       yystacksize *= 2;
1011       if (YYMAXDEPTH < yystacksize)
1012         yystacksize = YYMAXDEPTH;
1013
1014       {
1015         short *yyss1 = yyss;
1016         union yyalloc *yyptr =
1017           (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1018         if (! yyptr)
1019           goto yyoverflowlab;
1020         YYSTACK_RELOCATE (yyss);
1021         YYSTACK_RELOCATE (yyvs);
1022
1023 #  undef YYSTACK_RELOCATE
1024         if (yyss1 != yyssa)
1025           YYSTACK_FREE (yyss1);
1026       }
1027 # endif
1028 #endif /* no yyoverflow */
1029
1030       yyssp = yyss + yysize - 1;
1031       yyvsp = yyvs + yysize - 1;
1032
1033
1034       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1035                   (unsigned long int) yystacksize));
1036
1037       if (yyss + yystacksize - 1 <= yyssp)
1038         YYABORT;
1039     }
1040
1041   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1042
1043   goto yybackup;
1044
1045 /*-----------.
1046 | yybackup.  |
1047 `-----------*/
1048 yybackup:
1049
1050 /* Do appropriate processing given the current state.  */
1051 /* Read a lookahead token if we need one and don't already have one.  */
1052 /* yyresume: */
1053
1054   /* First try to decide what to do without reference to lookahead token.  */
1055
1056   yyn = yypact[yystate];
1057   if (yyn == YYPACT_NINF)
1058     goto yydefault;
1059
1060   /* Not known => get a lookahead token if don't already have one.  */
1061
1062   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1063   if (yychar == YYEMPTY)
1064     {
1065       YYDPRINTF ((stderr, "Reading a token: "));
1066       yychar = YYLEX;
1067     }
1068
1069   if (yychar <= YYEOF)
1070     {
1071       yychar = yytoken = YYEOF;
1072       YYDPRINTF ((stderr, "Now at end of input.\n"));
1073     }
1074   else
1075     {
1076       yytoken = YYTRANSLATE (yychar);
1077       YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1078     }
1079
1080   /* If the proper action on seeing token YYTOKEN is to reduce or to
1081      detect an error, take that action.  */
1082   yyn += yytoken;
1083   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1084     goto yydefault;
1085   yyn = yytable[yyn];
1086   if (yyn <= 0)
1087     {
1088       if (yyn == 0 || yyn == YYTABLE_NINF)
1089         goto yyerrlab;
1090       yyn = -yyn;
1091       goto yyreduce;
1092     }
1093
1094   if (yyn == YYFINAL)
1095     YYACCEPT;
1096
1097   /* Shift the lookahead token.  */
1098   YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1099
1100   /* Discard the token being shifted unless it is eof.  */
1101   if (yychar != YYEOF)
1102     yychar = YYEMPTY;
1103
1104   *++yyvsp = yylval;
1105
1106
1107   /* Count tokens shifted since error; after three, turn off error
1108      status.  */
1109   if (yyerrstatus)
1110     yyerrstatus--;
1111
1112   yystate = yyn;
1113   goto yynewstate;
1114
1115
1116 /*-----------------------------------------------------------.
1117 | yydefault -- do the default action for the current state.  |
1118 `-----------------------------------------------------------*/
1119 yydefault:
1120   yyn = yydefact[yystate];
1121   if (yyn == 0)
1122     goto yyerrlab;
1123   goto yyreduce;
1124
1125
1126 /*-----------------------------.
1127 | yyreduce -- Do a reduction.  |
1128 `-----------------------------*/
1129 yyreduce:
1130   /* yyn is the number of a rule to reduce with.  */
1131   yylen = yyr2[yyn];
1132
1133   /* If YYLEN is nonzero, implement the default value of the action:
1134      `$$ = $1'.
1135
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];
1142
1143
1144   YY_REDUCE_PRINT (yyn);
1145   switch (yyn)
1146     {
1147         case 4:
1148 #line 143 "parsedate.y"
1149     {
1150             yyHaveTime++;
1151 #ifdef lint
1152             /* I am compulsive about lint natterings... */
1153             if (yyHaveTime == -1) {
1154                 YYERROR;
1155             }
1156 #endif /* lint */
1157         }
1158     break;
1159
1160   case 5:
1161 #line 152 "parsedate.y"
1162     {
1163             yyHaveTime++;
1164             yyTimezone = yyvsp[0].Number;
1165         }
1166     break;
1167
1168   case 6:
1169 #line 156 "parsedate.y"
1170     {
1171             yyHaveDate++;
1172         }
1173     break;
1174
1175   case 7:
1176 #line 159 "parsedate.y"
1177     {
1178             yyHaveRel = 1;
1179         }
1180     break;
1181
1182   case 8:
1183 #line 164 "parsedate.y"
1184     {
1185             if (yyvsp[-1].Number < 100) {
1186                 yyHour = yyvsp[-1].Number;
1187                 yyMinutes = 0;
1188             }
1189             else {
1190                 yyHour = yyvsp[-1].Number / 100;
1191                 yyMinutes = yyvsp[-1].Number % 100;
1192             }
1193             yySeconds = 0;
1194             yyMeridian = yyvsp[0].Meridian;
1195         }
1196     break;
1197
1198   case 9:
1199 #line 176 "parsedate.y"
1200     {
1201             yyHour = yyvsp[-3].Number;
1202             yyMinutes = yyvsp[-1].Number;
1203             yySeconds = 0;
1204             yyMeridian = yyvsp[0].Meridian;
1205         }
1206     break;
1207
1208   case 10:
1209 #line 182 "parsedate.y"
1210     {
1211             yyHour = yyvsp[-3].Number;
1212             yyMinutes = yyvsp[-1].Number;
1213             yyTimezone = yyvsp[0].Number;
1214             yyMeridian = MER24;
1215             yyDSTmode = DSToff;
1216         }
1217     break;
1218
1219   case 11:
1220 #line 189 "parsedate.y"
1221     {
1222             yyHour = yyvsp[-5].Number;
1223             yyMinutes = yyvsp[-3].Number;
1224             yySeconds = yyvsp[-1].Number;
1225             yyMeridian = yyvsp[0].Meridian;
1226         }
1227     break;
1228
1229   case 12:
1230 #line 195 "parsedate.y"
1231     {
1232             yyHour = yyvsp[-5].Number;
1233             yyMinutes = yyvsp[-3].Number;
1234             yySeconds = yyvsp[-1].Number;
1235             yyTimezone = yyvsp[0].Number;
1236             yyMeridian = MER24;
1237             yyDSTmode = DSToff;
1238         }
1239     break;
1240
1241   case 13:
1242 #line 205 "parsedate.y"
1243     {
1244             yyval.Number = yyvsp[0].Number;
1245             yyDSTmode = DSToff;
1246         }
1247     break;
1248
1249   case 14:
1250 #line 209 "parsedate.y"
1251     {
1252             yyval.Number = yyvsp[0].Number;
1253             yyDSTmode = DSTon;
1254         }
1255     break;
1256
1257   case 15:
1258 #line 213 "parsedate.y"
1259     {
1260             /* Only allow "GMT+300" and "GMT-0800" */
1261             if (yyvsp[-1].Number != 0) {
1262                 YYABORT;
1263             }
1264             yyval.Number = yyvsp[0].Number;
1265             yyDSTmode = DSToff;
1266         }
1267     break;
1268
1269   case 16:
1270 #line 221 "parsedate.y"
1271     {
1272             yyval.Number = yyvsp[0].Number;
1273             yyDSTmode = DSToff;
1274         }
1275     break;
1276
1277   case 17:
1278 #line 227 "parsedate.y"
1279     {
1280             int         i;
1281
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) {
1287                     YYABORT;
1288                 }
1289                 yyval.Number = (yyvsp[0].Number / 100) * 60 + i;
1290             }
1291             else {
1292                 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1293                     YYABORT;
1294                 }
1295                 yyval.Number = -((yyvsp[0].Number / 100) * 60 + i);
1296             }
1297         }
1298     break;
1299
1300   case 18:
1301 #line 248 "parsedate.y"
1302     {
1303             yyMonth = yyvsp[-2].Number;
1304             yyDay = yyvsp[0].Number;
1305         }
1306     break;
1307
1308   case 19:
1309 #line 252 "parsedate.y"
1310     {
1311             if (yyvsp[-4].Number > 100) {
1312                 yyYear = yyvsp[-4].Number;
1313                 yyMonth = yyvsp[-2].Number;
1314                 yyDay = yyvsp[0].Number;
1315             }
1316             else {
1317                 yyMonth = yyvsp[-4].Number;
1318                 yyDay = yyvsp[-2].Number;
1319                 yyYear = yyvsp[0].Number;
1320             }
1321         }
1322     break;
1323
1324   case 20:
1325 #line 264 "parsedate.y"
1326     {
1327             yyMonth = yyvsp[-1].Number;
1328             yyDay = yyvsp[0].Number;
1329         }
1330     break;
1331
1332   case 21:
1333 #line 268 "parsedate.y"
1334     {
1335             yyMonth = yyvsp[-3].Number;
1336             yyDay = yyvsp[-2].Number;
1337             yyYear = yyvsp[0].Number;
1338         }
1339     break;
1340
1341   case 22:
1342 #line 273 "parsedate.y"
1343     {
1344             yyDay = yyvsp[-1].Number;
1345             yyMonth = yyvsp[0].Number;
1346         }
1347     break;
1348
1349   case 23:
1350 #line 277 "parsedate.y"
1351     {
1352             yyDay = yyvsp[-2].Number;
1353             yyMonth = yyvsp[-1].Number;
1354             yyYear = yyvsp[0].Number;
1355         }
1356     break;
1357
1358   case 24:
1359 #line 282 "parsedate.y"
1360     {
1361             yyDay = yyvsp[-2].Number;
1362             yyMonth = yyvsp[-1].Number;
1363             yyYear = yyvsp[0].Number;
1364         }
1365     break;
1366
1367   case 25:
1368 #line 289 "parsedate.y"
1369     {
1370             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1371         }
1372     break;
1373
1374   case 26:
1375 #line 292 "parsedate.y"
1376     {
1377             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1378         }
1379     break;
1380
1381   case 27:
1382 #line 295 "parsedate.y"
1383     {
1384             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1385         }
1386     break;
1387
1388   case 28:
1389 #line 298 "parsedate.y"
1390     {
1391             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1392         }
1393     break;
1394
1395   case 29:
1396 #line 303 "parsedate.y"
1397     {
1398             yyval.Meridian = MER24;
1399         }
1400     break;
1401
1402   case 30:
1403 #line 306 "parsedate.y"
1404     {
1405             yyval.Meridian = yyvsp[0].Meridian;
1406         }
1407     break;
1408
1409
1410     }
1411
1412 /* Line 1000 of yacc.c.  */
1413 #line 1414 "y.tab.c"
1414 \f
1415   yyvsp -= yylen;
1416   yyssp -= yylen;
1417
1418
1419   YY_STACK_PRINT (yyss, yyssp);
1420
1421   *++yyvsp = yyval;
1422
1423
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.  */
1427
1428   yyn = yyr1[yyn];
1429
1430   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1431   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1432     yystate = yytable[yystate];
1433   else
1434     yystate = yydefgoto[yyn - YYNTOKENS];
1435
1436   goto yynewstate;
1437
1438
1439 /*------------------------------------.
1440 | yyerrlab -- here on detecting error |
1441 `------------------------------------*/
1442 yyerrlab:
1443   /* If not already recovering from an error, report this error.  */
1444   if (!yyerrstatus)
1445     {
1446       ++yynerrs;
1447 #if YYERROR_VERBOSE
1448       yyn = yypact[yystate];
1449
1450       if (YYPACT_NINF < yyn && yyn < YYLAST)
1451         {
1452           YYSIZE_T yysize = 0;
1453           int yytype = YYTRANSLATE (yychar);
1454           const char* yyprefix;
1455           char *yymsg;
1456           int yyx;
1457
1458           /* Start YYX at -YYN if negative to avoid negative indexes in
1459              YYCHECK.  */
1460           int yyxbegin = yyn < 0 ? -yyn : 0;
1461
1462           /* Stay within bounds of both yycheck and yytname.  */
1463           int yychecklim = YYLAST - yyn;
1464           int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1465           int yycount = 0;
1466
1467           yyprefix = ", expecting ";
1468           for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1469             if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1470               {
1471                 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1472                 yycount += 1;
1473                 if (yycount == 5)
1474                   {
1475                     yysize = 0;
1476                     break;
1477                   }
1478               }
1479           yysize += (sizeof ("syntax error, unexpected ")
1480                      + yystrlen (yytname[yytype]));
1481           yymsg = (char *) YYSTACK_ALLOC (yysize);
1482           if (yymsg != 0)
1483             {
1484               char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1485               yyp = yystpcpy (yyp, yytname[yytype]);
1486
1487               if (yycount < 5)
1488                 {
1489                   yyprefix = ", expecting ";
1490                   for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1491                     if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1492                       {
1493                         yyp = yystpcpy (yyp, yyprefix);
1494                         yyp = yystpcpy (yyp, yytname[yyx]);
1495                         yyprefix = " or ";
1496                       }
1497                 }
1498               yyerror (yymsg);
1499               YYSTACK_FREE (yymsg);
1500             }
1501           else
1502             yyerror ("syntax error; also virtual memory exhausted");
1503         }
1504       else
1505 #endif /* YYERROR_VERBOSE */
1506         yyerror ("syntax error");
1507     }
1508
1509
1510
1511   if (yyerrstatus == 3)
1512     {
1513       /* If just tried and failed to reuse lookahead token after an
1514          error, discard it.  */
1515
1516       if (yychar <= YYEOF)
1517         {
1518           /* If at end of input, pop the error token,
1519              then the rest of the stack, then return failure.  */
1520           if (yychar == YYEOF)
1521              for (;;)
1522                {
1523                  YYPOPSTACK;
1524                  if (yyssp == yyss)
1525                    YYABORT;
1526                  YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1527                  yydestruct (yystos[*yyssp], yyvsp);
1528                }
1529         }
1530       else
1531         {
1532           YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1533           yydestruct (yytoken, &yylval);
1534           yychar = YYEMPTY;
1535
1536         }
1537     }
1538
1539   /* Else will try to reuse lookahead token after shifting the error
1540      token.  */
1541   goto yyerrlab1;
1542
1543
1544 /*---------------------------------------------------.
1545 | yyerrorlab -- error raised explicitly by YYERROR.  |
1546 `---------------------------------------------------*/
1547 yyerrorlab:
1548
1549 #ifdef __GNUC__
1550   /* Pacify GCC when the user code never invokes YYERROR and the label
1551      yyerrorlab therefore never appears in user code.  */
1552   if (0)
1553      goto yyerrorlab;
1554 #endif
1555
1556   yyvsp -= yylen;
1557   yyssp -= yylen;
1558   yystate = *yyssp;
1559   goto yyerrlab1;
1560
1561
1562 /*-------------------------------------------------------------.
1563 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
1564 `-------------------------------------------------------------*/
1565 yyerrlab1:
1566   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
1567
1568   for (;;)
1569     {
1570       yyn = yypact[yystate];
1571       if (yyn != YYPACT_NINF)
1572         {
1573           yyn += YYTERROR;
1574           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1575             {
1576               yyn = yytable[yyn];
1577               if (0 < yyn)
1578                 break;
1579             }
1580         }
1581
1582       /* Pop the current state because it cannot handle the error token.  */
1583       if (yyssp == yyss)
1584         YYABORT;
1585
1586       YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1587       yydestruct (yystos[yystate], yyvsp);
1588       YYPOPSTACK;
1589       yystate = *yyssp;
1590       YY_STACK_PRINT (yyss, yyssp);
1591     }
1592
1593   if (yyn == YYFINAL)
1594     YYACCEPT;
1595
1596   YYDPRINTF ((stderr, "Shifting error token, "));
1597
1598   *++yyvsp = yylval;
1599
1600
1601   yystate = yyn;
1602   goto yynewstate;
1603
1604
1605 /*-------------------------------------.
1606 | yyacceptlab -- YYACCEPT comes here.  |
1607 `-------------------------------------*/
1608 yyacceptlab:
1609   yyresult = 0;
1610   goto yyreturn;
1611
1612 /*-----------------------------------.
1613 | yyabortlab -- YYABORT comes here.  |
1614 `-----------------------------------*/
1615 yyabortlab:
1616   yyresult = 1;
1617   goto yyreturn;
1618
1619 #ifndef yyoverflow
1620 /*----------------------------------------------.
1621 | yyoverflowlab -- parser overflow comes here.  |
1622 `----------------------------------------------*/
1623 yyoverflowlab:
1624   yyerror ("parser stack overflow");
1625   yyresult = 2;
1626   /* Fall through.  */
1627 #endif
1628
1629 yyreturn:
1630 #ifndef yyoverflow
1631   if (yyss != yyssa)
1632     YYSTACK_FREE (yyss);
1633 #endif
1634   return yyresult;
1635 }
1636
1637
1638 #line 311 "parsedate.y"
1639
1640
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 },
1663 };
1664
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 },
1676 };
1677
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 */
1728
1729     /* For completeness we include the following entries. */
1730 #if 0
1731
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 */
1759
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 */
1788 #endif /* 0 */
1789 };
1790
1791
1792 /* ARGSUSED */
1793 static void
1794 date_error(char *s)
1795 {
1796     /* NOTREACHED */
1797 }
1798
1799
1800 static time_t
1801 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1802 {
1803     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
1804         return -1;
1805     if (Meridian == MER24) {
1806         if (Hours < 0 || Hours > 23)
1807             return -1;
1808     }
1809     else {
1810         if (Hours < 1 || Hours > 12)
1811             return -1;
1812         if (Hours == 12)
1813             Hours = 0;
1814         if (Meridian == MERpm)
1815             Hours += 12;
1816     }
1817     return (Hours * 60L + Minutes) * 60L + Seconds;
1818 }
1819
1820
1821 static time_t
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)
1825 {
1826     static int  DaysNormal[13] = {
1827         0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1828     };
1829     static int  DaysLeap[13] = {
1830         0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1831     };
1832     static int  LeapYears[] = {
1833         1972, 1976, 1980, 1984, 1988, 1992, 1996,
1834         2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
1835     };
1836     register int        *yp;
1837     register int        *mp;
1838     register time_t     Julian;
1839     register int        i;
1840     time_t              tod;
1841
1842     if (Year < 0)
1843         Year = -Year;
1844     if (Year < 100)
1845         Year += 1900;
1846     if (Year < EPOCH)
1847         Year += 100;
1848     for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
1849         if (Year == *yp) {
1850             mp = DaysLeap;
1851             break;
1852         }
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])
1857         return -1;
1858
1859     Julian = Day - 1 + (Year - EPOCH) * 365;
1860     for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
1861         if (Year <= *yp)
1862             break;
1863     for (i = 1; i < Month; i++)
1864         Julian += *++mp;
1865     Julian *= SECSPERDAY;
1866     Julian += yyTimezone * 60L;
1867     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1868         return -1;
1869     Julian += tod;
1870     tod = Julian;
1871     if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
1872         Julian -= DST_OFFSET * 60L * 60L;
1873     return Julian;
1874 }
1875
1876
1877 static time_t
1878 DSTcorrect(time_t Start, time_t Future)
1879 {
1880     time_t      StartDay;
1881     time_t      FutureDay;
1882
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;
1886 }
1887
1888
1889 static time_t
1890 RelativeMonth(time_t Start, time_t RelMonth)
1891 {
1892     struct tm   *tm;
1893     time_t      Month;
1894     time_t      Year;
1895
1896     tm = localtime(&Start);
1897     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
1898     Year = Month / 12;
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,
1903                 MER24, DSTmaybe));
1904 }
1905
1906
1907 static int
1908 LookupWord(char *buff, register int length)
1909 {
1910     register char       *p;
1911     register char       *q;
1912     register TABLE      *tp;
1913     register int        c;
1914
1915     p = buff;
1916     c = p[0];
1917
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++) {
1921             q = tp->name;
1922             if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
1923                 yylval.Number = tp->value;
1924                 return tp->type;
1925             }
1926         }
1927     else
1928         for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
1929             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1930                 yylval.Number = tp->value;
1931                 return tp->type;
1932             }
1933
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;
1939             return tp->type;
1940         }
1941
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;
1946             return tp->type;
1947         }
1948
1949     /* Strip off any plural and try the units table again. */
1950     if (--length > 0 && p[length] == 's') {
1951         p[length] = '\0';
1952         for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1953             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1954                 p[length] = 's';
1955                 yylval.Number = tp->value;
1956                 return tp->type;
1957             }
1958         p[length] = 's';
1959     }
1960     length++;
1961
1962     /* Drop out any periods. */
1963     for (p = buff, q = (char*)buff; *q; q++)
1964         if (*q != '.')
1965             *p++ = *q;
1966     *p = '\0';
1967
1968     /* Try the meridians. */
1969     if (buff[1] == 'm' && buff[2] == '\0') {
1970         if (buff[0] == 'a') {
1971             yylval.Meridian = MERam;
1972             return tMERIDIAN;
1973         }
1974         if (buff[0] == 'p') {
1975             yylval.Meridian = MERpm;
1976             return tMERIDIAN;
1977         }
1978     }
1979
1980     /* If we saw any periods, try the timezones again. */
1981     if (p - buff != length) {
1982         c = buff[0];
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;
1987                 return tp->type;
1988             }
1989     }
1990
1991     /* Unknown word -- assume GMT timezone. */
1992     yylval.Number = 0;
1993     return tZONE;
1994 }
1995
1996
1997 int
1998 date_lex(void)
1999 {
2000     register char       c;
2001     register char       *p;
2002     char                buff[20];
2003     register int        sign;
2004     register int        i;
2005     register int        nesting;
2006
2007     for ( ; ; ) {
2008         /* Get first character after the whitespace. */
2009         for ( ; ; ) {
2010             while (isspace(*yyInput))
2011                 yyInput++;
2012             c = *yyInput;
2013
2014             /* Ignore RFC 822 comments, typically time zone names. */
2015             if (c != LPAREN)
2016                 break;
2017             for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
2018                 if (c == LPAREN)
2019                     nesting++;
2020                 else if (!IS7BIT(c) || c == '\0' || c == '\r'
2021                      || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
2022                     /* Lexical error: bad comment. */
2023                     return '?';
2024             yyInput++;
2025         }
2026
2027         /* A number? */
2028         if (isdigit(c) || c == '-' || c == '+') {
2029             if (c == '-' || c == '+') {
2030                 sign = c == '-' ? -1 : 1;
2031                 yyInput++;
2032                 if (!isdigit(*yyInput))
2033                     /* Skip the plus or minus sign. */
2034                     continue;
2035             }
2036             else
2037                 sign = 0;
2038             for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
2039                 i = 10 * i + c - '0';
2040             yyInput--;
2041             yylval.Number = sign < 0 ? -i : i;
2042             return sign ? tSNUMBER : tUNUMBER;
2043         }
2044
2045         /* A word? */
2046         if (isalpha(c)) {
2047             for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
2048                 if (p < &buff[sizeof buff - 1])
2049                     *p++ = isupper(c) ? tolower(c) : c;
2050             *p = '\0';
2051             yyInput--;
2052             return LookupWord(buff, p - buff);
2053         }
2054
2055         return *yyInput++;
2056     }
2057 }
2058
2059
2060 time_t
2061 parsedate(char *p)
2062 {
2063     extern int          date_parse(void);
2064     time_t              Start;
2065
2066     yyInput = p;
2067
2068     yyYear = 0;
2069     yyMonth = 0;
2070     yyDay = 0;
2071     yyTimezone = 0;
2072     yyDSTmode = DSTmaybe;
2073     yyHour = 0;
2074     yyMinutes = 0;
2075     yySeconds = 0;
2076     yyMeridian = MER24;
2077     yyRelSeconds = 0;
2078     yyRelMonth = 0;
2079     yyHaveDate = 0;
2080     yyHaveRel = 0;
2081     yyHaveTime = 0;
2082
2083     if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
2084         return -1;
2085
2086     if (yyHaveDate || yyHaveTime) {
2087         Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2088                     yyMeridian, yyDSTmode);
2089         if (Start < 0)
2090             return -1;
2091     }
2092     else
2093         return -1;
2094
2095     Start += yyRelSeconds;
2096     if (yyRelMonth)
2097         Start += RelativeMonth(Start, yyRelMonth);
2098
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;
2102 }
2103
2104
2105 #ifdef TEST
2106
2107 #if YYDEBUG
2108 extern int      yydebug;
2109 #endif /* YYDEBUG */
2110
2111 /* ARGSUSED */
2112 int
2113 main(int ac, char *av[])
2114 {
2115     char        buff[128];
2116     time_t      d;
2117
2118 #if YYDEBUG
2119     yydebug = 1;
2120 #endif /* YYDEBUG */
2121
2122     (void)printf("Enter date, or blank line to exit.\n\t> ");
2123     for ( ; ; ) {
2124         (void)printf("\t> ");
2125         (void)fflush(stdout);
2126         if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2127             break;
2128 #if YYDEBUG
2129         if (strcmp(buff, "yydebug") == 0) {
2130             yydebug = !yydebug;
2131             printf("yydebug = %s\n", yydebug ? "on" : "off");
2132             continue;
2133         }
2134 #endif /* YYDEBUG */
2135         d = parsedate(buff, (TIMEINFO *)NULL);
2136         if (d == -1)
2137             (void)printf("Bad format - couldn't convert.\n");
2138         else
2139             (void)printf("%s", ctime(&d));
2140     }
2141
2142     exit(0);
2143     /* NOTREACHED */
2144 }
2145 #endif /* TEST */
2146
2147