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