source: examples/erfsplit/getdate.tab.c @ d896967f

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

added erfsplit into libtrace.

erfsplit builds cleanly, supports date matching and bpf filters

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