source: examples/erfsplit/getdate.tab.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 4e92740, checked in by Daniel Lawson <dlawson@…>, 16 years ago

poink

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