Add missing end tags
[Samba/bjacke.git] / source / modules / getdate.c
blob149a3e1ab977b126118ed60ea555484f3d4b0b9c
1 /* A Bison parser, made by GNU Bison 1.875a. */
3 /* Skeleton parser for Yacc-like parsing with Bison,
4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
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.
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.
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/>. */
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. */
24 /* Written by Richard Stallman by simplifying the original so called
25 ``semantic'' parser. */
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. */
34 /* Identify Bison output. */
35 #define YYBISON 1
37 /* Skeleton name. */
38 #define YYSKELETON_NAME "yacc.c"
40 /* Pure parsers. */
41 #define YYPURE 1
43 /* Using locations. */
44 #define YYLSP_NEEDED 0
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
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
92 /* Copy the first part of user declarations. */
93 #line 1 "getdate.y"
95 /* Parse a string into an internal time stamp.
96 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
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.
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.
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/>. */
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.
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. */
120 #ifdef HAVE_CONFIG_H
121 # include <config.h>
122 # ifdef HAVE_ALLOCA_H
123 # include <alloca.h>
124 # endif
125 #endif
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
137 #include <ctype.h>
138 #include <string.h>
140 #if HAVE_STDLIB_H
141 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
142 #endif
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
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))
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)
164 #if STDC_HEADERS || HAVE_STRING_H
165 # include <string.h>
166 #endif
168 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
169 # define __attribute__(x)
170 #endif
172 #ifndef ATTRIBUTE_UNUSED
173 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
174 #endif
176 #define EPOCH_YEAR 1970
177 #define TM_YEAR_BASE 1900
179 #define HOUR(x) ((x) * 60)
181 /* An integer value, and the number of digits in its textual
182 representation. */
183 typedef struct
185 int value;
186 int digits;
187 } textint;
189 /* An entry in the lexical lookup table. */
190 typedef struct
192 char const *name;
193 int type;
194 int value;
195 } table;
197 /* Meridian: am, pm, or 24-hour style. */
198 enum { MERam, MERpm, MER24 };
200 /* Information passed to and from the parser. */
201 typedef struct
203 /* The input string remaining to be parsed. */
204 const char *input;
206 /* N, if this is the Nth Tuesday. */
207 int day_ordinal;
209 /* Day of week; Sunday is 0. */
210 int day_number;
212 /* tm_isdst flag for the local zone. */
213 int local_isdst;
215 /* Time zone, in minutes east of UTC. */
216 int time_zone;
218 /* Style used for time. */
219 int meridian;
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;
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;
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;
245 /* Table of local time zone abbrevations, terminated by a null entry. */
246 table local_time_zone_table[3];
247 } parser_control;
249 #define PC (* (parser_control *) parm)
250 #define YYLEX_PARAM parm
251 #define YYPARSE_PARAM parm
253 static int yyerror ();
254 static int yylex ();
258 /* Enabling traces. */
259 #ifndef YYDEBUG
260 # define YYDEBUG 0
261 #endif
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
271 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
272 #line 172 "getdate.y"
273 typedef 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
286 /* Copy the second part of user declarations. */
289 /* Line 214 of yacc.c. */
290 #line 293 "getdate.c"
292 #if ! defined (yyoverflow) || YYERROR_VERBOSE
294 /* The parser invokes alloca or malloc; define the necessary symbols. */
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
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 */
324 #if (! defined (yyoverflow) \
325 && (! defined (__cplusplus) \
326 || (YYSTYPE_IS_TRIVIAL)))
328 /* A type that is properly aligned for any stack member. */
329 union yyalloc
331 short yyss;
332 YYSTYPE yyvs;
335 /* The size of the maximum gap between one aligned stack and the next. */
336 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
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)
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 \
354 register YYSIZE_T yyi; \
355 for (yyi = 0; yyi < (Count); yyi++) \
356 (To)[yyi] = (From)[yyi]; \
358 while (0)
359 # endif
360 # endif
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 \
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); \
376 while (0)
378 #endif
380 #if defined (__STDC__) || defined (__cplusplus)
381 typedef signed char yysigned_char;
382 #else
383 typedef short yysigned_char;
384 #endif
386 /* YYFINAL -- State number of the termination state. */
387 #define YYFINAL 2
388 /* YYLAST -- Last index in YYTABLE. */
389 #define YYLAST 52
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
400 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
401 #define YYUNDEFTOK 2
402 #define YYMAXUTOK 273
404 #define YYTRANSLATE(YYX) \
405 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
407 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
408 static const unsigned char yytranslate[] =
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
440 #if YYDEBUG
441 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
442 YYRHS. */
443 static const unsigned char yyprhs[] =
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
453 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
454 static const yysigned_char yyrhs[] =
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
474 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
475 static const unsigned short yyrline[] =
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
484 #endif
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. */
489 static const char *const yytname[] =
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
498 #endif
500 # ifdef YYPRINT
501 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
502 token YYLEX-NUM. */
503 static const unsigned short yytoknum[] =
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
509 # endif
511 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
512 static const unsigned char yyr1[] =
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
522 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
523 static const unsigned char yyr2[] =
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
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. */
536 static const unsigned char yydefact[] =
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
547 /* YYDEFGOTO[NTERM-NUM]. */
548 static const yysigned_char yydefgoto[] =
550 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
551 24, 58
554 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
555 STATE-NUM. */
556 #define YYPACT_NINF -17
557 static const yysigned_char yypact[] =
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
568 /* YYPGOTO[NTERM-NUM]. */
569 static const yysigned_char yypgoto[] =
571 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
572 -17, -10
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
580 static const unsigned char yytable[] =
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
590 static const unsigned char yycheck[] =
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
600 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
601 symbol of state STATE-NUM. */
602 static const unsigned char yystos[] =
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
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
629 #define yyerrok (yyerrstatus = 0)
630 #define yyclearin (yychar = YYEMPTY)
631 #define YYEMPTY (-2)
632 #define YYEOF 0
634 #define YYACCEPT goto yyacceptlab
635 #define YYABORT goto yyabortlab
636 #define YYERROR goto yyerrlab1
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. */
643 #define YYFAIL goto yyerrlab
645 #define YYRECOVERING() (!!yyerrstatus)
647 #define YYBACKUP(Token, Value) \
648 do \
649 if (yychar == YYEMPTY && yylen == 1) \
651 yychar = (Token); \
652 yylval = (Value); \
653 yytoken = YYTRANSLATE (yychar); \
654 YYPOPSTACK; \
655 goto yybackup; \
657 else \
659 yyerror ("syntax error: cannot back up");\
660 YYERROR; \
662 while (0)
664 #define YYTERROR 1
665 #define YYERRCODE 256
667 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
668 are run). */
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
678 /* YYLEX -- calling `yylex' with the right arguments. */
680 #ifdef YYLEX_PARAM
681 # define YYLEX yylex (&yylval, YYLEX_PARAM)
682 #else
683 # define YYLEX yylex (&yylval)
684 #endif
686 /* Enable debugging if requested. */
687 #if YYDEBUG
689 # ifndef YYFPRINTF
690 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
691 # define YYFPRINTF fprintf
692 # endif
694 # define YYDPRINTF(Args) \
695 do { \
696 if (yydebug) \
697 YYFPRINTF Args; \
698 } while (0)
700 # define YYDSYMPRINT(Args) \
701 do { \
702 if (yydebug) \
703 yysymprint Args; \
704 } while (0)
706 # define YYDSYMPRINTF(Title, Token, Value, Location) \
707 do { \
708 if (yydebug) \
710 YYFPRINTF (stderr, "%s ", Title); \
711 yysymprint (stderr, \
712 Token, Value); \
713 YYFPRINTF (stderr, "\n"); \
715 } while (0)
717 /*------------------------------------------------------------------.
718 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
719 | TOP (cinluded). |
720 `------------------------------------------------------------------*/
722 #if defined (__STDC__) || defined (__cplusplus)
723 static void
724 yy_stack_print (short *bottom, short *top)
725 #else
726 static void
727 yy_stack_print (bottom, top)
728 short *bottom;
729 short *top;
730 #endif
732 YYFPRINTF (stderr, "Stack now");
733 for (/* Nothing. */; bottom <= top; ++bottom)
734 YYFPRINTF (stderr, " %d", *bottom);
735 YYFPRINTF (stderr, "\n");
738 # define YY_STACK_PRINT(Bottom, Top) \
739 do { \
740 if (yydebug) \
741 yy_stack_print ((Bottom), (Top)); \
742 } while (0)
745 /*------------------------------------------------.
746 | Report that the YYRULE is going to be reduced. |
747 `------------------------------------------------*/
749 #if defined (__STDC__) || defined (__cplusplus)
750 static void
751 yy_reduce_print (int yyrule)
752 #else
753 static void
754 yy_reduce_print (yyrule)
755 int yyrule;
756 #endif
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]]);
768 # define YY_REDUCE_PRINT(Rule) \
769 do { \
770 if (yydebug) \
771 yy_reduce_print (Rule); \
772 } while (0)
774 /* Nonzero means print parse trace. It is left uninitialized so that
775 multiple parsers can coexist. */
776 int 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 */
786 /* YYINITDEPTH -- initial size of the parser's stacks. */
787 #ifndef YYINITDEPTH
788 # define YYINITDEPTH 200
789 #endif
791 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
792 if the built-in stack extension method is used).
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. */
798 #if YYMAXDEPTH == 0
799 # undef YYMAXDEPTH
800 #endif
802 #ifndef YYMAXDEPTH
803 # define YYMAXDEPTH 10000
804 #endif
808 #if YYERROR_VERBOSE
810 # ifndef yystrlen
811 # if defined (__GLIBC__) && defined (_STRING_H)
812 # define yystrlen strlen
813 # else
814 /* Return the length of YYSTR. */
815 static YYSIZE_T
816 # if defined (__STDC__) || defined (__cplusplus)
817 yystrlen (const char *yystr)
818 # else
819 yystrlen (yystr)
820 const char *yystr;
821 # endif
823 register const char *yys = yystr;
825 while (*yys++ != '\0')
826 continue;
828 return yys - yystr - 1;
830 # endif
831 # endif
833 # ifndef yystpcpy
834 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
835 # define yystpcpy stpcpy
836 # else
837 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
838 YYDEST. */
839 static char *
840 # if defined (__STDC__) || defined (__cplusplus)
841 yystpcpy (char *yydest, const char *yysrc)
842 # else
843 yystpcpy (yydest, yysrc)
844 char *yydest;
845 const char *yysrc;
846 # endif
848 register char *yyd = yydest;
849 register const char *yys = yysrc;
851 while ((*yyd++ = *yys++) != '\0')
852 continue;
854 return yyd - 1;
856 # endif
857 # endif
859 #endif /* !YYERROR_VERBOSE */
863 #if YYDEBUG
864 /*--------------------------------.
865 | Print this symbol on YYOUTPUT. |
866 `--------------------------------*/
868 #if defined (__STDC__) || defined (__cplusplus)
869 static void
870 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
871 #else
872 static void
873 yysymprint (yyoutput, yytype, yyvaluep)
874 FILE *yyoutput;
875 int yytype;
876 YYSTYPE *yyvaluep;
877 #endif
879 /* Pacify ``unused variable'' warnings. */
880 (void) yyvaluep;
882 if (yytype < YYNTOKENS)
884 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
885 # ifdef YYPRINT
886 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
887 # endif
889 else
890 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
892 switch (yytype)
894 default:
895 break;
897 YYFPRINTF (yyoutput, ")");
900 #endif /* ! YYDEBUG */
901 /*-----------------------------------------------.
902 | Release the memory associated to this symbol. |
903 `-----------------------------------------------*/
905 #if defined (__STDC__) || defined (__cplusplus)
906 static void
907 yydestruct (int yytype, YYSTYPE *yyvaluep)
908 #else
909 static void
910 yydestruct (yytype, yyvaluep)
911 int yytype;
912 YYSTYPE *yyvaluep;
913 #endif
915 /* Pacify ``unused variable'' warnings. */
916 (void) yyvaluep;
918 switch (yytype)
921 default:
922 break;
927 /* Prevent warnings from -Wmissing-prototypes. */
929 #ifdef YYPARSE_PARAM
930 # if defined (__STDC__) || defined (__cplusplus)
931 int yyparse (void *YYPARSE_PARAM);
932 # else
933 int yyparse ();
934 # endif
935 #else /* ! YYPARSE_PARAM */
936 #if defined (__STDC__) || defined (__cplusplus)
937 int yyparse (void);
938 #else
939 int yyparse ();
940 #endif
941 #endif /* ! YYPARSE_PARAM */
948 /*----------.
949 | yyparse. |
950 `----------*/
952 #ifdef YYPARSE_PARAM
953 # if defined (__STDC__) || defined (__cplusplus)
954 int yyparse (void *YYPARSE_PARAM)
955 # else
956 int yyparse (YYPARSE_PARAM)
957 void *YYPARSE_PARAM;
958 # endif
959 #else /* ! YYPARSE_PARAM */
960 #if defined (__STDC__) || defined (__cplusplus)
962 yyparse (void)
963 #else
965 yyparse ()
967 #endif
968 #endif
970 /* The lookahead symbol. */
971 int yychar;
973 /* The semantic value of the lookahead symbol. */
974 YYSTYPE yylval;
976 /* Number of syntax errors so far. */
977 int yynerrs;
979 register int yystate;
980 register int yyn;
981 int yyresult;
982 /* Number of tokens to shift before error messages enabled. */
983 int yyerrstatus;
984 /* Lookahead token as an internal (translated) token number. */
985 int yytoken = 0;
987 /* Three stacks and their tools:
988 `yyss': related to states,
989 `yyvs': related to semantic values,
990 `yyls': related to locations.
992 Refer to the stacks thru separate pointers, to allow yyoverflow
993 to reallocate them elsewhere. */
995 /* The state stack. */
996 short yyssa[YYINITDEPTH];
997 short *yyss = yyssa;
998 register short *yyssp;
1000 /* The semantic value stack. */
1001 YYSTYPE yyvsa[YYINITDEPTH];
1002 YYSTYPE *yyvs = yyvsa;
1003 register YYSTYPE *yyvsp;
1007 #define YYPOPSTACK (yyvsp--, yyssp--)
1009 YYSIZE_T yystacksize = YYINITDEPTH;
1011 /* The variables used to return semantic value and location from the
1012 action routines. */
1013 YYSTYPE yyval;
1016 /* When reducing, the number of symbols on the RHS of the reduced
1017 rule. */
1018 int yylen;
1020 YYDPRINTF ((stderr, "Starting parse\n"));
1022 yystate = 0;
1023 yyerrstatus = 0;
1024 yynerrs = 0;
1025 yychar = YYEMPTY; /* Cause a token to be read. */
1027 /* Initialize stack pointers.
1028 Waste one element of value and location stack
1029 so that they stay on the same level as the state stack.
1030 The wasted elements are never initialized. */
1032 yyssp = yyss;
1033 yyvsp = yyvs;
1035 goto yysetstate;
1037 /*------------------------------------------------------------.
1038 | yynewstate -- Push a new state, which is found in yystate. |
1039 `------------------------------------------------------------*/
1040 yynewstate:
1041 /* In all cases, when you get here, the value and location stacks
1042 have just been pushed. so pushing a state here evens the stacks.
1044 yyssp++;
1046 yysetstate:
1047 *yyssp = yystate;
1049 if (yyss + yystacksize - 1 <= yyssp)
1051 /* Get the current used size of the three stacks, in elements. */
1052 YYSIZE_T yysize = yyssp - yyss + 1;
1054 #ifdef yyoverflow
1056 /* Give user a chance to reallocate the stack. Use copies of
1057 these so that the &'s don't force the real ones into
1058 memory. */
1059 YYSTYPE *yyvs1 = yyvs;
1060 short *yyss1 = yyss;
1063 /* Each stack pointer address is followed by the size of the
1064 data in use in that stack, in bytes. This used to be a
1065 conditional around just the two extra args, but that might
1066 be undefined if yyoverflow is a macro. */
1067 yyoverflow ("parser stack overflow",
1068 &yyss1, yysize * sizeof (*yyssp),
1069 &yyvs1, yysize * sizeof (*yyvsp),
1071 &yystacksize);
1073 yyss = yyss1;
1074 yyvs = yyvs1;
1076 #else /* no yyoverflow */
1077 # ifndef YYSTACK_RELOCATE
1078 goto yyoverflowlab;
1079 # else
1080 /* Extend the stack our own way. */
1081 if (YYMAXDEPTH <= yystacksize)
1082 goto yyoverflowlab;
1083 yystacksize *= 2;
1084 if (YYMAXDEPTH < yystacksize)
1085 yystacksize = YYMAXDEPTH;
1088 short *yyss1 = yyss;
1089 union yyalloc *yyptr =
1090 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1091 if (! yyptr)
1092 goto yyoverflowlab;
1093 YYSTACK_RELOCATE (yyss);
1094 YYSTACK_RELOCATE (yyvs);
1096 # undef YYSTACK_RELOCATE
1097 if (yyss1 != yyssa)
1098 YYSTACK_FREE (yyss1);
1100 # endif
1101 #endif /* no yyoverflow */
1103 yyssp = yyss + yysize - 1;
1104 yyvsp = yyvs + yysize - 1;
1107 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1108 (unsigned long int) yystacksize));
1110 if (yyss + yystacksize - 1 <= yyssp)
1111 YYABORT;
1114 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1116 goto yybackup;
1118 /*-----------.
1119 | yybackup. |
1120 `-----------*/
1121 yybackup:
1123 /* Do appropriate processing given the current state. */
1124 /* Read a lookahead token if we need one and don't already have one. */
1125 /* yyresume: */
1127 /* First try to decide what to do without reference to lookahead token. */
1129 yyn = yypact[yystate];
1130 if (yyn == YYPACT_NINF)
1131 goto yydefault;
1133 /* Not known => get a lookahead token if don't already have one. */
1135 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1136 if (yychar == YYEMPTY)
1138 YYDPRINTF ((stderr, "Reading a token: "));
1139 yychar = YYLEX;
1142 if (yychar <= YYEOF)
1144 yychar = yytoken = YYEOF;
1145 YYDPRINTF ((stderr, "Now at end of input.\n"));
1147 else
1149 yytoken = YYTRANSLATE (yychar);
1150 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1153 /* If the proper action on seeing token YYTOKEN is to reduce or to
1154 detect an error, take that action. */
1155 yyn += yytoken;
1156 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1157 goto yydefault;
1158 yyn = yytable[yyn];
1159 if (yyn <= 0)
1161 if (yyn == 0 || yyn == YYTABLE_NINF)
1162 goto yyerrlab;
1163 yyn = -yyn;
1164 goto yyreduce;
1167 if (yyn == YYFINAL)
1168 YYACCEPT;
1170 /* Shift the lookahead token. */
1171 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1173 /* Discard the token being shifted unless it is eof. */
1174 if (yychar != YYEOF)
1175 yychar = YYEMPTY;
1177 *++yyvsp = yylval;
1180 /* Count tokens shifted since error; after three, turn off error
1181 status. */
1182 if (yyerrstatus)
1183 yyerrstatus--;
1185 yystate = yyn;
1186 goto yynewstate;
1189 /*-----------------------------------------------------------.
1190 | yydefault -- do the default action for the current state. |
1191 `-----------------------------------------------------------*/
1192 yydefault:
1193 yyn = yydefact[yystate];
1194 if (yyn == 0)
1195 goto yyerrlab;
1196 goto yyreduce;
1199 /*-----------------------------.
1200 | yyreduce -- Do a reduction. |
1201 `-----------------------------*/
1202 yyreduce:
1203 /* yyn is the number of a rule to reduce with. */
1204 yylen = yyr2[yyn];
1206 /* If YYLEN is nonzero, implement the default value of the action:
1207 `$$ = $1'.
1209 Otherwise, the following line sets YYVAL to garbage.
1210 This behavior is undocumented and Bison
1211 users should not rely upon it. Assigning to YYVAL
1212 unconditionally makes the parser a bit smaller, and it avoids a
1213 GCC warning that YYVAL may be used uninitialized. */
1214 yyval = yyvsp[1-yylen];
1217 YY_REDUCE_PRINT (yyn);
1218 switch (yyn)
1220 case 4:
1221 #line 195 "getdate.y"
1222 { PC.times_seen++; }
1223 break;
1225 case 5:
1226 #line 197 "getdate.y"
1227 { PC.local_zones_seen++; }
1228 break;
1230 case 6:
1231 #line 199 "getdate.y"
1232 { PC.zones_seen++; }
1233 break;
1235 case 7:
1236 #line 201 "getdate.y"
1237 { PC.dates_seen++; }
1238 break;
1240 case 8:
1241 #line 203 "getdate.y"
1242 { PC.days_seen++; }
1243 break;
1245 case 9:
1246 #line 205 "getdate.y"
1247 { PC.rels_seen++; }
1248 break;
1250 case 11:
1251 #line 211 "getdate.y"
1253 PC.hour = yyvsp[-1].textintval.value;
1254 PC.minutes = 0;
1255 PC.seconds = 0;
1256 PC.meridian = yyvsp[0].intval;
1258 break;
1260 case 12:
1261 #line 218 "getdate.y"
1263 PC.hour = yyvsp[-3].textintval.value;
1264 PC.minutes = yyvsp[-1].textintval.value;
1265 PC.seconds = 0;
1266 PC.meridian = yyvsp[0].intval;
1268 break;
1270 case 13:
1271 #line 225 "getdate.y"
1273 PC.hour = yyvsp[-3].textintval.value;
1274 PC.minutes = yyvsp[-1].textintval.value;
1275 PC.meridian = MER24;
1276 PC.zones_seen++;
1277 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1279 break;
1281 case 14:
1282 #line 233 "getdate.y"
1284 PC.hour = yyvsp[-5].textintval.value;
1285 PC.minutes = yyvsp[-3].textintval.value;
1286 PC.seconds = yyvsp[-1].textintval.value;
1287 PC.meridian = yyvsp[0].intval;
1289 break;
1291 case 15:
1292 #line 240 "getdate.y"
1294 PC.hour = yyvsp[-5].textintval.value;
1295 PC.minutes = yyvsp[-3].textintval.value;
1296 PC.seconds = yyvsp[-1].textintval.value;
1297 PC.meridian = MER24;
1298 PC.zones_seen++;
1299 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1301 break;
1303 case 16:
1304 #line 252 "getdate.y"
1305 { PC.local_isdst = yyvsp[0].intval; }
1306 break;
1308 case 17:
1309 #line 254 "getdate.y"
1310 { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1311 break;
1313 case 18:
1314 #line 259 "getdate.y"
1315 { PC.time_zone = yyvsp[0].intval; }
1316 break;
1318 case 19:
1319 #line 261 "getdate.y"
1320 { PC.time_zone = yyvsp[0].intval + 60; }
1321 break;
1323 case 20:
1324 #line 263 "getdate.y"
1325 { PC.time_zone = yyvsp[-1].intval + 60; }
1326 break;
1328 case 21:
1329 #line 268 "getdate.y"
1331 PC.day_ordinal = 1;
1332 PC.day_number = yyvsp[0].intval;
1334 break;
1336 case 22:
1337 #line 273 "getdate.y"
1339 PC.day_ordinal = 1;
1340 PC.day_number = yyvsp[-1].intval;
1342 break;
1344 case 23:
1345 #line 278 "getdate.y"
1347 PC.day_ordinal = yyvsp[-1].textintval.value;
1348 PC.day_number = yyvsp[0].intval;
1350 break;
1352 case 24:
1353 #line 286 "getdate.y"
1355 PC.month = yyvsp[-2].textintval.value;
1356 PC.day = yyvsp[0].textintval.value;
1358 break;
1360 case 25:
1361 #line 291 "getdate.y"
1363 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1364 otherwise as MM/DD/YY.
1365 The goal in recognizing YYYY/MM/DD is solely to support legacy
1366 machine-generated dates like those in an RCS log listing. If
1367 you want portability, use the ISO 8601 format. */
1368 if (4 <= yyvsp[-4].textintval.digits)
1370 PC.year = yyvsp[-4].textintval;
1371 PC.month = yyvsp[-2].textintval.value;
1372 PC.day = yyvsp[0].textintval.value;
1374 else
1376 PC.month = yyvsp[-4].textintval.value;
1377 PC.day = yyvsp[-2].textintval.value;
1378 PC.year = yyvsp[0].textintval;
1381 break;
1383 case 26:
1384 #line 311 "getdate.y"
1386 /* ISO 8601 format. YYYY-MM-DD. */
1387 PC.year = yyvsp[-2].textintval;
1388 PC.month = -yyvsp[-1].textintval.value;
1389 PC.day = -yyvsp[0].textintval.value;
1391 break;
1393 case 27:
1394 #line 318 "getdate.y"
1396 /* e.g. 17-JUN-1992. */
1397 PC.day = yyvsp[-2].textintval.value;
1398 PC.month = yyvsp[-1].intval;
1399 PC.year.value = -yyvsp[0].textintval.value;
1400 PC.year.digits = yyvsp[0].textintval.digits;
1402 break;
1404 case 28:
1405 #line 326 "getdate.y"
1407 PC.month = yyvsp[-1].intval;
1408 PC.day = yyvsp[0].textintval.value;
1410 break;
1412 case 29:
1413 #line 331 "getdate.y"
1415 PC.month = yyvsp[-3].intval;
1416 PC.day = yyvsp[-2].textintval.value;
1417 PC.year = yyvsp[0].textintval;
1419 break;
1421 case 30:
1422 #line 337 "getdate.y"
1424 PC.day = yyvsp[-1].textintval.value;
1425 PC.month = yyvsp[0].intval;
1427 break;
1429 case 31:
1430 #line 342 "getdate.y"
1432 PC.day = yyvsp[-2].textintval.value;
1433 PC.month = yyvsp[-1].intval;
1434 PC.year = yyvsp[0].textintval;
1436 break;
1438 case 32:
1439 #line 351 "getdate.y"
1441 PC.rel_seconds = -PC.rel_seconds;
1442 PC.rel_minutes = -PC.rel_minutes;
1443 PC.rel_hour = -PC.rel_hour;
1444 PC.rel_day = -PC.rel_day;
1445 PC.rel_month = -PC.rel_month;
1446 PC.rel_year = -PC.rel_year;
1448 break;
1450 case 34:
1451 #line 364 "getdate.y"
1452 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1453 break;
1455 case 35:
1456 #line 366 "getdate.y"
1457 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1458 break;
1460 case 36:
1461 #line 368 "getdate.y"
1462 { PC.rel_year += yyvsp[0].intval; }
1463 break;
1465 case 37:
1466 #line 370 "getdate.y"
1467 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1468 break;
1470 case 38:
1471 #line 372 "getdate.y"
1472 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1473 break;
1475 case 39:
1476 #line 374 "getdate.y"
1477 { PC.rel_month += yyvsp[0].intval; }
1478 break;
1480 case 40:
1481 #line 376 "getdate.y"
1482 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1483 break;
1485 case 41:
1486 #line 378 "getdate.y"
1487 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1488 break;
1490 case 42:
1491 #line 380 "getdate.y"
1492 { PC.rel_day += yyvsp[0].intval; }
1493 break;
1495 case 43:
1496 #line 382 "getdate.y"
1497 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1498 break;
1500 case 44:
1501 #line 384 "getdate.y"
1502 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1503 break;
1505 case 45:
1506 #line 386 "getdate.y"
1507 { PC.rel_hour += yyvsp[0].intval; }
1508 break;
1510 case 46:
1511 #line 388 "getdate.y"
1512 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1513 break;
1515 case 47:
1516 #line 390 "getdate.y"
1517 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1518 break;
1520 case 48:
1521 #line 392 "getdate.y"
1522 { PC.rel_minutes += yyvsp[0].intval; }
1523 break;
1525 case 49:
1526 #line 394 "getdate.y"
1527 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1528 break;
1530 case 50:
1531 #line 396 "getdate.y"
1532 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1533 break;
1535 case 51:
1536 #line 398 "getdate.y"
1537 { PC.rel_seconds += yyvsp[0].intval; }
1538 break;
1540 case 52:
1541 #line 403 "getdate.y"
1543 if (PC.dates_seen
1544 && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
1545 PC.year = yyvsp[0].textintval;
1546 else
1548 if (4 < yyvsp[0].textintval.digits)
1550 PC.dates_seen++;
1551 PC.day = yyvsp[0].textintval.value % 100;
1552 PC.month = (yyvsp[0].textintval.value / 100) % 100;
1553 PC.year.value = yyvsp[0].textintval.value / 10000;
1554 PC.year.digits = yyvsp[0].textintval.digits - 4;
1556 else
1558 PC.times_seen++;
1559 if (yyvsp[0].textintval.digits <= 2)
1561 PC.hour = yyvsp[0].textintval.value;
1562 PC.minutes = 0;
1564 else
1566 PC.hour = yyvsp[0].textintval.value / 100;
1567 PC.minutes = yyvsp[0].textintval.value % 100;
1569 PC.seconds = 0;
1570 PC.meridian = MER24;
1574 break;
1576 case 53:
1577 #line 439 "getdate.y"
1578 { yyval.intval = MER24; }
1579 break;
1581 case 54:
1582 #line 441 "getdate.y"
1583 { yyval.intval = yyvsp[0].intval; }
1584 break;
1589 /* Line 999 of yacc.c. */
1590 #line 1593 "getdate.c"
1592 yyvsp -= yylen;
1593 yyssp -= yylen;
1596 YY_STACK_PRINT (yyss, yyssp);
1598 *++yyvsp = yyval;
1601 /* Now `shift' the result of the reduction. Determine what state
1602 that goes to, based on the state we popped back to and the rule
1603 number reduced by. */
1605 yyn = yyr1[yyn];
1607 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1608 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1609 yystate = yytable[yystate];
1610 else
1611 yystate = yydefgoto[yyn - YYNTOKENS];
1613 goto yynewstate;
1616 /*------------------------------------.
1617 | yyerrlab -- here on detecting error |
1618 `------------------------------------*/
1619 yyerrlab:
1620 /* If not already recovering from an error, report this error. */
1621 if (!yyerrstatus)
1623 ++yynerrs;
1624 #if YYERROR_VERBOSE
1625 yyn = yypact[yystate];
1627 if (YYPACT_NINF < yyn && yyn < YYLAST)
1629 YYSIZE_T yysize = 0;
1630 int yytype = YYTRANSLATE (yychar);
1631 char *yymsg;
1632 int yyx, yycount;
1634 yycount = 0;
1635 /* Start YYX at -YYN if negative to avoid negative indexes in
1636 YYCHECK. */
1637 for (yyx = yyn < 0 ? -yyn : 0;
1638 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1639 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1640 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1641 yysize += yystrlen ("syntax error, unexpected ") + 1;
1642 yysize += yystrlen (yytname[yytype]);
1643 yymsg = (char *) YYSTACK_ALLOC (yysize);
1644 if (yymsg != 0)
1646 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1647 yyp = yystpcpy (yyp, yytname[yytype]);
1649 if (yycount < 5)
1651 yycount = 0;
1652 for (yyx = yyn < 0 ? -yyn : 0;
1653 yyx < (int) (sizeof (yytname) / sizeof (char *));
1654 yyx++)
1655 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1657 const char *yyq = ! yycount ? ", expecting " : " or ";
1658 yyp = yystpcpy (yyp, yyq);
1659 yyp = yystpcpy (yyp, yytname[yyx]);
1660 yycount++;
1663 yyerror (yymsg);
1664 YYSTACK_FREE (yymsg);
1666 else
1667 yyerror ("syntax error; also virtual memory exhausted");
1669 else
1670 #endif /* YYERROR_VERBOSE */
1671 yyerror ("syntax error");
1676 if (yyerrstatus == 3)
1678 /* If just tried and failed to reuse lookahead token after an
1679 error, discard it. */
1681 /* Return failure if at end of input. */
1682 if (yychar == YYEOF)
1684 /* Pop the error token. */
1685 YYPOPSTACK;
1686 /* Pop the rest of the stack. */
1687 while (yyss < yyssp)
1689 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1690 yydestruct (yystos[*yyssp], yyvsp);
1691 YYPOPSTACK;
1693 YYABORT;
1696 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1697 yydestruct (yytoken, &yylval);
1698 yychar = YYEMPTY;
1702 /* Else will try to reuse lookahead token after shifting the error
1703 token. */
1704 goto yyerrlab1;
1707 /*----------------------------------------------------.
1708 | yyerrlab1 -- error raised explicitly by an action. |
1709 `----------------------------------------------------*/
1710 yyerrlab1:
1711 yyerrstatus = 3; /* Each real token shifted decrements this. */
1713 for (;;)
1715 yyn = yypact[yystate];
1716 if (yyn != YYPACT_NINF)
1718 yyn += YYTERROR;
1719 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1721 yyn = yytable[yyn];
1722 if (0 < yyn)
1723 break;
1727 /* Pop the current state because it cannot handle the error token. */
1728 if (yyssp == yyss)
1729 YYABORT;
1731 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1732 yydestruct (yystos[yystate], yyvsp);
1733 yyvsp--;
1734 yystate = *--yyssp;
1736 YY_STACK_PRINT (yyss, yyssp);
1739 if (yyn == YYFINAL)
1740 YYACCEPT;
1742 YYDPRINTF ((stderr, "Shifting error token, "));
1744 *++yyvsp = yylval;
1747 yystate = yyn;
1748 goto yynewstate;
1751 /*-------------------------------------.
1752 | yyacceptlab -- YYACCEPT comes here. |
1753 `-------------------------------------*/
1754 yyacceptlab:
1755 yyresult = 0;
1756 goto yyreturn;
1758 /*-----------------------------------.
1759 | yyabortlab -- YYABORT comes here. |
1760 `-----------------------------------*/
1761 yyabortlab:
1762 yyresult = 1;
1763 goto yyreturn;
1765 #ifndef yyoverflow
1766 /*----------------------------------------------.
1767 | yyoverflowlab -- parser overflow comes here. |
1768 `----------------------------------------------*/
1769 yyoverflowlab:
1770 yyerror ("parser stack overflow");
1771 yyresult = 2;
1772 /* Fall through. */
1773 #endif
1775 yyreturn:
1776 #ifndef yyoverflow
1777 if (yyss != yyssa)
1778 YYSTACK_FREE (yyss);
1779 #endif
1780 return yyresult;
1784 #line 444 "getdate.y"
1787 /* Include this file down here because bison inserts code above which
1788 may define-away `const'. We want the prototype for get_date to have
1789 the same signature as the function definition. */
1790 #include "modules/getdate.h"
1792 #ifndef gmtime
1793 struct tm *gmtime ();
1794 #endif
1795 #ifndef localtime
1796 struct tm *localtime ();
1797 #endif
1798 #ifndef mktime
1799 time_t mktime ();
1800 #endif
1802 static table const meridian_table[] =
1804 { "AM", tMERIDIAN, MERam },
1805 { "A.M.", tMERIDIAN, MERam },
1806 { "PM", tMERIDIAN, MERpm },
1807 { "P.M.", tMERIDIAN, MERpm },
1808 { 0, 0, 0 }
1811 static table const dst_table[] =
1813 { "DST", tDST, 0 }
1816 static table const month_and_day_table[] =
1818 { "JANUARY", tMONTH, 1 },
1819 { "FEBRUARY", tMONTH, 2 },
1820 { "MARCH", tMONTH, 3 },
1821 { "APRIL", tMONTH, 4 },
1822 { "MAY", tMONTH, 5 },
1823 { "JUNE", tMONTH, 6 },
1824 { "JULY", tMONTH, 7 },
1825 { "AUGUST", tMONTH, 8 },
1826 { "SEPTEMBER",tMONTH, 9 },
1827 { "SEPT", tMONTH, 9 },
1828 { "OCTOBER", tMONTH, 10 },
1829 { "NOVEMBER", tMONTH, 11 },
1830 { "DECEMBER", tMONTH, 12 },
1831 { "SUNDAY", tDAY, 0 },
1832 { "MONDAY", tDAY, 1 },
1833 { "TUESDAY", tDAY, 2 },
1834 { "TUES", tDAY, 2 },
1835 { "WEDNESDAY",tDAY, 3 },
1836 { "WEDNES", tDAY, 3 },
1837 { "THURSDAY", tDAY, 4 },
1838 { "THUR", tDAY, 4 },
1839 { "THURS", tDAY, 4 },
1840 { "FRIDAY", tDAY, 5 },
1841 { "SATURDAY", tDAY, 6 },
1842 { 0, 0, 0 }
1845 static table const time_units_table[] =
1847 { "YEAR", tYEAR_UNIT, 1 },
1848 { "MONTH", tMONTH_UNIT, 1 },
1849 { "FORTNIGHT",tDAY_UNIT, 14 },
1850 { "WEEK", tDAY_UNIT, 7 },
1851 { "DAY", tDAY_UNIT, 1 },
1852 { "HOUR", tHOUR_UNIT, 1 },
1853 { "MINUTE", tMINUTE_UNIT, 1 },
1854 { "MIN", tMINUTE_UNIT, 1 },
1855 { "SECOND", tSEC_UNIT, 1 },
1856 { "SEC", tSEC_UNIT, 1 },
1857 { 0, 0, 0 }
1860 /* Assorted relative-time words. */
1861 static table const relative_time_table[] =
1863 { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
1864 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
1865 { "TODAY", tMINUTE_UNIT, 0 },
1866 { "NOW", tMINUTE_UNIT, 0 },
1867 { "LAST", tUNUMBER, -1 },
1868 { "THIS", tUNUMBER, 0 },
1869 { "NEXT", tUNUMBER, 1 },
1870 { "FIRST", tUNUMBER, 1 },
1871 /*{ "SECOND", tUNUMBER, 2 }, */
1872 { "THIRD", tUNUMBER, 3 },
1873 { "FOURTH", tUNUMBER, 4 },
1874 { "FIFTH", tUNUMBER, 5 },
1875 { "SIXTH", tUNUMBER, 6 },
1876 { "SEVENTH", tUNUMBER, 7 },
1877 { "EIGHTH", tUNUMBER, 8 },
1878 { "NINTH", tUNUMBER, 9 },
1879 { "TENTH", tUNUMBER, 10 },
1880 { "ELEVENTH", tUNUMBER, 11 },
1881 { "TWELFTH", tUNUMBER, 12 },
1882 { "AGO", tAGO, 1 },
1883 { 0, 0, 0 }
1886 /* The time zone table. This table is necessarily incomplete, as time
1887 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1888 as Eastern time in Australia, not as US Eastern Standard Time.
1889 You cannot rely on getdate to handle arbitrary time zone
1890 abbreviations; use numeric abbreviations like `-0500' instead. */
1891 static table const time_zone_table[] =
1893 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1894 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1895 { "UTC", tZONE, HOUR ( 0) },
1896 { "WET", tZONE, HOUR ( 0) }, /* Western European */
1897 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
1898 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
1899 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
1900 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
1901 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1902 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1903 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1904 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
1905 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1906 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
1907 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1908 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
1909 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1910 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
1911 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1912 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
1913 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1914 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
1915 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1916 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
1917 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1918 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
1919 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1920 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1921 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
1922 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
1923 { "CET", tZONE, HOUR ( 1) }, /* Central European */
1924 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
1925 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
1926 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
1927 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1928 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1929 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
1930 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
1931 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
1932 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
1933 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
1934 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
1935 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
1936 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
1937 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
1938 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
1939 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
1940 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
1941 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
1942 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
1943 { 0, 0, 0 }
1946 /* Military time zone table. */
1947 static table const military_table[] =
1949 { "A", tZONE, -HOUR ( 1) },
1950 { "B", tZONE, -HOUR ( 2) },
1951 { "C", tZONE, -HOUR ( 3) },
1952 { "D", tZONE, -HOUR ( 4) },
1953 { "E", tZONE, -HOUR ( 5) },
1954 { "F", tZONE, -HOUR ( 6) },
1955 { "G", tZONE, -HOUR ( 7) },
1956 { "H", tZONE, -HOUR ( 8) },
1957 { "I", tZONE, -HOUR ( 9) },
1958 { "K", tZONE, -HOUR (10) },
1959 { "L", tZONE, -HOUR (11) },
1960 { "M", tZONE, -HOUR (12) },
1961 { "N", tZONE, HOUR ( 1) },
1962 { "O", tZONE, HOUR ( 2) },
1963 { "P", tZONE, HOUR ( 3) },
1964 { "Q", tZONE, HOUR ( 4) },
1965 { "R", tZONE, HOUR ( 5) },
1966 { "S", tZONE, HOUR ( 6) },
1967 { "T", tZONE, HOUR ( 7) },
1968 { "U", tZONE, HOUR ( 8) },
1969 { "V", tZONE, HOUR ( 9) },
1970 { "W", tZONE, HOUR (10) },
1971 { "X", tZONE, HOUR (11) },
1972 { "Y", tZONE, HOUR (12) },
1973 { "Z", tZONE, HOUR ( 0) },
1974 { 0, 0, 0 }
1979 static int
1980 to_hour (int hours, int meridian)
1982 switch (meridian)
1984 case MER24:
1985 return 0 <= hours && hours < 24 ? hours : -1;
1986 case MERam:
1987 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1988 case MERpm:
1989 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
1990 default:
1991 abort ();
1993 /* NOTREACHED */
1994 return 0;
1997 static int
1998 to_year (textint textyear)
2000 int year = textyear.value;
2002 if (year < 0)
2003 year = -year;
2005 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2006 years 69-99 map to 1969-1999. */
2007 if (textyear.digits == 2)
2008 year += year < 69 ? 2000 : 1900;
2010 return year;
2013 static table const *
2014 lookup_zone (parser_control const *pc, char const *name)
2016 table const *tp;
2018 /* Try local zone abbreviations first; they're more likely to be right. */
2019 for (tp = pc->local_time_zone_table; tp->name; tp++)
2020 if (strcmp (name, tp->name) == 0)
2021 return tp;
2023 for (tp = time_zone_table; tp->name; tp++)
2024 if (strcmp (name, tp->name) == 0)
2025 return tp;
2027 return 0;
2030 #if ! HAVE_TM_GMTOFF
2031 /* Yield the difference between *A and *B,
2032 measured in seconds, ignoring leap seconds.
2033 The body of this function is taken directly from the GNU C Library;
2034 see src/strftime.c. */
2035 static int
2036 tm_diff (struct tm const *a, struct tm const *b)
2038 /* Compute intervening leap days correctly even if year is negative.
2039 Take care to avoid int overflow in leap day calculations,
2040 but it's OK to assume that A and B are close to each other. */
2041 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2042 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2043 int a100 = a4 / 25 - (a4 % 25 < 0);
2044 int b100 = b4 / 25 - (b4 % 25 < 0);
2045 int a400 = a100 >> 2;
2046 int b400 = b100 >> 2;
2047 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2048 int years = a->tm_year - b->tm_year;
2049 int days = (365 * years + intervening_leap_days
2050 + (a->tm_yday - b->tm_yday));
2051 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2052 + (a->tm_min - b->tm_min))
2053 + (a->tm_sec - b->tm_sec));
2055 #endif /* ! HAVE_TM_GMTOFF */
2057 static table const *
2058 lookup_word (parser_control const *pc, char *word)
2060 char *p;
2061 char *q;
2062 size_t wordlen;
2063 table const *tp;
2064 int i;
2065 int abbrev;
2067 /* Make it uppercase. */
2068 for (p = word; *p; p++)
2069 if (ISLOWER ((unsigned char) *p))
2070 *p = toupper ((unsigned char) *p);
2072 for (tp = meridian_table; tp->name; tp++)
2073 if (strcmp (word, tp->name) == 0)
2074 return tp;
2076 /* See if we have an abbreviation for a month. */
2077 wordlen = strlen (word);
2078 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2080 for (tp = month_and_day_table; tp->name; tp++)
2081 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2082 return tp;
2084 if ((tp = lookup_zone (pc, word)))
2085 return tp;
2087 if (strcmp (word, dst_table[0].name) == 0)
2088 return dst_table;
2090 for (tp = time_units_table; tp->name; tp++)
2091 if (strcmp (word, tp->name) == 0)
2092 return tp;
2094 /* Strip off any plural and try the units table again. */
2095 if (word[wordlen - 1] == 'S')
2097 word[wordlen - 1] = '\0';
2098 for (tp = time_units_table; tp->name; tp++)
2099 if (strcmp (word, tp->name) == 0)
2100 return tp;
2101 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2104 for (tp = relative_time_table; tp->name; tp++)
2105 if (strcmp (word, tp->name) == 0)
2106 return tp;
2108 /* Military time zones. */
2109 if (wordlen == 1)
2110 for (tp = military_table; tp->name; tp++)
2111 if (word[0] == tp->name[0])
2112 return tp;
2114 /* Drop out any periods and try the time zone table again. */
2115 for (i = 0, p = q = word; (*p = *q); q++)
2116 if (*q == '.')
2117 i = 1;
2118 else
2119 p++;
2120 if (i && (tp = lookup_zone (pc, word)))
2121 return tp;
2123 return 0;
2126 static int
2127 yylex (YYSTYPE *lvalp, parser_control *pc)
2129 unsigned char c;
2130 int count;
2132 for (;;)
2134 while (c = *pc->input, ISSPACE (c))
2135 pc->input++;
2137 if (ISDIGIT (c) || c == '-' || c == '+')
2139 char const *p;
2140 int sign;
2141 int value;
2142 if (c == '-' || c == '+')
2144 sign = c == '-' ? -1 : 1;
2145 c = *++pc->input;
2146 if (! ISDIGIT (c))
2147 /* skip the '-' sign */
2148 continue;
2150 else
2151 sign = 0;
2152 p = pc->input;
2153 value = 0;
2156 value = 10 * value + c - '0';
2157 c = *++p;
2159 while (ISDIGIT (c));
2160 lvalp->textintval.value = sign < 0 ? -value : value;
2161 lvalp->textintval.digits = p - pc->input;
2162 pc->input = p;
2163 return sign ? tSNUMBER : tUNUMBER;
2166 if (ISALPHA (c))
2168 char buff[20];
2169 char *p = buff;
2170 table const *tp;
2174 if (p < buff + sizeof buff - 1)
2175 *p++ = c;
2176 c = *++pc->input;
2178 while (ISALPHA (c) || c == '.');
2180 *p = '\0';
2181 tp = lookup_word (pc, buff);
2182 if (! tp)
2183 return '?';
2184 lvalp->intval = tp->value;
2185 return tp->type;
2188 if (c != '(')
2189 return *pc->input++;
2190 count = 0;
2193 c = *pc->input++;
2194 if (c == '\0')
2195 return c;
2196 if (c == '(')
2197 count++;
2198 else if (c == ')')
2199 count--;
2201 while (count > 0);
2205 /* Do nothing if the parser reports an error. */
2206 static int
2207 yyerror (char *s ATTRIBUTE_UNUSED)
2209 return 0;
2212 /* Parse a date/time string P. Return the corresponding time_t value,
2213 or (time_t) -1 if there is an error. P can be an incomplete or
2214 relative time specification; if so, use *NOW as the basis for the
2215 returned time. */
2216 time_t
2217 get_date (const char *p, const time_t *now)
2219 time_t Start = now ? *now : time (0);
2220 struct tm *tmp = localtime (&Start);
2221 struct tm tm;
2222 struct tm tm0;
2223 parser_control pc;
2225 if (! tmp)
2226 return -1;
2228 pc.input = p;
2229 pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2230 pc.year.digits = 4;
2231 pc.month = tmp->tm_mon + 1;
2232 pc.day = tmp->tm_mday;
2233 pc.hour = tmp->tm_hour;
2234 pc.minutes = tmp->tm_min;
2235 pc.seconds = tmp->tm_sec;
2236 tm.tm_isdst = tmp->tm_isdst;
2238 pc.meridian = MER24;
2239 pc.rel_seconds = 0;
2240 pc.rel_minutes = 0;
2241 pc.rel_hour = 0;
2242 pc.rel_day = 0;
2243 pc.rel_month = 0;
2244 pc.rel_year = 0;
2245 pc.dates_seen = 0;
2246 pc.days_seen = 0;
2247 pc.rels_seen = 0;
2248 pc.times_seen = 0;
2249 pc.local_zones_seen = 0;
2250 pc.zones_seen = 0;
2252 #if HAVE_STRUCT_TM_TM_ZONE
2253 pc.local_time_zone_table[0].name = tmp->tm_zone;
2254 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2255 pc.local_time_zone_table[0].value = tmp->tm_isdst;
2256 pc.local_time_zone_table[1].name = 0;
2258 /* Probe the names used in the next three calendar quarters, looking
2259 for a tm_isdst different from the one we already have. */
2261 int quarter;
2262 for (quarter = 1; quarter <= 3; quarter++)
2264 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2265 struct tm *probe_tm = localtime (&probe);
2266 if (probe_tm && probe_tm->tm_zone
2267 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2270 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2271 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2272 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2273 pc.local_time_zone_table[2].name = 0;
2275 break;
2279 #else
2280 #if HAVE_TZNAME
2282 # ifndef tzname
2283 extern char *tzname[];
2284 # endif
2285 int i;
2286 for (i = 0; i < 2; i++)
2288 pc.local_time_zone_table[i].name = tzname[i];
2289 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2290 pc.local_time_zone_table[i].value = i;
2292 pc.local_time_zone_table[i].name = 0;
2294 #else
2295 pc.local_time_zone_table[0].name = 0;
2296 #endif
2297 #endif
2299 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2300 && ! strcmp (pc.local_time_zone_table[0].name,
2301 pc.local_time_zone_table[1].name))
2303 /* This locale uses the same abbrevation for standard and
2304 daylight times. So if we see that abbreviation, we don't
2305 know whether it's daylight time. */
2306 pc.local_time_zone_table[0].value = -1;
2307 pc.local_time_zone_table[1].name = 0;
2310 if (yyparse (&pc) != 0
2311 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2312 || 1 < (pc.local_zones_seen + pc.zones_seen)
2313 || (pc.local_zones_seen && 1 < pc.local_isdst))
2314 return -1;
2316 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2317 tm.tm_mon = pc.month - 1 + pc.rel_month;
2318 tm.tm_mday = pc.day + pc.rel_day;
2319 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2321 tm.tm_hour = to_hour (pc.hour, pc.meridian);
2322 if (tm.tm_hour < 0)
2323 return -1;
2324 tm.tm_min = pc.minutes;
2325 tm.tm_sec = pc.seconds;
2327 else
2329 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2332 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2333 or if the relative time stamp mentions days, months, or years. */
2334 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2335 | pc.rel_month | pc.rel_year)
2336 tm.tm_isdst = -1;
2338 /* But if the input explicitly specifies local time with or without
2339 DST, give mktime that information. */
2340 if (pc.local_zones_seen)
2341 tm.tm_isdst = pc.local_isdst;
2343 tm0 = tm;
2345 Start = mktime (&tm);
2347 if (Start == (time_t) -1)
2350 /* Guard against falsely reporting errors near the time_t boundaries
2351 when parsing times in other time zones. For example, if the min
2352 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2353 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2354 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2355 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2356 zone by 24 hours to compensate. This algorithm assumes that
2357 there is no DST transition within a day of the time_t boundaries. */
2358 if (pc.zones_seen)
2360 tm = tm0;
2361 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2363 tm.tm_mday++;
2364 pc.time_zone += 24 * 60;
2366 else
2368 tm.tm_mday--;
2369 pc.time_zone -= 24 * 60;
2371 Start = mktime (&tm);
2374 if (Start == (time_t) -1)
2375 return Start;
2378 if (pc.days_seen && ! pc.dates_seen)
2380 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2381 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2382 tm.tm_isdst = -1;
2383 Start = mktime (&tm);
2384 if (Start == (time_t) -1)
2385 return Start;
2388 if (pc.zones_seen)
2390 int delta = pc.time_zone * 60;
2391 #ifdef HAVE_TM_GMTOFF
2392 delta -= tm.tm_gmtoff;
2393 #else
2394 struct tm *gmt = gmtime (&Start);
2395 if (! gmt)
2396 return -1;
2397 delta -= tm_diff (&tm, gmt);
2398 #endif
2399 if ((Start < Start - delta) != (delta < 0))
2400 return -1; /* time_t overflow */
2401 Start -= delta;
2404 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2405 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2406 leap second. Typically this is not what the user wants, but it's
2407 too hard to do it the other way, because the time zone indicator
2408 must be applied before relative times, and if mktime is applied
2409 again the time zone will be lost. */
2411 time_t t0 = Start;
2412 long d1 = 60 * 60 * (long) pc.rel_hour;
2413 time_t t1 = t0 + d1;
2414 long d2 = 60 * (long) pc.rel_minutes;
2415 time_t t2 = t1 + d2;
2416 int d3 = pc.rel_seconds;
2417 time_t t3 = t2 + d3;
2418 if ((d1 / (60 * 60) ^ pc.rel_hour)
2419 | (d2 / 60 ^ pc.rel_minutes)
2420 | ((t0 + d1 < t0) ^ (d1 < 0))
2421 | ((t1 + d2 < t1) ^ (d2 < 0))
2422 | ((t2 + d3 < t2) ^ (d3 < 0)))
2423 return -1;
2424 Start = t3;
2427 return Start;
2430 #if TEST
2432 #include <stdio.h>
2435 main (int ac, char **av)
2437 char buff[BUFSIZ];
2438 time_t d;
2440 printf ("Enter date, or blank line to exit.\n\t> ");
2441 fflush (stdout);
2443 buff[BUFSIZ - 1] = 0;
2444 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2446 d = get_date (buff, 0);
2447 if (d == (time_t) -1)
2448 printf ("Bad format - couldn't convert.\n");
2449 else
2450 printf ("%s", ctime (&d));
2451 printf ("\t> ");
2452 fflush (stdout);
2454 return 0;
2456 #endif /* defined TEST */