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