Implement window size passing between real tty and virtual console.
[dragonfly/vkernel-mp.git] / contrib / tar / lib / getdate.c
blob77bbd02d14927b97cc33abbd2a9ea375ff3d4f9f
2 /* A Bison parser, made from getdate.y
3 by GNU bison 1.29. */
5 #define YYBISON 1 /* Identify Bison output. */
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
24 #line 1 "getdate.y"
26 /* Parse a string into an internal time stamp.
27 Copyright 1999, 2000 Free Software Foundation, Inc.
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.
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.
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. */
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.
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. */
52 #ifdef HAVE_CONFIG_H
53 # include <config.h>
54 # ifdef HAVE_ALLOCA_H
55 # include <alloca.h>
56 # endif
57 #endif
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
69 #include <ctype.h>
71 #if HAVE_STDLIB_H
72 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
73 #endif
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
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))
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)
96 #if STDC_HEADERS || HAVE_STRING_H
97 # include <string.h>
98 #endif
100 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
101 # define __attribute__(x)
102 #endif
104 #ifndef ATTRIBUTE_UNUSED
105 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
106 #endif
108 #define EPOCH_YEAR 1970
109 #define TM_YEAR_BASE 1900
111 #define HOUR(x) ((x) * 60)
113 /* An integer value, and the number of digits in its textual
114 representation. */
115 typedef struct
117 int value;
118 int digits;
119 } textint;
121 /* An entry in the lexical lookup table. */
122 typedef struct
124 char const *name;
125 int type;
126 int value;
127 } table;
129 /* Meridian: am, pm, or 24-hour style. */
130 enum { MERam, MERpm, MER24 };
132 /* Information passed to and from the parser. */
133 typedef struct
135 /* The input string remaining to be parsed. */
136 const char *input;
138 /* N, if this is the Nth Tuesday. */
139 int day_ordinal;
141 /* Day of week; Sunday is 0. */
142 int day_number;
144 /* tm_isdst flag for the local zone. */
145 int local_isdst;
147 /* Time zone, in minutes east of UTC. */
148 int time_zone;
150 /* Style used for time. */
151 int meridian;
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;
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;
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;
177 /* Table of local time zone abbrevations, terminated by a null entry. */
178 table local_time_zone_table[3];
179 } parser_control;
181 #define PC (* (parser_control *) parm)
182 #define YYLEX_PARAM parm
183 #define YYPARSE_PARAM parm
185 static int yyerror ();
186 static int yylex ();
189 #line 172 "getdate.y"
190 typedef union
192 int intval;
193 textint textintval;
194 } YYSTYPE;
195 #include <stdio.h>
199 #define YYFINAL 64
200 #define YYFLAG -32768
201 #define YYNTBASE 22
203 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */
204 #define YYTRANSLATE(x) ((unsigned)(x) <= 272 ? yytranslate[x] : 33)
206 /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */
207 static const char yytranslate[] =
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
239 #if YYDEBUG != 0
240 static const short yyprhs[] =
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
249 static const short yyrhs[] =
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
269 #endif
271 #if YYDEBUG != 0
272 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
273 static const short yyrline[] =
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
282 #endif
285 #if YYDEBUG != 0 || defined YYERROR_VERBOSE
287 /* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */
288 static const char *const yytname[] =
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
296 #endif
298 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
299 static const short yyr1[] =
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
309 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
310 static const short yyr2[] =
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
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[] =
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
334 static const short yydefgoto[] =
336 1, 15, 16, 17, 18, 19, 20, 21, 22, 23,
340 static const short yypact[] =
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
351 static const short yypgoto[] =
353 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
358 #define YYLAST 53
361 static const short yytable[] =
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
371 static const short yycheck[] =
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
380 #define YYPURE 1
382 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
383 #line 3 "/opt/reb/share/bison/bison.simple"
385 /* Skeleton output parser for bison,
386 Copyright 1984, 1989, 1990, 2000, 2001 Free Software Foundation, Inc.
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.
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.
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. */
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. */
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. */
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 */
457 #if YYSTACK_USE_ALLOCA
458 # define YYSTACK_ALLOC alloca
459 #else
460 # define YYSTACK_ALLOC malloc
461 #endif
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) \
479 yychar = (Token); \
480 yylval = (Value); \
481 yychar1 = YYTRANSLATE (yychar); \
482 YYPOPSTACK; \
483 goto yybackup; \
485 else \
487 yyerror ("syntax error: cannot back up"); \
488 YYERROR; \
490 while (0)
492 #define YYTERROR 1
493 #define YYERRCODE 256
496 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
497 are run).
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. */
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
510 /* YYLEX -- calling `yylex' with the right arguments. */
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 */
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.
542 int yydebug;
543 #else /* !YYDEBUG */
544 # define YYDPRINTF(Args)
545 #endif /* !YYDEBUG */
547 /* YYINITDEPTH -- initial size of the parser's stacks. */
548 #ifndef YYINITDEPTH
549 # define YYINITDEPTH 200
550 #endif
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
558 #ifndef YYMAXDEPTH
559 # define YYMAXDEPTH 10000
560 #endif
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. */
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++ */
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
583 register const char *f = from;
584 register char *t = to;
585 register int i = count;
587 while (i-- > 0)
588 *t++ = *f++;
591 #endif
593 #line 212 "/opt/reb/share/bison/bison.simple"
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. */
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 */
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
624 /* YY_DECL_VARIABLES -- depending whether we use a pure parser,
625 variables are global, or local to YYPARSE. */
627 #define _YY_DECL_VARIABLES \
628 /* The lookahead symbol. */ \
629 int yychar; \
631 /* The semantic value of the lookahead symbol. */ \
632 YYSTYPE yylval; \
634 /* Number of parse errors so far. */ \
635 int yynerrs;
637 #if YYLSP_NEEDED
638 # define YY_DECL_VARIABLES \
639 _YY_DECL_VARIABLES \
641 /* Location data for the lookahead symbol. */ \
642 YYLTYPE yylloc;
643 #else
644 # define YY_DECL_VARIABLES \
645 _YY_DECL_VARIABLES
646 #endif
649 /* If nonreentrant, generate the variables here. */
651 #if !YYPURE
652 YY_DECL_VARIABLES
653 #endif /* !YYPURE */
656 yyparse (YYPARSE_PARAM_ARG)
657 YYPARSE_PARAM_DECL
659 /* If reentrant, generate the variables here. */
660 #if YYPURE
661 YY_DECL_VARIABLES
662 #endif /* !YYPURE */
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;
671 /* Three stacks and their tools:
672 `yyss': related to states,
673 `yysv': related to semantic values,
674 `yyls': related to locations.
676 Refer to the stacks thru separate pointers, to allow yyoverflow
677 to reallocate them elsewhere. */
679 /* The state stack. */
680 short yyssa[YYINITDEPTH];
681 short *yyss = yyssa;
682 register short *yyssp;
684 /* The semantic value stack. */
685 YYSTYPE yyvsa[YYINITDEPTH];
686 YYSTYPE *yyvs = yyvsa;
687 register YYSTYPE *yyvsp;
689 #if YYLSP_NEEDED
690 /* The location stack. */
691 YYLTYPE yylsa[YYINITDEPTH];
692 YYLTYPE *yyls = yylsa;
693 YYLTYPE *yylsp;
694 #endif
696 #if YYLSP_NEEDED
697 # define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
698 #else
699 # define YYPOPSTACK (yyvsp--, yyssp--)
700 #endif
702 int yystacksize = YYINITDEPTH;
703 int yyfree_stacks = 0;
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
713 /* When reducing, the number of symbols on the RHS of the reduced
714 rule. */
715 int yylen;
717 YYDPRINTF ((stderr, "Starting parse\n"));
719 yystate = 0;
720 yyerrstatus = 0;
721 yynerrs = 0;
722 yychar = YYEMPTY; /* Cause a token to be read. */
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. */
729 yyssp = yyss;
730 yyvsp = yyvs;
731 #if YYLSP_NEEDED
732 yylsp = yyls;
733 #endif
734 goto yysetstate;
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.
743 yyssp++;
745 yysetstate:
746 *yyssp = yystate;
748 if (yyssp >= yyss + yystacksize - 1)
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.
753 YYSTYPE *yyvs1 = yyvs;
754 short *yyss1 = yyss;
755 #if YYLSP_NEEDED
756 YYLTYPE *yyls1 = yyls;
757 #endif
759 /* Get the current used size of the three stacks, in elements. */
760 int size = yyssp - yyss + 1;
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
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)
788 yyerror ("parser stack overflow");
789 if (yyfree_stacks)
791 free (yyss);
792 free (yyvs);
793 # if YYLSP_NEEDED
794 free (yyls);
795 # endif
797 return 2;
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 */
818 yyssp = yyss + size - 1;
819 yyvsp = yyvs + size - 1;
820 #if YYLSP_NEEDED
821 yylsp = yyls + size - 1;
822 #endif
824 YYDPRINTF ((stderr, "Stack size increased to %d\n", yystacksize));
826 if (yyssp >= yyss + yystacksize - 1)
827 YYABORT;
830 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
832 goto yybackup;
835 /*-----------.
836 | yybackup. |
837 `-----------*/
838 yybackup:
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: */
844 /* First try to decide what to do without reference to lookahead token. */
846 yyn = yypact[yystate];
847 if (yyn == YYFLAG)
848 goto yydefault;
850 /* Not known => get a lookahead token if don't already have one. */
852 /* yychar is either YYEMPTY or YYEOF
853 or a valid token in external form. */
855 if (yychar == YYEMPTY)
857 YYDPRINTF ((stderr, "Reading a token: "));
858 yychar = YYLEX;
861 /* Convert token to internal form (in yychar1) for indexing tables with */
863 if (yychar <= 0) /* This means end of input. */
865 yychar1 = 0;
866 yychar = YYEOF; /* Don't call YYLEX any more */
868 YYDPRINTF ((stderr, "Now at end of input.\n"));
870 else
872 yychar1 = YYTRANSLATE (yychar);
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)
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");
887 #endif
890 yyn += yychar1;
891 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
892 goto yydefault;
894 yyn = yytable[yyn];
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. */
903 if (yyn < 0)
905 if (yyn == YYFLAG)
906 goto yyerrlab;
907 yyn = -yyn;
908 goto yyreduce;
910 else if (yyn == 0)
911 goto yyerrlab;
913 if (yyn == YYFINAL)
914 YYACCEPT;
916 /* Shift the lookahead token. */
917 YYDPRINTF ((stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]));
919 /* Discard the token being shifted unless it is eof. */
920 if (yychar != YYEOF)
921 yychar = YYEMPTY;
923 *++yyvsp = yylval;
924 #if YYLSP_NEEDED
925 *++yylsp = yylloc;
926 #endif
928 /* Count tokens shifted since error; after three, turn off error
929 status. */
930 if (yyerrstatus)
931 yyerrstatus--;
933 yystate = yyn;
934 goto yynewstate;
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;
947 /*-----------------------------.
948 | yyreduce -- Do a reduction. |
949 `-----------------------------*/
950 yyreduce:
951 /* yyn is the number of a rule to reduce with. */
952 yylen = yyr2[yyn];
954 /* If YYLEN is nonzero, implement the default value of the action:
955 `$$ = $1'.
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];
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
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)
976 int i;
978 fprintf (stderr, "Reducing via rule %d (line %d), ",
979 yyn, yyrline[yyn]);
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]]);
986 #endif
988 switch (yyn) {
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"
1017 PC.hour = yyvsp[-1].textintval.value;
1018 PC.minutes = 0;
1019 PC.seconds = 0;
1020 PC.meridian = yyvsp[0].intval;
1022 break;}
1023 case 11:
1024 #line 219 "getdate.y"
1026 PC.hour = yyvsp[-3].textintval.value;
1027 PC.minutes = yyvsp[-1].textintval.value;
1028 PC.seconds = 0;
1029 PC.meridian = yyvsp[0].intval;
1031 break;}
1032 case 12:
1033 #line 226 "getdate.y"
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;
1041 break;}
1042 case 13:
1043 #line 234 "getdate.y"
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;
1050 break;}
1051 case 14:
1052 #line 241 "getdate.y"
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;
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"
1085 PC.day_ordinal = 1;
1086 PC.day_number = yyvsp[0].intval;
1088 break;}
1089 case 21:
1090 #line 274 "getdate.y"
1092 PC.day_ordinal = 1;
1093 PC.day_number = yyvsp[-1].intval;
1095 break;}
1096 case 22:
1097 #line 279 "getdate.y"
1099 PC.day_ordinal = yyvsp[-1].textintval.value;
1100 PC.day_number = yyvsp[0].intval;
1102 break;}
1103 case 23:
1104 #line 287 "getdate.y"
1106 PC.month = yyvsp[-2].textintval.value;
1107 PC.day = yyvsp[0].textintval.value;
1109 break;}
1110 case 24:
1111 #line 292 "getdate.y"
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)
1120 PC.year = yyvsp[-4].textintval;
1121 PC.month = yyvsp[-2].textintval.value;
1122 PC.day = yyvsp[0].textintval.value;
1124 else
1126 PC.month = yyvsp[-4].textintval.value;
1127 PC.day = yyvsp[-2].textintval.value;
1128 PC.year = yyvsp[0].textintval;
1131 break;}
1132 case 25:
1133 #line 312 "getdate.y"
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;
1140 break;}
1141 case 26:
1142 #line 319 "getdate.y"
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;
1150 break;}
1151 case 27:
1152 #line 327 "getdate.y"
1154 PC.month = yyvsp[-1].intval;
1155 PC.day = yyvsp[0].textintval.value;
1157 break;}
1158 case 28:
1159 #line 332 "getdate.y"
1161 PC.month = yyvsp[-3].intval;
1162 PC.day = yyvsp[-2].textintval.value;
1163 PC.year = yyvsp[0].textintval;
1165 break;}
1166 case 29:
1167 #line 338 "getdate.y"
1169 PC.day = yyvsp[-1].textintval.value;
1170 PC.month = yyvsp[0].intval;
1172 break;}
1173 case 30:
1174 #line 343 "getdate.y"
1176 PC.day = yyvsp[-2].textintval.value;
1177 PC.month = yyvsp[-1].intval;
1178 PC.year = yyvsp[0].textintval;
1180 break;}
1181 case 31:
1182 #line 352 "getdate.y"
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;
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"
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
1272 if (4 < yyvsp[0].textintval.digits)
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;
1280 else
1282 PC.times_seen++;
1283 if (yyvsp[0].textintval.digits <= 2)
1285 PC.hour = yyvsp[0].textintval.value;
1286 PC.minutes = 0;
1288 else
1290 PC.hour = yyvsp[0].textintval.value / 100;
1291 PC.minutes = yyvsp[0].textintval.value % 100;
1293 PC.seconds = 0;
1294 PC.meridian = MER24;
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;}
1309 #line 606 "/opt/reb/share/bison/bison.simple"
1312 yyvsp -= yylen;
1313 yyssp -= yylen;
1314 #if YYLSP_NEEDED
1315 yylsp -= yylen;
1316 #endif
1318 #if YYDEBUG
1319 if (yydebug)
1321 short *ssp1 = yyss - 1;
1322 fprintf (stderr, "state stack now");
1323 while (ssp1 != yyssp)
1324 fprintf (stderr, " %d", *++ssp1);
1325 fprintf (stderr, "\n");
1327 #endif
1329 *++yyvsp = yyval;
1330 #if YYLSP_NEEDED
1331 *++yylsp = yyloc;
1332 #endif
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. */
1338 yyn = yyr1[yyn];
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];
1346 goto yynewstate;
1349 /*------------------------------------.
1350 | yyerrlab -- here on detecting error |
1351 `------------------------------------*/
1352 yyerrlab:
1353 /* If not already recovering from an error, report this error. */
1354 if (!yyerrstatus)
1356 ++yynerrs;
1358 #ifdef YYERROR_VERBOSE
1359 yyn = yypact[yystate];
1361 if (yyn > YYFLAG && yyn < YYLAST)
1363 int size = 0;
1364 char *msg;
1365 int x, count;
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)
1378 strcpy (msg, "parse error, unexpected `");
1379 strcat (msg, yytname[YYTRANSLATE (yychar)]);
1380 strcat (msg, "'");
1382 if (count < 5)
1384 count = 0;
1385 for (x = (yyn < 0 ? -yyn : 0);
1386 x < (int) (sizeof (yytname) / sizeof (char *)); x++)
1387 if (yycheck[x + yyn] == x)
1389 strcat (msg, count == 0 ? ", expecting `" : " or `");
1390 strcat (msg, yytname[x]);
1391 strcat (msg, "'");
1392 count++;
1395 yyerror (msg);
1396 free (msg);
1398 else
1399 yyerror ("parse error; also virtual memory exceeded");
1401 else
1402 #endif /* YYERROR_VERBOSE */
1403 yyerror ("parse error");
1405 goto yyerrlab1;
1408 /*--------------------------------------------------.
1409 | yyerrlab1 -- error raised explicitly by an action |
1410 `--------------------------------------------------*/
1411 yyerrlab1:
1412 if (yyerrstatus == 3)
1414 /* If just tried and failed to reuse lookahead token after an
1415 error, discard it. */
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;
1425 /* Else will try to reuse lookahead token after shifting the error
1426 token. */
1428 yyerrstatus = 3; /* Each real token shifted decrements this */
1430 goto yyerrhandle;
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. */
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
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
1462 #if YYDEBUG
1463 if (yydebug)
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");
1471 #endif
1473 /*--------------.
1474 | yyerrhandle. |
1475 `--------------*/
1476 yyerrhandle:
1477 yyn = yypact[yystate];
1478 if (yyn == YYFLAG)
1479 goto yyerrdefault;
1481 yyn += YYTERROR;
1482 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1483 goto yyerrdefault;
1485 yyn = yytable[yyn];
1486 if (yyn < 0)
1488 if (yyn == YYFLAG)
1489 goto yyerrpop;
1490 yyn = -yyn;
1491 goto yyreduce;
1493 else if (yyn == 0)
1494 goto yyerrpop;
1496 if (yyn == YYFINAL)
1497 YYACCEPT;
1499 YYDPRINTF ((stderr, "Shifting error token, "));
1501 *++yyvsp = yylval;
1502 #if YYLSP_NEEDED
1503 *++yylsp = yylloc;
1504 #endif
1506 yystate = yyn;
1507 goto yynewstate;
1510 /*-------------------------------------.
1511 | yyacceptlab -- YYACCEPT comes here. |
1512 `-------------------------------------*/
1513 yyacceptlab:
1514 if (yyfree_stacks)
1516 free (yyss);
1517 free (yyvs);
1518 #if YYLSP_NEEDED
1519 free (yyls);
1520 #endif
1522 return 0;
1525 /*-----------------------------------.
1526 | yyabortlab -- YYABORT comes here. |
1527 `-----------------------------------*/
1528 yyabortlab:
1529 if (yyfree_stacks)
1531 free (yyss);
1532 free (yyvs);
1533 #if YYLSP_NEEDED
1534 free (yyls);
1535 #endif
1537 return 1;
1539 #line 445 "getdate.y"
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"
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
1557 static table const meridian_table[] =
1559 { "AM", tMERIDIAN, MERam },
1560 { "A.M.", tMERIDIAN, MERam },
1561 { "PM", tMERIDIAN, MERpm },
1562 { "P.M.", tMERIDIAN, MERpm },
1563 { 0, 0, 0 }
1566 static table const dst_table[] =
1568 { "DST", tDST, 0 }
1571 static table const month_and_day_table[] =
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 }
1600 static table const time_units_table[] =
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 }
1615 /* Assorted relative-time words. */
1616 static table const relative_time_table[] =
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 }
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[] =
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 }
1701 /* Military time zone table. */
1702 static table const military_table[] =
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 }
1734 static int
1735 to_hour (int hours, int meridian)
1737 switch (meridian)
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 ();
1748 /* NOTREACHED */
1751 static int
1752 to_year (textint textyear)
1754 int year = textyear.value;
1756 if (year < 0)
1757 year = -year;
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;
1764 return year;
1767 static table const *
1768 lookup_zone (parser_control const *pc, char const *name)
1770 table const *tp;
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;
1777 for (tp = time_zone_table; tp->name; tp++)
1778 if (strcmp (name, tp->name) == 0)
1779 return tp;
1781 return 0;
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)
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));
1809 #endif /* ! HAVE_TM_GMTOFF */
1811 static table const *
1812 lookup_word (parser_control const *pc, char *word)
1814 char *p;
1815 char *q;
1816 size_t wordlen;
1817 table const *tp;
1818 int i;
1819 int abbrev;
1821 /* Make it uppercase. */
1822 for (p = word; *p; p++)
1823 if (ISLOWER ((unsigned char) *p))
1824 *p = toupper ((unsigned char) *p);
1826 for (tp = meridian_table; tp->name; tp++)
1827 if (strcmp (word, tp->name) == 0)
1828 return tp;
1830 /* See if we have an abbreviation for a month. */
1831 wordlen = strlen (word);
1832 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
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;
1838 if ((tp = lookup_zone (pc, word)))
1839 return tp;
1841 if (strcmp (word, dst_table[0].name) == 0)
1842 return dst_table;
1844 for (tp = time_units_table; tp->name; tp++)
1845 if (strcmp (word, tp->name) == 0)
1846 return tp;
1848 /* Strip off any plural and try the units table again. */
1849 if (word[wordlen - 1] == 'S')
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. */
1858 for (tp = relative_time_table; tp->name; tp++)
1859 if (strcmp (word, tp->name) == 0)
1860 return tp;
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;
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;
1877 return 0;
1880 static int
1881 yylex (YYSTYPE *lvalp, parser_control *pc)
1883 unsigned char c;
1884 int count;
1886 for (;;)
1888 while (c = *pc->input, ISSPACE (c))
1889 pc->input++;
1891 if (ISDIGIT (c) || c == '-' || c == '+')
1893 char const *p;
1894 int sign;
1895 int value;
1896 if (c == '-' || c == '+')
1898 sign = c == '-' ? -1 : 1;
1899 c = *++pc->input;
1900 if (! ISDIGIT (c))
1901 /* skip the '-' sign */
1902 continue;
1904 else
1905 sign = 0;
1906 p = pc->input;
1907 value = 0;
1910 value = 10 * value + c - '0';
1911 c = *++p;
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;
1920 if (ISALPHA (c))
1922 char buff[20];
1923 char *p = buff;
1924 table const *tp;
1928 if (p < buff + sizeof buff - 1)
1929 *p++ = c;
1930 c = *++pc->input;
1932 while (ISALPHA (c) || c == '.');
1934 *p = '\0';
1935 tp = lookup_word (pc, buff);
1936 if (! tp)
1937 return '?';
1938 lvalp->intval = tp->value;
1939 return tp->type;
1942 if (c != '(')
1943 return *pc->input++;
1944 count = 0;
1947 c = *pc->input++;
1948 if (c == '\0')
1949 return c;
1950 if (c == '(')
1951 count++;
1952 else if (c == ')')
1953 count--;
1955 while (count > 0);
1959 /* Do nothing if the parser reports an error. */
1960 static int
1961 yyerror (char *s ATTRIBUTE_UNUSED)
1963 return 0;
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)
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;
1979 if (! tmp)
1980 return -1;
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;
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;
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;
2012 /* Probe the names used in the next three calendar quarters, looking
2013 for a tm_isdst different from the one we already have. */
2015 int quarter;
2016 for (quarter = 1; quarter <= 3; quarter++)
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)
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;
2029 break;
2033 #else
2034 #if HAVE_TZNAME
2036 # ifndef tzname
2037 extern char *tzname[];
2038 # endif
2039 int i;
2040 for (i = 0; i < 2; i++)
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;
2046 pc.local_time_zone_table[i].name = 0;
2048 #else
2049 pc.local_time_zone_table[0].name = 0;
2050 #endif
2051 #endif
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))
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;
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;
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))
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;
2081 else
2083 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
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;
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;
2097 tm0 = tm;
2099 Start = mktime (&tm);
2101 if (Start == (time_t) -1)
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)
2114 tm = tm0;
2115 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2117 tm.tm_mday++;
2118 pc.time_zone += 24 * 60;
2120 else
2122 tm.tm_mday--;
2123 pc.time_zone -= 24 * 60;
2125 Start = mktime (&tm);
2128 if (Start == (time_t) -1)
2129 return Start;
2132 if (pc.days_seen && ! pc.dates_seen)
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;
2142 if (pc.zones_seen)
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;
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. */
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;
2181 return Start;
2184 #if TEST
2186 #include <stdio.h>
2189 main (int ac, char **av)
2191 char buff[BUFSIZ];
2192 time_t d;
2194 printf ("Enter date, or blank line to exit.\n\t> ");
2195 fflush (stdout);
2197 buff[BUFSIZ - 1] = 0;
2198 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
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);
2208 return 0;
2210 #endif /* defined TEST */