b7845b2fe1215ed07925b8544486205e5f214aee
[citadel.git] / citadel / parsedate.c
1 /* A Bison parser, made by GNU Bison 1.875.  */
2
3 /* Skeleton parser for Yacc-like parsing with Bison,
4    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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 226 "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 238 "y.tab.c"
239
240 #if ! defined (yyoverflow) || YYERROR_VERBOSE
241
242 /* The parser invokes alloca or malloc; define the necessary symbols.  */
243
244 # if YYSTACK_USE_ALLOCA
245 #  define YYSTACK_ALLOC alloca
246 # else
247 #  ifndef YYSTACK_USE_ALLOCA
248 #   if defined (alloca) || defined (_ALLOCA_H)
249 #    define YYSTACK_ALLOC alloca
250 #   else
251 #    ifdef __GNUC__
252 #     define YYSTACK_ALLOC __builtin_alloca
253 #    endif
254 #   endif
255 #  endif
256 # endif
257
258 # ifdef YYSTACK_ALLOC
259    /* Pacify GCC's `empty if-body' warning. */
260 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
261 # else
262 #  if defined (__STDC__) || defined (__cplusplus)
263 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
264 #   define YYSIZE_T size_t
265 #  endif
266 #  define YYSTACK_ALLOC malloc
267 #  define YYSTACK_FREE free
268 # endif
269 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
270
271
272 #if (! defined (yyoverflow) \
273      && (! defined (__cplusplus) \
274          || (YYSTYPE_IS_TRIVIAL)))
275
276 /* A type that is properly aligned for any stack member.  */
277 union yyalloc
278 {
279   short yyss;
280   YYSTYPE yyvs;
281   };
282
283 /* The size of the maximum gap between one aligned stack and the next.  */
284 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
285
286 /* The size of an array large to enough to hold all stacks, each with
287    N elements.  */
288 # define YYSTACK_BYTES(N) \
289      ((N) * (sizeof (short) + sizeof (YYSTYPE))                         \
290       + YYSTACK_GAP_MAXIMUM)
291
292 /* Copy COUNT objects from FROM to TO.  The source and destination do
293    not overlap.  */
294 # ifndef YYCOPY
295 #  if 1 < __GNUC__
296 #   define YYCOPY(To, From, Count) \
297       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
298 #  else
299 #   define YYCOPY(To, From, Count)              \
300       do                                        \
301         {                                       \
302           register YYSIZE_T yyi;                \
303           for (yyi = 0; yyi < (Count); yyi++)   \
304             (To)[yyi] = (From)[yyi];            \
305         }                                       \
306       while (0)
307 #  endif
308 # endif
309
310 /* Relocate STACK from its old location to the new one.  The
311    local variables YYSIZE and YYSTACKSIZE give the old and new number of
312    elements in the stack, and YYPTR gives the new location of the
313    stack.  Advance YYPTR to a properly aligned location for the next
314    stack.  */
315 # define YYSTACK_RELOCATE(Stack)                                        \
316     do                                                                  \
317       {                                                                 \
318         YYSIZE_T yynewbytes;                                            \
319         YYCOPY (&yyptr->Stack, Stack, yysize);                          \
320         Stack = &yyptr->Stack;                                          \
321         yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
322         yyptr += yynewbytes / sizeof (*yyptr);                          \
323       }                                                                 \
324     while (0)
325
326 #endif
327
328 #if defined (__STDC__) || defined (__cplusplus)
329    typedef signed char yysigned_char;
330 #else
331    typedef short yysigned_char;
332 #endif
333
334 /* YYFINAL -- State number of the termination state. */
335 #define YYFINAL  2
336 /* YYLAST -- Last index in YYTABLE.  */
337 #define YYLAST   40
338
339 /* YYNTOKENS -- Number of terminals. */
340 #define YYNTOKENS  15
341 /* YYNNTS -- Number of nonterminals. */
342 #define YYNNTS  9
343 /* YYNRULES -- Number of rules. */
344 #define YYNRULES  30
345 /* YYNRULES -- Number of states. */
346 #define YYNSTATES  44
347
348 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
349 #define YYUNDEFTOK  2
350 #define YYMAXUTOK   266
351
352 #define YYTRANSLATE(YYX)                                                \
353   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
354
355 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
356 static const unsigned char yytranslate[] =
357 {
358        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
359        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
360        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
361        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
362        2,     2,     2,     2,    14,     2,     2,    13,     2,     2,
363        2,     2,     2,     2,     2,     2,     2,     2,    12,     2,
364        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
365        2,     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,     2,     2,     2,     2,     2,     2,
370        2,     2,     2,     2,     2,     2,     2,     2,     2,     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,     1,     2,     3,     4,
384        5,     6,     7,     8,     9,    10,    11
385 };
386
387 #if YYDEBUG
388 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
389    YYRHS.  */
390 static const unsigned char yyprhs[] =
391 {
392        0,     0,     3,     4,     7,     9,    12,    14,    16,    19,
393       24,    29,    36,    43,    45,    47,    50,    52,    54,    58,
394       64,    67,    72,    75,    79,    85,    88,    91,    94,    97,
395       98
396 };
397
398 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
399 static const yysigned_char yyrhs[] =
400 {
401       16,     0,    -1,    -1,    16,    17,    -1,    18,    -1,    18,
402       19,    -1,    21,    -1,    22,    -1,    10,    23,    -1,    10,
403       12,    10,    23,    -1,    10,    12,    10,    20,    -1,    10,
404       12,    10,    12,    10,    23,    -1,    10,    12,    10,    12,
405       10,    20,    -1,    11,    -1,     4,    -1,    11,    20,    -1,
406       20,    -1,     9,    -1,    10,    13,    10,    -1,    10,    13,
407       10,    13,    10,    -1,     6,    10,    -1,     6,    10,    14,
408       10,    -1,    10,     6,    -1,    10,     6,    10,    -1,     3,
409       14,    10,     6,    10,    -1,     9,     8,    -1,    10,     8,
410       -1,     9,     7,    -1,    10,     7,    -1,    -1,     5,    -1
411 };
412
413 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
414 static const unsigned short yyrline[] =
415 {
416        0,   139,   139,   140,   143,   152,   156,   159,   164,   176,
417      182,   189,   195,   205,   209,   213,   221,   227,   248,   252,
418      264,   268,   273,   277,   282,   289,   292,   295,   298,   303,
419      306
420 };
421 #endif
422
423 #if YYDEBUG || YYERROR_VERBOSE
424 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
425    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
426 static const char *const yytname[] =
427 {
428   "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN", "tMONTH", 
429   "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE", "':'", 
430   "'/'", "','", "$accept", "spec", "item", "time", "zone", "numzone", 
431   "date", "rel", "o_merid", 0
432 };
433 #endif
434
435 # ifdef YYPRINT
436 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
437    token YYLEX-NUM.  */
438 static const unsigned short yytoknum[] =
439 {
440        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
441      265,   266,    58,    47,    44
442 };
443 # endif
444
445 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
446 static const unsigned char yyr1[] =
447 {
448        0,    15,    16,    16,    17,    17,    17,    17,    18,    18,
449       18,    18,    18,    19,    19,    19,    19,    20,    21,    21,
450       21,    21,    21,    21,    21,    22,    22,    22,    22,    23,
451       23
452 };
453
454 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
455 static const unsigned char yyr2[] =
456 {
457        0,     2,     0,     2,     1,     2,     1,     1,     2,     4,
458        4,     6,     6,     1,     1,     2,     1,     1,     3,     5,
459        2,     4,     2,     3,     5,     2,     2,     2,     2,     0,
460        1
461 };
462
463 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
464    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
465    means the default is an error.  */
466 static const unsigned char yydefact[] =
467 {
468        2,     0,     1,     0,     0,     0,    29,     3,     4,     6,
469        7,     0,    20,    27,    25,    30,    22,    28,    26,     0,
470        0,     8,    14,    17,    13,     5,    16,     0,     0,    23,
471       29,    18,    15,     0,    21,     0,    10,     9,     0,    24,
472       29,    19,    12,    11
473 };
474
475 /* YYDEFGOTO[NTERM-NUM]. */
476 static const yysigned_char yydefgoto[] =
477 {
478       -1,     1,     7,     8,    25,    26,     9,    10,    21
479 };
480
481 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
482    STATE-NUM.  */
483 #define YYPACT_NINF -29
484 static const yysigned_char yypact[] =
485 {
486      -29,     1,   -29,   -11,    11,    20,    12,   -29,     4,   -29,
487      -29,    13,    16,   -29,   -29,   -29,    21,   -29,   -29,    22,
488       23,   -29,   -29,   -29,     5,   -29,   -29,    28,    25,   -29,
489       17,    24,   -29,    26,   -29,    29,   -29,   -29,    30,   -29,
490        0,   -29,   -29,   -29
491 };
492
493 /* YYPGOTO[NTERM-NUM].  */
494 static const yysigned_char yypgoto[] =
495 {
496      -29,   -29,   -29,   -29,   -29,   -24,   -29,   -29,   -28
497 };
498
499 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
500    positive, shift that token.  If negative, reduce the rule which
501    number is the opposite.  If zero, do what YYDEFACT says.
502    If YYTABLE_NINF, syntax error.  */
503 #define YYTABLE_NINF -1
504 static const unsigned char yytable[] =
505 {
506       32,     2,    37,    11,     3,    15,    36,     4,    22,    23,
507        5,     6,    43,    23,    23,    24,    42,    15,    16,    17,
508       18,    12,    15,    27,    19,    20,    23,    13,    14,    35,
509       28,    29,    30,    31,    33,    34,    39,    38,     0,    40,
510       41
511 };
512
513 static const yysigned_char yycheck[] =
514 {
515       24,     0,    30,    14,     3,     5,    30,     6,     4,     9,
516        9,    10,    40,     9,     9,    11,    40,     5,     6,     7,
517        8,    10,     5,    10,    12,    13,     9,     7,     8,    12,
518       14,    10,    10,    10,     6,    10,    10,    13,    -1,    10,
519       10
520 };
521
522 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
523    symbol of state STATE-NUM.  */
524 static const unsigned char yystos[] =
525 {
526        0,    16,     0,     3,     6,     9,    10,    17,    18,    21,
527       22,    14,    10,     7,     8,     5,     6,     7,     8,    12,
528       13,    23,     4,     9,    11,    19,    20,    10,    14,    10,
529       10,    10,    20,     6,    10,    12,    20,    23,    13,    10,
530       10,    10,    20,    23
531 };
532
533 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
534 # define YYSIZE_T __SIZE_TYPE__
535 #endif
536 #if ! defined (YYSIZE_T) && defined (size_t)
537 # define YYSIZE_T size_t
538 #endif
539 #if ! defined (YYSIZE_T)
540 # if defined (__STDC__) || defined (__cplusplus)
541 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
542 #  define YYSIZE_T size_t
543 # endif
544 #endif
545 #if ! defined (YYSIZE_T)
546 # define YYSIZE_T unsigned int
547 #endif
548
549 #define yyerrok         (yyerrstatus = 0)
550 #define yyclearin       (yychar = YYEMPTY)
551 #define YYEMPTY         (-2)
552 #define YYEOF           0
553
554 #define YYACCEPT        goto yyacceptlab
555 #define YYABORT         goto yyabortlab
556 #define YYERROR         goto yyerrlab1
557
558
559 /* Like YYERROR except do call yyerror.  This remains here temporarily
560    to ease the transition to the new meaning of YYERROR, for GCC.
561    Once GCC version 2 has supplanted version 1, this can go.  */
562
563 #define YYFAIL          goto yyerrlab
564
565 #define YYRECOVERING()  (!!yyerrstatus)
566
567 #define YYBACKUP(Token, Value)                                  \
568 do                                                              \
569   if (yychar == YYEMPTY && yylen == 1)                          \
570     {                                                           \
571       yychar = (Token);                                         \
572       yylval = (Value);                                         \
573       yytoken = YYTRANSLATE (yychar);                           \
574       YYPOPSTACK;                                               \
575       goto yybackup;                                            \
576     }                                                           \
577   else                                                          \
578     {                                                           \
579       yyerror ("syntax error: cannot back up");\
580       YYERROR;                                                  \
581     }                                                           \
582 while (0)
583
584 #define YYTERROR        1
585 #define YYERRCODE       256
586
587 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
588    are run).  */
589
590 #ifndef YYLLOC_DEFAULT
591 # define YYLLOC_DEFAULT(Current, Rhs, N)         \
592   Current.first_line   = Rhs[1].first_line;      \
593   Current.first_column = Rhs[1].first_column;    \
594   Current.last_line    = Rhs[N].last_line;       \
595   Current.last_column  = Rhs[N].last_column;
596 #endif
597
598 /* YYLEX -- calling `yylex' with the right arguments.  */
599
600 #ifdef YYLEX_PARAM
601 # define YYLEX yylex (YYLEX_PARAM)
602 #else
603 # define YYLEX yylex ()
604 #endif
605
606 /* Enable debugging if requested.  */
607 #if YYDEBUG
608
609 # ifndef YYFPRINTF
610 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
611 #  define YYFPRINTF fprintf
612 # endif
613
614 # define YYDPRINTF(Args)                        \
615 do {                                            \
616   if (yydebug)                                  \
617     YYFPRINTF Args;                             \
618 } while (0)
619
620 # define YYDSYMPRINT(Args)                      \
621 do {                                            \
622   if (yydebug)                                  \
623     yysymprint Args;                            \
624 } while (0)
625
626 # define YYDSYMPRINTF(Title, Token, Value, Location)            \
627 do {                                                            \
628   if (yydebug)                                                  \
629     {                                                           \
630       YYFPRINTF (stderr, "%s ", Title);                         \
631       yysymprint (stderr,                                       \
632                   Token, Value);        \
633       YYFPRINTF (stderr, "\n");                                 \
634     }                                                           \
635 } while (0)
636
637 /*------------------------------------------------------------------.
638 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
639 | TOP (cinluded).                                                   |
640 `------------------------------------------------------------------*/
641
642 #if defined (__STDC__) || defined (__cplusplus)
643 static void
644 yy_stack_print (short *bottom, short *top)
645 #else
646 static void
647 yy_stack_print (bottom, top)
648     short *bottom;
649     short *top;
650 #endif
651 {
652   YYFPRINTF (stderr, "Stack now");
653   for (/* Nothing. */; bottom <= top; ++bottom)
654     YYFPRINTF (stderr, " %d", *bottom);
655   YYFPRINTF (stderr, "\n");
656 }
657
658 # define YY_STACK_PRINT(Bottom, Top)                            \
659 do {                                                            \
660   if (yydebug)                                                  \
661     yy_stack_print ((Bottom), (Top));                           \
662 } while (0)
663
664
665 /*------------------------------------------------.
666 | Report that the YYRULE is going to be reduced.  |
667 `------------------------------------------------*/
668
669 #if defined (__STDC__) || defined (__cplusplus)
670 static void
671 yy_reduce_print (int yyrule)
672 #else
673 static void
674 yy_reduce_print (yyrule)
675     int yyrule;
676 #endif
677 {
678   int yyi;
679   unsigned int yylineno = yyrline[yyrule];
680   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
681              yyrule - 1, yylineno);
682   /* Print the symbols being reduced, and their result.  */
683   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
684     YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
685   YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
686 }
687
688 # define YY_REDUCE_PRINT(Rule)          \
689 do {                                    \
690   if (yydebug)                          \
691     yy_reduce_print (Rule);             \
692 } while (0)
693
694 /* Nonzero means print parse trace.  It is left uninitialized so that
695    multiple parsers can coexist.  */
696 int yydebug;
697 #else /* !YYDEBUG */
698 # define YYDPRINTF(Args)
699 # define YYDSYMPRINT(Args)
700 # define YYDSYMPRINTF(Title, Token, Value, Location)
701 # define YY_STACK_PRINT(Bottom, Top)
702 # define YY_REDUCE_PRINT(Rule)
703 #endif /* !YYDEBUG */
704
705
706 /* YYINITDEPTH -- initial size of the parser's stacks.  */
707 #ifndef YYINITDEPTH
708 # define YYINITDEPTH 200
709 #endif
710
711 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
712    if the built-in stack extension method is used).
713
714    Do not make this value too large; the results are undefined if
715    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
716    evaluated with infinite-precision integer arithmetic.  */
717
718 #if YYMAXDEPTH == 0
719 # undef YYMAXDEPTH
720 #endif
721
722 #ifndef YYMAXDEPTH
723 # define YYMAXDEPTH 10000
724 #endif
725
726 \f
727
728 #if YYERROR_VERBOSE
729
730 # ifndef yystrlen
731 #  if defined (__GLIBC__) && defined (_STRING_H)
732 #   define yystrlen strlen
733 #  else
734 /* Return the length of YYSTR.  */
735 static YYSIZE_T
736 #   if defined (__STDC__) || defined (__cplusplus)
737 yystrlen (const char *yystr)
738 #   else
739 yystrlen (yystr)
740      const char *yystr;
741 #   endif
742 {
743   register const char *yys = yystr;
744
745   while (*yys++ != '\0')
746     continue;
747
748   return yys - yystr - 1;
749 }
750 #  endif
751 # endif
752
753 # ifndef yystpcpy
754 #  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
755 #   define yystpcpy stpcpy
756 #  else
757 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
758    YYDEST.  */
759 static char *
760 #   if defined (__STDC__) || defined (__cplusplus)
761 yystpcpy (char *yydest, const char *yysrc)
762 #   else
763 yystpcpy (yydest, yysrc)
764      char *yydest;
765      const char *yysrc;
766 #   endif
767 {
768   register char *yyd = yydest;
769   register const char *yys = yysrc;
770
771   while ((*yyd++ = *yys++) != '\0')
772     continue;
773
774   return yyd - 1;
775 }
776 #  endif
777 # endif
778
779 #endif /* !YYERROR_VERBOSE */
780
781 \f
782
783 #if YYDEBUG
784 /*--------------------------------.
785 | Print this symbol on YYOUTPUT.  |
786 `--------------------------------*/
787
788 #if defined (__STDC__) || defined (__cplusplus)
789 static void
790 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
791 #else
792 static void
793 yysymprint (yyoutput, yytype, yyvaluep)
794     FILE *yyoutput;
795     int yytype;
796     YYSTYPE *yyvaluep;
797 #endif
798 {
799   /* Pacify ``unused variable'' warnings.  */
800   (void) yyvaluep;
801
802   if (yytype < YYNTOKENS)
803     {
804       YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
805 # ifdef YYPRINT
806       YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
807 # endif
808     }
809   else
810     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
811
812   switch (yytype)
813     {
814       default:
815         break;
816     }
817   YYFPRINTF (yyoutput, ")");
818 }
819
820 #endif /* ! YYDEBUG */
821 /*-----------------------------------------------.
822 | Release the memory associated to this symbol.  |
823 `-----------------------------------------------*/
824
825 #if defined (__STDC__) || defined (__cplusplus)
826 static void
827 yydestruct (int yytype, YYSTYPE *yyvaluep)
828 #else
829 static void
830 yydestruct (yytype, yyvaluep)
831     int yytype;
832     YYSTYPE *yyvaluep;
833 #endif
834 {
835   /* Pacify ``unused variable'' warnings.  */
836   (void) yyvaluep;
837
838   switch (yytype)
839     {
840
841       default:
842         break;
843     }
844 }
845 \f
846
847 /* Prevent warnings from -Wmissing-prototypes.  */
848
849 #ifdef YYPARSE_PARAM
850 # if defined (__STDC__) || defined (__cplusplus)
851 int yyparse (void *YYPARSE_PARAM);
852 # else
853 int yyparse ();
854 # endif
855 #else /* ! YYPARSE_PARAM */
856 #if defined (__STDC__) || defined (__cplusplus)
857 int yyparse (void);
858 #else
859 int yyparse ();
860 #endif
861 #endif /* ! YYPARSE_PARAM */
862
863
864
865 /* The lookahead symbol.  */
866 int yychar;
867
868 /* The semantic value of the lookahead symbol.  */
869 YYSTYPE yylval;
870
871 /* Number of syntax errors so far.  */
872 int yynerrs;
873
874
875
876 /*----------.
877 | yyparse.  |
878 `----------*/
879
880 #ifdef YYPARSE_PARAM
881 # if defined (__STDC__) || defined (__cplusplus)
882 int yyparse (void *YYPARSE_PARAM)
883 # else
884 int yyparse (YYPARSE_PARAM)
885   void *YYPARSE_PARAM;
886 # endif
887 #else /* ! YYPARSE_PARAM */
888 #if defined (__STDC__) || defined (__cplusplus)
889 int
890 yyparse (void)
891 #else
892 int
893 yyparse ()
894
895 #endif
896 #endif
897 {
898   
899   register int yystate;
900   register int yyn;
901   int yyresult;
902   /* Number of tokens to shift before error messages enabled.  */
903   int yyerrstatus;
904   /* Lookahead token as an internal (translated) token number.  */
905   int yytoken = 0;
906
907   /* Three stacks and their tools:
908      `yyss': related to states,
909      `yyvs': related to semantic values,
910      `yyls': related to locations.
911
912      Refer to the stacks thru separate pointers, to allow yyoverflow
913      to reallocate them elsewhere.  */
914
915   /* The state stack.  */
916   short yyssa[YYINITDEPTH];
917   short *yyss = yyssa;
918   register short *yyssp;
919
920   /* The semantic value stack.  */
921   YYSTYPE yyvsa[YYINITDEPTH];
922   YYSTYPE *yyvs = yyvsa;
923   register YYSTYPE *yyvsp;
924
925
926
927 #define YYPOPSTACK   (yyvsp--, yyssp--)
928
929   YYSIZE_T yystacksize = YYINITDEPTH;
930
931   /* The variables used to return semantic value and location from the
932      action routines.  */
933   YYSTYPE yyval;
934
935
936   /* When reducing, the number of symbols on the RHS of the reduced
937      rule.  */
938   int yylen;
939
940   YYDPRINTF ((stderr, "Starting parse\n"));
941
942   yystate = 0;
943   yyerrstatus = 0;
944   yynerrs = 0;
945   yychar = YYEMPTY;             /* Cause a token to be read.  */
946
947   /* Initialize stack pointers.
948      Waste one element of value and location stack
949      so that they stay on the same level as the state stack.
950      The wasted elements are never initialized.  */
951
952   yyssp = yyss;
953   yyvsp = yyvs;
954
955   goto yysetstate;
956
957 /*------------------------------------------------------------.
958 | yynewstate -- Push a new state, which is found in yystate.  |
959 `------------------------------------------------------------*/
960  yynewstate:
961   /* In all cases, when you get here, the value and location stacks
962      have just been pushed. so pushing a state here evens the stacks.
963      */
964   yyssp++;
965
966  yysetstate:
967   *yyssp = yystate;
968
969   if (yyss + yystacksize - 1 <= yyssp)
970     {
971       /* Get the current used size of the three stacks, in elements.  */
972       YYSIZE_T yysize = yyssp - yyss + 1;
973
974 #ifdef yyoverflow
975       {
976         /* Give user a chance to reallocate the stack. Use copies of
977            these so that the &'s don't force the real ones into
978            memory.  */
979         YYSTYPE *yyvs1 = yyvs;
980         short *yyss1 = yyss;
981
982
983         /* Each stack pointer address is followed by the size of the
984            data in use in that stack, in bytes.  This used to be a
985            conditional around just the two extra args, but that might
986            be undefined if yyoverflow is a macro.  */
987         yyoverflow ("parser stack overflow",
988                     &yyss1, yysize * sizeof (*yyssp),
989                     &yyvs1, yysize * sizeof (*yyvsp),
990
991                     &yystacksize);
992
993         yyss = yyss1;
994         yyvs = yyvs1;
995       }
996 #else /* no yyoverflow */
997 # ifndef YYSTACK_RELOCATE
998       goto yyoverflowlab;
999 # else
1000       /* Extend the stack our own way.  */
1001       if (YYMAXDEPTH <= yystacksize)
1002         goto yyoverflowlab;
1003       yystacksize *= 2;
1004       if (YYMAXDEPTH < yystacksize)
1005         yystacksize = YYMAXDEPTH;
1006
1007       {
1008         short *yyss1 = yyss;
1009         union yyalloc *yyptr =
1010           (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1011         if (! yyptr)
1012           goto yyoverflowlab;
1013         YYSTACK_RELOCATE (yyss);
1014         YYSTACK_RELOCATE (yyvs);
1015
1016 #  undef YYSTACK_RELOCATE
1017         if (yyss1 != yyssa)
1018           YYSTACK_FREE (yyss1);
1019       }
1020 # endif
1021 #endif /* no yyoverflow */
1022
1023       yyssp = yyss + yysize - 1;
1024       yyvsp = yyvs + yysize - 1;
1025
1026
1027       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1028                   (unsigned long int) yystacksize));
1029
1030       if (yyss + yystacksize - 1 <= yyssp)
1031         YYABORT;
1032     }
1033
1034   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1035
1036   goto yybackup;
1037
1038 /*-----------.
1039 | yybackup.  |
1040 `-----------*/
1041 yybackup:
1042
1043 /* Do appropriate processing given the current state.  */
1044 /* Read a lookahead token if we need one and don't already have one.  */
1045 /* yyresume: */
1046
1047   /* First try to decide what to do without reference to lookahead token.  */
1048
1049   yyn = yypact[yystate];
1050   if (yyn == YYPACT_NINF)
1051     goto yydefault;
1052
1053   /* Not known => get a lookahead token if don't already have one.  */
1054
1055   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1056   if (yychar == YYEMPTY)
1057     {
1058       YYDPRINTF ((stderr, "Reading a token: "));
1059       yychar = YYLEX;
1060     }
1061
1062   if (yychar <= YYEOF)
1063     {
1064       yychar = yytoken = YYEOF;
1065       YYDPRINTF ((stderr, "Now at end of input.\n"));
1066     }
1067   else
1068     {
1069       yytoken = YYTRANSLATE (yychar);
1070       YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1071     }
1072
1073   /* If the proper action on seeing token YYTOKEN is to reduce or to
1074      detect an error, take that action.  */
1075   yyn += yytoken;
1076   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1077     goto yydefault;
1078   yyn = yytable[yyn];
1079   if (yyn <= 0)
1080     {
1081       if (yyn == 0 || yyn == YYTABLE_NINF)
1082         goto yyerrlab;
1083       yyn = -yyn;
1084       goto yyreduce;
1085     }
1086
1087   if (yyn == YYFINAL)
1088     YYACCEPT;
1089
1090   /* Shift the lookahead token.  */
1091   YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1092
1093   /* Discard the token being shifted unless it is eof.  */
1094   if (yychar != YYEOF)
1095     yychar = YYEMPTY;
1096
1097   *++yyvsp = yylval;
1098
1099
1100   /* Count tokens shifted since error; after three, turn off error
1101      status.  */
1102   if (yyerrstatus)
1103     yyerrstatus--;
1104
1105   yystate = yyn;
1106   goto yynewstate;
1107
1108
1109 /*-----------------------------------------------------------.
1110 | yydefault -- do the default action for the current state.  |
1111 `-----------------------------------------------------------*/
1112 yydefault:
1113   yyn = yydefact[yystate];
1114   if (yyn == 0)
1115     goto yyerrlab;
1116   goto yyreduce;
1117
1118
1119 /*-----------------------------.
1120 | yyreduce -- Do a reduction.  |
1121 `-----------------------------*/
1122 yyreduce:
1123   /* yyn is the number of a rule to reduce with.  */
1124   yylen = yyr2[yyn];
1125
1126   /* If YYLEN is nonzero, implement the default value of the action:
1127      `$$ = $1'.
1128
1129      Otherwise, the following line sets YYVAL to garbage.
1130      This behavior is undocumented and Bison
1131      users should not rely upon it.  Assigning to YYVAL
1132      unconditionally makes the parser a bit smaller, and it avoids a
1133      GCC warning that YYVAL may be used uninitialized.  */
1134   yyval = yyvsp[1-yylen];
1135
1136
1137   YY_REDUCE_PRINT (yyn);
1138   switch (yyn)
1139     {
1140         case 4:
1141 #line 143 "parsedate.y"
1142     {
1143             yyHaveTime++;
1144 #ifdef lint
1145             /* I am compulsive about lint natterings... */
1146             if (yyHaveTime == -1) {
1147                 YYERROR;
1148             }
1149 #endif /* lint */
1150         }
1151     break;
1152
1153   case 5:
1154 #line 152 "parsedate.y"
1155     {
1156             yyHaveTime++;
1157             yyTimezone = yyvsp[0].Number;
1158         }
1159     break;
1160
1161   case 6:
1162 #line 156 "parsedate.y"
1163     {
1164             yyHaveDate++;
1165         }
1166     break;
1167
1168   case 7:
1169 #line 159 "parsedate.y"
1170     {
1171             yyHaveRel = 1;
1172         }
1173     break;
1174
1175   case 8:
1176 #line 164 "parsedate.y"
1177     {
1178             if (yyvsp[-1].Number < 100) {
1179                 yyHour = yyvsp[-1].Number;
1180                 yyMinutes = 0;
1181             }
1182             else {
1183                 yyHour = yyvsp[-1].Number / 100;
1184                 yyMinutes = yyvsp[-1].Number % 100;
1185             }
1186             yySeconds = 0;
1187             yyMeridian = yyvsp[0].Meridian;
1188         }
1189     break;
1190
1191   case 9:
1192 #line 176 "parsedate.y"
1193     {
1194             yyHour = yyvsp[-3].Number;
1195             yyMinutes = yyvsp[-1].Number;
1196             yySeconds = 0;
1197             yyMeridian = yyvsp[0].Meridian;
1198         }
1199     break;
1200
1201   case 10:
1202 #line 182 "parsedate.y"
1203     {
1204             yyHour = yyvsp[-3].Number;
1205             yyMinutes = yyvsp[-1].Number;
1206             yyTimezone = yyvsp[0].Number;
1207             yyMeridian = MER24;
1208             yyDSTmode = DSToff;
1209         }
1210     break;
1211
1212   case 11:
1213 #line 189 "parsedate.y"
1214     {
1215             yyHour = yyvsp[-5].Number;
1216             yyMinutes = yyvsp[-3].Number;
1217             yySeconds = yyvsp[-1].Number;
1218             yyMeridian = yyvsp[0].Meridian;
1219         }
1220     break;
1221
1222   case 12:
1223 #line 195 "parsedate.y"
1224     {
1225             yyHour = yyvsp[-5].Number;
1226             yyMinutes = yyvsp[-3].Number;
1227             yySeconds = yyvsp[-1].Number;
1228             yyTimezone = yyvsp[0].Number;
1229             yyMeridian = MER24;
1230             yyDSTmode = DSToff;
1231         }
1232     break;
1233
1234   case 13:
1235 #line 205 "parsedate.y"
1236     {
1237             yyval.Number = yyvsp[0].Number;
1238             yyDSTmode = DSToff;
1239         }
1240     break;
1241
1242   case 14:
1243 #line 209 "parsedate.y"
1244     {
1245             yyval.Number = yyvsp[0].Number;
1246             yyDSTmode = DSTon;
1247         }
1248     break;
1249
1250   case 15:
1251 #line 213 "parsedate.y"
1252     {
1253             /* Only allow "GMT+300" and "GMT-0800" */
1254             if (yyvsp[-1].Number != 0) {
1255                 YYABORT;
1256             }
1257             yyval.Number = yyvsp[0].Number;
1258             yyDSTmode = DSToff;
1259         }
1260     break;
1261
1262   case 16:
1263 #line 221 "parsedate.y"
1264     {
1265             yyval.Number = yyvsp[0].Number;
1266             yyDSTmode = DSToff;
1267         }
1268     break;
1269
1270   case 17:
1271 #line 227 "parsedate.y"
1272     {
1273             int         i;
1274
1275             /* Unix and GMT and numeric timezones -- a little confusing. */
1276             if (yyvsp[0].Number < 0) {
1277                 /* Don't work with negative modulus. */
1278                 yyvsp[0].Number = -yyvsp[0].Number;
1279                 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1280                     YYABORT;
1281                 }
1282                 yyval.Number = (yyvsp[0].Number / 100) * 60 + i;
1283             }
1284             else {
1285                 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1286                     YYABORT;
1287                 }
1288                 yyval.Number = -((yyvsp[0].Number / 100) * 60 + i);
1289             }
1290         }
1291     break;
1292
1293   case 18:
1294 #line 248 "parsedate.y"
1295     {
1296             yyMonth = yyvsp[-2].Number;
1297             yyDay = yyvsp[0].Number;
1298         }
1299     break;
1300
1301   case 19:
1302 #line 252 "parsedate.y"
1303     {
1304             if (yyvsp[-4].Number > 100) {
1305                 yyYear = yyvsp[-4].Number;
1306                 yyMonth = yyvsp[-2].Number;
1307                 yyDay = yyvsp[0].Number;
1308             }
1309             else {
1310                 yyMonth = yyvsp[-4].Number;
1311                 yyDay = yyvsp[-2].Number;
1312                 yyYear = yyvsp[0].Number;
1313             }
1314         }
1315     break;
1316
1317   case 20:
1318 #line 264 "parsedate.y"
1319     {
1320             yyMonth = yyvsp[-1].Number;
1321             yyDay = yyvsp[0].Number;
1322         }
1323     break;
1324
1325   case 21:
1326 #line 268 "parsedate.y"
1327     {
1328             yyMonth = yyvsp[-3].Number;
1329             yyDay = yyvsp[-2].Number;
1330             yyYear = yyvsp[0].Number;
1331         }
1332     break;
1333
1334   case 22:
1335 #line 273 "parsedate.y"
1336     {
1337             yyDay = yyvsp[-1].Number;
1338             yyMonth = yyvsp[0].Number;
1339         }
1340     break;
1341
1342   case 23:
1343 #line 277 "parsedate.y"
1344     {
1345             yyDay = yyvsp[-2].Number;
1346             yyMonth = yyvsp[-1].Number;
1347             yyYear = yyvsp[0].Number;
1348         }
1349     break;
1350
1351   case 24:
1352 #line 282 "parsedate.y"
1353     {
1354             yyDay = yyvsp[-2].Number;
1355             yyMonth = yyvsp[-1].Number;
1356             yyYear = yyvsp[0].Number;
1357         }
1358     break;
1359
1360   case 25:
1361 #line 289 "parsedate.y"
1362     {
1363             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1364         }
1365     break;
1366
1367   case 26:
1368 #line 292 "parsedate.y"
1369     {
1370             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1371         }
1372     break;
1373
1374   case 27:
1375 #line 295 "parsedate.y"
1376     {
1377             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1378         }
1379     break;
1380
1381   case 28:
1382 #line 298 "parsedate.y"
1383     {
1384             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1385         }
1386     break;
1387
1388   case 29:
1389 #line 303 "parsedate.y"
1390     {
1391             yyval.Meridian = MER24;
1392         }
1393     break;
1394
1395   case 30:
1396 #line 306 "parsedate.y"
1397     {
1398             yyval.Meridian = yyvsp[0].Meridian;
1399         }
1400     break;
1401
1402
1403     }
1404
1405 /* Line 999 of yacc.c.  */
1406 #line 1406 "y.tab.c"
1407 \f
1408   yyvsp -= yylen;
1409   yyssp -= yylen;
1410
1411
1412   YY_STACK_PRINT (yyss, yyssp);
1413
1414   *++yyvsp = yyval;
1415
1416
1417   /* Now `shift' the result of the reduction.  Determine what state
1418      that goes to, based on the state we popped back to and the rule
1419      number reduced by.  */
1420
1421   yyn = yyr1[yyn];
1422
1423   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1424   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1425     yystate = yytable[yystate];
1426   else
1427     yystate = yydefgoto[yyn - YYNTOKENS];
1428
1429   goto yynewstate;
1430
1431
1432 /*------------------------------------.
1433 | yyerrlab -- here on detecting error |
1434 `------------------------------------*/
1435 yyerrlab:
1436   /* If not already recovering from an error, report this error.  */
1437   if (!yyerrstatus)
1438     {
1439       ++yynerrs;
1440 #if YYERROR_VERBOSE
1441       yyn = yypact[yystate];
1442
1443       if (YYPACT_NINF < yyn && yyn < YYLAST)
1444         {
1445           YYSIZE_T yysize = 0;
1446           int yytype = YYTRANSLATE (yychar);
1447           char *yymsg;
1448           int yyx, yycount;
1449
1450           yycount = 0;
1451           /* Start YYX at -YYN if negative to avoid negative indexes in
1452              YYCHECK.  */
1453           for (yyx = yyn < 0 ? -yyn : 0;
1454                yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1455             if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1456               yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1457           yysize += yystrlen ("syntax error, unexpected ") + 1;
1458           yysize += yystrlen (yytname[yytype]);
1459           yymsg = (char *) YYSTACK_ALLOC (yysize);
1460           if (yymsg != 0)
1461             {
1462               char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1463               yyp = yystpcpy (yyp, yytname[yytype]);
1464
1465               if (yycount < 5)
1466                 {
1467                   yycount = 0;
1468                   for (yyx = yyn < 0 ? -yyn : 0;
1469                        yyx < (int) (sizeof (yytname) / sizeof (char *));
1470                        yyx++)
1471                     if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1472                       {
1473                         const char *yyq = ! yycount ? ", expecting " : " or ";
1474                         yyp = yystpcpy (yyp, yyq);
1475                         yyp = yystpcpy (yyp, yytname[yyx]);
1476                         yycount++;
1477                       }
1478                 }
1479               yyerror (yymsg);
1480               YYSTACK_FREE (yymsg);
1481             }
1482           else
1483             yyerror ("syntax error; also virtual memory exhausted");
1484         }
1485       else
1486 #endif /* YYERROR_VERBOSE */
1487         yyerror ("syntax error");
1488     }
1489
1490
1491
1492   if (yyerrstatus == 3)
1493     {
1494       /* If just tried and failed to reuse lookahead token after an
1495          error, discard it.  */
1496
1497       /* Return failure if at end of input.  */
1498       if (yychar == YYEOF)
1499         {
1500           /* Pop the error token.  */
1501           YYPOPSTACK;
1502           /* Pop the rest of the stack.  */
1503           while (yyss < yyssp)
1504             {
1505               YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1506               yydestruct (yystos[*yyssp], yyvsp);
1507               YYPOPSTACK;
1508             }
1509           YYABORT;
1510         }
1511
1512       YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1513       yydestruct (yytoken, &yylval);
1514       yychar = YYEMPTY;
1515
1516     }
1517
1518   /* Else will try to reuse lookahead token after shifting the error
1519      token.  */
1520   goto yyerrlab1;
1521
1522
1523 /*----------------------------------------------------.
1524 | yyerrlab1 -- error raised explicitly by an action.  |
1525 `----------------------------------------------------*/
1526 yyerrlab1:
1527   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
1528
1529   for (;;)
1530     {
1531       yyn = yypact[yystate];
1532       if (yyn != YYPACT_NINF)
1533         {
1534           yyn += YYTERROR;
1535           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1536             {
1537               yyn = yytable[yyn];
1538               if (0 < yyn)
1539                 break;
1540             }
1541         }
1542
1543       /* Pop the current state because it cannot handle the error token.  */
1544       if (yyssp == yyss)
1545         YYABORT;
1546
1547       YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1548       yydestruct (yystos[yystate], yyvsp);
1549       yyvsp--;
1550       yystate = *--yyssp;
1551
1552       YY_STACK_PRINT (yyss, yyssp);
1553     }
1554
1555   if (yyn == YYFINAL)
1556     YYACCEPT;
1557
1558   YYDPRINTF ((stderr, "Shifting error token, "));
1559
1560   *++yyvsp = yylval;
1561
1562
1563   yystate = yyn;
1564   goto yynewstate;
1565
1566
1567 /*-------------------------------------.
1568 | yyacceptlab -- YYACCEPT comes here.  |
1569 `-------------------------------------*/
1570 yyacceptlab:
1571   yyresult = 0;
1572   goto yyreturn;
1573
1574 /*-----------------------------------.
1575 | yyabortlab -- YYABORT comes here.  |
1576 `-----------------------------------*/
1577 yyabortlab:
1578   yyresult = 1;
1579   goto yyreturn;
1580
1581 #ifndef yyoverflow
1582 /*----------------------------------------------.
1583 | yyoverflowlab -- parser overflow comes here.  |
1584 `----------------------------------------------*/
1585 yyoverflowlab:
1586   yyerror ("parser stack overflow");
1587   yyresult = 2;
1588   /* Fall through.  */
1589 #endif
1590
1591 yyreturn:
1592 #ifndef yyoverflow
1593   if (yyss != yyssa)
1594     YYSTACK_FREE (yyss);
1595 #endif
1596   return yyresult;
1597 }
1598
1599
1600 #line 311 "parsedate.y"
1601
1602
1603 /* Month and day table. */
1604 static TABLE    MonthDayTable[] = {
1605     { "january",        tMONTH,  1 },
1606     { "february",       tMONTH,  2 },
1607     { "march",          tMONTH,  3 },
1608     { "april",          tMONTH,  4 },
1609     { "may",            tMONTH,  5 },
1610     { "june",           tMONTH,  6 },
1611     { "july",           tMONTH,  7 },
1612     { "august",         tMONTH,  8 },
1613     { "september",      tMONTH,  9 },
1614     { "october",        tMONTH, 10 },
1615     { "november",       tMONTH, 11 },
1616     { "december",       tMONTH, 12 },
1617         /* The value of the day isn't used... */
1618     { "sunday",         tDAY, 0 },
1619     { "monday",         tDAY, 0 },
1620     { "tuesday",        tDAY, 0 },
1621     { "wednesday",      tDAY, 0 },
1622     { "thursday",       tDAY, 0 },
1623     { "friday",         tDAY, 0 },
1624     { "saturday",       tDAY, 0 },
1625 };
1626
1627 /* Time units table. */
1628 static TABLE    UnitsTable[] = {
1629     { "year",           tMONTH_UNIT,    12 },
1630     { "month",          tMONTH_UNIT,    1 },
1631     { "week",           tSEC_UNIT,      7L * 24 * 60 * 60 },
1632     { "day",            tSEC_UNIT,      1L * 24 * 60 * 60 },
1633     { "hour",           tSEC_UNIT,      60 * 60 },
1634     { "minute",         tSEC_UNIT,      60 },
1635     { "min",            tSEC_UNIT,      60 },
1636     { "second",         tSEC_UNIT,      1 },
1637     { "sec",            tSEC_UNIT,      1 },
1638 };
1639
1640 /* Timezone table. */
1641 static TABLE    TimezoneTable[] = {
1642     { "gmt",    tZONE,     HOUR( 0) },  /* Greenwich Mean */
1643     { "ut",     tZONE,     HOUR( 0) },  /* Universal */
1644     { "utc",    tZONE,     HOUR( 0) },  /* Universal Coordinated */
1645     { "cut",    tZONE,     HOUR( 0) },  /* Coordinated Universal */
1646     { "z",      tZONE,     HOUR( 0) },  /* Greenwich Mean */
1647     { "wet",    tZONE,     HOUR( 0) },  /* Western European */
1648     { "bst",    tDAYZONE,  HOUR( 0) },  /* British Summer */
1649     { "nst",    tZONE,     HOUR(3)+30 }, /* Newfoundland Standard */
1650     { "ndt",    tDAYZONE,  HOUR(3)+30 }, /* Newfoundland Daylight */
1651     { "ast",    tZONE,     HOUR( 4) },  /* Atlantic Standard */
1652     { "adt",    tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
1653     { "est",    tZONE,     HOUR( 5) },  /* Eastern Standard */
1654     { "edt",    tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
1655     { "cst",    tZONE,     HOUR( 6) },  /* Central Standard */
1656     { "cdt",    tDAYZONE,  HOUR( 6) },  /* Central Daylight */
1657     { "mst",    tZONE,     HOUR( 7) },  /* Mountain Standard */
1658     { "mdt",    tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
1659     { "pst",    tZONE,     HOUR( 8) },  /* Pacific Standard */
1660     { "pdt",    tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
1661     { "yst",    tZONE,     HOUR( 9) },  /* Yukon Standard */
1662     { "ydt",    tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
1663     { "akst",   tZONE,     HOUR( 9) },  /* Alaska Standard */
1664     { "akdt",   tDAYZONE,  HOUR( 9) },  /* Alaska Daylight */
1665     { "hst",    tZONE,     HOUR(10) },  /* Hawaii Standard */
1666     { "hast",   tZONE,     HOUR(10) },  /* Hawaii-Aleutian Standard */
1667     { "hadt",   tDAYZONE,  HOUR(10) },  /* Hawaii-Aleutian Daylight */
1668     { "ces",    tDAYZONE,  -HOUR(1) },  /* Central European Summer */
1669     { "cest",   tDAYZONE,  -HOUR(1) },  /* Central European Summer */
1670     { "mez",    tZONE,     -HOUR(1) },  /* Middle European */
1671     { "mezt",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
1672     { "cet",    tZONE,     -HOUR(1) },  /* Central European */
1673     { "met",    tZONE,     -HOUR(1) },  /* Middle European */
1674     { "eet",    tZONE,     -HOUR(2) },  /* Eastern Europe */
1675     { "msk",    tZONE,     -HOUR(3) },  /* Moscow Winter */
1676     { "msd",    tDAYZONE,  -HOUR(3) },  /* Moscow Summer */
1677     { "wast",   tZONE,     -HOUR(8) },  /* West Australian Standard */
1678     { "wadt",   tDAYZONE,  -HOUR(8) },  /* West Australian Daylight */
1679     { "hkt",    tZONE,     -HOUR(8) },  /* Hong Kong */
1680     { "cct",    tZONE,     -HOUR(8) },  /* China Coast */
1681     { "jst",    tZONE,     -HOUR(9) },  /* Japan Standard */
1682     { "kst",    tZONE,     -HOUR(9) },  /* Korean Standard */
1683     { "kdt",    tZONE,     -HOUR(9) },  /* Korean Daylight */
1684     { "cast",   tZONE,     -(HOUR(9)+30) }, /* Central Australian Standard */
1685     { "cadt",   tDAYZONE,  -(HOUR(9)+30) }, /* Central Australian Daylight */
1686     { "east",   tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
1687     { "eadt",   tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
1688     { "nzst",   tZONE,     -HOUR(12) }, /* New Zealand Standard */
1689     { "nzdt",   tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
1690
1691     /* For completeness we include the following entries. */
1692 #if 0
1693
1694     /* Duplicate names.  Either they conflict with a zone listed above
1695      * (which is either more likely to be seen or just been in circulation
1696      * longer), or they conflict with another zone in this section and
1697      * we could not reasonably choose one over the other. */
1698     { "fst",    tZONE,     HOUR( 2) },  /* Fernando De Noronha Standard */
1699     { "fdt",    tDAYZONE,  HOUR( 2) },  /* Fernando De Noronha Daylight */
1700     { "bst",    tZONE,     HOUR( 3) },  /* Brazil Standard */
1701     { "est",    tZONE,     HOUR( 3) },  /* Eastern Standard (Brazil) */
1702     { "edt",    tDAYZONE,  HOUR( 3) },  /* Eastern Daylight (Brazil) */
1703     { "wst",    tZONE,     HOUR( 4) },  /* Western Standard (Brazil) */
1704     { "wdt",    tDAYZONE,  HOUR( 4) },  /* Western Daylight (Brazil) */
1705     { "cst",    tZONE,     HOUR( 5) },  /* Chile Standard */
1706     { "cdt",    tDAYZONE,  HOUR( 5) },  /* Chile Daylight */
1707     { "ast",    tZONE,     HOUR( 5) },  /* Acre Standard */
1708     { "adt",    tDAYZONE,  HOUR( 5) },  /* Acre Daylight */
1709     { "cst",    tZONE,     HOUR( 5) },  /* Cuba Standard */
1710     { "cdt",    tDAYZONE,  HOUR( 5) },  /* Cuba Daylight */
1711     { "est",    tZONE,     HOUR( 6) },  /* Easter Island Standard */
1712     { "edt",    tDAYZONE,  HOUR( 6) },  /* Easter Island Daylight */
1713     { "sst",    tZONE,     HOUR(11) },  /* Samoa Standard */
1714     { "ist",    tZONE,     -HOUR(2) },  /* Israel Standard */
1715     { "idt",    tDAYZONE,  -HOUR(2) },  /* Israel Daylight */
1716     { "idt",    tDAYZONE,  -(HOUR(3)+30) }, /* Iran Daylight */
1717     { "ist",    tZONE,     -(HOUR(3)+30) }, /* Iran Standard */
1718     { "cst",     tZONE,     -HOUR(8) }, /* China Standard */
1719     { "cdt",     tDAYZONE,  -HOUR(8) }, /* China Daylight */
1720     { "sst",     tZONE,     -HOUR(8) }, /* Singapore Standard */
1721
1722     /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
1723     { "gst",    tZONE,     HOUR( 3) },  /* Greenland Standard */
1724     { "wat",    tZONE,     -HOUR(1) },  /* West Africa */
1725     { "at",     tZONE,     HOUR( 2) },  /* Azores */
1726     { "gst",    tZONE,     -HOUR(10) }, /* Guam Standard */
1727     { "nft",    tZONE,     HOUR(3)+30 }, /* Newfoundland */
1728     { "idlw",   tZONE,     HOUR(12) },  /* International Date Line West */
1729     { "mewt",   tZONE,     -HOUR(1) },  /* Middle European Winter */
1730     { "mest",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
1731     { "swt",    tZONE,     -HOUR(1) },  /* Swedish Winter */
1732     { "sst",    tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
1733     { "fwt",    tZONE,     -HOUR(1) },  /* French Winter */
1734     { "fst",    tDAYZONE,  -HOUR(1) },  /* French Summer */
1735     { "bt",     tZONE,     -HOUR(3) },  /* Baghdad */
1736     { "it",     tZONE,     -(HOUR(3)+30) }, /* Iran */
1737     { "zp4",    tZONE,     -HOUR(4) },  /* USSR Zone 3 */
1738     { "zp5",    tZONE,     -HOUR(5) },  /* USSR Zone 4 */
1739     { "ist",    tZONE,     -(HOUR(5)+30) }, /* Indian Standard */
1740     { "zp6",    tZONE,     -HOUR(6) },  /* USSR Zone 5 */
1741     { "nst",    tZONE,     -HOUR(7) },  /* North Sumatra */
1742     { "sst",    tZONE,     -HOUR(7) },  /* South Sumatra */
1743     { "jt",     tZONE,     -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
1744     { "nzt",    tZONE,     -HOUR(12) }, /* New Zealand */
1745     { "idle",   tZONE,     -HOUR(12) }, /* International Date Line East */
1746     { "cat",    tZONE,     HOUR(10) },  /* -- expired 1967 */
1747     { "nt",     tZONE,     HOUR(11) },  /* -- expired 1967 */
1748     { "ahst",   tZONE,     HOUR(10) },  /* -- expired 1983 */
1749     { "hdt",    tDAYZONE,  HOUR(10) },  /* -- expired 1986 */
1750 #endif /* 0 */
1751 };
1752
1753
1754 /* ARGSUSED */
1755 static void
1756 date_error(char *s)
1757 {
1758     /* NOTREACHED */
1759 }
1760
1761
1762 static time_t
1763 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1764 {
1765     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
1766         return -1;
1767     if (Meridian == MER24) {
1768         if (Hours < 0 || Hours > 23)
1769             return -1;
1770     }
1771     else {
1772         if (Hours < 1 || Hours > 12)
1773             return -1;
1774         if (Hours == 12)
1775             Hours = 0;
1776         if (Meridian == MERpm)
1777             Hours += 12;
1778     }
1779     return (Hours * 60L + Minutes) * 60L + Seconds;
1780 }
1781
1782
1783 static time_t
1784 Convert(time_t Month, time_t Day, time_t Year,
1785         time_t Hours, time_t Minutes, time_t Seconds,
1786         MERIDIAN Meridian, DSTMODE dst)
1787 {
1788     static int  DaysNormal[13] = {
1789         0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1790     };
1791     static int  DaysLeap[13] = {
1792         0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1793     };
1794     static int  LeapYears[] = {
1795         1972, 1976, 1980, 1984, 1988, 1992, 1996,
1796         2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
1797     };
1798     register int        *yp;
1799     register int        *mp;
1800     register time_t     Julian;
1801     register int        i;
1802     time_t              tod;
1803
1804     if (Year < 0)
1805         Year = -Year;
1806     if (Year < 100)
1807         Year += 1900;
1808     if (Year < EPOCH)
1809         Year += 100;
1810     for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
1811         if (Year == *yp) {
1812             mp = DaysLeap;
1813             break;
1814         }
1815     if (Year < EPOCH || Year > END_OF_TIME
1816      || Month < 1 || Month > 12
1817      /* NOSTRICT *//* conversion from long may lose accuracy */
1818      || Day < 1 || Day > mp[(int)Month])
1819         return -1;
1820
1821     Julian = Day - 1 + (Year - EPOCH) * 365;
1822     for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
1823         if (Year <= *yp)
1824             break;
1825     for (i = 1; i < Month; i++)
1826         Julian += *++mp;
1827     Julian *= SECSPERDAY;
1828     Julian += yyTimezone * 60L;
1829     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1830         return -1;
1831     Julian += tod;
1832     tod = Julian;
1833     if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
1834         Julian -= DST_OFFSET * 60L * 60L;
1835     return Julian;
1836 }
1837
1838
1839 static time_t
1840 DSTcorrect(time_t Start, time_t Future)
1841 {
1842     time_t      StartDay;
1843     time_t      FutureDay;
1844
1845     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
1846     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
1847     return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L;
1848 }
1849
1850
1851 static time_t
1852 RelativeMonth(time_t Start, time_t RelMonth)
1853 {
1854     struct tm   *tm;
1855     time_t      Month;
1856     time_t      Year;
1857
1858     tm = localtime(&Start);
1859     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
1860     Year = Month / 12;
1861     Month = Month % 12 + 1;
1862     return DSTcorrect(Start,
1863             Convert(Month, (time_t)tm->tm_mday, Year,
1864                 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
1865                 MER24, DSTmaybe));
1866 }
1867
1868
1869 static int
1870 LookupWord(char *buff, register int length)
1871 {
1872     register char       *p;
1873     register char       *q;
1874     register TABLE      *tp;
1875     register int        c;
1876
1877     p = buff;
1878     c = p[0];
1879
1880     /* See if we have an abbreviation for a month. */
1881     if (length == 3 || (length == 4 && p[3] == '.'))
1882         for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
1883             q = tp->name;
1884             if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
1885                 yylval.Number = tp->value;
1886                 return tp->type;
1887             }
1888         }
1889     else
1890         for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
1891             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1892                 yylval.Number = tp->value;
1893                 return tp->type;
1894             }
1895
1896     /* Try for a timezone. */
1897     for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1898         if (c == tp->name[0] && p[1] == tp->name[1]
1899          && strcmp(p, tp->name) == 0) {
1900             yylval.Number = tp->value;
1901             return tp->type;
1902         }
1903
1904     /* Try the units table. */
1905     for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1906         if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1907             yylval.Number = tp->value;
1908             return tp->type;
1909         }
1910
1911     /* Strip off any plural and try the units table again. */
1912     if (--length > 0 && p[length] == 's') {
1913         p[length] = '\0';
1914         for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1915             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1916                 p[length] = 's';
1917                 yylval.Number = tp->value;
1918                 return tp->type;
1919             }
1920         p[length] = 's';
1921     }
1922     length++;
1923
1924     /* Drop out any periods. */
1925     for (p = buff, q = (char*)buff; *q; q++)
1926         if (*q != '.')
1927             *p++ = *q;
1928     *p = '\0';
1929
1930     /* Try the meridians. */
1931     if (buff[1] == 'm' && buff[2] == '\0') {
1932         if (buff[0] == 'a') {
1933             yylval.Meridian = MERam;
1934             return tMERIDIAN;
1935         }
1936         if (buff[0] == 'p') {
1937             yylval.Meridian = MERpm;
1938             return tMERIDIAN;
1939         }
1940     }
1941
1942     /* If we saw any periods, try the timezones again. */
1943     if (p - buff != length) {
1944         c = buff[0];
1945         for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1946             if (c == tp->name[0] && p[1] == tp->name[1]
1947             && strcmp(p, tp->name) == 0) {
1948                 yylval.Number = tp->value;
1949                 return tp->type;
1950             }
1951     }
1952
1953     /* Unknown word -- assume GMT timezone. */
1954     yylval.Number = 0;
1955     return tZONE;
1956 }
1957
1958
1959 int
1960 date_lex(void)
1961 {
1962     register char       c;
1963     register char       *p;
1964     char                buff[20];
1965     register int        sign;
1966     register int        i;
1967     register int        nesting;
1968
1969     for ( ; ; ) {
1970         /* Get first character after the whitespace. */
1971         for ( ; ; ) {
1972             while (isspace(*yyInput))
1973                 yyInput++;
1974             c = *yyInput;
1975
1976             /* Ignore RFC 822 comments, typically time zone names. */
1977             if (c != LPAREN)
1978                 break;
1979             for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
1980                 if (c == LPAREN)
1981                     nesting++;
1982                 else if (!IS7BIT(c) || c == '\0' || c == '\r'
1983                      || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
1984                     /* Lexical error: bad comment. */
1985                     return '?';
1986             yyInput++;
1987         }
1988
1989         /* A number? */
1990         if (isdigit(c) || c == '-' || c == '+') {
1991             if (c == '-' || c == '+') {
1992                 sign = c == '-' ? -1 : 1;
1993                 yyInput++;
1994                 if (!isdigit(*yyInput))
1995                     /* Skip the plus or minus sign. */
1996                     continue;
1997             }
1998             else
1999                 sign = 0;
2000             for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
2001                 i = 10 * i + c - '0';
2002             yyInput--;
2003             yylval.Number = sign < 0 ? -i : i;
2004             return sign ? tSNUMBER : tUNUMBER;
2005         }
2006
2007         /* A word? */
2008         if (isalpha(c)) {
2009             for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
2010                 if (p < &buff[sizeof buff - 1])
2011                     *p++ = isupper(c) ? tolower(c) : c;
2012             *p = '\0';
2013             yyInput--;
2014             return LookupWord(buff, p - buff);
2015         }
2016
2017         return *yyInput++;
2018     }
2019 }
2020
2021
2022 time_t
2023 parsedate(char *p)
2024 {
2025     extern int          date_parse(void);
2026     time_t              Start;
2027
2028     yyInput = p;
2029
2030     yyYear = 0;
2031     yyMonth = 0;
2032     yyDay = 0;
2033     yyTimezone = 0;
2034     yyDSTmode = DSTmaybe;
2035     yyHour = 0;
2036     yyMinutes = 0;
2037     yySeconds = 0;
2038     yyMeridian = MER24;
2039     yyRelSeconds = 0;
2040     yyRelMonth = 0;
2041     yyHaveDate = 0;
2042     yyHaveRel = 0;
2043     yyHaveTime = 0;
2044
2045     if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
2046         return -1;
2047
2048     if (yyHaveDate || yyHaveTime) {
2049         Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2050                     yyMeridian, yyDSTmode);
2051         if (Start < 0)
2052             return -1;
2053     }
2054     else
2055         return -1;
2056
2057     Start += yyRelSeconds;
2058     if (yyRelMonth)
2059         Start += RelativeMonth(Start, yyRelMonth);
2060
2061     /* Have to do *something* with a legitimate -1 so it's distinguishable
2062      * from the error return value.  (Alternately could set errno on error.) */
2063     return Start == -1 ? 0 : Start;
2064 }
2065
2066
2067 #ifdef TEST
2068
2069 #if YYDEBUG
2070 extern int      yydebug;
2071 #endif /* YYDEBUG */
2072
2073 /* ARGSUSED */
2074 int
2075 main(int ac, char *av[])
2076 {
2077     char        buff[128];
2078     time_t      d;
2079
2080 #if YYDEBUG
2081     yydebug = 1;
2082 #endif /* YYDEBUG */
2083
2084     (void)printf("Enter date, or blank line to exit.\n\t> ");
2085     for ( ; ; ) {
2086         (void)printf("\t> ");
2087         (void)fflush(stdout);
2088         if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2089             break;
2090 #if YYDEBUG
2091         if (strcmp(buff, "yydebug") == 0) {
2092             yydebug = !yydebug;
2093             printf("yydebug = %s\n", yydebug ? "on" : "off");
2094             continue;
2095         }
2096 #endif /* YYDEBUG */
2097         d = parsedate(buff, (TIMEINFO *)NULL);
2098         if (d == -1)
2099             (void)printf("Bad format - couldn't convert.\n");
2100         else
2101             (void)printf("%s", ctime(&d));
2102     }
2103
2104     exit(0);
2105     /* NOTREACHED */
2106 }
2107 #endif /* TEST */
2108
2109