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