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