3 #pragma warning( disable: 4028 )
6 /* A Bison parser, made from getdate.y
7 by GNU Bison version 1.28 */
9 #define YYBISON 1 /* Identify Bison output. */
16 #define tHOUR_UNIT 262
19 #define tMINUTE_UNIT 265
21 #define tMONTH_UNIT 267
25 #define tYEAR_UNIT 271
31 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
32 ** at the University of North Carolina at Chapel Hill. Later tweaked by
33 ** a couple of people on Usenet. Completely overhauled by Rich $alz
34 ** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
36 ** This code has been modified since it was included in curl, to make it
37 ** thread-safe and to make compilers complain less about it.
39 ** This code is in the public domain and has no copyright.
53 /* to satisfy gcc -Wundef, we set this to 0 */
57 /* Since the code of getdate.y is not included in the Emacs executable
58 itself, there is no need to #define static in this file. Even if
59 the code were included in the Emacs executable, it probably
60 wouldn't do any harm to #undef it here; this will only cause
61 problems if we try to write to a static variable, which I don't
62 think this code needs to do. */
68 #include <sys/types.h>
69 #include <sys/malloc.h>
78 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
87 #if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
88 # define IN_CTYPE_DOMAIN(c) 1
90 # define IN_CTYPE_DOMAIN(c) isascii(c)
93 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
94 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
95 #define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
96 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
98 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
99 - Its arg may be any int or unsigned int; it need not be an unsigned char.
100 - It's guaranteed to evaluate its argument exactly once.
101 - It's typically faster.
102 Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
103 only '0' through '9' are digits. Prefer ISDIGIT to ISDIGIT_LOCALE unless
104 it's important to use the locale's definition of `digit' even when the
105 host does not conform to Posix. */
106 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
108 #if defined (STDC_HEADERS) || defined (USG)
112 /* The last #include file should be: */
114 #include "memdebug.h"
121 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
122 # define __attribute__(x)
125 #ifndef ATTRIBUTE_UNUSED
126 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
129 /* Some old versions of bison generate parsers that use bcopy.
130 That loses on systems that don't provide the function, so we have
131 to redefine it here. */
132 #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
133 # define bcopy(from, to, len) memcpy ((to), (from), (len))
136 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
137 as well as gratuitiously global symbol names, so we can have multiple
138 yacc generated parsers in the same program. Note that these are only
139 the variables produced by yacc. If other parser generators (bison,
140 byacc, etc) produce additional global names that conflict at link time,
141 then those parser generators need to be fixed instead of adding those
142 names to this list. */
144 #define yymaxdepth Curl_gd_maxdepth
145 #define yyparse Curl_gd_parse
146 #define yylex Curl_gd_lex
147 #define yyerror Curl_gd_error
148 #define yylval Curl_gd_lval
149 #define yychar Curl_gd_char
150 #define yydebug Curl_gd_debug
151 #define yypact Curl_gd_pact
152 #define yyr1 Curl_gd_r1
153 #define yyr2 Curl_gd_r2
154 #define yydef Curl_gd_def
155 #define yychk Curl_gd_chk
156 #define yypgo Curl_gd_pgo
157 #define yyact Curl_gd_act
158 #define yyexca Curl_gd_exca
159 #define yyerrflag Curl_gd_errflag
160 #define yynerrs Curl_gd_nerrs
161 #define yyps Curl_gd_ps
162 #define yypv Curl_gd_pv
163 #define yys Curl_gd_s
164 #define yy_yys Curl_gd_yys
165 #define yystate Curl_gd_state
166 #define yytmp Curl_gd_tmp
167 #define yyv Curl_gd_v
168 #define yy_yyv Curl_gd_yyv
169 #define yyval Curl_gd_val
170 #define yylloc Curl_gd_lloc
171 #define yyreds Curl_gd_reds /* With YYDEBUG defined */
172 #define yytoks Curl_gd_toks /* With YYDEBUG defined */
173 #define yylhs Curl_gd_yylhs
174 #define yylen Curl_gd_yylen
175 #define yydefred Curl_gd_yydefred
176 #define yydgoto Curl_gd_yydgoto
177 #define yysindex Curl_gd_yysindex
178 #define yyrindex Curl_gd_yyrindex
179 #define yygindex Curl_gd_yygindex
180 #define yytable Curl_gd_yytable
181 #define yycheck Curl_gd_yycheck
184 #define HOUR(x) ((x) * 60)
186 #define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
189 ** An entry in the lexical lookup table.
191 typedef struct _TABLE {
199 ** Meridian: am, pm, or 24-hour style.
201 typedef enum _MERIDIAN {
205 /* parse results and input string */
206 typedef struct _CURL_CONTEXT {
231 /* enable use of extra argument to yyparse and yylex which can be used to pass
232 ** in a user defined value (CURL_CONTEXT struct in our case)
234 #define YYPARSE_PARAM cookie
235 #define YYLEX_PARAM cookie
236 #define context ((CURL_CONTEXT *) cookie)
238 #line 219 "getdate.y"
241 enum _MERIDIAN Meridian;
243 #line 224 "getdate.y"
245 static int yylex (YYSTYPE *yylval, void *cookie);
246 static int yyerror (const char *s);
258 #define YYFLAG -32768
261 #define YYTRANSLATE(x) ((unsigned)(x) <= 272 ? yytranslate[x] : 32)
263 static const char yytranslate[] = { 0,
264 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
265 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
266 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
267 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
268 2, 2, 2, 20, 2, 2, 21, 2, 2, 2,
269 2, 2, 2, 2, 2, 2, 2, 19, 2, 2,
270 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
271 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
272 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
273 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
274 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
275 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
276 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
277 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
278 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
279 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
280 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
281 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
282 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
283 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
284 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
285 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
286 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
287 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
288 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
289 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
290 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
295 static const short yyprhs[] = { 0,
296 0, 1, 4, 6, 8, 10, 12, 14, 16, 19,
297 24, 29, 36, 43, 45, 47, 50, 52, 55, 58,
298 62, 68, 72, 76, 79, 84, 87, 91, 94, 96,
299 99, 102, 104, 107, 110, 112, 115, 118, 120, 123,
300 126, 128, 131, 134, 136, 139, 142, 144, 146, 147
303 static const short yyrhs[] = { -1,
304 22, 23, 0, 24, 0, 25, 0, 27, 0, 26,
305 0, 28, 0, 30, 0, 16, 10, 0, 16, 19,
306 16, 31, 0, 16, 19, 16, 15, 0, 16, 19,
307 16, 19, 16, 31, 0, 16, 19, 16, 19, 16,
308 15, 0, 18, 0, 6, 0, 18, 7, 0, 4,
309 0, 4, 20, 0, 16, 4, 0, 16, 21, 16,
310 0, 16, 21, 16, 21, 16, 0, 16, 15, 15,
311 0, 16, 12, 15, 0, 12, 16, 0, 12, 16,
312 20, 16, 0, 16, 12, 0, 16, 12, 16, 0,
313 29, 3, 0, 29, 0, 16, 17, 0, 15, 17,
314 0, 17, 0, 16, 13, 0, 15, 13, 0, 13,
315 0, 16, 5, 0, 15, 5, 0, 5, 0, 16,
316 8, 0, 15, 8, 0, 8, 0, 16, 11, 0,
317 15, 11, 0, 11, 0, 16, 14, 0, 15, 14,
318 0, 14, 0, 16, 0, 0, 10, 0
324 static const short yyrline[] = { 0,
325 240, 241, 244, 247, 250, 253, 256, 259, 262, 268,
326 274, 283, 289, 301, 304, 307, 313, 317, 321, 327,
327 331, 349, 355, 361, 365, 370, 374, 381, 389, 392,
328 395, 398, 401, 404, 407, 410, 413, 416, 419, 422,
329 425, 428, 431, 434, 437, 440, 443, 448, 482, 486
334 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
336 static const char * const yytname[] = { "$","error","$undefined.","tAGO","tDAY",
337 "tDAY_UNIT","tDAYZONE","tDST","tHOUR_UNIT","tID","tMERIDIAN","tMINUTE_UNIT",
338 "tMONTH","tMONTH_UNIT","tSEC_UNIT","tSNUMBER","tUNUMBER","tYEAR_UNIT","tZONE",
339 "':'","','","'/'","spec","item","time","zone","day","date","rel","relunit","number",
344 static const short yyr1[] = { 0,
345 22, 22, 23, 23, 23, 23, 23, 23, 24, 24,
346 24, 24, 24, 25, 25, 25, 26, 26, 26, 27,
347 27, 27, 27, 27, 27, 27, 27, 28, 28, 29,
348 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
349 29, 29, 29, 29, 29, 29, 29, 30, 31, 31
352 static const short yyr2[] = { 0,
353 0, 2, 1, 1, 1, 1, 1, 1, 2, 4,
354 4, 6, 6, 1, 1, 2, 1, 2, 2, 3,
355 5, 3, 3, 2, 4, 2, 3, 2, 1, 2,
356 2, 1, 2, 2, 1, 2, 2, 1, 2, 2,
357 1, 2, 2, 1, 2, 2, 1, 1, 0, 1
360 static const short yydefact[] = { 1,
361 0, 17, 38, 15, 41, 44, 0, 35, 47, 0,
362 48, 32, 14, 2, 3, 4, 6, 5, 7, 29,
363 8, 18, 24, 37, 40, 43, 34, 46, 31, 19,
364 36, 39, 9, 42, 26, 33, 45, 0, 30, 0,
365 0, 16, 28, 0, 23, 27, 22, 49, 20, 25,
366 50, 11, 0, 10, 0, 49, 21, 13, 12, 0,
370 static const short yydefgoto[] = { 1,
371 14, 15, 16, 17, 18, 19, 20, 21, 54
374 static const short yypact[] = {-32768,
375 0, -19,-32768,-32768,-32768,-32768, -13,-32768,-32768, 30,
376 15,-32768, 14,-32768,-32768,-32768,-32768,-32768,-32768, 19,
377 -32768,-32768, 4,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
378 -32768,-32768,-32768,-32768, -6,-32768,-32768, 16,-32768, 17,
379 23,-32768,-32768, 24,-32768,-32768,-32768, 27, 28,-32768,
380 -32768,-32768, 29,-32768, 32, -8,-32768,-32768,-32768, 50,
384 static const short yypgoto[] = {-32768,
385 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, -5
392 static const short yytable[] = { 60,
393 22, 51, 23, 2, 3, 4, 58, 5, 45, 46,
394 6, 7, 8, 9, 10, 11, 12, 13, 30, 31,
395 42, 43, 32, 44, 33, 34, 35, 36, 37, 38,
396 47, 39, 48, 40, 24, 41, 51, 25, 49, 50,
397 26, 52, 27, 28, 56, 53, 29, 57, 55, 61,
401 static const short yycheck[] = { 0,
402 20, 10, 16, 4, 5, 6, 15, 8, 15, 16,
403 11, 12, 13, 14, 15, 16, 17, 18, 4, 5,
404 7, 3, 8, 20, 10, 11, 12, 13, 14, 15,
405 15, 17, 16, 19, 5, 21, 10, 8, 16, 16,
406 11, 15, 13, 14, 16, 19, 17, 16, 21, 0,
411 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
412 #line 3 "/usr/lib/bison.simple"
413 /* This file comes from bison-1.28. */
415 /* Skeleton output parser for bison,
416 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
418 This program is free software; you can redistribute it and/or modify
419 it under the terms of the GNU General Public License as published by
420 the Free Software Foundation; either version 2, or (at your option)
423 This program is distributed in the hope that it will be useful,
424 but WITHOUT ANY WARRANTY; without even the implied warranty of
425 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
426 GNU General Public License for more details.
428 You should have received a copy of the GNU General Public License
429 along with this program; if not, write to the Free Software
430 Foundation, Inc., 59 Temple Place - Suite 330,
431 Boston, MA 02111-1307, USA. */
433 /* As a special exception, when this file is copied by Bison into a
434 Bison output file, you may use that output file without restriction.
435 This special exception was added by the Free Software Foundation
436 in version 1.24 of Bison. */
438 /* This is the parser code that is written into each bison parser
439 when the %semantic_parser declaration is not specified in the grammar.
440 It was written by Richard Stallman by simplifying the hairy parser
441 used when %semantic_parser is specified. */
443 #ifndef YYSTACK_USE_ALLOCA
445 #define YYSTACK_USE_ALLOCA
446 #else /* alloca not defined */
448 #define YYSTACK_USE_ALLOCA
449 #define alloca __builtin_alloca
450 #else /* not GNU C. */
451 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
452 #define YYSTACK_USE_ALLOCA
454 #else /* not sparc */
455 /* We think this test detects Watcom and Microsoft C. */
456 /* This used to test MSDOS, but that is a bad idea
457 since that symbol is in the user namespace. */
458 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
459 #if 0 /* No need for malloc.h, which pollutes the namespace;
460 instead, just don't use alloca. */
463 #else /* not MSDOS, or __TURBOC__ */
465 /* I don't know what this was needed for, but it pollutes the namespace.
466 So I turned it off. rms, 2 May 1997. */
467 /* #include <malloc.h> */
469 #define YYSTACK_USE_ALLOCA
470 #else /* not MSDOS, or __TURBOC__, or _AIX */
472 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
473 and on HPUX 10. Eventually we can turn this on. */
474 #define YYSTACK_USE_ALLOCA
475 #define alloca __builtin_alloca
478 #endif /* not _AIX */
479 #endif /* not MSDOS, or __TURBOC__ */
480 #endif /* not sparc */
481 #endif /* not GNU C */
482 #endif /* alloca not defined */
483 #endif /* YYSTACK_USE_ALLOCA not defined */
485 #ifdef YYSTACK_USE_ALLOCA
486 #define YYSTACK_ALLOC alloca
488 #define YYSTACK_ALLOC malloc
491 /* Note: there must be only one dollar sign in this file.
492 It is replaced by the list of actions, each action
493 as one case of the switch. */
495 #define yyerrok (yyerrstatus = 0)
496 #define yyclearin (yychar = YYEMPTY)
499 #define YYACCEPT goto yyacceptlab
500 #define YYABORT goto yyabortlab
501 #define YYERROR goto yyerrlab1
502 /* Like YYERROR except do call yyerror.
503 This remains here temporarily to ease the
504 transition to the new meaning of YYERROR, for GCC.
505 Once GCC version 2 has supplanted version 1, this can go. */
506 #define YYFAIL goto yyerrlab
507 #define YYRECOVERING() (!!yyerrstatus)
508 #define YYBACKUP(token, value) \
510 if (yychar == YYEMPTY && yylen == 1) \
511 { yychar = (token), yylval = (value); \
512 yychar1 = YYTRANSLATE (yychar); \
517 { yyerror ("syntax error: cannot back up"); YYERROR; } \
521 #define YYERRCODE 256
524 #define YYLEX yylex()
530 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
532 #define YYLEX yylex(&yylval, &yylloc)
534 #else /* not YYLSP_NEEDED */
536 #define YYLEX yylex(&yylval, YYLEX_PARAM)
538 #define YYLEX yylex(&yylval)
540 #endif /* not YYLSP_NEEDED */
543 /* If nonreentrant, generate the variables here */
547 int yychar; /* the lookahead symbol */
548 YYSTYPE yylval; /* the semantic value of the */
549 /* lookahead symbol */
552 YYLTYPE yylloc; /* location data for the lookahead */
556 int yynerrs; /* number of parse errors so far */
557 #endif /* not YYPURE */
560 int yydebug; /* nonzero means print parse trace */
561 /* Since this is uninitialized, it does not stop multiple parsers
565 /* YYINITDEPTH indicates the initial size of the parser's stacks */
568 #define YYINITDEPTH 200
571 /* YYMAXDEPTH is the maximum size the stacks can grow to
572 (effective only if the built-in stack extension method is used). */
579 #define YYMAXDEPTH 10000
582 /* Define __yy_memcpy. Note that the size argument
583 should be passed with type unsigned int, because that is what the non-GCC
584 definitions require. With GCC, __builtin_memcpy takes an arg
585 of type size_t, but it can handle unsigned int. */
587 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
588 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
589 #else /* not GNU C or C++ */
592 /* This is the most reliable way to avoid incompatibilities
593 in available built-in functions on various systems. */
595 __yy_memcpy (to, from, count)
600 register char *f = from;
601 register char *t = to;
602 register int i = count;
608 #else /* __cplusplus */
610 /* This is the most reliable way to avoid incompatibilities
611 in available built-in functions on various systems. */
613 __yy_memcpy (char *to, char *from, unsigned int count)
615 register char *t = to;
616 register char *f = from;
617 register int i = count;
626 #line 217 "/usr/lib/bison.simple"
628 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
629 into yyparse. The argument should have type void *.
630 It should actually point to an object.
631 Grammar actions can access the variable by casting it
632 to the proper pointer type. */
636 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
637 #define YYPARSE_PARAM_DECL
638 #else /* not __cplusplus */
639 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
640 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
641 #endif /* not __cplusplus */
642 #else /* not YYPARSE_PARAM */
643 #define YYPARSE_PARAM_ARG
644 #define YYPARSE_PARAM_DECL
645 #endif /* not YYPARSE_PARAM */
647 /* Prevent warning if -Wstrict-prototypes. */
650 int yyparse (void *);
657 yyparse(YYPARSE_PARAM_ARG)
660 register int yystate;
662 register short *yyssp;
663 register YYSTYPE *yyvsp;
664 int yyerrstatus; /* number of tokens to shift before error messages enabled */
665 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
667 short yyssa[YYINITDEPTH]; /* the state stack */
668 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
670 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
671 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
674 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
675 YYLTYPE *yyls = yylsa;
678 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
680 #define YYPOPSTACK (yyvsp--, yyssp--)
683 int yystacksize = YYINITDEPTH;
684 int yyfree_stacks = 0;
695 YYSTYPE yyval; /* the variable used to return */
696 /* semantic values from the action */
703 fprintf(stderr, "Starting parse\n");
709 yychar = YYEMPTY; /* Cause a token to be read. */
711 /* Initialize stack pointers.
712 Waste one element of value and location stack
713 so that they stay on the same level as the state stack.
714 The wasted elements are never initialized. */
722 /* Push a new state, which is found in yystate . */
723 /* In all cases, when you get here, the value and location stacks
724 have just been pushed. so pushing a state here evens the stacks. */
729 if (yyssp >= yyss + yystacksize - 1)
731 /* Give user a chance to reallocate the stack */
732 /* Use copies of these so that the &'s don't force the real ones into memory. */
733 YYSTYPE *yyvs1 = yyvs;
736 YYLTYPE *yyls1 = yyls;
739 /* Get the current used size of the three stacks, in elements. */
740 int size = yyssp - yyss + 1;
743 /* Each stack pointer address is followed by the size of
744 the data in use in that stack, in bytes. */
746 /* This used to be a conditional around just the two extra args,
747 but that might be undefined if yyoverflow is a macro. */
748 yyoverflow("parser stack overflow",
749 &yyss1, size * sizeof (*yyssp),
750 &yyvs1, size * sizeof (*yyvsp),
751 &yyls1, size * sizeof (*yylsp),
754 yyoverflow("parser stack overflow",
755 &yyss1, size * sizeof (*yyssp),
756 &yyvs1, size * sizeof (*yyvsp),
760 yyss = yyss1; yyvs = yyvs1;
764 #else /* no yyoverflow */
765 /* Extend the stack our own way. */
766 if (yystacksize >= YYMAXDEPTH)
768 yyerror("parser stack overflow");
780 if (yystacksize > YYMAXDEPTH)
781 yystacksize = YYMAXDEPTH;
782 #ifndef YYSTACK_USE_ALLOCA
785 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
786 __yy_memcpy ((char *)yyss, (char *)yyss1,
787 size * (unsigned int) sizeof (*yyssp));
788 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
789 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
790 size * (unsigned int) sizeof (*yyvsp));
792 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
793 __yy_memcpy ((char *)yyls, (char *)yyls1,
794 size * (unsigned int) sizeof (*yylsp));
796 #endif /* no yyoverflow */
798 yyssp = yyss + size - 1;
799 yyvsp = yyvs + size - 1;
801 yylsp = yyls + size - 1;
806 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
809 if (yyssp >= yyss + yystacksize - 1)
815 fprintf(stderr, "Entering state %d\n", yystate);
821 /* Do appropriate processing given the current state. */
822 /* Read a lookahead token if we need one and don't already have one. */
825 /* First try to decide what to do without reference to lookahead token. */
827 yyn = yypact[yystate];
831 /* Not known => get a lookahead token if don't already have one. */
833 /* yychar is either YYEMPTY or YYEOF
834 or a valid token in external form. */
836 if (yychar == YYEMPTY)
840 fprintf(stderr, "Reading a token: ");
845 /* Convert token to internal form (in yychar1) for indexing tables with */
847 if (yychar <= 0) /* This means end of input. */
850 yychar = YYEOF; /* Don't call YYLEX any more */
854 fprintf(stderr, "Now at end of input.\n");
859 yychar1 = YYTRANSLATE(yychar);
864 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
865 /* Give the individual parser a way to print the precise meaning
866 of a token, for further debugging info. */
868 YYPRINT (stderr, yychar, yylval);
870 fprintf (stderr, ")\n");
876 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
881 /* yyn is what to do for this token type in this state.
882 Negative => reduce, -yyn is rule number.
883 Positive => shift, yyn is new state.
884 New state is final state => don't bother to shift,
886 0, or most negative number => error. */
901 /* Shift the lookahead token. */
905 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
908 /* Discard the token being shifted unless it is eof. */
917 /* count tokens shifted since error; after three, turn off error status. */
918 if (yyerrstatus) yyerrstatus--;
923 /* Do the default action for the current state. */
926 yyn = yydefact[yystate];
930 /* Do a reduction. yyn is the number of a rule to reduce with. */
934 yyval = yyvsp[1-yylen]; /* implement default value of the action */
941 fprintf (stderr, "Reducing via rule %d (line %d), ",
944 /* Print the symbols being reduced, and their result. */
945 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
946 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
947 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
955 #line 244 "getdate.y"
957 context->yyHaveTime++;
961 #line 247 "getdate.y"
963 context->yyHaveZone++;
967 #line 250 "getdate.y"
969 context->yyHaveDate++;
973 #line 253 "getdate.y"
975 context->yyHaveDay++;
979 #line 256 "getdate.y"
981 context->yyHaveRel++;
985 #line 262 "getdate.y"
987 context->yyHour = yyvsp[-1].Number;
988 context->yyMinutes = 0;
989 context->yySeconds = 0;
990 context->yyMeridian = yyvsp[0].Meridian;
994 #line 268 "getdate.y"
996 context->yyHour = yyvsp[-3].Number;
997 context->yyMinutes = yyvsp[-1].Number;
998 context->yySeconds = 0;
999 context->yyMeridian = yyvsp[0].Meridian;
1003 #line 274 "getdate.y"
1005 context->yyHour = yyvsp[-3].Number;
1006 context->yyMinutes = yyvsp[-1].Number;
1007 context->yyMeridian = MER24;
1008 context->yyHaveZone++;
1009 context->yyTimezone = (yyvsp[0].Number < 0
1010 ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
1011 : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
1015 #line 283 "getdate.y"
1017 context->yyHour = yyvsp[-5].Number;
1018 context->yyMinutes = yyvsp[-3].Number;
1019 context->yySeconds = yyvsp[-1].Number;
1020 context->yyMeridian = yyvsp[0].Meridian;
1024 #line 289 "getdate.y"
1026 context->yyHour = yyvsp[-5].Number;
1027 context->yyMinutes = yyvsp[-3].Number;
1028 context->yySeconds = yyvsp[-1].Number;
1029 context->yyMeridian = MER24;
1030 context->yyHaveZone++;
1031 context->yyTimezone = (yyvsp[0].Number < 0
1032 ? -yyvsp[0].Number % 100 + (-yyvsp[0].Number / 100) * 60
1033 : - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60));
1037 #line 301 "getdate.y"
1039 context->yyTimezone = yyvsp[0].Number;
1043 #line 304 "getdate.y"
1045 context->yyTimezone = yyvsp[0].Number - 60;
1049 #line 308 "getdate.y"
1051 context->yyTimezone = yyvsp[-1].Number - 60;
1055 #line 313 "getdate.y"
1057 context->yyDayOrdinal = 1;
1058 context->yyDayNumber = yyvsp[0].Number;
1062 #line 317 "getdate.y"
1064 context->yyDayOrdinal = 1;
1065 context->yyDayNumber = yyvsp[-1].Number;
1069 #line 321 "getdate.y"
1071 context->yyDayOrdinal = yyvsp[-1].Number;
1072 context->yyDayNumber = yyvsp[0].Number;
1076 #line 327 "getdate.y"
1078 context->yyMonth = yyvsp[-2].Number;
1079 context->yyDay = yyvsp[0].Number;
1083 #line 331 "getdate.y"
1085 /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
1086 The goal in recognizing YYYY/MM/DD is solely to support legacy
1087 machine-generated dates like those in an RCS log listing. If
1088 you want portability, use the ISO 8601 format. */
1089 if (yyvsp[-4].Number >= 1000)
1091 context->yyYear = yyvsp[-4].Number;
1092 context->yyMonth = yyvsp[-2].Number;
1093 context->yyDay = yyvsp[0].Number;
1097 context->yyMonth = yyvsp[-4].Number;
1098 context->yyDay = yyvsp[-2].Number;
1099 context->yyYear = yyvsp[0].Number;
1104 #line 349 "getdate.y"
1106 /* ISO 8601 format. yyyy-mm-dd. */
1107 context->yyYear = yyvsp[-2].Number;
1108 context->yyMonth = -yyvsp[-1].Number;
1109 context->yyDay = -yyvsp[0].Number;
1113 #line 355 "getdate.y"
1115 /* e.g. 17-JUN-1992. */
1116 context->yyDay = yyvsp[-2].Number;
1117 context->yyMonth = yyvsp[-1].Number;
1118 context->yyYear = -yyvsp[0].Number;
1122 #line 361 "getdate.y"
1124 context->yyMonth = yyvsp[-1].Number;
1125 context->yyDay = yyvsp[0].Number;
1129 #line 365 "getdate.y"
1131 context->yyMonth = yyvsp[-3].Number;
1132 context->yyDay = yyvsp[-2].Number;
1133 context->yyYear = yyvsp[0].Number;
1137 #line 370 "getdate.y"
1139 context->yyMonth = yyvsp[0].Number;
1140 context->yyDay = yyvsp[-1].Number;
1144 #line 374 "getdate.y"
1146 context->yyMonth = yyvsp[-1].Number;
1147 context->yyDay = yyvsp[-2].Number;
1148 context->yyYear = yyvsp[0].Number;
1152 #line 381 "getdate.y"
1154 context->yyRelSeconds = -context->yyRelSeconds;
1155 context->yyRelMinutes = -context->yyRelMinutes;
1156 context->yyRelHour = -context->yyRelHour;
1157 context->yyRelDay = -context->yyRelDay;
1158 context->yyRelMonth = -context->yyRelMonth;
1159 context->yyRelYear = -context->yyRelYear;
1163 #line 392 "getdate.y"
1165 context->yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
1169 #line 395 "getdate.y"
1171 context->yyRelYear += yyvsp[-1].Number * yyvsp[0].Number;
1175 #line 398 "getdate.y"
1177 context->yyRelYear += yyvsp[0].Number;
1181 #line 401 "getdate.y"
1183 context->yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1187 #line 404 "getdate.y"
1189 context->yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1193 #line 407 "getdate.y"
1195 context->yyRelMonth += yyvsp[0].Number;
1199 #line 410 "getdate.y"
1201 context->yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
1205 #line 413 "getdate.y"
1207 context->yyRelDay += yyvsp[-1].Number * yyvsp[0].Number;
1211 #line 416 "getdate.y"
1213 context->yyRelDay += yyvsp[0].Number;
1217 #line 419 "getdate.y"
1219 context->yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
1223 #line 422 "getdate.y"
1225 context->yyRelHour += yyvsp[-1].Number * yyvsp[0].Number;
1229 #line 425 "getdate.y"
1231 context->yyRelHour += yyvsp[0].Number;
1235 #line 428 "getdate.y"
1237 context->yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
1241 #line 431 "getdate.y"
1243 context->yyRelMinutes += yyvsp[-1].Number * yyvsp[0].Number;
1247 #line 434 "getdate.y"
1249 context->yyRelMinutes += yyvsp[0].Number;
1253 #line 437 "getdate.y"
1255 context->yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1259 #line 440 "getdate.y"
1261 context->yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1265 #line 443 "getdate.y"
1267 context->yyRelSeconds += yyvsp[0].Number;
1271 #line 449 "getdate.y"
1273 if (context->yyHaveTime && context->yyHaveDate &&
1274 !context->yyHaveRel)
1275 context->yyYear = yyvsp[0].Number;
1278 if (yyvsp[0].Number>10000)
1280 context->yyHaveDate++;
1281 context->yyDay= (yyvsp[0].Number)%100;
1282 context->yyMonth= (yyvsp[0].Number/100)%100;
1283 context->yyYear = yyvsp[0].Number/10000;
1287 context->yyHaveTime++;
1288 if (yyvsp[0].Number < 100)
1290 context->yyHour = yyvsp[0].Number;
1291 context->yyMinutes = 0;
1295 context->yyHour = yyvsp[0].Number / 100;
1296 context->yyMinutes = yyvsp[0].Number % 100;
1298 context->yySeconds = 0;
1299 context->yyMeridian = MER24;
1305 #line 483 "getdate.y"
1307 yyval.Meridian = MER24;
1311 #line 487 "getdate.y"
1313 yyval.Meridian = yyvsp[0].Meridian;
1317 /* the action file gets copied in in place of this dollarsign */
1318 #line 543 "/usr/lib/bison.simple"
1329 short *ssp1 = yyss - 1;
1330 fprintf (stderr, "state stack now");
1331 while (ssp1 != yyssp)
1332 fprintf (stderr, " %d", *++ssp1);
1333 fprintf (stderr, "\n");
1343 yylsp->first_line = yylloc.first_line;
1344 yylsp->first_column = yylloc.first_column;
1345 yylsp->last_line = (yylsp-1)->last_line;
1346 yylsp->last_column = (yylsp-1)->last_column;
1351 yylsp->last_line = (yylsp+yylen-1)->last_line;
1352 yylsp->last_column = (yylsp+yylen-1)->last_column;
1356 /* Now "shift" the result of the reduction.
1357 Determine what state that goes to,
1358 based on the state we popped back to
1359 and the rule number reduced by. */
1363 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1364 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1365 yystate = yytable[yystate];
1367 yystate = yydefgoto[yyn - YYNTBASE];
1371 yyerrlab: /* here on detecting error */
1374 /* If not already recovering from an error, report this error. */
1378 #ifdef YYERROR_VERBOSE
1379 yyn = yypact[yystate];
1381 if (yyn > YYFLAG && yyn < YYLAST)
1388 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
1389 for (x = (yyn < 0 ? -yyn : 0);
1390 x < (sizeof(yytname) / sizeof(char *)); x++)
1391 if (yycheck[x + yyn] == x)
1392 size += strlen(yytname[x]) + 15, count++;
1393 msg = (char *) malloc(size + 15);
1396 strcpy(msg, "parse error");
1401 for (x = (yyn < 0 ? -yyn : 0);
1402 x < (sizeof(yytname) / sizeof(char *)); x++)
1403 if (yycheck[x + yyn] == x)
1405 strcat(msg, count == 0 ? ", expecting `" : " or `");
1406 strcat(msg, yytname[x]);
1415 yyerror ("parse error; also virtual memory exceeded");
1418 #endif /* YYERROR_VERBOSE */
1419 yyerror("parse error");
1423 yyerrlab1: /* here on error raised explicitly by an action */
1425 if (yyerrstatus == 3)
1427 /* if just tried and failed to reuse lookahead token after an error, discard it. */
1429 /* return failure if at end of input */
1430 if (yychar == YYEOF)
1435 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1441 /* Else will try to reuse lookahead token
1442 after shifting the error token. */
1444 yyerrstatus = 3; /* Each real token shifted decrements this */
1448 yyerrdefault: /* current state does not do anything special for the error token. */
1451 /* This is wrong; only states that explicitly want error tokens
1452 should shift them. */
1453 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
1454 if (yyn) goto yydefault;
1457 yyerrpop: /* pop the current state because it cannot handle the error token */
1459 if (yyssp == yyss) YYABORT;
1469 short *ssp1 = yyss - 1;
1470 fprintf (stderr, "Error: state stack now");
1471 while (ssp1 != yyssp)
1472 fprintf (stderr, " %d", *++ssp1);
1473 fprintf (stderr, "\n");
1479 yyn = yypact[yystate];
1484 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1503 fprintf(stderr, "Shifting error token, ");
1515 /* YYACCEPT comes here. */
1527 /* YYABORT comes here. */
1538 #line 492 "getdate.y"
1541 /* Include this file down here because bison inserts code above which
1542 may define-away `const'. We want the prototype for get_date to have
1543 the same signature as the function definition does. */
1544 #include "getdate.h"
1546 #ifndef WIN32 /* the windows dudes don't need these, does anyone really? */
1547 extern struct tm *gmtime (const time_t *);
1548 extern struct tm *localtime (const time_t *);
1549 extern time_t mktime (struct tm *);
1552 /* Month and day table. */
1553 static TABLE const MonthDayTable[] = {
1554 { "january", tMONTH, 1 },
1555 { "february", tMONTH, 2 },
1556 { "march", tMONTH, 3 },
1557 { "april", tMONTH, 4 },
1558 { "may", tMONTH, 5 },
1559 { "june", tMONTH, 6 },
1560 { "july", tMONTH, 7 },
1561 { "august", tMONTH, 8 },
1562 { "september", tMONTH, 9 },
1563 { "sept", tMONTH, 9 },
1564 { "october", tMONTH, 10 },
1565 { "november", tMONTH, 11 },
1566 { "december", tMONTH, 12 },
1567 { "sunday", tDAY, 0 },
1568 { "monday", tDAY, 1 },
1569 { "tuesday", tDAY, 2 },
1570 { "tues", tDAY, 2 },
1571 { "wednesday", tDAY, 3 },
1572 { "wednes", tDAY, 3 },
1573 { "thursday", tDAY, 4 },
1574 { "thur", tDAY, 4 },
1575 { "thurs", tDAY, 4 },
1576 { "friday", tDAY, 5 },
1577 { "saturday", tDAY, 6 },
1581 /* Time units table. */
1582 static TABLE const UnitsTable[] = {
1583 { "year", tYEAR_UNIT, 1 },
1584 { "month", tMONTH_UNIT, 1 },
1585 { "fortnight", tDAY_UNIT, 14 },
1586 { "week", tDAY_UNIT, 7 },
1587 { "day", tDAY_UNIT, 1 },
1588 { "hour", tHOUR_UNIT, 1 },
1589 { "minute", tMINUTE_UNIT, 1 },
1590 { "min", tMINUTE_UNIT, 1 },
1591 { "second", tSEC_UNIT, 1 },
1592 { "sec", tSEC_UNIT, 1 },
1596 /* Assorted relative-time words. */
1597 static TABLE const OtherTable[] = {
1598 { "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
1599 { "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
1600 { "today", tMINUTE_UNIT, 0 },
1601 { "now", tMINUTE_UNIT, 0 },
1602 { "last", tUNUMBER, -1 },
1603 { "this", tMINUTE_UNIT, 0 },
1604 { "next", tUNUMBER, 1 },
1605 { "first", tUNUMBER, 1 },
1606 /* { "second", tUNUMBER, 2 }, */
1607 { "third", tUNUMBER, 3 },
1608 { "fourth", tUNUMBER, 4 },
1609 { "fifth", tUNUMBER, 5 },
1610 { "sixth", tUNUMBER, 6 },
1611 { "seventh", tUNUMBER, 7 },
1612 { "eighth", tUNUMBER, 8 },
1613 { "ninth", tUNUMBER, 9 },
1614 { "tenth", tUNUMBER, 10 },
1615 { "eleventh", tUNUMBER, 11 },
1616 { "twelfth", tUNUMBER, 12 },
1621 /* The timezone table. */
1622 static TABLE const TimezoneTable[] = {
1623 { "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1624 { "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1625 { "utc", tZONE, HOUR ( 0) },
1626 { "wet", tZONE, HOUR ( 0) }, /* Western European */
1627 { "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
1628 { "wat", tZONE, HOUR ( 1) }, /* West Africa */
1629 { "at", tZONE, HOUR ( 2) }, /* Azores */
1631 /* For completeness. BST is also British Summer, and GST is
1632 * also Guam Standard. */
1633 { "bst", tZONE, HOUR ( 3) }, /* Brazil Standard */
1634 { "gst", tZONE, HOUR ( 3) }, /* Greenland Standard */
1637 { "nft", tZONE, HOUR (3.5) }, /* Newfoundland */
1638 { "nst", tZONE, HOUR (3.5) }, /* Newfoundland Standard */
1639 { "ndt", tDAYZONE, HOUR (3.5) }, /* Newfoundland Daylight */
1641 { "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
1642 { "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
1643 { "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
1644 { "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
1645 { "cst", tZONE, HOUR ( 6) }, /* Central Standard */
1646 { "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
1647 { "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
1648 { "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
1649 { "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
1650 { "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
1651 { "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
1652 { "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
1653 { "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
1654 { "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
1655 { "cat", tZONE, HOUR (10) }, /* Central Alaska */
1656 { "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
1657 { "nt", tZONE, HOUR (11) }, /* Nome */
1658 { "idlw", tZONE, HOUR (12) }, /* International Date Line West */
1659 { "cet", tZONE, -HOUR (1) }, /* Central European */
1660 { "met", tZONE, -HOUR (1) }, /* Middle European */
1661 { "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
1662 { "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
1663 { "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
1664 { "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
1665 { "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
1666 { "fwt", tZONE, -HOUR (1) }, /* French Winter */
1667 { "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
1668 { "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
1669 { "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
1671 { "it", tZONE, -HOUR (3.5) },/* Iran */
1673 { "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
1674 { "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
1676 { "ist", tZONE, -HOUR (5.5) },/* Indian Standard */
1678 { "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
1680 /* For completeness. NST is also Newfoundland Standard, and SST is
1681 * also Swedish Summer. */
1682 { "nst", tZONE, -HOUR (6.5) },/* North Sumatra */
1683 { "sst", tZONE, -HOUR (7) }, /* South Sumatra, USSR Zone 6 */
1685 { "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
1686 { "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
1688 { "jt", tZONE, -HOUR (7.5) },/* Java (3pm in Cronusland!) */
1690 { "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
1691 { "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
1693 { "cast", tZONE, -HOUR (9.5) },/* Central Australian Standard */
1694 { "cadt", tDAYZONE, -HOUR (9.5) },/* Central Australian Daylight */
1696 { "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
1697 { "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
1698 { "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
1699 { "nzt", tZONE, -HOUR (12) }, /* New Zealand */
1700 { "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
1701 { "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
1702 { "idle", tZONE, -HOUR (12) }, /* International Date Line East */
1706 /* Military timezone table. */
1707 static TABLE const MilitaryTable[] = {
1708 { "a", tZONE, HOUR ( 1) },
1709 { "b", tZONE, HOUR ( 2) },
1710 { "c", tZONE, HOUR ( 3) },
1711 { "d", tZONE, HOUR ( 4) },
1712 { "e", tZONE, HOUR ( 5) },
1713 { "f", tZONE, HOUR ( 6) },
1714 { "g", tZONE, HOUR ( 7) },
1715 { "h", tZONE, HOUR ( 8) },
1716 { "i", tZONE, HOUR ( 9) },
1717 { "k", tZONE, HOUR ( 10) },
1718 { "l", tZONE, HOUR ( 11) },
1719 { "m", tZONE, HOUR ( 12) },
1720 { "n", tZONE, HOUR (- 1) },
1721 { "o", tZONE, HOUR (- 2) },
1722 { "p", tZONE, HOUR (- 3) },
1723 { "q", tZONE, HOUR (- 4) },
1724 { "r", tZONE, HOUR (- 5) },
1725 { "s", tZONE, HOUR (- 6) },
1726 { "t", tZONE, HOUR (- 7) },
1727 { "u", tZONE, HOUR (- 8) },
1728 { "v", tZONE, HOUR (- 9) },
1729 { "w", tZONE, HOUR (-10) },
1730 { "x", tZONE, HOUR (-11) },
1731 { "y", tZONE, HOUR (-12) },
1732 { "z", tZONE, HOUR ( 0) },
1741 yyerror (const char *s ATTRIBUTE_UNUSED)
1747 ToHour (int Hours, MERIDIAN Meridian)
1752 if (Hours < 0 || Hours > 23)
1756 if (Hours < 1 || Hours > 12)
1762 if (Hours < 1 || Hours > 12)
1779 /* XPG4 suggests that years 00-68 map to 2000-2068, and
1780 years 69-99 map to 1969-1999. */
1783 else if (Year < 100)
1790 LookupWord (YYSTYPE *yylval, char *buff)
1794 register const TABLE *tp;
1798 /* Make it lowercase. */
1799 for (p = buff; *p; p++)
1800 if (ISUPPER ((unsigned char) *p))
1803 if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
1805 yylval->Meridian = MERam;
1808 if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
1810 yylval->Meridian = MERpm;
1814 /* See if we have an abbreviation for a month. */
1815 if (strlen (buff) == 3)
1817 else if (strlen (buff) == 4 && buff[3] == '.')
1825 for (tp = MonthDayTable; tp->name; tp++)
1829 if (strncmp (buff, tp->name, 3) == 0)
1831 yylval->Number = tp->value;
1835 else if (strcmp (buff, tp->name) == 0)
1837 yylval->Number = tp->value;
1842 for (tp = TimezoneTable; tp->name; tp++)
1843 if (strcmp (buff, tp->name) == 0)
1845 yylval->Number = tp->value;
1849 if (strcmp (buff, "dst") == 0)
1852 for (tp = UnitsTable; tp->name; tp++)
1853 if (strcmp (buff, tp->name) == 0)
1855 yylval->Number = tp->value;
1859 /* Strip off any plural and try the units table again. */
1860 i = strlen (buff) - 1;
1864 for (tp = UnitsTable; tp->name; tp++)
1865 if (strcmp (buff, tp->name) == 0)
1867 yylval->Number = tp->value;
1870 buff[i] = 's'; /* Put back for "this" in OtherTable. */
1873 for (tp = OtherTable; tp->name; tp++)
1874 if (strcmp (buff, tp->name) == 0)
1876 yylval->Number = tp->value;
1880 /* Military timezones. */
1881 if (buff[1] == '\0' && ISALPHA ((unsigned char) *buff))
1883 for (tp = MilitaryTable; tp->name; tp++)
1884 if (strcmp (buff, tp->name) == 0)
1886 yylval->Number = tp->value;
1891 /* Drop out any periods and try the timezone table again. */
1892 for (i = 0, p = q = buff; *q; q++)
1899 for (tp = TimezoneTable; tp->name; tp++)
1900 if (strcmp (buff, tp->name) == 0)
1902 yylval->Number = tp->value;
1910 yylex (YYSTYPE *yylval, void *cookie)
1912 register unsigned char c;
1920 while (ISSPACE ((unsigned char) *context->yyInput))
1923 if (ISDIGIT (c = *context->yyInput) || c == '-' || c == '+')
1925 if (c == '-' || c == '+')
1927 sign = c == '-' ? -1 : 1;
1928 if (!ISDIGIT (*++context->yyInput))
1929 /* skip the '-' sign */
1934 for (yylval->Number = 0; ISDIGIT (c = *context->yyInput++);)
1935 yylval->Number = 10 * yylval->Number + c - '0';
1938 yylval->Number = -yylval->Number;
1939 return sign ? tSNUMBER : tUNUMBER;
1943 for (p = buff; (c = *context->yyInput++, ISALPHA (c)) || c == '.';)
1944 if (p < &buff[sizeof buff - 1])
1948 return LookupWord (yylval, buff);
1951 return *context->yyInput++;
1955 c = *context->yyInput++;
1967 #define TM_YEAR_ORIGIN 1900
1969 /* Yield A - B, measured in seconds. */
1971 difftm (struct tm *a, struct tm *b)
1973 int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
1974 int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
1976 /* difference in day of year */
1977 a->tm_yday - b->tm_yday
1978 /* + intervening leap days */
1979 + ((ay >> 2) - (by >> 2))
1980 - (ay / 100 - by / 100)
1981 + ((ay / 100 >> 2) - (by / 100 >> 2))
1982 /* + difference in years * 365 */
1983 + (long) (ay - by) * 365
1985 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
1986 + (a->tm_min - b->tm_min))
1987 + (a->tm_sec - b->tm_sec));
1991 curl_getdate (const char *p, const time_t *now)
1993 struct tm tm, tm0, *tmp;
1995 CURL_CONTEXT cookie;
1996 #ifdef HAVE_LOCALTIME_R
2000 Start = now ? *now : time ((time_t *) NULL);
2001 #ifdef HAVE_LOCALTIME_R
2002 tmp = (struct tm *)localtime_r(&Start, &keeptime);
2004 tmp = localtime (&Start);
2008 cookie.yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
2009 cookie.yyMonth = tmp->tm_mon + 1;
2010 cookie.yyDay = tmp->tm_mday;
2011 cookie.yyHour = tmp->tm_hour;
2012 cookie.yyMinutes = tmp->tm_min;
2013 cookie.yySeconds = tmp->tm_sec;
2014 tm.tm_isdst = tmp->tm_isdst;
2015 cookie.yyMeridian = MER24;
2016 cookie.yyRelSeconds = 0;
2017 cookie.yyRelMinutes = 0;
2018 cookie.yyRelHour = 0;
2019 cookie.yyRelDay = 0;
2020 cookie.yyRelMonth = 0;
2021 cookie.yyRelYear = 0;
2022 cookie.yyHaveDate = 0;
2023 cookie.yyHaveDay = 0;
2024 cookie.yyHaveRel = 0;
2025 cookie.yyHaveTime = 0;
2026 cookie.yyHaveZone = 0;
2028 if (yyparse (&cookie)
2029 || cookie.yyHaveTime > 1 || cookie.yyHaveZone > 1 ||
2030 cookie.yyHaveDate > 1 || cookie.yyHaveDay > 1)
2033 tm.tm_year = ToYear (cookie.yyYear) - TM_YEAR_ORIGIN + cookie.yyRelYear;
2034 tm.tm_mon = cookie.yyMonth - 1 + cookie.yyRelMonth;
2035 tm.tm_mday = cookie.yyDay + cookie.yyRelDay;
2036 if (cookie.yyHaveTime ||
2037 (cookie.yyHaveRel && !cookie.yyHaveDate && !cookie.yyHaveDay))
2039 tm.tm_hour = ToHour (cookie.yyHour, cookie.yyMeridian);
2042 tm.tm_min = cookie.yyMinutes;
2043 tm.tm_sec = cookie.yySeconds;
2047 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2049 tm.tm_hour += cookie.yyRelHour;
2050 tm.tm_min += cookie.yyRelMinutes;
2051 tm.tm_sec += cookie.yyRelSeconds;
2053 /* Let mktime deduce tm_isdst if we have an absolute timestamp,
2054 or if the relative timestamp mentions days, months, or years. */
2055 if (cookie.yyHaveDate | cookie.yyHaveDay | cookie.yyHaveTime |
2056 cookie.yyRelDay | cookie.yyRelMonth | cookie.yyRelYear)
2061 Start = mktime (&tm);
2063 if (Start == (time_t) -1)
2066 /* Guard against falsely reporting errors near the time_t boundaries
2067 when parsing times in other time zones. For example, if the min
2068 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2069 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2070 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2071 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2072 zone by 24 hours to compensate. This algorithm assumes that
2073 there is no DST transition within a day of the time_t boundaries. */
2074 if (cookie.yyHaveZone)
2077 if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
2080 cookie.yyTimezone -= 24 * 60;
2085 cookie.yyTimezone += 24 * 60;
2087 Start = mktime (&tm);
2090 if (Start == (time_t) -1)
2094 if (cookie.yyHaveDay && !cookie.yyHaveDate)
2096 tm.tm_mday += ((cookie.yyDayNumber - tm.tm_wday + 7) % 7
2097 + 7 * (cookie.yyDayOrdinal - (0 < cookie.yyDayOrdinal)));
2098 Start = mktime (&tm);
2099 if (Start == (time_t) -1)
2103 if (cookie.yyHaveZone)
2107 #ifdef HAVE_GMTIME_R
2108 /* thread-safe version */
2109 struct tm keeptime2;
2110 gmt = (struct tm *)gmtime_r(&Start, &keeptime2);
2112 gmt = gmtime(&Start);
2116 delta = cookie.yyTimezone * 60L + difftm (&tm, gmt);
2117 if ((Start + delta < Start) != (delta < 0))
2118 return -1; /* time_t overflow */
2129 main (int ac, char *av[])
2131 char buff[MAX_BUFF_LEN + 1];
2134 (void) printf ("Enter date, or blank line to exit.\n\t> ");
2135 (void) fflush (stdout);
2137 buff[MAX_BUFF_LEN] = 0;
2138 while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
2140 d = curl_getdate (buff, (time_t *) NULL);
2142 (void) printf ("Bad format - couldn't convert.\n");
2144 (void) printf ("%s", ctime (&d));
2145 (void) printf ("\t> ");
2146 (void) fflush (stdout);
2151 #endif /* defined (TEST) */