source: branches/samba-3.3.x/source/modules/getdate.c@ 206

Last change on this file since 206 was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

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