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.  */
185typedef struct
186{
187  int value;
188  int digits;
189} textint;
190
191/* An entry in the lexical lookup table.  */
192typedef struct
193{
194  char const *name;
195  int type;
196  int value;
197} table;
198
199/* Meridian: am, pm, or 24-hour style.  */
200enum { MERam, MERpm, MER24 };
201
202/* Information passed to and from the parser.  */
203typedef 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
255static int yyerror ();
256static 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"
275typedef 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.  */
331union 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.  */
410static 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.  */
445static 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. */
456static 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.  */
477static 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. */
491static 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.  */
505static 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.  */
514static 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.  */
525static 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.  */
538static 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]. */
550static 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
559static 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].  */
571static 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
582static 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
592static 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.  */
604static 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)					\
650do								\
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    }								\
664while (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)			\
697do {						\
698  if (yydebug)					\
699    YYFPRINTF Args;				\
700} while (0)
701
702# define YYDSYMPRINT(Args)			\
703do {						\
704  if (yydebug)					\
705    yysymprint Args;				\
706} while (0)
707
708# define YYDSYMPRINTF(Title, Token, Value, Location)		\
709do {								\
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)
725static void
726yy_stack_print (short *bottom, short *top)
727#else
728static void
729yy_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)				\
741do {								\
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)
752static void
753yy_reduce_print (int yyrule)
754#else
755static void
756yy_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)		\
771do {					\
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.  */
778int 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
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.  */
817static YYSIZE_T
818#   if defined (__STDC__) || defined (__cplusplus)
819yystrlen (const char *yystr)
820#   else
821yystrlen (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.  */
841static char *
842#   if defined (__STDC__) || defined (__cplusplus)
843yystpcpy (char *yydest, const char *yysrc)
844#   else
845yystpcpy (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
864
865#if YYDEBUG
866/*--------------------------------.
867| Print this symbol on YYOUTPUT.  |
868`--------------------------------*/
869
870#if defined (__STDC__) || defined (__cplusplus)
871static void
872yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
873#else
874static void
875yysymprint (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)
908static void
909yydestruct (int yytype, YYSTYPE *yyvaluep)
910#else
911static void
912yydestruct (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
928
929/* Prevent warnings from -Wmissing-prototypes.  */
930
931#ifdef YYPARSE_PARAM
932# if defined (__STDC__) || defined (__cplusplus)
933int yyparse (void *YYPARSE_PARAM);
934# else
935int yyparse ();
936# endif
937#else /* ! YYPARSE_PARAM */
938#if defined (__STDC__) || defined (__cplusplus)
939int yyparse (void);
940#else
941int 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)
956int yyparse (void *YYPARSE_PARAM)
957# else
958int yyparse (YYPARSE_PARAM)
959  void *YYPARSE_PARAM;
960# endif
961#else /* ! YYPARSE_PARAM */
962#if defined (__STDC__) || defined (__cplusplus)
963int
964yyparse (void)
965#else
966int
967yyparse ()
968
969#endif
970#endif
971{
972  /* The lookahead symbol.  */
973int yychar;
974
975/* The semantic value of the lookahead symbol.  */
976YYSTYPE yylval;
977
978/* Number of syntax errors so far.  */
979int 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`-----------*/
1123yybackup:
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`-----------------------------------------------------------*/
1194yydefault:
1195  yyn = yydefact[yystate];
1196  if (yyn == 0)
1197    goto yyerrlab;
1198  goto yyreduce;
1199
1200
1201/*-----------------------------.
1202| yyreduce -- Do a reduction.  |
1203`-----------------------------*/
1204yyreduce:
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
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`------------------------------------*/
1621yyerrlab:
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`----------------------------------------------------*/
1712yyerrlab1:
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`-------------------------------------*/
1756yyacceptlab:
1757  yyresult = 0;
1758  goto yyreturn;
1759
1760/*-----------------------------------.
1761| yyabortlab -- YYABORT comes here.  |
1762`-----------------------------------*/
1763yyabortlab:
1764  yyresult = 1;
1765  goto yyreturn;
1766
1767#ifndef yyoverflow
1768/*----------------------------------------------.
1769| yyoverflowlab -- parser overflow comes here.  |
1770`----------------------------------------------*/
1771yyoverflowlab:
1772  yyerror ("parser stack overflow");
1773  yyresult = 2;
1774  /* Fall through.  */
1775#endif
1776
1777yyreturn:
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
1795struct tm *gmtime ();
1796#endif
1797#ifndef localtime
1798struct tm *localtime ();
1799#endif
1800#ifndef mktime
1801time_t mktime ();
1802#endif
1803
1804static 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
1813static table const dst_table[] =
1814{
1815  { "DST", tDST, 0 }
1816};
1817
1818static 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
1847static 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. */
1863static 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.  */
1893static 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. */
1949static 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
1980
1981static int
1982to_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
1999static int
2000to_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
2015static table const *
2016lookup_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.  */
2037static int
2038tm_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
2059static table const *
2060lookup_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
2128static int
2129yylex (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.  */
2208static int
2209yyerror (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.  */
2218time_t
2219get_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
2436int
2437main (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
2461