r6149: Fixes bugs #2498 and 2484.
[samba.git] / source / modules / getdate.c
1 /* A Bison parser, made by GNU Bison 1.875a.  */
2
3 /* Skeleton parser for Yacc-like parsing with Bison,
4    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 /* As a special exception, when this file is copied by Bison into a
22    Bison output file, you may use that output file without restriction.
23    This special exception was added by the Free Software Foundation
24    in version 1.24 of Bison.  */
25
26 /* Written by Richard Stallman by simplifying the original so called
27    ``semantic'' parser.  */
28
29 /* All symbols defined below should begin with yy or YY, to avoid
30    infringing on user name space.  This should be done even for local
31    variables, as they might otherwise be expanded by user macros.
32    There are some unavoidable exceptions within include files to
33    define necessary library symbols; they are noted "INFRINGES ON
34    USER NAME SPACE" below.  */
35
36 /* Identify Bison output.  */
37 #define YYBISON 1
38
39 /* Skeleton name.  */
40 #define YYSKELETON_NAME "yacc.c"
41
42 /* Pure parsers.  */
43 #define YYPURE 1
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      tAGO = 258,
57      tDST = 259,
58      tDAY = 260,
59      tDAY_UNIT = 261,
60      tDAYZONE = 262,
61      tHOUR_UNIT = 263,
62      tLOCAL_ZONE = 264,
63      tMERIDIAN = 265,
64      tMINUTE_UNIT = 266,
65      tMONTH = 267,
66      tMONTH_UNIT = 268,
67      tSEC_UNIT = 269,
68      tYEAR_UNIT = 270,
69      tZONE = 271,
70      tSNUMBER = 272,
71      tUNUMBER = 273
72    };
73 #endif
74 #define tAGO 258
75 #define tDST 259
76 #define tDAY 260
77 #define tDAY_UNIT 261
78 #define tDAYZONE 262
79 #define tHOUR_UNIT 263
80 #define tLOCAL_ZONE 264
81 #define tMERIDIAN 265
82 #define tMINUTE_UNIT 266
83 #define tMONTH 267
84 #define tMONTH_UNIT 268
85 #define tSEC_UNIT 269
86 #define tYEAR_UNIT 270
87 #define tZONE 271
88 #define tSNUMBER 272
89 #define tUNUMBER 273
90
91
92
93
94 /* Copy the first part of user declarations.  */
95 #line 1 "getdate.y"
96
97 /* Parse a string into an internal time stamp.
98    Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
99
100    This program is free software; you can redistribute it and/or modify
101    it under the terms of the GNU General Public License as published by
102    the Free Software Foundation; either version 2, or (at your option)
103    any later version.
104
105    This program is distributed in the hope that it will be useful,
106    but WITHOUT ANY WARRANTY; without even the implied warranty of
107    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108    GNU General Public License for more details.
109
110    You should have received a copy of the GNU General Public License
111    along with this program; if not, write to the Free Software Foundation,
112    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
113
114 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
115    at the University of North Carolina at Chapel Hill.  Later tweaked by
116    a couple of people on Usenet.  Completely overhauled by Rich $alz
117    <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
118
119    Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
120    the right thing about local DST.  Unlike previous versions, this
121    version is reentrant.  */
122
123 #include <config.h>
124
125 #ifdef HAVE_ALLOCA_H
126 # include <alloca.h>
127 #endif
128
129 /* Since the code of getdate.y is not included in the Emacs executable
130    itself, there is no need to #define static in this file.  Even if
131    the code were included in the Emacs executable, it probably
132    wouldn't do any harm to #undef it here; this will only cause
133    problems if we try to write to a static variable, which I don't
134    think this code needs to do.  */
135 #ifdef emacs
136 # undef static
137 #endif
138
139 #include <ctype.h>
140
141 #if HAVE_STDLIB_H
142 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
143 #endif
144
145 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
146 # define IN_CTYPE_DOMAIN(c) 1
147 #else
148 # define IN_CTYPE_DOMAIN(c) isascii (c)
149 #endif
150
151 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
152 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
153 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
154 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
155
156 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
157    - Its arg may be any int or unsigned int; it need not be an unsigned char.
158    - It's guaranteed to evaluate its argument exactly once.
159    - It's typically faster.
160    POSIX says that only '0' through '9' are digits.  Prefer ISDIGIT to
161    ISDIGIT_LOCALE unless it's important to use the locale's definition
162    of `digit' even when the host does not conform to POSIX.  */
163 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
164
165 #if STDC_HEADERS || HAVE_STRING_H
166 # include <string.h>
167 #endif
168
169 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
170 # define __attribute__(x)
171 #endif
172
173 #ifndef ATTRIBUTE_UNUSED
174 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
175 #endif
176
177 #define EPOCH_YEAR 1970
178 #define TM_YEAR_BASE 1900
179
180 #define HOUR(x) ((x) * 60)
181
182 /* An integer value, and the number of digits in its textual
183    representation.  */
184 typedef struct
185 {
186   int value;
187   int digits;
188 } textint;
189
190 /* An entry in the lexical lookup table.  */
191 typedef struct
192 {
193   char const *name;
194   int type;
195   int value;
196 } table;
197
198 /* Meridian: am, pm, or 24-hour style.  */
199 enum { MERam, MERpm, MER24 };
200
201 /* Information passed to and from the parser.  */
202 typedef struct
203 {
204   /* The input string remaining to be parsed. */
205   const char *input;
206
207   /* N, if this is the Nth Tuesday.  */
208   int day_ordinal;
209
210   /* Day of week; Sunday is 0.  */
211   int day_number;
212
213   /* tm_isdst flag for the local zone.  */
214   int local_isdst;
215
216   /* Time zone, in minutes east of UTC.  */
217   int time_zone;
218
219   /* Style used for time.  */
220   int meridian;
221
222   /* Gregorian year, month, day, hour, minutes, and seconds.  */
223   textint year;
224   int month;
225   int day;
226   int hour;
227   int minutes;
228   int seconds;
229
230   /* Relative year, month, day, hour, minutes, and seconds.  */
231   int rel_year;
232   int rel_month;
233   int rel_day;
234   int rel_hour;
235   int rel_minutes;
236   int rel_seconds;
237
238   /* Counts of nonterminals of various flavors parsed so far.  */
239   int dates_seen;
240   int days_seen;
241   int local_zones_seen;
242   int rels_seen;
243   int times_seen;
244   int zones_seen;
245
246   /* Table of local time zone abbrevations, terminated by a null entry.  */
247   table local_time_zone_table[3];
248 } parser_control;
249
250 #define PC (* (parser_control *) parm)
251 #define YYLEX_PARAM parm
252 #define YYPARSE_PARAM parm
253
254 static int yyerror ();
255 static int yylex ();
256
257
258
259 /* Enabling traces.  */
260 #ifndef YYDEBUG
261 # define YYDEBUG 0
262 #endif
263
264 /* Enabling verbose error messages.  */
265 #ifdef YYERROR_VERBOSE
266 # undef YYERROR_VERBOSE
267 # define YYERROR_VERBOSE 1
268 #else
269 # define YYERROR_VERBOSE 0
270 #endif
271
272 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
273 #line 172 "getdate.y"
274 typedef union YYSTYPE {
275   int intval;
276   textint textintval;
277 } YYSTYPE;
278 /* Line 191 of yacc.c.  */
279 #line 281 "getdate.c"
280 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
281 # define YYSTYPE_IS_DECLARED 1
282 # define YYSTYPE_IS_TRIVIAL 1
283 #endif
284
285
286
287 /* Copy the second part of user declarations.  */
288
289
290 /* Line 214 of yacc.c.  */
291 #line 293 "getdate.c"
292
293 #if ! defined (yyoverflow) || YYERROR_VERBOSE
294
295 /* The parser invokes alloca or malloc; define the necessary symbols.  */
296
297 # if YYSTACK_USE_ALLOCA
298 #  define YYSTACK_ALLOC alloca
299 # else
300 #  ifndef YYSTACK_USE_ALLOCA
301 #   if defined (alloca) || defined (_ALLOCA_H)
302 #    define YYSTACK_ALLOC alloca
303 #   else
304 #    ifdef __GNUC__
305 #     define YYSTACK_ALLOC __builtin_alloca
306 #    endif
307 #   endif
308 #  endif
309 # endif
310
311 # ifdef YYSTACK_ALLOC
312    /* Pacify GCC's `empty if-body' warning. */
313 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
314 # else
315 #  if defined (__STDC__) || defined (__cplusplus)
316 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
317 #   define YYSIZE_T size_t
318 #  endif
319 #  define YYSTACK_ALLOC malloc
320 #  define YYSTACK_FREE free
321 # endif
322 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
323
324
325 #if (! defined (yyoverflow) \
326      && (! defined (__cplusplus) \
327          || (YYSTYPE_IS_TRIVIAL)))
328
329 /* A type that is properly aligned for any stack member.  */
330 union yyalloc
331 {
332   short yyss;
333   YYSTYPE yyvs;
334   };
335
336 /* The size of the maximum gap between one aligned stack and the next.  */
337 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
338
339 /* The size of an array large to enough to hold all stacks, each with
340    N elements.  */
341 # define YYSTACK_BYTES(N) \
342      ((N) * (sizeof (short) + sizeof (YYSTYPE))                         \
343       + YYSTACK_GAP_MAXIMUM)
344
345 /* Copy COUNT objects from FROM to TO.  The source and destination do
346    not overlap.  */
347 # ifndef YYCOPY
348 #  if 1 < __GNUC__
349 #   define YYCOPY(To, From, Count) \
350       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
351 #  else
352 #   define YYCOPY(To, From, Count)              \
353       do                                        \
354         {                                       \
355           register YYSIZE_T yyi;                \
356           for (yyi = 0; yyi < (Count); yyi++)   \
357             (To)[yyi] = (From)[yyi];            \
358         }                                       \
359       while (0)
360 #  endif
361 # endif
362
363 /* Relocate STACK from its old location to the new one.  The
364    local variables YYSIZE and YYSTACKSIZE give the old and new number of
365    elements in the stack, and YYPTR gives the new location of the
366    stack.  Advance YYPTR to a properly aligned location for the next
367    stack.  */
368 # define YYSTACK_RELOCATE(Stack)                                        \
369     do                                                                  \
370       {                                                                 \
371         YYSIZE_T yynewbytes;                                            \
372         YYCOPY (&yyptr->Stack, Stack, yysize);                          \
373         Stack = &yyptr->Stack;                                          \
374         yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
375         yyptr += yynewbytes / sizeof (*yyptr);                          \
376       }                                                                 \
377     while (0)
378
379 #endif
380
381 #if defined (__STDC__) || defined (__cplusplus)
382    typedef signed char yysigned_char;
383 #else
384    typedef short yysigned_char;
385 #endif
386
387 /* YYFINAL -- State number of the termination state. */
388 #define YYFINAL  2
389 /* YYLAST -- Last index in YYTABLE.  */
390 #define YYLAST   52
391
392 /* YYNTOKENS -- Number of terminals. */
393 #define YYNTOKENS  22
394 /* YYNNTS -- Number of nonterminals. */
395 #define YYNNTS  12
396 /* YYNRULES -- Number of rules. */
397 #define YYNRULES  54
398 /* YYNRULES -- Number of states. */
399 #define YYNSTATES  64
400
401 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
402 #define YYUNDEFTOK  2
403 #define YYMAXUTOK   273
404
405 #define YYTRANSLATE(YYX)                                                \
406   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
407
408 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
409 static const unsigned char yytranslate[] =
410 {
411        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
412        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
413        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
414        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
415        2,     2,     2,     2,    20,     2,     2,    21,     2,     2,
416        2,     2,     2,     2,     2,     2,     2,     2,    19,     2,
417        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
418        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
419        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
420        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
421        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
422        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
423        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
424        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
425        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
426        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
427        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
428        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
429        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
430        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
431        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
432        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
433        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
434        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
435        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
436        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
437        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
438       15,    16,    17,    18
439 };
440
441 #if YYDEBUG
442 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
443    YYRHS.  */
444 static const unsigned char yyprhs[] =
445 {
446        0,     0,     3,     4,     7,     9,    11,    13,    15,    17,
447       19,    21,    24,    29,    34,    41,    48,    50,    53,    55,
448       57,    60,    62,    65,    68,    72,    78,    82,    86,    89,
449       94,    97,   101,   104,   106,   109,   112,   114,   117,   120,
450      122,   125,   128,   130,   133,   136,   138,   141,   144,   146,
451      149,   152,   154,   156,   157
452 };
453
454 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
455 static const yysigned_char yyrhs[] =
456 {
457       23,     0,    -1,    -1,    23,    24,    -1,    25,    -1,    26,
458       -1,    27,    -1,    29,    -1,    28,    -1,    30,    -1,    32,
459       -1,    18,    10,    -1,    18,    19,    18,    33,    -1,    18,
460       19,    18,    17,    -1,    18,    19,    18,    19,    18,    33,
461       -1,    18,    19,    18,    19,    18,    17,    -1,     9,    -1,
462        9,     4,    -1,    16,    -1,     7,    -1,    16,     4,    -1,
463        5,    -1,     5,    20,    -1,    18,     5,    -1,    18,    21,
464       18,    -1,    18,    21,    18,    21,    18,    -1,    18,    17,
465       17,    -1,    18,    12,    17,    -1,    12,    18,    -1,    12,
466       18,    20,    18,    -1,    18,    12,    -1,    18,    12,    18,
467       -1,    31,     3,    -1,    31,    -1,    18,    15,    -1,    17,
468       15,    -1,    15,    -1,    18,    13,    -1,    17,    13,    -1,
469       13,    -1,    18,     6,    -1,    17,     6,    -1,     6,    -1,
470       18,     8,    -1,    17,     8,    -1,     8,    -1,    18,    11,
471       -1,    17,    11,    -1,    11,    -1,    18,    14,    -1,    17,
472       14,    -1,    14,    -1,    18,    -1,    -1,    10,    -1
473 };
474
475 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
476 static const unsigned short yyrline[] =
477 {
478        0,   188,   188,   190,   194,   196,   198,   200,   202,   204,
479      206,   210,   217,   224,   232,   239,   251,   253,   258,   260,
480      262,   267,   272,   277,   285,   290,   310,   317,   325,   330,
481      336,   341,   350,   359,   363,   365,   367,   369,   371,   373,
482      375,   377,   379,   381,   383,   385,   387,   389,   391,   393,
483      395,   397,   402,   439,   440
484 };
485 #endif
486
487 #if YYDEBUG || YYERROR_VERBOSE
488 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
489    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
490 static const char *const yytname[] =
491 {
492   "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT", 
493   "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT", 
494   "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER", 
495   "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time", 
496   "local_zone", "zone", "day", "date", "rel", "relunit", "number", 
497   "o_merid", 0
498 };
499 #endif
500
501 # ifdef YYPRINT
502 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
503    token YYLEX-NUM.  */
504 static const unsigned short yytoknum[] =
505 {
506        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
507      265,   266,   267,   268,   269,   270,   271,   272,   273,    58,
508       44,    47
509 };
510 # endif
511
512 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
513 static const unsigned char yyr1[] =
514 {
515        0,    22,    23,    23,    24,    24,    24,    24,    24,    24,
516       24,    25,    25,    25,    25,    25,    26,    26,    27,    27,
517       27,    28,    28,    28,    29,    29,    29,    29,    29,    29,
518       29,    29,    30,    30,    31,    31,    31,    31,    31,    31,
519       31,    31,    31,    31,    31,    31,    31,    31,    31,    31,
520       31,    31,    32,    33,    33
521 };
522
523 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
524 static const unsigned char yyr2[] =
525 {
526        0,     2,     0,     2,     1,     1,     1,     1,     1,     1,
527        1,     2,     4,     4,     6,     6,     1,     2,     1,     1,
528        2,     1,     2,     2,     3,     5,     3,     3,     2,     4,
529        2,     3,     2,     1,     2,     2,     1,     2,     2,     1,
530        2,     2,     1,     2,     2,     1,     2,     2,     1,     2,
531        2,     1,     1,     0,     1
532 };
533
534 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
535    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
536    means the default is an error.  */
537 static const unsigned char yydefact[] =
538 {
539        2,     0,     1,    21,    42,    19,    45,    16,    48,     0,
540       39,    51,    36,    18,     0,    52,     3,     4,     5,     6,
541        8,     7,     9,    33,    10,    22,    17,    28,    20,    41,
542       44,    47,    38,    50,    35,    23,    40,    43,    11,    46,
543       30,    37,    49,    34,     0,     0,     0,    32,     0,    27,
544       31,    26,    53,    24,    29,    54,    13,     0,    12,     0,
545       53,    25,    15,    14
546 };
547
548 /* YYDEFGOTO[NTERM-NUM]. */
549 static const yysigned_char yydefgoto[] =
550 {
551       -1,     1,    16,    17,    18,    19,    20,    21,    22,    23,
552       24,    58
553 };
554
555 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
556    STATE-NUM.  */
557 #define YYPACT_NINF -17
558 static const yysigned_char yypact[] =
559 {
560      -17,     0,   -17,     1,   -17,   -17,   -17,    19,   -17,   -14,
561      -17,   -17,   -17,    32,    26,    14,   -17,   -17,   -17,   -17,
562      -17,   -17,   -17,    27,   -17,   -17,   -17,    22,   -17,   -17,
563      -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,
564      -16,   -17,   -17,   -17,    29,    25,    30,   -17,    31,   -17,
565      -17,   -17,    28,    23,   -17,   -17,   -17,    33,   -17,    34,
566       -7,   -17,   -17,   -17
567 };
568
569 /* YYPGOTO[NTERM-NUM].  */
570 static const yysigned_char yypgoto[] =
571 {
572      -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,   -17,
573      -17,   -10
574 };
575
576 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
577    positive, shift that token.  If negative, reduce the rule which
578    number is the opposite.  If zero, do what YYDEFACT says.
579    If YYTABLE_NINF, syntax error.  */
580 #define YYTABLE_NINF -1
581 static const unsigned char yytable[] =
582 {
583        2,    49,    50,    55,    27,     3,     4,     5,     6,     7,
584       62,     8,     9,    10,    11,    12,    13,    14,    15,    35,
585       36,    25,    37,    26,    38,    39,    40,    41,    42,    43,
586       47,    44,    29,    45,    30,    46,    28,    31,    55,    32,
587       33,    34,    48,    52,    59,    56,    51,    57,    53,    54,
588       63,    60,    61
589 };
590
591 static const unsigned char yycheck[] =
592 {
593        0,    17,    18,    10,    18,     5,     6,     7,     8,     9,
594       17,    11,    12,    13,    14,    15,    16,    17,    18,     5,
595        6,    20,     8,     4,    10,    11,    12,    13,    14,    15,
596        3,    17,     6,    19,     8,    21,     4,    11,    10,    13,
597       14,    15,    20,    18,    21,    17,    17,    19,    18,    18,
598       60,    18,    18
599 };
600
601 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
602    symbol of state STATE-NUM.  */
603 static const unsigned char yystos[] =
604 {
605        0,    23,     0,     5,     6,     7,     8,     9,    11,    12,
606       13,    14,    15,    16,    17,    18,    24,    25,    26,    27,
607       28,    29,    30,    31,    32,    20,     4,    18,     4,     6,
608        8,    11,    13,    14,    15,     5,     6,     8,    10,    11,
609       12,    13,    14,    15,    17,    19,    21,     3,    20,    17,
610       18,    17,    18,    18,    18,    10,    17,    19,    33,    21,
611       18,    18,    17,    33
612 };
613
614 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
615 # define YYSIZE_T __SIZE_TYPE__
616 #endif
617 #if ! defined (YYSIZE_T) && defined (size_t)
618 # define YYSIZE_T size_t
619 #endif
620 #if ! defined (YYSIZE_T)
621 # if defined (__STDC__) || defined (__cplusplus)
622 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
623 #  define YYSIZE_T size_t
624 # endif
625 #endif
626 #if ! defined (YYSIZE_T)
627 # define YYSIZE_T unsigned int
628 #endif
629
630 #define yyerrok         (yyerrstatus = 0)
631 #define yyclearin       (yychar = YYEMPTY)
632 #define YYEMPTY         (-2)
633 #define YYEOF           0
634
635 #define YYACCEPT        goto yyacceptlab
636 #define YYABORT         goto yyabortlab
637 #define YYERROR         goto yyerrlab1
638
639
640 /* Like YYERROR except do call yyerror.  This remains here temporarily
641    to ease the transition to the new meaning of YYERROR, for GCC.
642    Once GCC version 2 has supplanted version 1, this can go.  */
643
644 #define YYFAIL          goto yyerrlab
645
646 #define YYRECOVERING()  (!!yyerrstatus)
647
648 #define YYBACKUP(Token, Value)                                  \
649 do                                                              \
650   if (yychar == YYEMPTY && yylen == 1)                          \
651     {                                                           \
652       yychar = (Token);                                         \
653       yylval = (Value);                                         \
654       yytoken = YYTRANSLATE (yychar);                           \
655       YYPOPSTACK;                                               \
656       goto yybackup;                                            \
657     }                                                           \
658   else                                                          \
659     {                                                           \
660       yyerror ("syntax error: cannot back up");\
661       YYERROR;                                                  \
662     }                                                           \
663 while (0)
664
665 #define YYTERROR        1
666 #define YYERRCODE       256
667
668 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
669    are run).  */
670
671 #ifndef YYLLOC_DEFAULT
672 # define YYLLOC_DEFAULT(Current, Rhs, N)         \
673   Current.first_line   = Rhs[1].first_line;      \
674   Current.first_column = Rhs[1].first_column;    \
675   Current.last_line    = Rhs[N].last_line;       \
676   Current.last_column  = Rhs[N].last_column;
677 #endif
678
679 /* YYLEX -- calling `yylex' with the right arguments.  */
680
681 #ifdef YYLEX_PARAM
682 # define YYLEX yylex (&yylval, YYLEX_PARAM)
683 #else
684 # define YYLEX yylex (&yylval)
685 #endif
686
687 /* Enable debugging if requested.  */
688 #if YYDEBUG
689
690 # ifndef YYFPRINTF
691 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
692 #  define YYFPRINTF fprintf
693 # endif
694
695 # define YYDPRINTF(Args)                        \
696 do {                                            \
697   if (yydebug)                                  \
698     YYFPRINTF Args;                             \
699 } while (0)
700
701 # define YYDSYMPRINT(Args)                      \
702 do {                                            \
703   if (yydebug)                                  \
704     yysymprint Args;                            \
705 } while (0)
706
707 # define YYDSYMPRINTF(Title, Token, Value, Location)            \
708 do {                                                            \
709   if (yydebug)                                                  \
710     {                                                           \
711       YYFPRINTF (stderr, "%s ", Title);                         \
712       yysymprint (stderr,                                       \
713                   Token, Value);        \
714       YYFPRINTF (stderr, "\n");                                 \
715     }                                                           \
716 } while (0)
717
718 /*------------------------------------------------------------------.
719 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
720 | TOP (cinluded).                                                   |
721 `------------------------------------------------------------------*/
722
723 #if defined (__STDC__) || defined (__cplusplus)
724 static void
725 yy_stack_print (short *bottom, short *top)
726 #else
727 static void
728 yy_stack_print (bottom, top)
729     short *bottom;
730     short *top;
731 #endif
732 {
733   YYFPRINTF (stderr, "Stack now");
734   for (/* Nothing. */; bottom <= top; ++bottom)
735     YYFPRINTF (stderr, " %d", *bottom);
736   YYFPRINTF (stderr, "\n");
737 }
738
739 # define YY_STACK_PRINT(Bottom, Top)                            \
740 do {                                                            \
741   if (yydebug)                                                  \
742     yy_stack_print ((Bottom), (Top));                           \
743 } while (0)
744
745
746 /*------------------------------------------------.
747 | Report that the YYRULE is going to be reduced.  |
748 `------------------------------------------------*/
749
750 #if defined (__STDC__) || defined (__cplusplus)
751 static void
752 yy_reduce_print (int yyrule)
753 #else
754 static void
755 yy_reduce_print (yyrule)
756     int yyrule;
757 #endif
758 {
759   int yyi;
760   unsigned int yylineno = yyrline[yyrule];
761   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
762              yyrule - 1, yylineno);
763   /* Print the symbols being reduced, and their result.  */
764   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
765     YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
766   YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
767 }
768
769 # define YY_REDUCE_PRINT(Rule)          \
770 do {                                    \
771   if (yydebug)                          \
772     yy_reduce_print (Rule);             \
773 } while (0)
774
775 /* Nonzero means print parse trace.  It is left uninitialized so that
776    multiple parsers can coexist.  */
777 int yydebug;
778 #else /* !YYDEBUG */
779 # define YYDPRINTF(Args)
780 # define YYDSYMPRINT(Args)
781 # define YYDSYMPRINTF(Title, Token, Value, Location)
782 # define YY_STACK_PRINT(Bottom, Top)
783 # define YY_REDUCE_PRINT(Rule)
784 #endif /* !YYDEBUG */
785
786
787 /* YYINITDEPTH -- initial size of the parser's stacks.  */
788 #ifndef YYINITDEPTH
789 # define YYINITDEPTH 200
790 #endif
791
792 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
793    if the built-in stack extension method is used).
794
795    Do not make this value too large; the results are undefined if
796    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
797    evaluated with infinite-precision integer arithmetic.  */
798
799 #if YYMAXDEPTH == 0
800 # undef YYMAXDEPTH
801 #endif
802
803 #ifndef YYMAXDEPTH
804 # define YYMAXDEPTH 10000
805 #endif
806
807 \f
808
809 #if YYERROR_VERBOSE
810
811 # ifndef yystrlen
812 #  if defined (__GLIBC__) && defined (_STRING_H)
813 #   define yystrlen strlen
814 #  else
815 /* Return the length of YYSTR.  */
816 static YYSIZE_T
817 #   if defined (__STDC__) || defined (__cplusplus)
818 yystrlen (const char *yystr)
819 #   else
820 yystrlen (yystr)
821      const char *yystr;
822 #   endif
823 {
824   register const char *yys = yystr;
825
826   while (*yys++ != '\0')
827     continue;
828
829   return yys - yystr - 1;
830 }
831 #  endif
832 # endif
833
834 # ifndef yystpcpy
835 #  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
836 #   define yystpcpy stpcpy
837 #  else
838 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
839    YYDEST.  */
840 static char *
841 #   if defined (__STDC__) || defined (__cplusplus)
842 yystpcpy (char *yydest, const char *yysrc)
843 #   else
844 yystpcpy (yydest, yysrc)
845      char *yydest;
846      const char *yysrc;
847 #   endif
848 {
849   register char *yyd = yydest;
850   register const char *yys = yysrc;
851
852   while ((*yyd++ = *yys++) != '\0')
853     continue;
854
855   return yyd - 1;
856 }
857 #  endif
858 # endif
859
860 #endif /* !YYERROR_VERBOSE */
861
862 \f
863
864 #if YYDEBUG
865 /*--------------------------------.
866 | Print this symbol on YYOUTPUT.  |
867 `--------------------------------*/
868
869 #if defined (__STDC__) || defined (__cplusplus)
870 static void
871 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
872 #else
873 static void
874 yysymprint (yyoutput, yytype, yyvaluep)
875     FILE *yyoutput;
876     int yytype;
877     YYSTYPE *yyvaluep;
878 #endif
879 {
880   /* Pacify ``unused variable'' warnings.  */
881   (void) yyvaluep;
882
883   if (yytype < YYNTOKENS)
884     {
885       YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
886 # ifdef YYPRINT
887       YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
888 # endif
889     }
890   else
891     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
892
893   switch (yytype)
894     {
895       default:
896         break;
897     }
898   YYFPRINTF (yyoutput, ")");
899 }
900
901 #endif /* ! YYDEBUG */
902 /*-----------------------------------------------.
903 | Release the memory associated to this symbol.  |
904 `-----------------------------------------------*/
905
906 #if defined (__STDC__) || defined (__cplusplus)
907 static void
908 yydestruct (int yytype, YYSTYPE *yyvaluep)
909 #else
910 static void
911 yydestruct (yytype, yyvaluep)
912     int yytype;
913     YYSTYPE *yyvaluep;
914 #endif
915 {
916   /* Pacify ``unused variable'' warnings.  */
917   (void) yyvaluep;
918
919   switch (yytype)
920     {
921
922       default:
923         break;
924     }
925 }
926 \f
927
928 /* Prevent warnings from -Wmissing-prototypes.  */
929
930 #ifdef YYPARSE_PARAM
931 # if defined (__STDC__) || defined (__cplusplus)
932 int yyparse (void *YYPARSE_PARAM);
933 # else
934 int yyparse ();
935 # endif
936 #else /* ! YYPARSE_PARAM */
937 #if defined (__STDC__) || defined (__cplusplus)
938 int yyparse (void);
939 #else
940 int yyparse ();
941 #endif
942 #endif /* ! YYPARSE_PARAM */
943
944
945
946
947
948
949 /*----------.
950 | yyparse.  |
951 `----------*/
952
953 #ifdef YYPARSE_PARAM
954 # if defined (__STDC__) || defined (__cplusplus)
955 int yyparse (void *YYPARSE_PARAM)
956 # else
957 int yyparse (YYPARSE_PARAM)
958   void *YYPARSE_PARAM;
959 # endif
960 #else /* ! YYPARSE_PARAM */
961 #if defined (__STDC__) || defined (__cplusplus)
962 int
963 yyparse (void)
964 #else
965 int
966 yyparse ()
967
968 #endif
969 #endif
970 {
971   /* The lookahead symbol.  */
972 int yychar;
973
974 /* The semantic value of the lookahead symbol.  */
975 YYSTYPE yylval;
976
977 /* Number of syntax errors so far.  */
978 int yynerrs;
979
980   register int yystate;
981   register int yyn;
982   int yyresult;
983   /* Number of tokens to shift before error messages enabled.  */
984   int yyerrstatus;
985   /* Lookahead token as an internal (translated) token number.  */
986   int yytoken = 0;
987
988   /* Three stacks and their tools:
989      `yyss': related to states,
990      `yyvs': related to semantic values,
991      `yyls': related to locations.
992
993      Refer to the stacks thru separate pointers, to allow yyoverflow
994      to reallocate them elsewhere.  */
995
996   /* The state stack.  */
997   short yyssa[YYINITDEPTH];
998   short *yyss = yyssa;
999   register short *yyssp;
1000
1001   /* The semantic value stack.  */
1002   YYSTYPE yyvsa[YYINITDEPTH];
1003   YYSTYPE *yyvs = yyvsa;
1004   register YYSTYPE *yyvsp;
1005
1006
1007
1008 #define YYPOPSTACK   (yyvsp--, yyssp--)
1009
1010   YYSIZE_T yystacksize = YYINITDEPTH;
1011
1012   /* The variables used to return semantic value and location from the
1013      action routines.  */
1014   YYSTYPE yyval;
1015
1016
1017   /* When reducing, the number of symbols on the RHS of the reduced
1018      rule.  */
1019   int yylen;
1020
1021   YYDPRINTF ((stderr, "Starting parse\n"));
1022
1023   yystate = 0;
1024   yyerrstatus = 0;
1025   yynerrs = 0;
1026   yychar = YYEMPTY;             /* Cause a token to be read.  */
1027
1028   /* Initialize stack pointers.
1029      Waste one element of value and location stack
1030      so that they stay on the same level as the state stack.
1031      The wasted elements are never initialized.  */
1032
1033   yyssp = yyss;
1034   yyvsp = yyvs;
1035
1036   goto yysetstate;
1037
1038 /*------------------------------------------------------------.
1039 | yynewstate -- Push a new state, which is found in yystate.  |
1040 `------------------------------------------------------------*/
1041  yynewstate:
1042   /* In all cases, when you get here, the value and location stacks
1043      have just been pushed. so pushing a state here evens the stacks.
1044      */
1045   yyssp++;
1046
1047  yysetstate:
1048   *yyssp = yystate;
1049
1050   if (yyss + yystacksize - 1 <= yyssp)
1051     {
1052       /* Get the current used size of the three stacks, in elements.  */
1053       YYSIZE_T yysize = yyssp - yyss + 1;
1054
1055 #ifdef yyoverflow
1056       {
1057         /* Give user a chance to reallocate the stack. Use copies of
1058            these so that the &'s don't force the real ones into
1059            memory.  */
1060         YYSTYPE *yyvs1 = yyvs;
1061         short *yyss1 = yyss;
1062
1063
1064         /* Each stack pointer address is followed by the size of the
1065            data in use in that stack, in bytes.  This used to be a
1066            conditional around just the two extra args, but that might
1067            be undefined if yyoverflow is a macro.  */
1068         yyoverflow ("parser stack overflow",
1069                     &yyss1, yysize * sizeof (*yyssp),
1070                     &yyvs1, yysize * sizeof (*yyvsp),
1071
1072                     &yystacksize);
1073
1074         yyss = yyss1;
1075         yyvs = yyvs1;
1076       }
1077 #else /* no yyoverflow */
1078 # ifndef YYSTACK_RELOCATE
1079       goto yyoverflowlab;
1080 # else
1081       /* Extend the stack our own way.  */
1082       if (YYMAXDEPTH <= yystacksize)
1083         goto yyoverflowlab;
1084       yystacksize *= 2;
1085       if (YYMAXDEPTH < yystacksize)
1086         yystacksize = YYMAXDEPTH;
1087
1088       {
1089         short *yyss1 = yyss;
1090         union yyalloc *yyptr =
1091           (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1092         if (! yyptr)
1093           goto yyoverflowlab;
1094         YYSTACK_RELOCATE (yyss);
1095         YYSTACK_RELOCATE (yyvs);
1096
1097 #  undef YYSTACK_RELOCATE
1098         if (yyss1 != yyssa)
1099           YYSTACK_FREE (yyss1);
1100       }
1101 # endif
1102 #endif /* no yyoverflow */
1103
1104       yyssp = yyss + yysize - 1;
1105       yyvsp = yyvs + yysize - 1;
1106
1107
1108       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1109                   (unsigned long int) yystacksize));
1110
1111       if (yyss + yystacksize - 1 <= yyssp)
1112         YYABORT;
1113     }
1114
1115   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1116
1117   goto yybackup;
1118
1119 /*-----------.
1120 | yybackup.  |
1121 `-----------*/
1122 yybackup:
1123
1124 /* Do appropriate processing given the current state.  */
1125 /* Read a lookahead token if we need one and don't already have one.  */
1126 /* yyresume: */
1127
1128   /* First try to decide what to do without reference to lookahead token.  */
1129
1130   yyn = yypact[yystate];
1131   if (yyn == YYPACT_NINF)
1132     goto yydefault;
1133
1134   /* Not known => get a lookahead token if don't already have one.  */
1135
1136   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1137   if (yychar == YYEMPTY)
1138     {
1139       YYDPRINTF ((stderr, "Reading a token: "));
1140       yychar = YYLEX;
1141     }
1142
1143   if (yychar <= YYEOF)
1144     {
1145       yychar = yytoken = YYEOF;
1146       YYDPRINTF ((stderr, "Now at end of input.\n"));
1147     }
1148   else
1149     {
1150       yytoken = YYTRANSLATE (yychar);
1151       YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1152     }
1153
1154   /* If the proper action on seeing token YYTOKEN is to reduce or to
1155      detect an error, take that action.  */
1156   yyn += yytoken;
1157   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1158     goto yydefault;
1159   yyn = yytable[yyn];
1160   if (yyn <= 0)
1161     {
1162       if (yyn == 0 || yyn == YYTABLE_NINF)
1163         goto yyerrlab;
1164       yyn = -yyn;
1165       goto yyreduce;
1166     }
1167
1168   if (yyn == YYFINAL)
1169     YYACCEPT;
1170
1171   /* Shift the lookahead token.  */
1172   YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1173
1174   /* Discard the token being shifted unless it is eof.  */
1175   if (yychar != YYEOF)
1176     yychar = YYEMPTY;
1177
1178   *++yyvsp = yylval;
1179
1180
1181   /* Count tokens shifted since error; after three, turn off error
1182      status.  */
1183   if (yyerrstatus)
1184     yyerrstatus--;
1185
1186   yystate = yyn;
1187   goto yynewstate;
1188
1189
1190 /*-----------------------------------------------------------.
1191 | yydefault -- do the default action for the current state.  |
1192 `-----------------------------------------------------------*/
1193 yydefault:
1194   yyn = yydefact[yystate];
1195   if (yyn == 0)
1196     goto yyerrlab;
1197   goto yyreduce;
1198
1199
1200 /*-----------------------------.
1201 | yyreduce -- Do a reduction.  |
1202 `-----------------------------*/
1203 yyreduce:
1204   /* yyn is the number of a rule to reduce with.  */
1205   yylen = yyr2[yyn];
1206
1207   /* If YYLEN is nonzero, implement the default value of the action:
1208      `$$ = $1'.
1209
1210      Otherwise, the following line sets YYVAL to garbage.
1211      This behavior is undocumented and Bison
1212      users should not rely upon it.  Assigning to YYVAL
1213      unconditionally makes the parser a bit smaller, and it avoids a
1214      GCC warning that YYVAL may be used uninitialized.  */
1215   yyval = yyvsp[1-yylen];
1216
1217
1218   YY_REDUCE_PRINT (yyn);
1219   switch (yyn)
1220     {
1221         case 4:
1222 #line 195 "getdate.y"
1223     { PC.times_seen++; }
1224     break;
1225
1226   case 5:
1227 #line 197 "getdate.y"
1228     { PC.local_zones_seen++; }
1229     break;
1230
1231   case 6:
1232 #line 199 "getdate.y"
1233     { PC.zones_seen++; }
1234     break;
1235
1236   case 7:
1237 #line 201 "getdate.y"
1238     { PC.dates_seen++; }
1239     break;
1240
1241   case 8:
1242 #line 203 "getdate.y"
1243     { PC.days_seen++; }
1244     break;
1245
1246   case 9:
1247 #line 205 "getdate.y"
1248     { PC.rels_seen++; }
1249     break;
1250
1251   case 11:
1252 #line 211 "getdate.y"
1253     {
1254         PC.hour = yyvsp[-1].textintval.value;
1255         PC.minutes = 0;
1256         PC.seconds = 0;
1257         PC.meridian = yyvsp[0].intval;
1258       }
1259     break;
1260
1261   case 12:
1262 #line 218 "getdate.y"
1263     {
1264         PC.hour = yyvsp[-3].textintval.value;
1265         PC.minutes = yyvsp[-1].textintval.value;
1266         PC.seconds = 0;
1267         PC.meridian = yyvsp[0].intval;
1268       }
1269     break;
1270
1271   case 13:
1272 #line 225 "getdate.y"
1273     {
1274         PC.hour = yyvsp[-3].textintval.value;
1275         PC.minutes = yyvsp[-1].textintval.value;
1276         PC.meridian = MER24;
1277         PC.zones_seen++;
1278         PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1279       }
1280     break;
1281
1282   case 14:
1283 #line 233 "getdate.y"
1284     {
1285         PC.hour = yyvsp[-5].textintval.value;
1286         PC.minutes = yyvsp[-3].textintval.value;
1287         PC.seconds = yyvsp[-1].textintval.value;
1288         PC.meridian = yyvsp[0].intval;
1289       }
1290     break;
1291
1292   case 15:
1293 #line 240 "getdate.y"
1294     {
1295         PC.hour = yyvsp[-5].textintval.value;
1296         PC.minutes = yyvsp[-3].textintval.value;
1297         PC.seconds = yyvsp[-1].textintval.value;
1298         PC.meridian = MER24;
1299         PC.zones_seen++;
1300         PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1301       }
1302     break;
1303
1304   case 16:
1305 #line 252 "getdate.y"
1306     { PC.local_isdst = yyvsp[0].intval; }
1307     break;
1308
1309   case 17:
1310 #line 254 "getdate.y"
1311     { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1312     break;
1313
1314   case 18:
1315 #line 259 "getdate.y"
1316     { PC.time_zone = yyvsp[0].intval; }
1317     break;
1318
1319   case 19:
1320 #line 261 "getdate.y"
1321     { PC.time_zone = yyvsp[0].intval + 60; }
1322     break;
1323
1324   case 20:
1325 #line 263 "getdate.y"
1326     { PC.time_zone = yyvsp[-1].intval + 60; }
1327     break;
1328
1329   case 21:
1330 #line 268 "getdate.y"
1331     {
1332         PC.day_ordinal = 1;
1333         PC.day_number = yyvsp[0].intval;
1334       }
1335     break;
1336
1337   case 22:
1338 #line 273 "getdate.y"
1339     {
1340         PC.day_ordinal = 1;
1341         PC.day_number = yyvsp[-1].intval;
1342       }
1343     break;
1344
1345   case 23:
1346 #line 278 "getdate.y"
1347     {
1348         PC.day_ordinal = yyvsp[-1].textintval.value;
1349         PC.day_number = yyvsp[0].intval;
1350       }
1351     break;
1352
1353   case 24:
1354 #line 286 "getdate.y"
1355     {
1356         PC.month = yyvsp[-2].textintval.value;
1357         PC.day = yyvsp[0].textintval.value;
1358       }
1359     break;
1360
1361   case 25:
1362 #line 291 "getdate.y"
1363     {
1364         /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1365            otherwise as MM/DD/YY.
1366            The goal in recognizing YYYY/MM/DD is solely to support legacy
1367            machine-generated dates like those in an RCS log listing.  If
1368            you want portability, use the ISO 8601 format.  */
1369         if (4 <= yyvsp[-4].textintval.digits)
1370           {
1371             PC.year = yyvsp[-4].textintval;
1372             PC.month = yyvsp[-2].textintval.value;
1373             PC.day = yyvsp[0].textintval.value;
1374           }
1375         else
1376           {
1377             PC.month = yyvsp[-4].textintval.value;
1378             PC.day = yyvsp[-2].textintval.value;
1379             PC.year = yyvsp[0].textintval;
1380           }
1381       }
1382     break;
1383
1384   case 26:
1385 #line 311 "getdate.y"
1386     {
1387         /* ISO 8601 format.  YYYY-MM-DD.  */
1388         PC.year = yyvsp[-2].textintval;
1389         PC.month = -yyvsp[-1].textintval.value;
1390         PC.day = -yyvsp[0].textintval.value;
1391       }
1392     break;
1393
1394   case 27:
1395 #line 318 "getdate.y"
1396     {
1397         /* e.g. 17-JUN-1992.  */
1398         PC.day = yyvsp[-2].textintval.value;
1399         PC.month = yyvsp[-1].intval;
1400         PC.year.value = -yyvsp[0].textintval.value;
1401         PC.year.digits = yyvsp[0].textintval.digits;
1402       }
1403     break;
1404
1405   case 28:
1406 #line 326 "getdate.y"
1407     {
1408         PC.month = yyvsp[-1].intval;
1409         PC.day = yyvsp[0].textintval.value;
1410       }
1411     break;
1412
1413   case 29:
1414 #line 331 "getdate.y"
1415     {
1416         PC.month = yyvsp[-3].intval;
1417         PC.day = yyvsp[-2].textintval.value;
1418         PC.year = yyvsp[0].textintval;
1419       }
1420     break;
1421
1422   case 30:
1423 #line 337 "getdate.y"
1424     {
1425         PC.day = yyvsp[-1].textintval.value;
1426         PC.month = yyvsp[0].intval;
1427       }
1428     break;
1429
1430   case 31:
1431 #line 342 "getdate.y"
1432     {
1433         PC.day = yyvsp[-2].textintval.value;
1434         PC.month = yyvsp[-1].intval;
1435         PC.year = yyvsp[0].textintval;
1436       }
1437     break;
1438
1439   case 32:
1440 #line 351 "getdate.y"
1441     {
1442         PC.rel_seconds = -PC.rel_seconds;
1443         PC.rel_minutes = -PC.rel_minutes;
1444         PC.rel_hour = -PC.rel_hour;
1445         PC.rel_day = -PC.rel_day;
1446         PC.rel_month = -PC.rel_month;
1447         PC.rel_year = -PC.rel_year;
1448       }
1449     break;
1450
1451   case 34:
1452 #line 364 "getdate.y"
1453     { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1454     break;
1455
1456   case 35:
1457 #line 366 "getdate.y"
1458     { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1459     break;
1460
1461   case 36:
1462 #line 368 "getdate.y"
1463     { PC.rel_year += yyvsp[0].intval; }
1464     break;
1465
1466   case 37:
1467 #line 370 "getdate.y"
1468     { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1469     break;
1470
1471   case 38:
1472 #line 372 "getdate.y"
1473     { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1474     break;
1475
1476   case 39:
1477 #line 374 "getdate.y"
1478     { PC.rel_month += yyvsp[0].intval; }
1479     break;
1480
1481   case 40:
1482 #line 376 "getdate.y"
1483     { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1484     break;
1485
1486   case 41:
1487 #line 378 "getdate.y"
1488     { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1489     break;
1490
1491   case 42:
1492 #line 380 "getdate.y"
1493     { PC.rel_day += yyvsp[0].intval; }
1494     break;
1495
1496   case 43:
1497 #line 382 "getdate.y"
1498     { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1499     break;
1500
1501   case 44:
1502 #line 384 "getdate.y"
1503     { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1504     break;
1505
1506   case 45:
1507 #line 386 "getdate.y"
1508     { PC.rel_hour += yyvsp[0].intval; }
1509     break;
1510
1511   case 46:
1512 #line 388 "getdate.y"
1513     { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1514     break;
1515
1516   case 47:
1517 #line 390 "getdate.y"
1518     { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1519     break;
1520
1521   case 48:
1522 #line 392 "getdate.y"
1523     { PC.rel_minutes += yyvsp[0].intval; }
1524     break;
1525
1526   case 49:
1527 #line 394 "getdate.y"
1528     { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1529     break;
1530
1531   case 50:
1532 #line 396 "getdate.y"
1533     { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1534     break;
1535
1536   case 51:
1537 #line 398 "getdate.y"
1538     { PC.rel_seconds += yyvsp[0].intval; }
1539     break;
1540
1541   case 52:
1542 #line 403 "getdate.y"
1543     {
1544         if (PC.dates_seen
1545             && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
1546           PC.year = yyvsp[0].textintval;
1547         else
1548           {
1549             if (4 < yyvsp[0].textintval.digits)
1550               {
1551                 PC.dates_seen++;
1552                 PC.day = yyvsp[0].textintval.value % 100;
1553                 PC.month = (yyvsp[0].textintval.value / 100) % 100;
1554                 PC.year.value = yyvsp[0].textintval.value / 10000;
1555                 PC.year.digits = yyvsp[0].textintval.digits - 4;
1556               }
1557             else
1558               {
1559                 PC.times_seen++;
1560                 if (yyvsp[0].textintval.digits <= 2)
1561                   {
1562                     PC.hour = yyvsp[0].textintval.value;
1563                     PC.minutes = 0;
1564                   }
1565                 else
1566                   {
1567                     PC.hour = yyvsp[0].textintval.value / 100;
1568                     PC.minutes = yyvsp[0].textintval.value % 100;
1569                   }
1570                 PC.seconds = 0;
1571                 PC.meridian = MER24;
1572               }
1573           }
1574       }
1575     break;
1576
1577   case 53:
1578 #line 439 "getdate.y"
1579     { yyval.intval = MER24; }
1580     break;
1581
1582   case 54:
1583 #line 441 "getdate.y"
1584     { yyval.intval = yyvsp[0].intval; }
1585     break;
1586
1587
1588     }
1589
1590 /* Line 999 of yacc.c.  */
1591 #line 1593 "getdate.c"
1592 \f
1593   yyvsp -= yylen;
1594   yyssp -= yylen;
1595
1596
1597   YY_STACK_PRINT (yyss, yyssp);
1598
1599   *++yyvsp = yyval;
1600
1601
1602   /* Now `shift' the result of the reduction.  Determine what state
1603      that goes to, based on the state we popped back to and the rule
1604      number reduced by.  */
1605
1606   yyn = yyr1[yyn];
1607
1608   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1609   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1610     yystate = yytable[yystate];
1611   else
1612     yystate = yydefgoto[yyn - YYNTOKENS];
1613
1614   goto yynewstate;
1615
1616
1617 /*------------------------------------.
1618 | yyerrlab -- here on detecting error |
1619 `------------------------------------*/
1620 yyerrlab:
1621   /* If not already recovering from an error, report this error.  */
1622   if (!yyerrstatus)
1623     {
1624       ++yynerrs;
1625 #if YYERROR_VERBOSE
1626       yyn = yypact[yystate];
1627
1628       if (YYPACT_NINF < yyn && yyn < YYLAST)
1629         {
1630           YYSIZE_T yysize = 0;
1631           int yytype = YYTRANSLATE (yychar);
1632           char *yymsg;
1633           int yyx, yycount;
1634
1635           yycount = 0;
1636           /* Start YYX at -YYN if negative to avoid negative indexes in
1637              YYCHECK.  */
1638           for (yyx = yyn < 0 ? -yyn : 0;
1639                yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1640             if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1641               yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1642           yysize += yystrlen ("syntax error, unexpected ") + 1;
1643           yysize += yystrlen (yytname[yytype]);
1644           yymsg = (char *) YYSTACK_ALLOC (yysize);
1645           if (yymsg != 0)
1646             {
1647               char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1648               yyp = yystpcpy (yyp, yytname[yytype]);
1649
1650               if (yycount < 5)
1651                 {
1652                   yycount = 0;
1653                   for (yyx = yyn < 0 ? -yyn : 0;
1654                        yyx < (int) (sizeof (yytname) / sizeof (char *));
1655                        yyx++)
1656                     if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1657                       {
1658                         const char *yyq = ! yycount ? ", expecting " : " or ";
1659                         yyp = yystpcpy (yyp, yyq);
1660                         yyp = yystpcpy (yyp, yytname[yyx]);
1661                         yycount++;
1662                       }
1663                 }
1664               yyerror (yymsg);
1665               YYSTACK_FREE (yymsg);
1666             }
1667           else
1668             yyerror ("syntax error; also virtual memory exhausted");
1669         }
1670       else
1671 #endif /* YYERROR_VERBOSE */
1672         yyerror ("syntax error");
1673     }
1674
1675
1676
1677   if (yyerrstatus == 3)
1678     {
1679       /* If just tried and failed to reuse lookahead token after an
1680          error, discard it.  */
1681
1682       /* Return failure if at end of input.  */
1683       if (yychar == YYEOF)
1684         {
1685           /* Pop the error token.  */
1686           YYPOPSTACK;
1687           /* Pop the rest of the stack.  */
1688           while (yyss < yyssp)
1689             {
1690               YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1691               yydestruct (yystos[*yyssp], yyvsp);
1692               YYPOPSTACK;
1693             }
1694           YYABORT;
1695         }
1696
1697       YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1698       yydestruct (yytoken, &yylval);
1699       yychar = YYEMPTY;
1700
1701     }
1702
1703   /* Else will try to reuse lookahead token after shifting the error
1704      token.  */
1705   goto yyerrlab1;
1706
1707
1708 /*----------------------------------------------------.
1709 | yyerrlab1 -- error raised explicitly by an action.  |
1710 `----------------------------------------------------*/
1711 yyerrlab1:
1712   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
1713
1714   for (;;)
1715     {
1716       yyn = yypact[yystate];
1717       if (yyn != YYPACT_NINF)
1718         {
1719           yyn += YYTERROR;
1720           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1721             {
1722               yyn = yytable[yyn];
1723               if (0 < yyn)
1724                 break;
1725             }
1726         }
1727
1728       /* Pop the current state because it cannot handle the error token.  */
1729       if (yyssp == yyss)
1730         YYABORT;
1731
1732       YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1733       yydestruct (yystos[yystate], yyvsp);
1734       yyvsp--;
1735       yystate = *--yyssp;
1736
1737       YY_STACK_PRINT (yyss, yyssp);
1738     }
1739
1740   if (yyn == YYFINAL)
1741     YYACCEPT;
1742
1743   YYDPRINTF ((stderr, "Shifting error token, "));
1744
1745   *++yyvsp = yylval;
1746
1747
1748   yystate = yyn;
1749   goto yynewstate;
1750
1751
1752 /*-------------------------------------.
1753 | yyacceptlab -- YYACCEPT comes here.  |
1754 `-------------------------------------*/
1755 yyacceptlab:
1756   yyresult = 0;
1757   goto yyreturn;
1758
1759 /*-----------------------------------.
1760 | yyabortlab -- YYABORT comes here.  |
1761 `-----------------------------------*/
1762 yyabortlab:
1763   yyresult = 1;
1764   goto yyreturn;
1765
1766 #ifndef yyoverflow
1767 /*----------------------------------------------.
1768 | yyoverflowlab -- parser overflow comes here.  |
1769 `----------------------------------------------*/
1770 yyoverflowlab:
1771   yyerror ("parser stack overflow");
1772   yyresult = 2;
1773   /* Fall through.  */
1774 #endif
1775
1776 yyreturn:
1777 #ifndef yyoverflow
1778   if (yyss != yyssa)
1779     YYSTACK_FREE (yyss);
1780 #endif
1781   return yyresult;
1782 }
1783
1784
1785 #line 444 "getdate.y"
1786
1787
1788 /* Include this file down here because bison inserts code above which
1789    may define-away `const'.  We want the prototype for get_date to have
1790    the same signature as the function definition.  */
1791 #include "modules/getdate.h"
1792
1793 #ifndef gmtime
1794 struct tm *gmtime ();
1795 #endif
1796 #ifndef localtime
1797 struct tm *localtime ();
1798 #endif
1799 #ifndef mktime
1800 time_t mktime ();
1801 #endif
1802
1803 static table const meridian_table[] =
1804 {
1805   { "AM",   tMERIDIAN, MERam },
1806   { "A.M.", tMERIDIAN, MERam },
1807   { "PM",   tMERIDIAN, MERpm },
1808   { "P.M.", tMERIDIAN, MERpm },
1809   { 0, 0, 0 }
1810 };
1811
1812 static table const dst_table[] =
1813 {
1814   { "DST", tDST, 0 }
1815 };
1816
1817 static table const month_and_day_table[] =
1818 {
1819   { "JANUARY",  tMONTH,  1 },
1820   { "FEBRUARY", tMONTH,  2 },
1821   { "MARCH",    tMONTH,  3 },
1822   { "APRIL",    tMONTH,  4 },
1823   { "MAY",      tMONTH,  5 },
1824   { "JUNE",     tMONTH,  6 },
1825   { "JULY",     tMONTH,  7 },
1826   { "AUGUST",   tMONTH,  8 },
1827   { "SEPTEMBER",tMONTH,  9 },
1828   { "SEPT",     tMONTH,  9 },
1829   { "OCTOBER",  tMONTH, 10 },
1830   { "NOVEMBER", tMONTH, 11 },
1831   { "DECEMBER", tMONTH, 12 },
1832   { "SUNDAY",   tDAY,    0 },
1833   { "MONDAY",   tDAY,    1 },
1834   { "TUESDAY",  tDAY,    2 },
1835   { "TUES",     tDAY,    2 },
1836   { "WEDNESDAY",tDAY,    3 },
1837   { "WEDNES",   tDAY,    3 },
1838   { "THURSDAY", tDAY,    4 },
1839   { "THUR",     tDAY,    4 },
1840   { "THURS",    tDAY,    4 },
1841   { "FRIDAY",   tDAY,    5 },
1842   { "SATURDAY", tDAY,    6 },
1843   { 0, 0, 0 }
1844 };
1845
1846 static table const time_units_table[] =
1847 {
1848   { "YEAR",     tYEAR_UNIT,      1 },
1849   { "MONTH",    tMONTH_UNIT,     1 },
1850   { "FORTNIGHT",tDAY_UNIT,      14 },
1851   { "WEEK",     tDAY_UNIT,       7 },
1852   { "DAY",      tDAY_UNIT,       1 },
1853   { "HOUR",     tHOUR_UNIT,      1 },
1854   { "MINUTE",   tMINUTE_UNIT,    1 },
1855   { "MIN",      tMINUTE_UNIT,    1 },
1856   { "SECOND",   tSEC_UNIT,       1 },
1857   { "SEC",      tSEC_UNIT,       1 },
1858   { 0, 0, 0 }
1859 };
1860
1861 /* Assorted relative-time words. */
1862 static table const relative_time_table[] =
1863 {
1864   { "TOMORROW", tMINUTE_UNIT,   24 * 60 },
1865   { "YESTERDAY",tMINUTE_UNIT,   - (24 * 60) },
1866   { "TODAY",    tMINUTE_UNIT,    0 },
1867   { "NOW",      tMINUTE_UNIT,    0 },
1868   { "LAST",     tUNUMBER,       -1 },
1869   { "THIS",     tUNUMBER,        0 },
1870   { "NEXT",     tUNUMBER,        1 },
1871   { "FIRST",    tUNUMBER,        1 },
1872 /*{ "SECOND",   tUNUMBER,        2 }, */
1873   { "THIRD",    tUNUMBER,        3 },
1874   { "FOURTH",   tUNUMBER,        4 },
1875   { "FIFTH",    tUNUMBER,        5 },
1876   { "SIXTH",    tUNUMBER,        6 },
1877   { "SEVENTH",  tUNUMBER,        7 },
1878   { "EIGHTH",   tUNUMBER,        8 },
1879   { "NINTH",    tUNUMBER,        9 },
1880   { "TENTH",    tUNUMBER,       10 },
1881   { "ELEVENTH", tUNUMBER,       11 },
1882   { "TWELFTH",  tUNUMBER,       12 },
1883   { "AGO",      tAGO,            1 },
1884   { 0, 0, 0 }
1885 };
1886
1887 /* The time zone table.  This table is necessarily incomplete, as time
1888    zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1889    as Eastern time in Australia, not as US Eastern Standard Time.
1890    You cannot rely on getdate to handle arbitrary time zone
1891    abbreviations; use numeric abbreviations like `-0500' instead.  */
1892 static table const time_zone_table[] =
1893 {
1894   { "GMT",      tZONE,     HOUR ( 0) }, /* Greenwich Mean */
1895   { "UT",       tZONE,     HOUR ( 0) }, /* Universal (Coordinated) */
1896   { "UTC",      tZONE,     HOUR ( 0) },
1897   { "WET",      tZONE,     HOUR ( 0) }, /* Western European */
1898   { "WEST",     tDAYZONE,  HOUR ( 0) }, /* Western European Summer */
1899   { "BST",      tDAYZONE,  HOUR ( 0) }, /* British Summer */
1900   { "ART",      tZONE,    -HOUR ( 3) }, /* Argentina */
1901   { "BRT",      tZONE,    -HOUR ( 3) }, /* Brazil */
1902   { "BRST",     tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1903   { "NST",      tZONE,   -(HOUR ( 3) + 30) },   /* Newfoundland Standard */
1904   { "NDT",      tDAYZONE,-(HOUR ( 3) + 30) },   /* Newfoundland Daylight */
1905   { "AST",      tZONE,    -HOUR ( 4) }, /* Atlantic Standard */
1906   { "ADT",      tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1907   { "CLT",      tZONE,    -HOUR ( 4) }, /* Chile */
1908   { "CLST",     tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1909   { "EST",      tZONE,    -HOUR ( 5) }, /* Eastern Standard */
1910   { "EDT",      tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1911   { "CST",      tZONE,    -HOUR ( 6) }, /* Central Standard */
1912   { "CDT",      tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1913   { "MST",      tZONE,    -HOUR ( 7) }, /* Mountain Standard */
1914   { "MDT",      tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1915   { "PST",      tZONE,    -HOUR ( 8) }, /* Pacific Standard */
1916   { "PDT",      tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1917   { "AKST",     tZONE,    -HOUR ( 9) }, /* Alaska Standard */
1918   { "AKDT",     tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1919   { "HST",      tZONE,    -HOUR (10) }, /* Hawaii Standard */
1920   { "HAST",     tZONE,    -HOUR (10) }, /* Hawaii-Aleutian Standard */
1921   { "HADT",     tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1922   { "SST",      tZONE,    -HOUR (12) }, /* Samoa Standard */
1923   { "WAT",      tZONE,     HOUR ( 1) }, /* West Africa */
1924   { "CET",      tZONE,     HOUR ( 1) }, /* Central European */
1925   { "CEST",     tDAYZONE,  HOUR ( 1) }, /* Central European Summer */
1926   { "MET",      tZONE,     HOUR ( 1) }, /* Middle European */
1927   { "MEZ",      tZONE,     HOUR ( 1) }, /* Middle European */
1928   { "MEST",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
1929   { "MESZ",     tDAYZONE,  HOUR ( 1) }, /* Middle European Summer */
1930   { "EET",      tZONE,     HOUR ( 2) }, /* Eastern European */
1931   { "EEST",     tDAYZONE,  HOUR ( 2) }, /* Eastern European Summer */
1932   { "CAT",      tZONE,     HOUR ( 2) }, /* Central Africa */
1933   { "SAST",     tZONE,     HOUR ( 2) }, /* South Africa Standard */
1934   { "EAT",      tZONE,     HOUR ( 3) }, /* East Africa */
1935   { "MSK",      tZONE,     HOUR ( 3) }, /* Moscow */
1936   { "MSD",      tDAYZONE,  HOUR ( 3) }, /* Moscow Daylight */
1937   { "IST",      tZONE,    (HOUR ( 5) + 30) },   /* India Standard */
1938   { "SGT",      tZONE,     HOUR ( 8) }, /* Singapore */
1939   { "KST",      tZONE,     HOUR ( 9) }, /* Korea Standard */
1940   { "JST",      tZONE,     HOUR ( 9) }, /* Japan Standard */
1941   { "GST",      tZONE,     HOUR (10) }, /* Guam Standard */
1942   { "NZST",     tZONE,     HOUR (12) }, /* New Zealand Standard */
1943   { "NZDT",     tDAYZONE,  HOUR (12) }, /* New Zealand Daylight */
1944   { 0, 0, 0  }
1945 };
1946
1947 /* Military time zone table. */
1948 static table const military_table[] =
1949 {
1950   { "A", tZONE, -HOUR ( 1) },
1951   { "B", tZONE, -HOUR ( 2) },
1952   { "C", tZONE, -HOUR ( 3) },
1953   { "D", tZONE, -HOUR ( 4) },
1954   { "E", tZONE, -HOUR ( 5) },
1955   { "F", tZONE, -HOUR ( 6) },
1956   { "G", tZONE, -HOUR ( 7) },
1957   { "H", tZONE, -HOUR ( 8) },
1958   { "I", tZONE, -HOUR ( 9) },
1959   { "K", tZONE, -HOUR (10) },
1960   { "L", tZONE, -HOUR (11) },
1961   { "M", tZONE, -HOUR (12) },
1962   { "N", tZONE,  HOUR ( 1) },
1963   { "O", tZONE,  HOUR ( 2) },
1964   { "P", tZONE,  HOUR ( 3) },
1965   { "Q", tZONE,  HOUR ( 4) },
1966   { "R", tZONE,  HOUR ( 5) },
1967   { "S", tZONE,  HOUR ( 6) },
1968   { "T", tZONE,  HOUR ( 7) },
1969   { "U", tZONE,  HOUR ( 8) },
1970   { "V", tZONE,  HOUR ( 9) },
1971   { "W", tZONE,  HOUR (10) },
1972   { "X", tZONE,  HOUR (11) },
1973   { "Y", tZONE,  HOUR (12) },
1974   { "Z", tZONE,  HOUR ( 0) },
1975   { 0, 0, 0 }
1976 };
1977
1978 \f
1979
1980 static int
1981 to_hour (int hours, int meridian)
1982 {
1983   switch (meridian)
1984     {
1985     case MER24:
1986       return 0 <= hours && hours < 24 ? hours : -1;
1987     case MERam:
1988       return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1989     case MERpm:
1990       return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
1991     default:
1992       abort ();
1993     }
1994   /* NOTREACHED */
1995     return 0;
1996 }
1997
1998 static int
1999 to_year (textint textyear)
2000 {
2001   int year = textyear.value;
2002
2003   if (year < 0)
2004     year = -year;
2005
2006   /* XPG4 suggests that years 00-68 map to 2000-2068, and
2007      years 69-99 map to 1969-1999.  */
2008   if (textyear.digits == 2)
2009     year += year < 69 ? 2000 : 1900;
2010
2011   return year;
2012 }
2013
2014 static table const *
2015 lookup_zone (parser_control const *pc, char const *name)
2016 {
2017   table const *tp;
2018
2019   /* Try local zone abbreviations first; they're more likely to be right.  */
2020   for (tp = pc->local_time_zone_table; tp->name; tp++)
2021     if (strcmp (name, tp->name) == 0)
2022       return tp;
2023
2024   for (tp = time_zone_table; tp->name; tp++)
2025     if (strcmp (name, tp->name) == 0)
2026       return tp;
2027
2028   return 0;
2029 }
2030
2031 #if ! HAVE_TM_GMTOFF
2032 /* Yield the difference between *A and *B,
2033    measured in seconds, ignoring leap seconds.
2034    The body of this function is taken directly from the GNU C Library;
2035    see src/strftime.c.  */
2036 static int
2037 tm_diff (struct tm const *a, struct tm const *b)
2038 {
2039   /* Compute intervening leap days correctly even if year is negative.
2040      Take care to avoid int overflow in leap day calculations,
2041      but it's OK to assume that A and B are close to each other.  */
2042   int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2043   int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2044   int a100 = a4 / 25 - (a4 % 25 < 0);
2045   int b100 = b4 / 25 - (b4 % 25 < 0);
2046   int a400 = a100 >> 2;
2047   int b400 = b100 >> 2;
2048   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2049   int years = a->tm_year - b->tm_year;
2050   int days = (365 * years + intervening_leap_days
2051               + (a->tm_yday - b->tm_yday));
2052   return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2053                 + (a->tm_min - b->tm_min))
2054           + (a->tm_sec - b->tm_sec));
2055 }
2056 #endif /* ! HAVE_TM_GMTOFF */
2057
2058 static table const *
2059 lookup_word (parser_control const *pc, char *word)
2060 {
2061   char *p;
2062   char *q;
2063   size_t wordlen;
2064   table const *tp;
2065   int i;
2066   int abbrev;
2067
2068   /* Make it uppercase.  */
2069   for (p = word; *p; p++)
2070     if (ISLOWER ((unsigned char) *p))
2071       *p = toupper ((unsigned char) *p);
2072
2073   for (tp = meridian_table; tp->name; tp++)
2074     if (strcmp (word, tp->name) == 0)
2075       return tp;
2076
2077   /* See if we have an abbreviation for a month. */
2078   wordlen = strlen (word);
2079   abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2080
2081   for (tp = month_and_day_table; tp->name; tp++)
2082     if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2083       return tp;
2084
2085   if ((tp = lookup_zone (pc, word)))
2086     return tp;
2087
2088   if (strcmp (word, dst_table[0].name) == 0)
2089     return dst_table;
2090
2091   for (tp = time_units_table; tp->name; tp++)
2092     if (strcmp (word, tp->name) == 0)
2093       return tp;
2094
2095   /* Strip off any plural and try the units table again. */
2096   if (word[wordlen - 1] == 'S')
2097     {
2098       word[wordlen - 1] = '\0';
2099       for (tp = time_units_table; tp->name; tp++)
2100         if (strcmp (word, tp->name) == 0)
2101           return tp;
2102       word[wordlen - 1] = 'S';  /* For "this" in relative_time_table.  */
2103     }
2104
2105   for (tp = relative_time_table; tp->name; tp++)
2106     if (strcmp (word, tp->name) == 0)
2107       return tp;
2108
2109   /* Military time zones. */
2110   if (wordlen == 1)
2111     for (tp = military_table; tp->name; tp++)
2112       if (word[0] == tp->name[0])
2113         return tp;
2114
2115   /* Drop out any periods and try the time zone table again. */
2116   for (i = 0, p = q = word; (*p = *q); q++)
2117     if (*q == '.')
2118       i = 1;
2119     else
2120       p++;
2121   if (i && (tp = lookup_zone (pc, word)))
2122     return tp;
2123
2124   return 0;
2125 }
2126
2127 static int
2128 yylex (YYSTYPE *lvalp, parser_control *pc)
2129 {
2130   unsigned char c;
2131   int count;
2132
2133   for (;;)
2134     {
2135       while (c = *pc->input, ISSPACE (c))
2136         pc->input++;
2137
2138       if (ISDIGIT (c) || c == '-' || c == '+')
2139         {
2140           char const *p;
2141           int sign;
2142           int value;
2143           if (c == '-' || c == '+')
2144             {
2145               sign = c == '-' ? -1 : 1;
2146               c = *++pc->input;
2147               if (! ISDIGIT (c))
2148                 /* skip the '-' sign */
2149                 continue;
2150             }
2151           else
2152             sign = 0;
2153           p = pc->input;
2154           value = 0;
2155           do
2156             {
2157               value = 10 * value + c - '0';
2158               c = *++p;
2159             }
2160           while (ISDIGIT (c));
2161           lvalp->textintval.value = sign < 0 ? -value : value;
2162           lvalp->textintval.digits = p - pc->input;
2163           pc->input = p;
2164           return sign ? tSNUMBER : tUNUMBER;
2165         }
2166
2167       if (ISALPHA (c))
2168         {
2169           char buff[20];
2170           char *p = buff;
2171           table const *tp;
2172
2173           do
2174             {
2175               if (p < buff + sizeof buff - 1)
2176                 *p++ = c;
2177               c = *++pc->input;
2178             }
2179           while (ISALPHA (c) || c == '.');
2180
2181           *p = '\0';
2182           tp = lookup_word (pc, buff);
2183           if (! tp)
2184             return '?';
2185           lvalp->intval = tp->value;
2186           return tp->type;
2187         }
2188
2189       if (c != '(')
2190         return *pc->input++;
2191       count = 0;
2192       do
2193         {
2194           c = *pc->input++;
2195           if (c == '\0')
2196             return c;
2197           if (c == '(')
2198             count++;
2199           else if (c == ')')
2200             count--;
2201         }
2202       while (count > 0);
2203     }
2204 }
2205
2206 /* Do nothing if the parser reports an error.  */
2207 static int
2208 yyerror (char *s ATTRIBUTE_UNUSED)
2209 {
2210   return 0;
2211 }
2212
2213 /* Parse a date/time string P.  Return the corresponding time_t value,
2214    or (time_t) -1 if there is an error.  P can be an incomplete or
2215    relative time specification; if so, use *NOW as the basis for the
2216    returned time.  */
2217 time_t
2218 get_date (const char *p, const time_t *now)
2219 {
2220   time_t Start = now ? *now : time (0);
2221   struct tm *tmp = localtime (&Start);
2222   struct tm tm;
2223   struct tm tm0;
2224   parser_control pc;
2225
2226   if (! tmp)
2227     return -1;
2228
2229   pc.input = p;
2230   pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2231   pc.year.digits = 4;
2232   pc.month = tmp->tm_mon + 1;
2233   pc.day = tmp->tm_mday;
2234   pc.hour = tmp->tm_hour;
2235   pc.minutes = tmp->tm_min;
2236   pc.seconds = tmp->tm_sec;
2237   tm.tm_isdst = tmp->tm_isdst;
2238
2239   pc.meridian = MER24;
2240   pc.rel_seconds = 0;
2241   pc.rel_minutes = 0;
2242   pc.rel_hour = 0;
2243   pc.rel_day = 0;
2244   pc.rel_month = 0;
2245   pc.rel_year = 0;
2246   pc.dates_seen = 0;
2247   pc.days_seen = 0;
2248   pc.rels_seen = 0;
2249   pc.times_seen = 0;
2250   pc.local_zones_seen = 0;
2251   pc.zones_seen = 0;
2252
2253 #if HAVE_STRUCT_TM_TM_ZONE
2254   pc.local_time_zone_table[0].name = tmp->tm_zone;
2255   pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2256   pc.local_time_zone_table[0].value = tmp->tm_isdst;
2257   pc.local_time_zone_table[1].name = 0;
2258
2259   /* Probe the names used in the next three calendar quarters, looking
2260      for a tm_isdst different from the one we already have.  */
2261   {
2262     int quarter;
2263     for (quarter = 1; quarter <= 3; quarter++)
2264       {
2265         time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2266         struct tm *probe_tm = localtime (&probe);
2267         if (probe_tm && probe_tm->tm_zone
2268             && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2269           {
2270               {
2271                 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2272                 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2273                 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2274                 pc.local_time_zone_table[2].name = 0;
2275               }
2276             break;
2277           }
2278       }
2279   }
2280 #else
2281 #if HAVE_TZNAME
2282   {
2283 # ifndef tzname
2284     extern char *tzname[];
2285 # endif
2286     int i;
2287     for (i = 0; i < 2; i++)
2288       {
2289         pc.local_time_zone_table[i].name = tzname[i];
2290         pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2291         pc.local_time_zone_table[i].value = i;
2292       }
2293     pc.local_time_zone_table[i].name = 0;
2294   }
2295 #else
2296   pc.local_time_zone_table[0].name = 0;
2297 #endif
2298 #endif
2299
2300   if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2301       && ! strcmp (pc.local_time_zone_table[0].name,
2302                    pc.local_time_zone_table[1].name))
2303     {
2304       /* This locale uses the same abbrevation for standard and
2305          daylight times.  So if we see that abbreviation, we don't
2306          know whether it's daylight time.  */
2307       pc.local_time_zone_table[0].value = -1;
2308       pc.local_time_zone_table[1].name = 0;
2309     }
2310
2311   if (yyparse (&pc) != 0
2312       || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2313       || 1 < (pc.local_zones_seen + pc.zones_seen)
2314       || (pc.local_zones_seen && 1 < pc.local_isdst))
2315     return -1;
2316
2317   tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2318   tm.tm_mon = pc.month - 1 + pc.rel_month;
2319   tm.tm_mday = pc.day + pc.rel_day;
2320   if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2321     {
2322       tm.tm_hour = to_hour (pc.hour, pc.meridian);
2323       if (tm.tm_hour < 0)
2324         return -1;
2325       tm.tm_min = pc.minutes;
2326       tm.tm_sec = pc.seconds;
2327     }
2328   else
2329     {
2330       tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2331     }
2332
2333   /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2334      or if the relative time stamp mentions days, months, or years.  */
2335   if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2336       | pc.rel_month | pc.rel_year)
2337     tm.tm_isdst = -1;
2338
2339   /* But if the input explicitly specifies local time with or without
2340      DST, give mktime that information.  */
2341   if (pc.local_zones_seen)
2342     tm.tm_isdst = pc.local_isdst;
2343
2344   tm0 = tm;
2345
2346   Start = mktime (&tm);
2347
2348   if (Start == (time_t) -1)
2349     {
2350
2351       /* Guard against falsely reporting errors near the time_t boundaries
2352          when parsing times in other time zones.  For example, if the min
2353          time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2354          of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2355          we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2356          we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2357          zone by 24 hours to compensate.  This algorithm assumes that
2358          there is no DST transition within a day of the time_t boundaries.  */
2359       if (pc.zones_seen)
2360         {
2361           tm = tm0;
2362           if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2363             {
2364               tm.tm_mday++;
2365               pc.time_zone += 24 * 60;
2366             }
2367           else
2368             {
2369               tm.tm_mday--;
2370               pc.time_zone -= 24 * 60;
2371             }
2372           Start = mktime (&tm);
2373         }
2374
2375       if (Start == (time_t) -1)
2376         return Start;
2377     }
2378
2379   if (pc.days_seen && ! pc.dates_seen)
2380     {
2381       tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2382                      + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2383       tm.tm_isdst = -1;
2384       Start = mktime (&tm);
2385       if (Start == (time_t) -1)
2386         return Start;
2387     }
2388
2389   if (pc.zones_seen)
2390     {
2391       int delta = pc.time_zone * 60;
2392 #ifdef HAVE_TM_GMTOFF
2393       delta -= tm.tm_gmtoff;
2394 #else
2395       struct tm *gmt = gmtime (&Start);
2396       if (! gmt)
2397         return -1;
2398       delta -= tm_diff (&tm, gmt);
2399 #endif
2400       if ((Start < Start - delta) != (delta < 0))
2401         return -1;      /* time_t overflow */
2402       Start -= delta;
2403     }
2404
2405   /* Add relative hours, minutes, and seconds.  Ignore leap seconds;
2406      i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2407      leap second.  Typically this is not what the user wants, but it's
2408      too hard to do it the other way, because the time zone indicator
2409      must be applied before relative times, and if mktime is applied
2410      again the time zone will be lost.  */
2411   {
2412     time_t t0 = Start;
2413     long d1 = 60 * 60 * (long) pc.rel_hour;
2414     time_t t1 = t0 + d1;
2415     long d2 = 60 * (long) pc.rel_minutes;
2416     time_t t2 = t1 + d2;
2417     int d3 = pc.rel_seconds;
2418     time_t t3 = t2 + d3;
2419     if ((d1 / (60 * 60) ^ pc.rel_hour)
2420         | (d2 / 60 ^ pc.rel_minutes)
2421         | ((t0 + d1 < t0) ^ (d1 < 0))
2422         | ((t1 + d2 < t1) ^ (d2 < 0))
2423         | ((t2 + d3 < t2) ^ (d3 < 0)))
2424       return -1;
2425     Start = t3;
2426   }
2427
2428   return Start;
2429 }
2430
2431 #if TEST
2432
2433 #include <stdio.h>
2434
2435 int
2436 main (int ac, char **av)
2437 {
2438   char buff[BUFSIZ];
2439   time_t d;
2440
2441   printf ("Enter date, or blank line to exit.\n\t> ");
2442   fflush (stdout);
2443
2444   buff[BUFSIZ - 1] = 0;
2445   while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2446     {
2447       d = get_date (buff, 0);
2448       if (d == (time_t) -1)
2449         printf ("Bad format - couldn't convert.\n");
2450       else
2451         printf ("%s", ctime (&d));
2452       printf ("\t> ");
2453       fflush (stdout);
2454     }
2455   return 0;
2456 }
2457 #endif /* defined TEST */
2458
2459