Initial revision
[libcurl.git] / lib / getdate.c
blobe3342ff3a5c2e589ad3ba560f106519eb59e1c13
2 /* A Bison parser, made from getdate.y
3 by GNU Bison version 1.27
4 */
6 #define YYBISON 1 /* Identify Bison output. */
8 #define tAGO 257
9 #define tDAY 258
10 #define tDAY_UNIT 259
11 #define tDAYZONE 260
12 #define tDST 261
13 #define tHOUR_UNIT 262
14 #define tID 263
15 #define tMERIDIAN 264
16 #define tMINUTE_UNIT 265
17 #define tMONTH 266
18 #define tMONTH_UNIT 267
19 #define tSEC_UNIT 268
20 #define tSNUMBER 269
21 #define tUNUMBER 270
22 #define tYEAR_UNIT 271
23 #define tZONE 272
25 #line 1 "getdate.y"
28 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
29 ** at the University of North Carolina at Chapel Hill. Later tweaked by
30 ** a couple of people on Usenet. Completely overhauled by Rich $alz
31 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
33 ** This code is in the public domain and has no copyright.
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 # ifdef HAVE_ALLOCA_H
39 # include <alloca.h>
40 # endif
41 #endif
43 /* Since the code of getdate.y is not included in the Emacs executable
44 itself, there is no need to #define static in this file. Even if
45 the code were included in the Emacs executable, it probably
46 wouldn't do any harm to #undef it here; this will only cause
47 problems if we try to write to a static variable, which I don't
48 think this code needs to do. */
49 #ifdef emacs
50 # undef static
51 #endif
53 #include <malloc.h>
54 #include <string.h>
55 #include <stdio.h>
56 #include <ctype.h>
58 #if HAVE_STDLIB_H
59 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
60 #endif
62 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
63 # define IN_CTYPE_DOMAIN(c) 1
64 #else
65 # define IN_CTYPE_DOMAIN(c) isascii(c)
66 #endif
68 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
69 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
70 #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
71 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
73 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
74 - Its arg may be any int or unsigned int; it need not be an unsigned char.
75 - It's guaranteed to evaluate its argument exactly once.
76 - It's typically faster.
77 Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
78 only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
79 it's important to use the locale's definition of `digit' even when the
80 host does not conform to Posix. */
81 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
83 #if defined (STDC_HEADERS) || defined (USG)
84 # include <string.h>
85 #endif
87 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
88 # define __attribute__(x)
89 #endif
91 #ifndef ATTRIBUTE_UNUSED
92 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
93 #endif
95 /* Some old versions of bison generate parsers that use bcopy.
96 That loses on systems that don't provide the function, so we have
97 to redefine it here. */
98 #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
99 # define bcopy(from, to, len) memcpy ((to), (from), (len))
100 #endif
102 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
103 as well as gratuitiously global symbol names, so we can have multiple
104 yacc generated parsers in the same program. Note that these are only
105 the variables produced by yacc. If other parser generators (bison,
106 byacc, etc) produce additional global names that conflict at link time,
107 then those parser generators need to be fixed instead of adding those
108 names to this list. */
110 #define yymaxdepth gd_maxdepth
111 #define yyparse gd_parse
112 #define yylex gd_lex
113 #define yyerror gd_error
114 #define yylval gd_lval
115 #define yychar gd_char
116 #define yydebug gd_debug
117 #define yypact gd_pact
118 #define yyr1 gd_r1
119 #define yyr2 gd_r2
120 #define yydef gd_def
121 #define yychk gd_chk
122 #define yypgo gd_pgo
123 #define yyact gd_act
124 #define yyexca gd_exca
125 #define yyerrflag gd_errflag
126 #define yynerrs gd_nerrs
127 #define yyps gd_ps
128 #define yypv gd_pv
129 #define yys gd_s
130 #define yy_yys gd_yys
131 #define yystate gd_state
132 #define yytmp gd_tmp
133 #define yyv gd_v
134 #define yy_yyv gd_yyv
135 #define yyval gd_val
136 #define yylloc gd_lloc
137 #define yyreds gd_reds /* With YYDEBUG defined */
138 #define yytoks gd_toks /* With YYDEBUG defined */
139 #define yylhs gd_yylhs
140 #define yylen gd_yylen
141 #define yydefred gd_yydefred
142 #define yydgoto gd_yydgoto
143 #define yysindex gd_yysindex
144 #define yyrindex gd_yyrindex
145 #define yygindex gd_yygindex
146 #define yytable gd_yytable
147 #define yycheck gd_yycheck
149 static int yylex ();
150 static int yyerror ();
152 #define EPOCH 1970
153 #define HOUR(x) ((x) * 60)
155 #define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
158 ** An entry in the lexical lookup table.
160 typedef struct _TABLE {
161 const char *name;
162 int type;
163 int value;
164 } TABLE;
168 ** Meridian: am, pm, or 24-hour style.
170 typedef enum _MERIDIAN {
171 MERam, MERpm, MER24
172 } MERIDIAN;
176 ** Global variables. We could get rid of most of these by using a good
177 ** union as the yacc stack. (This routine was originally written before
178 ** yacc had the %union construct.) Maybe someday; right now we only use
179 ** the %union very rarely.
181 static const char *yyInput;
182 static int yyDayOrdinal;
183 static int yyDayNumber;
184 static int yyHaveDate;
185 static int yyHaveDay;
186 static int yyHaveRel;
187 static int yyHaveTime;
188 static int yyHaveZone;
189 static int yyTimezone;
190 static int yyDay;
191 static int yyHour;
192 static int yyMinutes;
193 static int yyMonth;
194 static int yySeconds;
195 static int yyYear;
196 static MERIDIAN yyMeridian;
197 static int yyRelDay;
198 static int yyRelHour;
199 static int yyRelMinutes;
200 static int yyRelMonth;
201 static int yyRelSeconds;
202 static int yyRelYear;
205 #line 184 "getdate.y"
206 typedef union {
207 int Number;
208 enum _MERIDIAN Meridian;
209 } YYSTYPE;
210 #include <stdio.h>
212 #ifndef __cplusplus
213 #ifndef __STDC__
214 #ifndef const
215 #define const
216 #endif
217 #endif
218 #endif
222 #define YYFINAL 61
223 #define YYFLAG -32768
224 #define YYNTBASE 22
226 #define YYTRANSLATE(x) ((unsigned)(x) <= 272 ? yytranslate[x] : 32)
228 static const char yytranslate[] = { 0,
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, 20, 2, 2, 21, 2, 2, 2,
234 2, 2, 2, 2, 2, 2, 2, 19, 2, 2,
235 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
236 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
237 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
238 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
239 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
240 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
241 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
242 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
243 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
244 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
245 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
246 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
247 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
248 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
249 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
250 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
251 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
252 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
253 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
254 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
255 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
256 17, 18
259 #if YYDEBUG != 0
260 static const short yyprhs[] = { 0,
261 0, 1, 4, 6, 8, 10, 12, 14, 16, 19,
262 24, 29, 36, 43, 45, 47, 50, 52, 55, 58,
263 62, 68, 72, 76, 79, 84, 87, 91, 94, 96,
264 99, 102, 104, 107, 110, 112, 115, 118, 120, 123,
265 126, 128, 131, 134, 136, 139, 142, 144, 146, 147
268 static const short yyrhs[] = { -1,
269 22, 23, 0, 24, 0, 25, 0, 27, 0, 26,
270 0, 28, 0, 30, 0, 16, 10, 0, 16, 19,
271 16, 31, 0, 16, 19, 16, 15, 0, 16, 19,
272 16, 19, 16, 31, 0, 16, 19, 16, 19, 16,
273 15, 0, 18, 0, 6, 0, 18, 7, 0, 4,
274 0, 4, 20, 0, 16, 4, 0, 16, 21, 16,
275 0, 16, 21, 16, 21, 16, 0, 16, 15, 15,
276 0, 16, 12, 15, 0, 12, 16, 0, 12, 16,
277 20, 16, 0, 16, 12, 0, 16, 12, 16, 0,
278 29, 3, 0, 29, 0, 16, 17, 0, 15, 17,
279 0, 17, 0, 16, 13, 0, 15, 13, 0, 13,
280 0, 16, 5, 0, 15, 5, 0, 5, 0, 16,
281 8, 0, 15, 8, 0, 8, 0, 16, 11, 0,
282 15, 11, 0, 11, 0, 16, 14, 0, 15, 14,
283 0, 14, 0, 16, 0, 0, 10, 0
286 #endif
288 #if YYDEBUG != 0
289 static const short yyrline[] = { 0,
290 200, 201, 204, 207, 210, 213, 216, 219, 222, 228,
291 234, 243, 249, 261, 264, 267, 273, 277, 281, 287,
292 291, 309, 315, 321, 325, 330, 334, 341, 349, 352,
293 355, 358, 361, 364, 367, 370, 373, 376, 379, 382,
294 385, 388, 391, 394, 397, 400, 403, 408, 441, 445
296 #endif
299 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
301 static const char * const yytname[] = { "$","error","$undefined.","tAGO","tDAY",
302 "tDAY_UNIT","tDAYZONE","tDST","tHOUR_UNIT","tID","tMERIDIAN","tMINUTE_UNIT",
303 "tMONTH","tMONTH_UNIT","tSEC_UNIT","tSNUMBER","tUNUMBER","tYEAR_UNIT","tZONE",
304 "':'","','","'/'","spec","item","time","zone","day","date","rel","relunit","number",
305 "o_merid", NULL
307 #endif
309 static const short yyr1[] = { 0,
310 22, 22, 23, 23, 23, 23, 23, 23, 24, 24,
311 24, 24, 24, 25, 25, 25, 26, 26, 26, 27,
312 27, 27, 27, 27, 27, 27, 27, 28, 28, 29,
313 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
314 29, 29, 29, 29, 29, 29, 29, 30, 31, 31
317 static const short yyr2[] = { 0,
318 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
319 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
320 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
321 2, 1, 2, 2, 1, 2, 2, 1, 2, 2,
322 1, 2, 2, 1, 2, 2, 1, 1, 0, 1
325 static const short yydefact[] = { 1,
326 0, 17, 38, 15, 41, 44, 0, 35, 47, 0,
327 48, 32, 14, 2, 3, 4, 6, 5, 7, 29,
328 8, 18, 24, 37, 40, 43, 34, 46, 31, 19,
329 36, 39, 9, 42, 26, 33, 45, 0, 30, 0,
330 0, 16, 28, 0, 23, 27, 22, 49, 20, 25,
331 50, 11, 0, 10, 0, 49, 21, 13, 12, 0,
335 static const short yydefgoto[] = { 1,
336 14, 15, 16, 17, 18, 19, 20, 21, 54
339 static const short yypact[] = {-32768,
340 0, -19,-32768,-32768,-32768,-32768, -13,-32768,-32768, 30,
341 15,-32768, 14,-32768,-32768,-32768,-32768,-32768,-32768, 19,
342 -32768,-32768, 4,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
343 -32768,-32768,-32768,-32768, -6,-32768,-32768, 16,-32768, 17,
344 23,-32768,-32768, 24,-32768,-32768,-32768, 27, 28,-32768,
345 -32768,-32768, 29,-32768, 32, -8,-32768,-32768,-32768, 50,
346 -32768
349 static const short yypgoto[] = {-32768,
350 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5
354 #define YYLAST 51
357 static const short yytable[] = { 60,
358 22, 51, 23, 2, 3, 4, 58, 5, 45, 46,
359 6, 7, 8, 9, 10, 11, 12, 13, 30, 31,
360 42, 43, 32, 44, 33, 34, 35, 36, 37, 38,
361 47, 39, 48, 40, 24, 41, 51, 25, 49, 50,
362 26, 52, 27, 28, 56, 53, 29, 57, 55, 61,
366 static const short yycheck[] = { 0,
367 20, 10, 16, 4, 5, 6, 15, 8, 15, 16,
368 11, 12, 13, 14, 15, 16, 17, 18, 4, 5,
369 7, 3, 8, 20, 10, 11, 12, 13, 14, 15,
370 15, 17, 16, 19, 5, 21, 10, 8, 16, 16,
371 11, 15, 13, 14, 16, 19, 17, 16, 21, 0,
374 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
375 #line 3 "/boot/apps/GeekGadgets/share/bison.simple"
376 /* This file comes from bison-1.27. */
378 /* Skeleton output parser for bison,
379 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
381 This program is free software; you can redistribute it and/or modify
382 it under the terms of the GNU General Public License as published by
383 the Free Software Foundation; either version 2, or (at your option)
384 any later version.
386 This program is distributed in the hope that it will be useful,
387 but WITHOUT ANY WARRANTY; without even the implied warranty of
388 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
389 GNU General Public License for more details.
391 You should have received a copy of the GNU General Public License
392 along with this program; if not, write to the Free Software
393 Foundation, Inc., 59 Temple Place - Suite 330,
394 Boston, MA 02111-1307, USA. */
396 /* As a special exception, when this file is copied by Bison into a
397 Bison output file, you may use that output file without restriction.
398 This special exception was added by the Free Software Foundation
399 in version 1.24 of Bison. */
401 /* This is the parser code that is written into each bison parser
402 when the %semantic_parser declaration is not specified in the grammar.
403 It was written by Richard Stallman by simplifying the hairy parser
404 used when %semantic_parser is specified. */
406 #ifndef YYSTACK_USE_ALLOCA
407 #ifdef alloca
408 #define YYSTACK_USE_ALLOCA
409 #else /* alloca not defined */
410 #ifdef __GNUC__
411 #define YYSTACK_USE_ALLOCA
412 #define alloca __builtin_alloca
413 #else /* not GNU C. */
414 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
415 #define YYSTACK_USE_ALLOCA
416 #include <alloca.h>
417 #else /* not sparc */
418 /* We think this test detects Watcom and Microsoft C. */
419 /* This used to test MSDOS, but that is a bad idea
420 since that symbol is in the user namespace. */
421 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
422 #if 0 /* No need for malloc.h, which pollutes the namespace;
423 instead, just don't use alloca. */
424 #include <malloc.h>
425 #endif
426 #else /* not MSDOS, or __TURBOC__ */
427 #if defined(_AIX)
428 /* I don't know what this was needed for, but it pollutes the namespace.
429 So I turned it off. rms, 2 May 1997. */
430 /* #include <malloc.h> */
431 #pragma alloca
432 #define YYSTACK_USE_ALLOCA
433 #else /* not MSDOS, or __TURBOC__, or _AIX */
434 #if 0
435 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
436 and on HPUX 10. Eventually we can turn this on. */
437 #define YYSTACK_USE_ALLOCA
438 #define alloca __builtin_alloca
439 #endif /* __hpux */
440 #endif
441 #endif /* not _AIX */
442 #endif /* not MSDOS, or __TURBOC__ */
443 #endif /* not sparc */
444 #endif /* not GNU C */
445 #endif /* alloca not defined */
446 #endif /* YYSTACK_USE_ALLOCA not defined */
448 #ifdef YYSTACK_USE_ALLOCA
449 #define YYSTACK_ALLOC alloca
450 #else
451 #define YYSTACK_ALLOC malloc
452 #endif
454 /* Note: there must be only one dollar sign in this file.
455 It is replaced by the list of actions, each action
456 as one case of the switch. */
458 #define yyerrok (yyerrstatus = 0)
459 #define yyclearin (yychar = YYEMPTY)
460 #define YYEMPTY -2
461 #define YYEOF 0
462 #define YYACCEPT goto yyacceptlab
463 #define YYABORT goto yyabortlab
464 #define YYERROR goto yyerrlab1
465 /* Like YYERROR except do call yyerror.
466 This remains here temporarily to ease the
467 transition to the new meaning of YYERROR, for GCC.
468 Once GCC version 2 has supplanted version 1, this can go. */
469 #define YYFAIL goto yyerrlab
470 #define YYRECOVERING() (!!yyerrstatus)
471 #define YYBACKUP(token, value) \
472 do \
473 if (yychar == YYEMPTY && yylen == 1) \
474 { yychar = (token), yylval = (value); \
475 yychar1 = YYTRANSLATE (yychar); \
476 YYPOPSTACK; \
477 goto yybackup; \
479 else \
480 { yyerror ("syntax error: cannot back up"); YYERROR; } \
481 while (0)
483 #define YYTERROR 1
484 #define YYERRCODE 256
486 #ifndef YYPURE
487 #define YYLEX yylex()
488 #endif
490 #ifdef YYPURE
491 #ifdef YYLSP_NEEDED
492 #ifdef YYLEX_PARAM
493 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
494 #else
495 #define YYLEX yylex(&yylval, &yylloc)
496 #endif
497 #else /* not YYLSP_NEEDED */
498 #ifdef YYLEX_PARAM
499 #define YYLEX yylex(&yylval, YYLEX_PARAM)
500 #else
501 #define YYLEX yylex(&yylval)
502 #endif
503 #endif /* not YYLSP_NEEDED */
504 #endif
506 /* If nonreentrant, generate the variables here */
508 #ifndef YYPURE
510 int yychar; /* the lookahead symbol */
511 YYSTYPE yylval; /* the semantic value of the */
512 /* lookahead symbol */
514 #ifdef YYLSP_NEEDED
515 YYLTYPE yylloc; /* location data for the lookahead */
516 /* symbol */
517 #endif
519 int yynerrs; /* number of parse errors so far */
520 #endif /* not YYPURE */
522 #if YYDEBUG != 0
523 int yydebug; /* nonzero means print parse trace */
524 /* Since this is uninitialized, it does not stop multiple parsers
525 from coexisting. */
526 #endif
528 /* YYINITDEPTH indicates the initial size of the parser's stacks */
530 #ifndef YYINITDEPTH
531 #define YYINITDEPTH 200
532 #endif
534 /* YYMAXDEPTH is the maximum size the stacks can grow to
535 (effective only if the built-in stack extension method is used). */
537 #if YYMAXDEPTH == 0
538 #undef YYMAXDEPTH
539 #endif
541 #ifndef YYMAXDEPTH
542 #define YYMAXDEPTH 10000
543 #endif
545 /* Define __yy_memcpy. Note that the size argument
546 should be passed with type unsigned int, because that is what the non-GCC
547 definitions require. With GCC, __builtin_memcpy takes an arg
548 of type size_t, but it can handle unsigned int. */
550 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
551 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
552 #else /* not GNU C or C++ */
553 #ifndef __cplusplus
555 /* This is the most reliable way to avoid incompatibilities
556 in available built-in functions on various systems. */
557 static void
558 __yy_memcpy (to, from, count)
559 char *to;
560 char *from;
561 unsigned int count;
563 register char *f = from;
564 register char *t = to;
565 register int i = count;
567 while (i-- > 0)
568 *t++ = *f++;
571 #else /* __cplusplus */
573 /* This is the most reliable way to avoid incompatibilities
574 in available built-in functions on various systems. */
575 static void
576 __yy_memcpy (char *to, char *from, unsigned int count)
578 register char *t = to;
579 register char *f = from;
580 register int i = count;
582 while (i-- > 0)
583 *t++ = *f++;
586 #endif
587 #endif
589 #line 216 "/boot/apps/GeekGadgets/share/bison.simple"
591 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
592 into yyparse. The argument should have type void *.
593 It should actually point to an object.
594 Grammar actions can access the variable by casting it
595 to the proper pointer type. */
597 #ifdef YYPARSE_PARAM
598 #ifdef __cplusplus
599 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
600 #define YYPARSE_PARAM_DECL
601 #else /* not __cplusplus */
602 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
603 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
604 #endif /* not __cplusplus */
605 #else /* not YYPARSE_PARAM */
606 #define YYPARSE_PARAM_ARG
607 #define YYPARSE_PARAM_DECL
608 #endif /* not YYPARSE_PARAM */
610 /* Prevent warning if -Wstrict-prototypes. */
611 #ifdef __GNUC__
612 #ifdef YYPARSE_PARAM
613 int yyparse (void *);
614 #else
615 int yyparse (void);
616 #endif
617 #endif
620 yyparse(YYPARSE_PARAM_ARG)
621 YYPARSE_PARAM_DECL
623 register int yystate;
624 register int yyn;
625 register short *yyssp;
626 register YYSTYPE *yyvsp;
627 int yyerrstatus; /* number of tokens to shift before error messages enabled */
628 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
630 short yyssa[YYINITDEPTH]; /* the state stack */
631 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
633 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
634 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
636 #ifdef YYLSP_NEEDED
637 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
638 YYLTYPE *yyls = yylsa;
639 YYLTYPE *yylsp;
641 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
642 #else
643 #define YYPOPSTACK (yyvsp--, yyssp--)
644 #endif
646 int yystacksize = YYINITDEPTH;
647 int yyfree_stacks = 0;
649 #ifdef YYPURE
650 int yychar;
651 YYSTYPE yylval;
652 int yynerrs;
653 #ifdef YYLSP_NEEDED
654 YYLTYPE yylloc;
655 #endif
656 #endif
658 YYSTYPE yyval; /* the variable used to return */
659 /* semantic values from the action */
660 /* routines */
662 int yylen;
664 #if YYDEBUG != 0
665 if (yydebug)
666 fprintf(stderr, "Starting parse\n");
667 #endif
669 yystate = 0;
670 yyerrstatus = 0;
671 yynerrs = 0;
672 yychar = YYEMPTY; /* Cause a token to be read. */
674 /* Initialize stack pointers.
675 Waste one element of value and location stack
676 so that they stay on the same level as the state stack.
677 The wasted elements are never initialized. */
679 yyssp = yyss - 1;
680 yyvsp = yyvs;
681 #ifdef YYLSP_NEEDED
682 yylsp = yyls;
683 #endif
685 /* Push a new state, which is found in yystate . */
686 /* In all cases, when you get here, the value and location stacks
687 have just been pushed. so pushing a state here evens the stacks. */
688 yynewstate:
690 *++yyssp = yystate;
692 if (yyssp >= yyss + yystacksize - 1)
694 /* Give user a chance to reallocate the stack */
695 /* Use copies of these so that the &'s don't force the real ones into memory. */
696 YYSTYPE *yyvs1 = yyvs;
697 short *yyss1 = yyss;
698 #ifdef YYLSP_NEEDED
699 YYLTYPE *yyls1 = yyls;
700 #endif
702 /* Get the current used size of the three stacks, in elements. */
703 int size = yyssp - yyss + 1;
705 #ifdef yyoverflow
706 /* Each stack pointer address is followed by the size of
707 the data in use in that stack, in bytes. */
708 #ifdef YYLSP_NEEDED
709 /* This used to be a conditional around just the two extra args,
710 but that might be undefined if yyoverflow is a macro. */
711 yyoverflow("parser stack overflow",
712 &yyss1, size * sizeof (*yyssp),
713 &yyvs1, size * sizeof (*yyvsp),
714 &yyls1, size * sizeof (*yylsp),
715 &yystacksize);
716 #else
717 yyoverflow("parser stack overflow",
718 &yyss1, size * sizeof (*yyssp),
719 &yyvs1, size * sizeof (*yyvsp),
720 &yystacksize);
721 #endif
723 yyss = yyss1; yyvs = yyvs1;
724 #ifdef YYLSP_NEEDED
725 yyls = yyls1;
726 #endif
727 #else /* no yyoverflow */
728 /* Extend the stack our own way. */
729 if (yystacksize >= YYMAXDEPTH)
731 yyerror("parser stack overflow");
732 if (yyfree_stacks)
734 free (yyss);
735 free (yyvs);
736 #ifdef YYLSP_NEEDED
737 free (yyls);
738 #endif
740 return 2;
742 yystacksize *= 2;
743 if (yystacksize > YYMAXDEPTH)
744 yystacksize = YYMAXDEPTH;
745 #ifndef YYSTACK_USE_ALLOCA
746 yyfree_stacks = 1;
747 #endif
748 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
749 __yy_memcpy ((char *)yyss, (char *)yyss1,
750 size * (unsigned int) sizeof (*yyssp));
751 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
752 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
753 size * (unsigned int) sizeof (*yyvsp));
754 #ifdef YYLSP_NEEDED
755 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
756 __yy_memcpy ((char *)yyls, (char *)yyls1,
757 size * (unsigned int) sizeof (*yylsp));
758 #endif
759 #endif /* no yyoverflow */
761 yyssp = yyss + size - 1;
762 yyvsp = yyvs + size - 1;
763 #ifdef YYLSP_NEEDED
764 yylsp = yyls + size - 1;
765 #endif
767 #if YYDEBUG != 0
768 if (yydebug)
769 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
770 #endif
772 if (yyssp >= yyss + yystacksize - 1)
773 YYABORT;
776 #if YYDEBUG != 0
777 if (yydebug)
778 fprintf(stderr, "Entering state %d\n", yystate);
779 #endif
781 goto yybackup;
782 yybackup:
784 /* Do appropriate processing given the current state. */
785 /* Read a lookahead token if we need one and don't already have one. */
786 /* yyresume: */
788 /* First try to decide what to do without reference to lookahead token. */
790 yyn = yypact[yystate];
791 if (yyn == YYFLAG)
792 goto yydefault;
794 /* Not known => get a lookahead token if don't already have one. */
796 /* yychar is either YYEMPTY or YYEOF
797 or a valid token in external form. */
799 if (yychar == YYEMPTY)
801 #if YYDEBUG != 0
802 if (yydebug)
803 fprintf(stderr, "Reading a token: ");
804 #endif
805 yychar = YYLEX;
808 /* Convert token to internal form (in yychar1) for indexing tables with */
810 if (yychar <= 0) /* This means end of input. */
812 yychar1 = 0;
813 yychar = YYEOF; /* Don't call YYLEX any more */
815 #if YYDEBUG != 0
816 if (yydebug)
817 fprintf(stderr, "Now at end of input.\n");
818 #endif
820 else
822 yychar1 = YYTRANSLATE(yychar);
824 #if YYDEBUG != 0
825 if (yydebug)
827 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
828 /* Give the individual parser a way to print the precise meaning
829 of a token, for further debugging info. */
830 #ifdef YYPRINT
831 YYPRINT (stderr, yychar, yylval);
832 #endif
833 fprintf (stderr, ")\n");
835 #endif
838 yyn += yychar1;
839 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
840 goto yydefault;
842 yyn = yytable[yyn];
844 /* yyn is what to do for this token type in this state.
845 Negative => reduce, -yyn is rule number.
846 Positive => shift, yyn is new state.
847 New state is final state => don't bother to shift,
848 just return success.
849 0, or most negative number => error. */
851 if (yyn < 0)
853 if (yyn == YYFLAG)
854 goto yyerrlab;
855 yyn = -yyn;
856 goto yyreduce;
858 else if (yyn == 0)
859 goto yyerrlab;
861 if (yyn == YYFINAL)
862 YYACCEPT;
864 /* Shift the lookahead token. */
866 #if YYDEBUG != 0
867 if (yydebug)
868 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
869 #endif
871 /* Discard the token being shifted unless it is eof. */
872 if (yychar != YYEOF)
873 yychar = YYEMPTY;
875 *++yyvsp = yylval;
876 #ifdef YYLSP_NEEDED
877 *++yylsp = yylloc;
878 #endif
880 /* count tokens shifted since error; after three, turn off error status. */
881 if (yyerrstatus) yyerrstatus--;
883 yystate = yyn;
884 goto yynewstate;
886 /* Do the default action for the current state. */
887 yydefault:
889 yyn = yydefact[yystate];
890 if (yyn == 0)
891 goto yyerrlab;
893 /* Do a reduction. yyn is the number of a rule to reduce with. */
894 yyreduce:
895 yylen = yyr2[yyn];
896 if (yylen > 0)
897 yyval = yyvsp[1-yylen]; /* implement default value of the action */
899 #if YYDEBUG != 0
900 if (yydebug)
902 int i;
904 fprintf (stderr, "Reducing via rule %d (line %d), ",
905 yyn, yyrline[yyn]);
907 /* Print the symbols being reduced, and their result. */
908 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
909 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
910 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
912 #endif
915 switch (yyn) {
917 case 3:
918 #line 204 "getdate.y"
920 yyHaveTime++;
922 break;}
923 case 4:
924 #line 207 "getdate.y"
926 yyHaveZone++;
928 break;}
929 case 5:
930 #line 210 "getdate.y"
932 yyHaveDate++;
934 break;}
935 case 6:
936 #line 213 "getdate.y"
938 yyHaveDay++;
940 break;}
941 case 7:
942 #line 216 "getdate.y"
944 yyHaveRel++;
946 break;}
947 case 9:
948 #line 222 "getdate.y"
950 yyHour = yyvsp[-1].Number;
951 yyMinutes = 0;
952 yySeconds = 0;
953 yyMeridian = yyvsp[0].Meridian;
955 break;}
956 case 10:
957 #line 228 "getdate.y"
959 yyHour = yyvsp[-3].Number;
960 yyMinutes = yyvsp[-1].Number;
961 yySeconds = 0;
962 yyMeridian = yyvsp[0].Meridian;
964 break;}
965 case 11:
966 #line 234 "getdate.y"
968 yyHour = yyvsp[-3].Number;
969 yyMinutes = yyvsp[-1].Number;
970 yyMeridian = MER24;
971 yyHaveZone++;
972 yyTimezone = (yyvsp[0].Number < 0
973 ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
974 : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
976 break;}
977 case 12:
978 #line 243 "getdate.y"
980 yyHour = yyvsp[-5].Number;
981 yyMinutes = yyvsp[-3].Number;
982 yySeconds = yyvsp[-1].Number;
983 yyMeridian = yyvsp[0].Meridian;
985 break;}
986 case 13:
987 #line 249 "getdate.y"
989 yyHour = yyvsp[-5].Number;
990 yyMinutes = yyvsp[-3].Number;
991 yySeconds = yyvsp[-1].Number;
992 yyMeridian = MER24;
993 yyHaveZone++;
994 yyTimezone = (yyvsp[0].Number < 0
995 ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
996 : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
998 break;}
999 case 14:
1000 #line 261 "getdate.y"
1002 yyTimezone = yyvsp[0].Number;
1004 break;}
1005 case 15:
1006 #line 264 "getdate.y"
1008 yyTimezone = yyvsp[0].Number - 60;
1010 break;}
1011 case 16:
1012 #line 268 "getdate.y"
1014 yyTimezone = yyvsp[-1].Number - 60;
1016 break;}
1017 case 17:
1018 #line 273 "getdate.y"
1020 yyDayOrdinal = 1;
1021 yyDayNumber = yyvsp[0].Number;
1023 break;}
1024 case 18:
1025 #line 277 "getdate.y"
1027 yyDayOrdinal = 1;
1028 yyDayNumber = yyvsp[-1].Number;
1030 break;}
1031 case 19:
1032 #line 281 "getdate.y"
1034 yyDayOrdinal = yyvsp[-1].Number;
1035 yyDayNumber = yyvsp[0].Number;
1037 break;}
1038 case 20:
1039 #line 287 "getdate.y"
1041 yyMonth = yyvsp[-2].Number;
1042 yyDay = yyvsp[0].Number;
1044 break;}
1045 case 21:
1046 #line 291 "getdate.y"
1048 /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
1049 The goal in recognizing YYYY/MM/DD is solely to support legacy
1050 machine-generated dates like those in an RCS log listing. If
1051 you want portability, use the ISO 8601 format. */
1052 if (yyvsp[-4].Number >= 1000)
1054 yyYear = yyvsp[-4].Number;
1055 yyMonth = yyvsp[-2].Number;
1056 yyDay = yyvsp[0].Number;
1058 else
1060 yyMonth = yyvsp[-4].Number;
1061 yyDay = yyvsp[-2].Number;
1062 yyYear = yyvsp[0].Number;
1065 break;}
1066 case 22:
1067 #line 309 "getdate.y"
1069 /* ISO 8601 format. yyyy-mm-dd. */
1070 yyYear = yyvsp[-2].Number;
1071 yyMonth = -yyvsp[-1].Number;
1072 yyDay = -yyvsp[0].Number;
1074 break;}
1075 case 23:
1076 #line 315 "getdate.y"
1078 /* e.g. 17-JUN-1992. */
1079 yyDay = yyvsp[-2].Number;
1080 yyMonth = yyvsp[-1].Number;
1081 yyYear = -yyvsp[0].Number;
1083 break;}
1084 case 24:
1085 #line 321 "getdate.y"
1087 yyMonth = yyvsp[-1].Number;
1088 yyDay = yyvsp[0].Number;
1090 break;}
1091 case 25:
1092 #line 325 "getdate.y"
1094 yyMonth = yyvsp[-3].Number;
1095 yyDay = yyvsp[-2].Number;
1096 yyYear = yyvsp[0].Number;
1098 break;}
1099 case 26:
1100 #line 330 "getdate.y"
1102 yyMonth = yyvsp[0].Number;
1103 yyDay = yyvsp[-1].Number;
1105 break;}
1106 case 27:
1107 #line 334 "getdate.y"
1109 yyMonth = yyvsp[-1].Number;
1110 yyDay = yyvsp[-2].Number;
1111 yyYear = yyvsp[0].Number;
1113 break;}
1114 case 28:
1115 #line 341 "getdate.y"
1117 yyRelSeconds = -yyRelSeconds;
1118 yyRelMinutes = -yyRelMinutes;
1119 yyRelHour = -yyRelHour;
1120 yyRelDay = -yyRelDay;
1121 yyRelMonth = -yyRelMonth;
1122 yyRelYear = -yyRelYear;
1124 break;}
1125 case 30:
1126 #line 352 "getdate.y"
1128 yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
1130 break;}
1131 case 31:
1132 #line 355 "getdate.y"
1134 yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
1136 break;}
1137 case 32:
1138 #line 358 "getdate.y"
1140 yyRelYear += yyvsp[0].Number;
1142 break;}
1143 case 33:
1144 #line 361 "getdate.y"
1146 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1148 break;}
1149 case 34:
1150 #line 364 "getdate.y"
1152 yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1154 break;}
1155 case 35:
1156 #line 367 "getdate.y"
1158 yyRelMonth += yyvsp[0].Number;
1160 break;}
1161 case 36:
1162 #line 370 "getdate.y"
1164 yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
1166 break;}
1167 case 37:
1168 #line 373 "getdate.y"
1170 yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
1172 break;}
1173 case 38:
1174 #line 376 "getdate.y"
1176 yyRelDay += yyvsp[0].Number;
1178 break;}
1179 case 39:
1180 #line 379 "getdate.y"
1182 yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
1184 break;}
1185 case 40:
1186 #line 382 "getdate.y"
1188 yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
1190 break;}
1191 case 41:
1192 #line 385 "getdate.y"
1194 yyRelHour += yyvsp[0].Number;
1196 break;}
1197 case 42:
1198 #line 388 "getdate.y"
1200 yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
1202 break;}
1203 case 43:
1204 #line 391 "getdate.y"
1206 yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
1208 break;}
1209 case 44:
1210 #line 394 "getdate.y"
1212 yyRelMinutes += yyvsp[0].Number;
1214 break;}
1215 case 45:
1216 #line 397 "getdate.y"
1218 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1220 break;}
1221 case 46:
1222 #line 400 "getdate.y"
1224 yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1226 break;}
1227 case 47:
1228 #line 403 "getdate.y"
1230 yyRelSeconds += yyvsp[0].Number;
1232 break;}
1233 case 48:
1234 #line 409 "getdate.y"
1236 if (yyHaveTime && yyHaveDate && !yyHaveRel)
1237 yyYear = yyvsp[0].Number;
1238 else
1240 if (yyvsp[0].Number>10000)
1242 yyHaveDate++;
1243 yyDay= (yyvsp[0].Number)%100;
1244 yyMonth= (yyvsp[0].Number/100)%100;
1245 yyYear = yyvsp[0].Number/10000;
1247 else
1249 yyHaveTime++;
1250 if (yyvsp[0].Number < 100)
1252 yyHour = yyvsp[0].Number;
1253 yyMinutes = 0;
1255 else
1257 yyHour = yyvsp[0].Number / 100;
1258 yyMinutes = yyvsp[0].Number % 100;
1260 yySeconds = 0;
1261 yyMeridian = MER24;
1265 break;}
1266 case 49:
1267 #line 442 "getdate.y"
1269 yyval.Meridian = MER24;
1271 break;}
1272 case 50:
1273 #line 446 "getdate.y"
1275 yyval.Meridian = yyvsp[0].Meridian;
1277 break;}
1279 /* the action file gets copied in in place of this dollarsign */
1280 #line 542 "/boot/apps/GeekGadgets/share/bison.simple"
1282 yyvsp -= yylen;
1283 yyssp -= yylen;
1284 #ifdef YYLSP_NEEDED
1285 yylsp -= yylen;
1286 #endif
1288 #if YYDEBUG != 0
1289 if (yydebug)
1291 short *ssp1 = yyss - 1;
1292 fprintf (stderr, "state stack now");
1293 while (ssp1 != yyssp)
1294 fprintf (stderr, " %d", *++ssp1);
1295 fprintf (stderr, "\n");
1297 #endif
1299 *++yyvsp = yyval;
1301 #ifdef YYLSP_NEEDED
1302 yylsp++;
1303 if (yylen == 0)
1305 yylsp->first_line = yylloc.first_line;
1306 yylsp->first_column = yylloc.first_column;
1307 yylsp->last_line = (yylsp-1)->last_line;
1308 yylsp->last_column = (yylsp-1)->last_column;
1309 yylsp->text = 0;
1311 else
1313 yylsp->last_line = (yylsp+yylen-1)->last_line;
1314 yylsp->last_column = (yylsp+yylen-1)->last_column;
1316 #endif
1318 /* Now "shift" the result of the reduction.
1319 Determine what state that goes to,
1320 based on the state we popped back to
1321 and the rule number reduced by. */
1323 yyn = yyr1[yyn];
1325 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1326 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1327 yystate = yytable[yystate];
1328 else
1329 yystate = yydefgoto[yyn - YYNTBASE];
1331 goto yynewstate;
1333 yyerrlab: /* here on detecting error */
1335 if (! yyerrstatus)
1336 /* If not already recovering from an error, report this error. */
1338 ++yynerrs;
1340 #ifdef YYERROR_VERBOSE
1341 yyn = yypact[yystate];
1343 if (yyn > YYFLAG && yyn < YYLAST)
1345 int size = 0;
1346 char *msg;
1347 int x, count;
1349 count = 0;
1350 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1351 for (x = (yyn < 0 ? -yyn : 0);
1352 x < (sizeof(yytname) / sizeof(char *)); x++)
1353 if (yycheck[x + yyn] == x)
1354 size += strlen(yytname[x]) + 15, count++;
1355 msg = (char *) malloc(size + 15);
1356 if (msg != 0)
1358 strcpy(msg, "parse error");
1360 if (count < 5)
1362 count = 0;
1363 for (x = (yyn < 0 ? -yyn : 0);
1364 x < (sizeof(yytname) / sizeof(char *)); x++)
1365 if (yycheck[x + yyn] == x)
1367 strcat(msg, count == 0 ? ", expecting `" : " or `");
1368 strcat(msg, yytname[x]);
1369 strcat(msg, "'");
1370 count++;
1373 yyerror(msg);
1374 free(msg);
1376 else
1377 yyerror ("parse error; also virtual memory exceeded");
1379 else
1380 #endif /* YYERROR_VERBOSE */
1381 yyerror("parse error");
1384 goto yyerrlab1;
1385 yyerrlab1: /* here on error raised explicitly by an action */
1387 if (yyerrstatus == 3)
1389 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1391 /* return failure if at end of input */
1392 if (yychar == YYEOF)
1393 YYABORT;
1395 #if YYDEBUG != 0
1396 if (yydebug)
1397 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1398 #endif
1400 yychar = YYEMPTY;
1403 /* Else will try to reuse lookahead token
1404 after shifting the error token. */
1406 yyerrstatus = 3; /* Each real token shifted decrements this */
1408 goto yyerrhandle;
1410 yyerrdefault: /* current state does not do anything special for the error token. */
1412 #if 0
1413 /* This is wrong; only states that explicitly want error tokens
1414 should shift them. */
1415 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1416 if (yyn) goto yydefault;
1417 #endif
1419 yyerrpop: /* pop the current state because it cannot handle the error token */
1421 if (yyssp == yyss) YYABORT;
1422 yyvsp--;
1423 yystate = *--yyssp;
1424 #ifdef YYLSP_NEEDED
1425 yylsp--;
1426 #endif
1428 #if YYDEBUG != 0
1429 if (yydebug)
1431 short *ssp1 = yyss - 1;
1432 fprintf (stderr, "Error: state stack now");
1433 while (ssp1 != yyssp)
1434 fprintf (stderr, " %d", *++ssp1);
1435 fprintf (stderr, "\n");
1437 #endif
1439 yyerrhandle:
1441 yyn = yypact[yystate];
1442 if (yyn == YYFLAG)
1443 goto yyerrdefault;
1445 yyn += YYTERROR;
1446 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1447 goto yyerrdefault;
1449 yyn = yytable[yyn];
1450 if (yyn < 0)
1452 if (yyn == YYFLAG)
1453 goto yyerrpop;
1454 yyn = -yyn;
1455 goto yyreduce;
1457 else if (yyn == 0)
1458 goto yyerrpop;
1460 if (yyn == YYFINAL)
1461 YYACCEPT;
1463 #if YYDEBUG != 0
1464 if (yydebug)
1465 fprintf(stderr, "Shifting error token, ");
1466 #endif
1468 *++yyvsp = yylval;
1469 #ifdef YYLSP_NEEDED
1470 *++yylsp = yylloc;
1471 #endif
1473 yystate = yyn;
1474 goto yynewstate;
1476 yyacceptlab:
1477 /* YYACCEPT comes here. */
1478 if (yyfree_stacks)
1480 free (yyss);
1481 free (yyvs);
1482 #ifdef YYLSP_NEEDED
1483 free (yyls);
1484 #endif
1486 return 0;
1488 yyabortlab:
1489 /* YYABORT comes here. */
1490 if (yyfree_stacks)
1492 free (yyss);
1493 free (yyvs);
1494 #ifdef YYLSP_NEEDED
1495 free (yyls);
1496 #endif
1498 return 1;
1500 #line 451 "getdate.y"
1503 /* Include this file down here because bison inserts code above which
1504 may define-away `const'. We want the prototype for get_date to have
1505 the same signature as the function definition does. */
1506 #include "getdate.h"
1508 extern struct tm *gmtime ();
1509 extern struct tm *localtime ();
1510 extern time_t mktime ();
1512 /* Month and day table. */
1513 static TABLE const MonthDayTable[] = {
1514 { "january", tMONTH, 1 },
1515 { "february", tMONTH, 2 },
1516 { "march", tMONTH, 3 },
1517 { "april", tMONTH, 4 },
1518 { "may", tMONTH, 5 },
1519 { "june", tMONTH, 6 },
1520 { "july", tMONTH, 7 },
1521 { "august", tMONTH, 8 },
1522 { "september", tMONTH, 9 },
1523 { "sept", tMONTH, 9 },
1524 { "october", tMONTH, 10 },
1525 { "november", tMONTH, 11 },
1526 { "december", tMONTH, 12 },
1527 { "sunday", tDAY, 0 },
1528 { "monday", tDAY, 1 },
1529 { "tuesday", tDAY, 2 },
1530 { "tues", tDAY, 2 },
1531 { "wednesday", tDAY, 3 },
1532 { "wednes", tDAY, 3 },
1533 { "thursday", tDAY, 4 },
1534 { "thur", tDAY, 4 },
1535 { "thurs", tDAY, 4 },
1536 { "friday", tDAY, 5 },
1537 { "saturday", tDAY, 6 },
1538 { NULL, 0, 0 }
1541 /* Time units table. */
1542 static TABLE const UnitsTable[] = {
1543 { "year", tYEAR_UNIT, 1 },
1544 { "month", tMONTH_UNIT, 1 },
1545 { "fortnight", tDAY_UNIT, 14 },
1546 { "week", tDAY_UNIT, 7 },
1547 { "day", tDAY_UNIT, 1 },
1548 { "hour", tHOUR_UNIT, 1 },
1549 { "minute", tMINUTE_UNIT, 1 },
1550 { "min", tMINUTE_UNIT, 1 },
1551 { "second", tSEC_UNIT, 1 },
1552 { "sec", tSEC_UNIT, 1 },
1553 { NULL, 0, 0 }
1556 /* Assorted relative-time words. */
1557 static TABLE const OtherTable[] = {
1558 { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
1559 { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
1560 { "today", tMINUTE_UNIT, 0 },
1561 { "now", tMINUTE_UNIT, 0 },
1562 { "last", tUNUMBER, -1 },
1563 { "this", tMINUTE_UNIT, 0 },
1564 { "next", tUNUMBER, 1 },
1565 { "first", tUNUMBER, 1 },
1566 /* { "second", tUNUMBER, 2 }, */
1567 { "third", tUNUMBER, 3 },
1568 { "fourth", tUNUMBER, 4 },
1569 { "fifth", tUNUMBER, 5 },
1570 { "sixth", tUNUMBER, 6 },
1571 { "seventh", tUNUMBER, 7 },
1572 { "eighth", tUNUMBER, 8 },
1573 { "ninth", tUNUMBER, 9 },
1574 { "tenth", tUNUMBER, 10 },
1575 { "eleventh", tUNUMBER, 11 },
1576 { "twelfth", tUNUMBER, 12 },
1577 { "ago", tAGO, 1 },
1578 { NULL, 0, 0 }
1581 /* The timezone table. */
1582 static TABLE const TimezoneTable[] = {
1583 { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1584 { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1585 { "utc", tZONE, HOUR ( 0) },
1586 { "wet", tZONE, HOUR ( 0) }, /* Western European */
1587 { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
1588 { "wat", tZONE, HOUR ( 1) }, /* West Africa */
1589 { "at", tZONE, HOUR ( 2) }, /* Azores */
1590 #if 0
1591 /* For completeness. BST is also British Summer, and GST is
1592 * also Guam Standard. */
1593 { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */
1594 { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */
1595 #endif
1596 #if 0
1597 { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */
1598 { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */
1599 { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */
1600 #endif
1601 { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
1602 { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
1603 { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
1604 { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
1605 { "cst", tZONE, HOUR ( 6) }, /* Central Standard */
1606 { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
1607 { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
1608 { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
1609 { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
1610 { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
1611 { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
1612 { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
1613 { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
1614 { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
1615 { "cat", tZONE, HOUR (10) }, /* Central Alaska */
1616 { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
1617 { "nt", tZONE, HOUR (11) }, /* Nome */
1618 { "idlw", tZONE, HOUR (12) }, /* International Date Line West */
1619 { "cet", tZONE, -HOUR (1) }, /* Central European */
1620 { "met", tZONE, -HOUR (1) }, /* Middle European */
1621 { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
1622 { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
1623 { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
1624 { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
1625 { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
1626 { "fwt", tZONE, -HOUR (1) }, /* French Winter */
1627 { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
1628 { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
1629 { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
1630 #if 0
1631 { "it", tZONE, -HOUR (3.5) },/* Iran */
1632 #endif
1633 { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
1634 { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
1635 #if 0
1636 { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */
1637 #endif
1638 { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
1639 #if 0
1640 /* For completeness. NST is also Newfoundland Standard, and SST is
1641 * also Swedish Summer. */
1642 { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */
1643 { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */
1644 #endif /* 0 */
1645 { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
1646 { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
1647 #if 0
1648 { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */
1649 #endif
1650 { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
1651 { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
1652 #if 0
1653 { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */
1654 { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */
1655 #endif
1656 { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
1657 { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
1658 { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
1659 { "nzt", tZONE, -HOUR (12) }, /* New Zealand */
1660 { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
1661 { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
1662 { "idle", tZONE, -HOUR (12) }, /* International Date Line East */
1663 { NULL, 0, 0 }
1666 /* Military timezone table. */
1667 static TABLE const MilitaryTable[] = {
1668 { "a", tZONE, HOUR ( 1) },
1669 { "b", tZONE, HOUR ( 2) },
1670 { "c", tZONE, HOUR ( 3) },
1671 { "d", tZONE, HOUR ( 4) },
1672 { "e", tZONE, HOUR ( 5) },
1673 { "f", tZONE, HOUR ( 6) },
1674 { "g", tZONE, HOUR ( 7) },
1675 { "h", tZONE, HOUR ( 8) },
1676 { "i", tZONE, HOUR ( 9) },
1677 { "k", tZONE, HOUR ( 10) },
1678 { "l", tZONE, HOUR ( 11) },
1679 { "m", tZONE, HOUR ( 12) },
1680 { "n", tZONE, HOUR (- 1) },
1681 { "o", tZONE, HOUR (- 2) },
1682 { "p", tZONE, HOUR (- 3) },
1683 { "q", tZONE, HOUR (- 4) },
1684 { "r", tZONE, HOUR (- 5) },
1685 { "s", tZONE, HOUR (- 6) },
1686 { "t", tZONE, HOUR (- 7) },
1687 { "u", tZONE, HOUR (- 8) },
1688 { "v", tZONE, HOUR (- 9) },
1689 { "w", tZONE, HOUR (-10) },
1690 { "x", tZONE, HOUR (-11) },
1691 { "y", tZONE, HOUR (-12) },
1692 { "z", tZONE, HOUR ( 0) },
1693 { NULL, 0, 0 }
1699 /* ARGSUSED */
1700 static int
1701 yyerror (s)
1702 char *s ATTRIBUTE_UNUSED;
1704 return 0;
1707 static int
1708 ToHour (Hours, Meridian)
1709 int Hours;
1710 MERIDIAN Meridian;
1712 switch (Meridian)
1714 case MER24:
1715 if (Hours < 0 || Hours > 23)
1716 return -1;
1717 return Hours;
1718 case MERam:
1719 if (Hours < 1 || Hours > 12)
1720 return -1;
1721 if (Hours == 12)
1722 Hours = 0;
1723 return Hours;
1724 case MERpm:
1725 if (Hours < 1 || Hours > 12)
1726 return -1;
1727 if (Hours == 12)
1728 Hours = 0;
1729 return Hours + 12;
1730 default:
1731 abort ();
1733 /* NOTREACHED */
1736 static int
1737 ToYear (Year)
1738 int Year;
1740 if (Year < 0)
1741 Year = -Year;
1743 /* XPG4 suggests that years 00-68 map to 2000-2068, and
1744 years 69-99 map to 1969-1999. */
1745 if (Year < 69)
1746 Year += 2000;
1747 else if (Year < 100)
1748 Year += 1900;
1750 return Year;
1753 static int
1754 LookupWord (buff)
1755 char *buff;
1757 register char *p;
1758 register char *q;
1759 register const TABLE *tp;
1760 int i;
1761 int abbrev;
1763 /* Make it lowercase. */
1764 for (p = buff; *p; p++)
1765 if (ISUPPER ((unsigned char) *p))
1766 *p = tolower (*p);
1768 if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
1770 yylval.Meridian = MERam;
1771 return tMERIDIAN;
1773 if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
1775 yylval.Meridian = MERpm;
1776 return tMERIDIAN;
1779 /* See if we have an abbreviation for a month. */
1780 if (strlen (buff) == 3)
1781 abbrev = 1;
1782 else if (strlen (buff) == 4 && buff[3] == '.')
1784 abbrev = 1;
1785 buff[3] = '\0';
1787 else
1788 abbrev = 0;
1790 for (tp = MonthDayTable; tp->name; tp++)
1792 if (abbrev)
1794 if (strncmp (buff, tp->name, 3) == 0)
1796 yylval.Number = tp->value;
1797 return tp->type;
1800 else if (strcmp (buff, tp->name) == 0)
1802 yylval.Number = tp->value;
1803 return tp->type;
1807 for (tp = TimezoneTable; tp->name; tp++)
1808 if (strcmp (buff, tp->name) == 0)
1810 yylval.Number = tp->value;
1811 return tp->type;
1814 if (strcmp (buff, "dst") == 0)
1815 return tDST;
1817 for (tp = UnitsTable; tp->name; tp++)
1818 if (strcmp (buff, tp->name) == 0)
1820 yylval.Number = tp->value;
1821 return tp->type;
1824 /* Strip off any plural and try the units table again. */
1825 i = strlen (buff) - 1;
1826 if (buff[i] == 's')
1828 buff[i] = '\0';
1829 for (tp = UnitsTable; tp->name; tp++)
1830 if (strcmp (buff, tp->name) == 0)
1832 yylval.Number = tp->value;
1833 return tp->type;
1835 buff[i] = 's'; /* Put back for "this" in OtherTable. */
1838 for (tp = OtherTable; tp->name; tp++)
1839 if (strcmp (buff, tp->name) == 0)
1841 yylval.Number = tp->value;
1842 return tp->type;
1845 /* Military timezones. */
1846 if (buff[1] == '\0' && ISALPHA ((unsigned char) *buff))
1848 for (tp = MilitaryTable; tp->name; tp++)
1849 if (strcmp (buff, tp->name) == 0)
1851 yylval.Number = tp->value;
1852 return tp->type;
1856 /* Drop out any periods and try the timezone table again. */
1857 for (i = 0, p = q = buff; *q; q++)
1858 if (*q != '.')
1859 *p++ = *q;
1860 else
1861 i++;
1862 *p = '\0';
1863 if (i)
1864 for (tp = TimezoneTable; tp->name; tp++)
1865 if (strcmp (buff, tp->name) == 0)
1867 yylval.Number = tp->value;
1868 return tp->type;
1871 return tID;
1874 static int
1875 yylex ()
1877 register unsigned char c;
1878 register char *p;
1879 char buff[20];
1880 int Count;
1881 int sign;
1883 for (;;)
1885 while (ISSPACE ((unsigned char) *yyInput))
1886 yyInput++;
1888 if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
1890 if (c == '-' || c == '+')
1892 sign = c == '-' ? -1 : 1;
1893 if (!ISDIGIT (*++yyInput))
1894 /* skip the '-' sign */
1895 continue;
1897 else
1898 sign = 0;
1899 for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
1900 yylval.Number = 10 * yylval.Number + c - '0';
1901 yyInput--;
1902 if (sign < 0)
1903 yylval.Number = -yylval.Number;
1904 return sign ? tSNUMBER : tUNUMBER;
1906 if (ISALPHA (c))
1908 for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
1909 if (p < &buff[sizeof buff - 1])
1910 *p++ = c;
1911 *p = '\0';
1912 yyInput--;
1913 return LookupWord (buff);
1915 if (c != '(')
1916 return *yyInput++;
1917 Count = 0;
1920 c = *yyInput++;
1921 if (c == '\0')
1922 return c;
1923 if (c == '(')
1924 Count++;
1925 else if (c == ')')
1926 Count--;
1928 while (Count > 0);
1932 #define TM_YEAR_ORIGIN 1900
1934 /* Yield A - B, measured in seconds. */
1935 static long
1936 difftm (struct tm *a, struct tm *b)
1938 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
1939 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
1940 long days = (
1941 /* difference in day of year */
1942 a->tm_yday - b->tm_yday
1943 /* + intervening leap days */
1944 + ((ay >> 2) - (by >> 2))
1945 - (ay / 100 - by / 100)
1946 + ((ay / 100 >> 2) - (by / 100 >> 2))
1947 /* + difference in years * 365 */
1948 + (long) (ay - by) * 365
1950 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
1951 + (a->tm_min - b->tm_min))
1952 + (a->tm_sec - b->tm_sec));
1955 time_t
1956 get_date (const char *p, const time_t *now)
1958 struct tm tm, tm0, *tmp;
1959 time_t Start;
1961 yyInput = p;
1962 Start = now ? *now : time ((time_t *) NULL);
1963 tmp = localtime (&Start);
1964 if (!tmp)
1965 return -1;
1966 yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
1967 yyMonth = tmp->tm_mon + 1;
1968 yyDay = tmp->tm_mday;
1969 yyHour = tmp->tm_hour;
1970 yyMinutes = tmp->tm_min;
1971 yySeconds = tmp->tm_sec;
1972 tm.tm_isdst = tmp->tm_isdst;
1973 yyMeridian = MER24;
1974 yyRelSeconds = 0;
1975 yyRelMinutes = 0;
1976 yyRelHour = 0;
1977 yyRelDay = 0;
1978 yyRelMonth = 0;
1979 yyRelYear = 0;
1980 yyHaveDate = 0;
1981 yyHaveDay = 0;
1982 yyHaveRel = 0;
1983 yyHaveTime = 0;
1984 yyHaveZone = 0;
1986 if (yyparse ()
1987 || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
1988 return -1;
1990 tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
1991 tm.tm_mon = yyMonth - 1 + yyRelMonth;
1992 tm.tm_mday = yyDay + yyRelDay;
1993 if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay))
1995 tm.tm_hour = ToHour (yyHour, yyMeridian);
1996 if (tm.tm_hour < 0)
1997 return -1;
1998 tm.tm_min = yyMinutes;
1999 tm.tm_sec = yySeconds;
2001 else
2003 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2005 tm.tm_hour += yyRelHour;
2006 tm.tm_min += yyRelMinutes;
2007 tm.tm_sec += yyRelSeconds;
2009 /* Let mktime deduce tm_isdst if we have an absolute timestamp,
2010 or if the relative timestamp mentions days, months, or years. */
2011 if (yyHaveDate | yyHaveDay | yyHaveTime | yyRelDay | yyRelMonth | yyRelYear)
2012 tm.tm_isdst = -1;
2014 tm0 = tm;
2016 Start = mktime (&tm);
2018 if (Start == (time_t) -1)
2021 /* Guard against falsely reporting errors near the time_t boundaries
2022 when parsing times in other time zones. For example, if the min
2023 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2024 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2025 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2026 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2027 zone by 24 hours to compensate. This algorithm assumes that
2028 there is no DST transition within a day of the time_t boundaries. */
2029 if (yyHaveZone)
2031 tm = tm0;
2032 if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
2034 tm.tm_mday++;
2035 yyTimezone -= 24 * 60;
2037 else
2039 tm.tm_mday--;
2040 yyTimezone += 24 * 60;
2042 Start = mktime (&tm);
2045 if (Start == (time_t) -1)
2046 return Start;
2049 if (yyHaveDay && !yyHaveDate)
2051 tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
2052 + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
2053 Start = mktime (&tm);
2054 if (Start == (time_t) -1)
2055 return Start;
2058 if (yyHaveZone)
2060 long delta;
2061 struct tm *gmt = gmtime (&Start);
2062 if (!gmt)
2063 return -1;
2064 delta = yyTimezone * 60L + difftm (&tm, gmt);
2065 if ((Start + delta < Start) != (delta < 0))
2066 return -1; /* time_t overflow */
2067 Start += delta;
2070 return Start;
2073 #if defined (TEST)
2075 /* ARGSUSED */
2077 main (ac, av)
2078 int ac;
2079 char *av[];
2081 char buff[MAX_BUFF_LEN + 1];
2082 time_t d;
2084 (void) printf ("Enter date, or blank line to exit.\n\t> ");
2085 (void) fflush (stdout);
2087 buff[MAX_BUFF_LEN] = 0;
2088 while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
2090 d = get_date (buff, (time_t *) NULL);
2091 if (d == -1)
2092 (void) printf ("Bad format - couldn't convert.\n");
2093 else
2094 (void) printf ("%s", ctime (&d));
2095 (void) printf ("\t> ");
2096 (void) fflush (stdout);
2098 exit (0);
2099 /* NOTREACHED */
2101 #endif /* defined (TEST) */