source: examples/erfsplit/getdate.c @ 5dfa670

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 5dfa670 was c773929, checked in by Daniel Lawson <dlawson@…>, 16 years ago

added erfsplit into libtrace.

erfsplit builds cleanly, supports date matching and bpf filters

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