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