r23041: Remainder of fix for 4630: fix special case of unix_to_nt_time() for
[Samba/nascimento.git] / source3 / modules / getdate.c
blob51211f316d5c44f2de7d287355836168255b6a54
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, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 /* As a special exception, when this file is copied by Bison into a
22 Bison output file, you may use that output file without restriction.
23 This special exception was added by the Free Software Foundation
24 in version 1.24 of Bison. */
26 /* Written by Richard Stallman by simplifying the original so called
27 ``semantic'' parser. */
29 /* All symbols defined below should begin with yy or YY, to avoid
30 infringing on user name space. This should be done even for local
31 variables, as they might otherwise be expanded by user macros.
32 There are some unavoidable exceptions within include files to
33 define necessary library symbols; they are noted "INFRINGES ON
34 USER NAME SPACE" below. */
36 /* Identify Bison output. */
37 #define YYBISON 1
39 /* Skeleton name. */
40 #define YYSKELETON_NAME "yacc.c"
42 /* Pure parsers. */
43 #define YYPURE 1
45 /* Using locations. */
46 #define YYLSP_NEEDED 0
50 /* Tokens. */
51 #ifndef YYTOKENTYPE
52 # define YYTOKENTYPE
53 /* Put the tokens into the symbol table, so that GDB and other debuggers
54 know about them. */
55 enum yytokentype {
56 tAGO = 258,
57 tDST = 259,
58 tDAY = 260,
59 tDAY_UNIT = 261,
60 tDAYZONE = 262,
61 tHOUR_UNIT = 263,
62 tLOCAL_ZONE = 264,
63 tMERIDIAN = 265,
64 tMINUTE_UNIT = 266,
65 tMONTH = 267,
66 tMONTH_UNIT = 268,
67 tSEC_UNIT = 269,
68 tYEAR_UNIT = 270,
69 tZONE = 271,
70 tSNUMBER = 272,
71 tUNUMBER = 273
73 #endif
74 #define tAGO 258
75 #define tDST 259
76 #define tDAY 260
77 #define tDAY_UNIT 261
78 #define tDAYZONE 262
79 #define tHOUR_UNIT 263
80 #define tLOCAL_ZONE 264
81 #define tMERIDIAN 265
82 #define tMINUTE_UNIT 266
83 #define tMONTH 267
84 #define tMONTH_UNIT 268
85 #define tSEC_UNIT 269
86 #define tYEAR_UNIT 270
87 #define tZONE 271
88 #define tSNUMBER 272
89 #define tUNUMBER 273
94 /* Copy the first part of user declarations. */
95 #line 1 "getdate.y"
97 /* Parse a string into an internal time stamp.
98 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
100 This program is free software; you can redistribute it and/or modify
101 it under the terms of the GNU General Public License as published by
102 the Free Software Foundation; either version 2, or (at your option)
103 any later version.
105 This program is distributed in the hope that it will be useful,
106 but WITHOUT ANY WARRANTY; without even the implied warranty of
107 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108 GNU General Public License for more details.
110 You should have received a copy of the GNU General Public License
111 along with this program; if not, write to the Free Software Foundation,
112 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
114 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
115 at the University of North Carolina at Chapel Hill. Later tweaked by
116 a couple of people on Usenet. Completely overhauled by Rich $alz
117 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
119 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
120 the right thing about local DST. Unlike previous versions, this
121 version is reentrant. */
123 #ifdef HAVE_CONFIG_H
124 # include <config.h>
125 # ifdef HAVE_ALLOCA_H
126 # include <alloca.h>
127 # endif
128 #endif
130 /* Since the code of getdate.y is not included in the Emacs executable
131 itself, there is no need to #define static in this file. Even if
132 the code were included in the Emacs executable, it probably
133 wouldn't do any harm to #undef it here; this will only cause
134 problems if we try to write to a static variable, which I don't
135 think this code needs to do. */
136 #ifdef emacs
137 # undef static
138 #endif
140 #include <ctype.h>
141 #include <string.h>
143 #if HAVE_STDLIB_H
144 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
145 #endif
147 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
148 # define IN_CTYPE_DOMAIN(c) 1
149 #else
150 # define IN_CTYPE_DOMAIN(c) isascii (c)
151 #endif
153 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
154 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
155 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
156 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
158 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
159 - Its arg may be any int or unsigned int; it need not be an unsigned char.
160 - It's guaranteed to evaluate its argument exactly once.
161 - It's typically faster.
162 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
163 ISDIGIT_LOCALE unless it's important to use the locale's definition
164 of `digit' even when the host does not conform to POSIX. */
165 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
167 #if STDC_HEADERS || HAVE_STRING_H
168 # include <string.h>
169 #endif
171 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
172 # define __attribute__(x)
173 #endif
175 #ifndef ATTRIBUTE_UNUSED
176 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
177 #endif
179 #define EPOCH_YEAR 1970
180 #define TM_YEAR_BASE 1900
182 #define HOUR(x) ((x) * 60)
184 /* An integer value, and the number of digits in its textual
185 representation. */
186 typedef struct
188 int value;
189 int digits;
190 } textint;
192 /* An entry in the lexical lookup table. */
193 typedef struct
195 char const *name;
196 int type;
197 int value;
198 } table;
200 /* Meridian: am, pm, or 24-hour style. */
201 enum { MERam, MERpm, MER24 };
203 /* Information passed to and from the parser. */
204 typedef struct
206 /* The input string remaining to be parsed. */
207 const char *input;
209 /* N, if this is the Nth Tuesday. */
210 int day_ordinal;
212 /* Day of week; Sunday is 0. */
213 int day_number;
215 /* tm_isdst flag for the local zone. */
216 int local_isdst;
218 /* Time zone, in minutes east of UTC. */
219 int time_zone;
221 /* Style used for time. */
222 int meridian;
224 /* Gregorian year, month, day, hour, minutes, and seconds. */
225 textint year;
226 int month;
227 int day;
228 int hour;
229 int minutes;
230 int seconds;
232 /* Relative year, month, day, hour, minutes, and seconds. */
233 int rel_year;
234 int rel_month;
235 int rel_day;
236 int rel_hour;
237 int rel_minutes;
238 int rel_seconds;
240 /* Counts of nonterminals of various flavors parsed so far. */
241 int dates_seen;
242 int days_seen;
243 int local_zones_seen;
244 int rels_seen;
245 int times_seen;
246 int zones_seen;
248 /* Table of local time zone abbrevations, terminated by a null entry. */
249 table local_time_zone_table[3];
250 } parser_control;
252 #define PC (* (parser_control *) parm)
253 #define YYLEX_PARAM parm
254 #define YYPARSE_PARAM parm
256 static int yyerror ();
257 static int yylex ();
261 /* Enabling traces. */
262 #ifndef YYDEBUG
263 # define YYDEBUG 0
264 #endif
266 /* Enabling verbose error messages. */
267 #ifdef YYERROR_VERBOSE
268 # undef YYERROR_VERBOSE
269 # define YYERROR_VERBOSE 1
270 #else
271 # define YYERROR_VERBOSE 0
272 #endif
274 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
275 #line 172 "getdate.y"
276 typedef union YYSTYPE {
277 int intval;
278 textint textintval;
279 } YYSTYPE;
280 /* Line 191 of yacc.c. */
281 #line 281 "getdate.c"
282 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
283 # define YYSTYPE_IS_DECLARED 1
284 # define YYSTYPE_IS_TRIVIAL 1
285 #endif
289 /* Copy the second part of user declarations. */
292 /* Line 214 of yacc.c. */
293 #line 293 "getdate.c"
295 #if ! defined (yyoverflow) || YYERROR_VERBOSE
297 /* The parser invokes alloca or malloc; define the necessary symbols. */
299 # if YYSTACK_USE_ALLOCA
300 # define YYSTACK_ALLOC alloca
301 # else
302 # ifndef YYSTACK_USE_ALLOCA
303 # if defined (alloca) || defined (_ALLOCA_H)
304 # define YYSTACK_ALLOC alloca
305 # else
306 # ifdef __GNUC__
307 # define YYSTACK_ALLOC __builtin_alloca
308 # endif
309 # endif
310 # endif
311 # endif
313 # ifdef YYSTACK_ALLOC
314 /* Pacify GCC's `empty if-body' warning. */
315 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
316 # else
317 # if defined (__STDC__) || defined (__cplusplus)
318 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
319 # define YYSIZE_T size_t
320 # endif
321 # define YYSTACK_ALLOC malloc
322 # define YYSTACK_FREE free
323 # endif
324 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
327 #if (! defined (yyoverflow) \
328 && (! defined (__cplusplus) \
329 || (YYSTYPE_IS_TRIVIAL)))
331 /* A type that is properly aligned for any stack member. */
332 union yyalloc
334 short yyss;
335 YYSTYPE yyvs;
338 /* The size of the maximum gap between one aligned stack and the next. */
339 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
341 /* The size of an array large to enough to hold all stacks, each with
342 N elements. */
343 # define YYSTACK_BYTES(N) \
344 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
345 + YYSTACK_GAP_MAXIMUM)
347 /* Copy COUNT objects from FROM to TO. The source and destination do
348 not overlap. */
349 # ifndef YYCOPY
350 # if 1 < __GNUC__
351 # define YYCOPY(To, From, Count) \
352 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
353 # else
354 # define YYCOPY(To, From, Count) \
355 do \
357 register YYSIZE_T yyi; \
358 for (yyi = 0; yyi < (Count); yyi++) \
359 (To)[yyi] = (From)[yyi]; \
361 while (0)
362 # endif
363 # endif
365 /* Relocate STACK from its old location to the new one. The
366 local variables YYSIZE and YYSTACKSIZE give the old and new number of
367 elements in the stack, and YYPTR gives the new location of the
368 stack. Advance YYPTR to a properly aligned location for the next
369 stack. */
370 # define YYSTACK_RELOCATE(Stack) \
371 do \
373 YYSIZE_T yynewbytes; \
374 YYCOPY (&yyptr->Stack, Stack, yysize); \
375 Stack = &yyptr->Stack; \
376 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
377 yyptr += yynewbytes / sizeof (*yyptr); \
379 while (0)
381 #endif
383 #if defined (__STDC__) || defined (__cplusplus)
384 typedef signed char yysigned_char;
385 #else
386 typedef short yysigned_char;
387 #endif
389 /* YYFINAL -- State number of the termination state. */
390 #define YYFINAL 2
391 /* YYLAST -- Last index in YYTABLE. */
392 #define YYLAST 52
394 /* YYNTOKENS -- Number of terminals. */
395 #define YYNTOKENS 22
396 /* YYNNTS -- Number of nonterminals. */
397 #define YYNNTS 12
398 /* YYNRULES -- Number of rules. */
399 #define YYNRULES 54
400 /* YYNRULES -- Number of states. */
401 #define YYNSTATES 64
403 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
404 #define YYUNDEFTOK 2
405 #define YYMAXUTOK 273
407 #define YYTRANSLATE(YYX) \
408 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
410 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
411 static const unsigned char yytranslate[] =
413 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
416 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 19, 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, 2, 2, 2, 2,
436 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
437 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
438 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
439 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
440 15, 16, 17, 18
443 #if YYDEBUG
444 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
445 YYRHS. */
446 static const unsigned char yyprhs[] =
448 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
449 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
450 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
451 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
452 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
453 149, 152, 154, 156, 157
456 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
457 static const yysigned_char yyrhs[] =
459 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
460 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
461 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
462 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
463 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
464 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
465 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
466 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
467 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
468 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
469 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
470 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
471 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
472 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
473 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
474 14, -1, 14, -1, 18, -1, -1, 10, -1
477 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
478 static const unsigned short yyrline[] =
480 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
481 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
482 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
483 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
484 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
485 395, 397, 402, 439, 440
487 #endif
489 #if YYDEBUG || YYERROR_VERBOSE
490 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
491 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
492 static const char *const yytname[] =
494 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
495 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
496 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
497 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
498 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
499 "o_merid", 0
501 #endif
503 # ifdef YYPRINT
504 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
505 token YYLEX-NUM. */
506 static const unsigned short yytoknum[] =
508 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
509 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
510 44, 47
512 # endif
514 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
515 static const unsigned char yyr1[] =
517 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
518 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
519 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
520 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
521 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
522 31, 31, 32, 33, 33
525 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
526 static const unsigned char yyr2[] =
528 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
529 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
530 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
531 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
532 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
533 2, 1, 1, 0, 1
536 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
537 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
538 means the default is an error. */
539 static const unsigned char yydefact[] =
541 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
542 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
543 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
544 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
545 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
546 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
547 53, 25, 15, 14
550 /* YYDEFGOTO[NTERM-NUM]. */
551 static const yysigned_char yydefgoto[] =
553 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
554 24, 58
557 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
558 STATE-NUM. */
559 #define YYPACT_NINF -17
560 static const yysigned_char yypact[] =
562 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
563 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
564 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
565 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
566 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
567 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
568 -7, -17, -17, -17
571 /* YYPGOTO[NTERM-NUM]. */
572 static const yysigned_char yypgoto[] =
574 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
575 -17, -10
578 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
579 positive, shift that token. If negative, reduce the rule which
580 number is the opposite. If zero, do what YYDEFACT says.
581 If YYTABLE_NINF, syntax error. */
582 #define YYTABLE_NINF -1
583 static const unsigned char yytable[] =
585 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
586 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
587 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
588 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
589 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
590 63, 60, 61
593 static const unsigned char yycheck[] =
595 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
596 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
597 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
598 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
599 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
600 60, 18, 18
603 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
604 symbol of state STATE-NUM. */
605 static const unsigned char yystos[] =
607 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
608 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
609 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
610 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
611 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
612 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
613 18, 18, 17, 33
616 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
617 # define YYSIZE_T __SIZE_TYPE__
618 #endif
619 #if ! defined (YYSIZE_T) && defined (size_t)
620 # define YYSIZE_T size_t
621 #endif
622 #if ! defined (YYSIZE_T)
623 # if defined (__STDC__) || defined (__cplusplus)
624 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
625 # define YYSIZE_T size_t
626 # endif
627 #endif
628 #if ! defined (YYSIZE_T)
629 # define YYSIZE_T unsigned int
630 #endif
632 #define yyerrok (yyerrstatus = 0)
633 #define yyclearin (yychar = YYEMPTY)
634 #define YYEMPTY (-2)
635 #define YYEOF 0
637 #define YYACCEPT goto yyacceptlab
638 #define YYABORT goto yyabortlab
639 #define YYERROR goto yyerrlab1
642 /* Like YYERROR except do call yyerror. This remains here temporarily
643 to ease the transition to the new meaning of YYERROR, for GCC.
644 Once GCC version 2 has supplanted version 1, this can go. */
646 #define YYFAIL goto yyerrlab
648 #define YYRECOVERING() (!!yyerrstatus)
650 #define YYBACKUP(Token, Value) \
651 do \
652 if (yychar == YYEMPTY && yylen == 1) \
654 yychar = (Token); \
655 yylval = (Value); \
656 yytoken = YYTRANSLATE (yychar); \
657 YYPOPSTACK; \
658 goto yybackup; \
660 else \
662 yyerror ("syntax error: cannot back up");\
663 YYERROR; \
665 while (0)
667 #define YYTERROR 1
668 #define YYERRCODE 256
670 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
671 are run). */
673 #ifndef YYLLOC_DEFAULT
674 # define YYLLOC_DEFAULT(Current, Rhs, N) \
675 Current.first_line = Rhs[1].first_line; \
676 Current.first_column = Rhs[1].first_column; \
677 Current.last_line = Rhs[N].last_line; \
678 Current.last_column = Rhs[N].last_column;
679 #endif
681 /* YYLEX -- calling `yylex' with the right arguments. */
683 #ifdef YYLEX_PARAM
684 # define YYLEX yylex (&yylval, YYLEX_PARAM)
685 #else
686 # define YYLEX yylex (&yylval)
687 #endif
689 /* Enable debugging if requested. */
690 #if YYDEBUG
692 # ifndef YYFPRINTF
693 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
694 # define YYFPRINTF fprintf
695 # endif
697 # define YYDPRINTF(Args) \
698 do { \
699 if (yydebug) \
700 YYFPRINTF Args; \
701 } while (0)
703 # define YYDSYMPRINT(Args) \
704 do { \
705 if (yydebug) \
706 yysymprint Args; \
707 } while (0)
709 # define YYDSYMPRINTF(Title, Token, Value, Location) \
710 do { \
711 if (yydebug) \
713 YYFPRINTF (stderr, "%s ", Title); \
714 yysymprint (stderr, \
715 Token, Value); \
716 YYFPRINTF (stderr, "\n"); \
718 } while (0)
720 /*------------------------------------------------------------------.
721 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
722 | TOP (cinluded). |
723 `------------------------------------------------------------------*/
725 #if defined (__STDC__) || defined (__cplusplus)
726 static void
727 yy_stack_print (short *bottom, short *top)
728 #else
729 static void
730 yy_stack_print (bottom, top)
731 short *bottom;
732 short *top;
733 #endif
735 YYFPRINTF (stderr, "Stack now");
736 for (/* Nothing. */; bottom <= top; ++bottom)
737 YYFPRINTF (stderr, " %d", *bottom);
738 YYFPRINTF (stderr, "\n");
741 # define YY_STACK_PRINT(Bottom, Top) \
742 do { \
743 if (yydebug) \
744 yy_stack_print ((Bottom), (Top)); \
745 } while (0)
748 /*------------------------------------------------.
749 | Report that the YYRULE is going to be reduced. |
750 `------------------------------------------------*/
752 #if defined (__STDC__) || defined (__cplusplus)
753 static void
754 yy_reduce_print (int yyrule)
755 #else
756 static void
757 yy_reduce_print (yyrule)
758 int yyrule;
759 #endif
761 int yyi;
762 unsigned int yylineno = yyrline[yyrule];
763 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
764 yyrule - 1, yylineno);
765 /* Print the symbols being reduced, and their result. */
766 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
767 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
768 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
771 # define YY_REDUCE_PRINT(Rule) \
772 do { \
773 if (yydebug) \
774 yy_reduce_print (Rule); \
775 } while (0)
777 /* Nonzero means print parse trace. It is left uninitialized so that
778 multiple parsers can coexist. */
779 int yydebug;
780 #else /* !YYDEBUG */
781 # define YYDPRINTF(Args)
782 # define YYDSYMPRINT(Args)
783 # define YYDSYMPRINTF(Title, Token, Value, Location)
784 # define YY_STACK_PRINT(Bottom, Top)
785 # define YY_REDUCE_PRINT(Rule)
786 #endif /* !YYDEBUG */
789 /* YYINITDEPTH -- initial size of the parser's stacks. */
790 #ifndef YYINITDEPTH
791 # define YYINITDEPTH 200
792 #endif
794 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
795 if the built-in stack extension method is used).
797 Do not make this value too large; the results are undefined if
798 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
799 evaluated with infinite-precision integer arithmetic. */
801 #if YYMAXDEPTH == 0
802 # undef YYMAXDEPTH
803 #endif
805 #ifndef YYMAXDEPTH
806 # define YYMAXDEPTH 10000
807 #endif
811 #if YYERROR_VERBOSE
813 # ifndef yystrlen
814 # if defined (__GLIBC__) && defined (_STRING_H)
815 # define yystrlen strlen
816 # else
817 /* Return the length of YYSTR. */
818 static YYSIZE_T
819 # if defined (__STDC__) || defined (__cplusplus)
820 yystrlen (const char *yystr)
821 # else
822 yystrlen (yystr)
823 const char *yystr;
824 # endif
826 register const char *yys = yystr;
828 while (*yys++ != '\0')
829 continue;
831 return yys - yystr - 1;
833 # endif
834 # endif
836 # ifndef yystpcpy
837 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
838 # define yystpcpy stpcpy
839 # else
840 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
841 YYDEST. */
842 static char *
843 # if defined (__STDC__) || defined (__cplusplus)
844 yystpcpy (char *yydest, const char *yysrc)
845 # else
846 yystpcpy (yydest, yysrc)
847 char *yydest;
848 const char *yysrc;
849 # endif
851 register char *yyd = yydest;
852 register const char *yys = yysrc;
854 while ((*yyd++ = *yys++) != '\0')
855 continue;
857 return yyd - 1;
859 # endif
860 # endif
862 #endif /* !YYERROR_VERBOSE */
866 #if YYDEBUG
867 /*--------------------------------.
868 | Print this symbol on YYOUTPUT. |
869 `--------------------------------*/
871 #if defined (__STDC__) || defined (__cplusplus)
872 static void
873 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
874 #else
875 static void
876 yysymprint (yyoutput, yytype, yyvaluep)
877 FILE *yyoutput;
878 int yytype;
879 YYSTYPE *yyvaluep;
880 #endif
882 /* Pacify ``unused variable'' warnings. */
883 (void) yyvaluep;
885 if (yytype < YYNTOKENS)
887 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
888 # ifdef YYPRINT
889 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
890 # endif
892 else
893 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
895 switch (yytype)
897 default:
898 break;
900 YYFPRINTF (yyoutput, ")");
903 #endif /* ! YYDEBUG */
904 /*-----------------------------------------------.
905 | Release the memory associated to this symbol. |
906 `-----------------------------------------------*/
908 #if defined (__STDC__) || defined (__cplusplus)
909 static void
910 yydestruct (int yytype, YYSTYPE *yyvaluep)
911 #else
912 static void
913 yydestruct (yytype, yyvaluep)
914 int yytype;
915 YYSTYPE *yyvaluep;
916 #endif
918 /* Pacify ``unused variable'' warnings. */
919 (void) yyvaluep;
921 switch (yytype)
924 default:
925 break;
930 /* Prevent warnings from -Wmissing-prototypes. */
932 #ifdef YYPARSE_PARAM
933 # if defined (__STDC__) || defined (__cplusplus)
934 int yyparse (void *YYPARSE_PARAM);
935 # else
936 int yyparse ();
937 # endif
938 #else /* ! YYPARSE_PARAM */
939 #if defined (__STDC__) || defined (__cplusplus)
940 int yyparse (void);
941 #else
942 int yyparse ();
943 #endif
944 #endif /* ! YYPARSE_PARAM */
951 /*----------.
952 | yyparse. |
953 `----------*/
955 #ifdef YYPARSE_PARAM
956 # if defined (__STDC__) || defined (__cplusplus)
957 int yyparse (void *YYPARSE_PARAM)
958 # else
959 int yyparse (YYPARSE_PARAM)
960 void *YYPARSE_PARAM;
961 # endif
962 #else /* ! YYPARSE_PARAM */
963 #if defined (__STDC__) || defined (__cplusplus)
965 yyparse (void)
966 #else
968 yyparse ()
970 #endif
971 #endif
973 /* The lookahead symbol. */
974 int yychar;
976 /* The semantic value of the lookahead symbol. */
977 YYSTYPE yylval;
979 /* Number of syntax errors so far. */
980 int yynerrs;
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;
990 /* Three stacks and their tools:
991 `yyss': related to states,
992 `yyvs': related to semantic values,
993 `yyls': related to locations.
995 Refer to the stacks thru separate pointers, to allow yyoverflow
996 to reallocate them elsewhere. */
998 /* The state stack. */
999 short yyssa[YYINITDEPTH];
1000 short *yyss = yyssa;
1001 register short *yyssp;
1003 /* The semantic value stack. */
1004 YYSTYPE yyvsa[YYINITDEPTH];
1005 YYSTYPE *yyvs = yyvsa;
1006 register YYSTYPE *yyvsp;
1010 #define YYPOPSTACK (yyvsp--, yyssp--)
1012 YYSIZE_T yystacksize = YYINITDEPTH;
1014 /* The variables used to return semantic value and location from the
1015 action routines. */
1016 YYSTYPE yyval;
1019 /* When reducing, the number of symbols on the RHS of the reduced
1020 rule. */
1021 int yylen;
1023 YYDPRINTF ((stderr, "Starting parse\n"));
1025 yystate = 0;
1026 yyerrstatus = 0;
1027 yynerrs = 0;
1028 yychar = YYEMPTY; /* Cause a token to be read. */
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. */
1035 yyssp = yyss;
1036 yyvsp = yyvs;
1038 goto yysetstate;
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.
1047 yyssp++;
1049 yysetstate:
1050 *yyssp = yystate;
1052 if (yyss + yystacksize - 1 <= yyssp)
1054 /* Get the current used size of the three stacks, in elements. */
1055 YYSIZE_T yysize = yyssp - yyss + 1;
1057 #ifdef yyoverflow
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;
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),
1074 &yystacksize);
1076 yyss = yyss1;
1077 yyvs = yyvs1;
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;
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);
1099 # undef YYSTACK_RELOCATE
1100 if (yyss1 != yyssa)
1101 YYSTACK_FREE (yyss1);
1103 # endif
1104 #endif /* no yyoverflow */
1106 yyssp = yyss + yysize - 1;
1107 yyvsp = yyvs + yysize - 1;
1110 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1111 (unsigned long int) yystacksize));
1113 if (yyss + yystacksize - 1 <= yyssp)
1114 YYABORT;
1117 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1119 goto yybackup;
1121 /*-----------.
1122 | yybackup. |
1123 `-----------*/
1124 yybackup:
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: */
1130 /* First try to decide what to do without reference to lookahead token. */
1132 yyn = yypact[yystate];
1133 if (yyn == YYPACT_NINF)
1134 goto yydefault;
1136 /* Not known => get a lookahead token if don't already have one. */
1138 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1139 if (yychar == YYEMPTY)
1141 YYDPRINTF ((stderr, "Reading a token: "));
1142 yychar = YYLEX;
1145 if (yychar <= YYEOF)
1147 yychar = yytoken = YYEOF;
1148 YYDPRINTF ((stderr, "Now at end of input.\n"));
1150 else
1152 yytoken = YYTRANSLATE (yychar);
1153 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
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)
1164 if (yyn == 0 || yyn == YYTABLE_NINF)
1165 goto yyerrlab;
1166 yyn = -yyn;
1167 goto yyreduce;
1170 if (yyn == YYFINAL)
1171 YYACCEPT;
1173 /* Shift the lookahead token. */
1174 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1176 /* Discard the token being shifted unless it is eof. */
1177 if (yychar != YYEOF)
1178 yychar = YYEMPTY;
1180 *++yyvsp = yylval;
1183 /* Count tokens shifted since error; after three, turn off error
1184 status. */
1185 if (yyerrstatus)
1186 yyerrstatus--;
1188 yystate = yyn;
1189 goto yynewstate;
1192 /*-----------------------------------------------------------.
1193 | yydefault -- do the default action for the current state. |
1194 `-----------------------------------------------------------*/
1195 yydefault:
1196 yyn = yydefact[yystate];
1197 if (yyn == 0)
1198 goto yyerrlab;
1199 goto yyreduce;
1202 /*-----------------------------.
1203 | yyreduce -- Do a reduction. |
1204 `-----------------------------*/
1205 yyreduce:
1206 /* yyn is the number of a rule to reduce with. */
1207 yylen = yyr2[yyn];
1209 /* If YYLEN is nonzero, implement the default value of the action:
1210 `$$ = $1'.
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];
1220 YY_REDUCE_PRINT (yyn);
1221 switch (yyn)
1223 case 4:
1224 #line 195 "getdate.y"
1225 { PC.times_seen++; }
1226 break;
1228 case 5:
1229 #line 197 "getdate.y"
1230 { PC.local_zones_seen++; }
1231 break;
1233 case 6:
1234 #line 199 "getdate.y"
1235 { PC.zones_seen++; }
1236 break;
1238 case 7:
1239 #line 201 "getdate.y"
1240 { PC.dates_seen++; }
1241 break;
1243 case 8:
1244 #line 203 "getdate.y"
1245 { PC.days_seen++; }
1246 break;
1248 case 9:
1249 #line 205 "getdate.y"
1250 { PC.rels_seen++; }
1251 break;
1253 case 11:
1254 #line 211 "getdate.y"
1256 PC.hour = yyvsp[-1].textintval.value;
1257 PC.minutes = 0;
1258 PC.seconds = 0;
1259 PC.meridian = yyvsp[0].intval;
1261 break;
1263 case 12:
1264 #line 218 "getdate.y"
1266 PC.hour = yyvsp[-3].textintval.value;
1267 PC.minutes = yyvsp[-1].textintval.value;
1268 PC.seconds = 0;
1269 PC.meridian = yyvsp[0].intval;
1271 break;
1273 case 13:
1274 #line 225 "getdate.y"
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;
1282 break;
1284 case 14:
1285 #line 233 "getdate.y"
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;
1292 break;
1294 case 15:
1295 #line 240 "getdate.y"
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;
1304 break;
1306 case 16:
1307 #line 252 "getdate.y"
1308 { PC.local_isdst = yyvsp[0].intval; }
1309 break;
1311 case 17:
1312 #line 254 "getdate.y"
1313 { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1314 break;
1316 case 18:
1317 #line 259 "getdate.y"
1318 { PC.time_zone = yyvsp[0].intval; }
1319 break;
1321 case 19:
1322 #line 261 "getdate.y"
1323 { PC.time_zone = yyvsp[0].intval + 60; }
1324 break;
1326 case 20:
1327 #line 263 "getdate.y"
1328 { PC.time_zone = yyvsp[-1].intval + 60; }
1329 break;
1331 case 21:
1332 #line 268 "getdate.y"
1334 PC.day_ordinal = 1;
1335 PC.day_number = yyvsp[0].intval;
1337 break;
1339 case 22:
1340 #line 273 "getdate.y"
1342 PC.day_ordinal = 1;
1343 PC.day_number = yyvsp[-1].intval;
1345 break;
1347 case 23:
1348 #line 278 "getdate.y"
1350 PC.day_ordinal = yyvsp[-1].textintval.value;
1351 PC.day_number = yyvsp[0].intval;
1353 break;
1355 case 24:
1356 #line 286 "getdate.y"
1358 PC.month = yyvsp[-2].textintval.value;
1359 PC.day = yyvsp[0].textintval.value;
1361 break;
1363 case 25:
1364 #line 291 "getdate.y"
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)
1373 PC.year = yyvsp[-4].textintval;
1374 PC.month = yyvsp[-2].textintval.value;
1375 PC.day = yyvsp[0].textintval.value;
1377 else
1379 PC.month = yyvsp[-4].textintval.value;
1380 PC.day = yyvsp[-2].textintval.value;
1381 PC.year = yyvsp[0].textintval;
1384 break;
1386 case 26:
1387 #line 311 "getdate.y"
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;
1394 break;
1396 case 27:
1397 #line 318 "getdate.y"
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;
1405 break;
1407 case 28:
1408 #line 326 "getdate.y"
1410 PC.month = yyvsp[-1].intval;
1411 PC.day = yyvsp[0].textintval.value;
1413 break;
1415 case 29:
1416 #line 331 "getdate.y"
1418 PC.month = yyvsp[-3].intval;
1419 PC.day = yyvsp[-2].textintval.value;
1420 PC.year = yyvsp[0].textintval;
1422 break;
1424 case 30:
1425 #line 337 "getdate.y"
1427 PC.day = yyvsp[-1].textintval.value;
1428 PC.month = yyvsp[0].intval;
1430 break;
1432 case 31:
1433 #line 342 "getdate.y"
1435 PC.day = yyvsp[-2].textintval.value;
1436 PC.month = yyvsp[-1].intval;
1437 PC.year = yyvsp[0].textintval;
1439 break;
1441 case 32:
1442 #line 351 "getdate.y"
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;
1451 break;
1453 case 34:
1454 #line 364 "getdate.y"
1455 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1456 break;
1458 case 35:
1459 #line 366 "getdate.y"
1460 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1461 break;
1463 case 36:
1464 #line 368 "getdate.y"
1465 { PC.rel_year += yyvsp[0].intval; }
1466 break;
1468 case 37:
1469 #line 370 "getdate.y"
1470 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1471 break;
1473 case 38:
1474 #line 372 "getdate.y"
1475 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1476 break;
1478 case 39:
1479 #line 374 "getdate.y"
1480 { PC.rel_month += yyvsp[0].intval; }
1481 break;
1483 case 40:
1484 #line 376 "getdate.y"
1485 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1486 break;
1488 case 41:
1489 #line 378 "getdate.y"
1490 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1491 break;
1493 case 42:
1494 #line 380 "getdate.y"
1495 { PC.rel_day += yyvsp[0].intval; }
1496 break;
1498 case 43:
1499 #line 382 "getdate.y"
1500 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1501 break;
1503 case 44:
1504 #line 384 "getdate.y"
1505 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1506 break;
1508 case 45:
1509 #line 386 "getdate.y"
1510 { PC.rel_hour += yyvsp[0].intval; }
1511 break;
1513 case 46:
1514 #line 388 "getdate.y"
1515 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1516 break;
1518 case 47:
1519 #line 390 "getdate.y"
1520 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1521 break;
1523 case 48:
1524 #line 392 "getdate.y"
1525 { PC.rel_minutes += yyvsp[0].intval; }
1526 break;
1528 case 49:
1529 #line 394 "getdate.y"
1530 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1531 break;
1533 case 50:
1534 #line 396 "getdate.y"
1535 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1536 break;
1538 case 51:
1539 #line 398 "getdate.y"
1540 { PC.rel_seconds += yyvsp[0].intval; }
1541 break;
1543 case 52:
1544 #line 403 "getdate.y"
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
1551 if (4 < yyvsp[0].textintval.digits)
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;
1559 else
1561 PC.times_seen++;
1562 if (yyvsp[0].textintval.digits <= 2)
1564 PC.hour = yyvsp[0].textintval.value;
1565 PC.minutes = 0;
1567 else
1569 PC.hour = yyvsp[0].textintval.value / 100;
1570 PC.minutes = yyvsp[0].textintval.value % 100;
1572 PC.seconds = 0;
1573 PC.meridian = MER24;
1577 break;
1579 case 53:
1580 #line 439 "getdate.y"
1581 { yyval.intval = MER24; }
1582 break;
1584 case 54:
1585 #line 441 "getdate.y"
1586 { yyval.intval = yyvsp[0].intval; }
1587 break;
1592 /* Line 999 of yacc.c. */
1593 #line 1593 "getdate.c"
1595 yyvsp -= yylen;
1596 yyssp -= yylen;
1599 YY_STACK_PRINT (yyss, yyssp);
1601 *++yyvsp = yyval;
1604 /* Now `shift' the result of the reduction. Determine what state
1605 that goes to, based on the state we popped back to and the rule
1606 number reduced by. */
1608 yyn = yyr1[yyn];
1610 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1611 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1612 yystate = yytable[yystate];
1613 else
1614 yystate = yydefgoto[yyn - YYNTOKENS];
1616 goto yynewstate;
1619 /*------------------------------------.
1620 | yyerrlab -- here on detecting error |
1621 `------------------------------------*/
1622 yyerrlab:
1623 /* If not already recovering from an error, report this error. */
1624 if (!yyerrstatus)
1626 ++yynerrs;
1627 #if YYERROR_VERBOSE
1628 yyn = yypact[yystate];
1630 if (YYPACT_NINF < yyn && yyn < YYLAST)
1632 YYSIZE_T yysize = 0;
1633 int yytype = YYTRANSLATE (yychar);
1634 char *yymsg;
1635 int yyx, yycount;
1637 yycount = 0;
1638 /* Start YYX at -YYN if negative to avoid negative indexes in
1639 YYCHECK. */
1640 for (yyx = yyn < 0 ? -yyn : 0;
1641 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1642 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1643 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1644 yysize += yystrlen ("syntax error, unexpected ") + 1;
1645 yysize += yystrlen (yytname[yytype]);
1646 yymsg = (char *) YYSTACK_ALLOC (yysize);
1647 if (yymsg != 0)
1649 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1650 yyp = yystpcpy (yyp, yytname[yytype]);
1652 if (yycount < 5)
1654 yycount = 0;
1655 for (yyx = yyn < 0 ? -yyn : 0;
1656 yyx < (int) (sizeof (yytname) / sizeof (char *));
1657 yyx++)
1658 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1660 const char *yyq = ! yycount ? ", expecting " : " or ";
1661 yyp = yystpcpy (yyp, yyq);
1662 yyp = yystpcpy (yyp, yytname[yyx]);
1663 yycount++;
1666 yyerror (yymsg);
1667 YYSTACK_FREE (yymsg);
1669 else
1670 yyerror ("syntax error; also virtual memory exhausted");
1672 else
1673 #endif /* YYERROR_VERBOSE */
1674 yyerror ("syntax error");
1679 if (yyerrstatus == 3)
1681 /* If just tried and failed to reuse lookahead token after an
1682 error, discard it. */
1684 /* Return failure if at end of input. */
1685 if (yychar == YYEOF)
1687 /* Pop the error token. */
1688 YYPOPSTACK;
1689 /* Pop the rest of the stack. */
1690 while (yyss < yyssp)
1692 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1693 yydestruct (yystos[*yyssp], yyvsp);
1694 YYPOPSTACK;
1696 YYABORT;
1699 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1700 yydestruct (yytoken, &yylval);
1701 yychar = YYEMPTY;
1705 /* Else will try to reuse lookahead token after shifting the error
1706 token. */
1707 goto yyerrlab1;
1710 /*----------------------------------------------------.
1711 | yyerrlab1 -- error raised explicitly by an action. |
1712 `----------------------------------------------------*/
1713 yyerrlab1:
1714 yyerrstatus = 3; /* Each real token shifted decrements this. */
1716 for (;;)
1718 yyn = yypact[yystate];
1719 if (yyn != YYPACT_NINF)
1721 yyn += YYTERROR;
1722 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1724 yyn = yytable[yyn];
1725 if (0 < yyn)
1726 break;
1730 /* Pop the current state because it cannot handle the error token. */
1731 if (yyssp == yyss)
1732 YYABORT;
1734 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1735 yydestruct (yystos[yystate], yyvsp);
1736 yyvsp--;
1737 yystate = *--yyssp;
1739 YY_STACK_PRINT (yyss, yyssp);
1742 if (yyn == YYFINAL)
1743 YYACCEPT;
1745 YYDPRINTF ((stderr, "Shifting error token, "));
1747 *++yyvsp = yylval;
1750 yystate = yyn;
1751 goto yynewstate;
1754 /*-------------------------------------.
1755 | yyacceptlab -- YYACCEPT comes here. |
1756 `-------------------------------------*/
1757 yyacceptlab:
1758 yyresult = 0;
1759 goto yyreturn;
1761 /*-----------------------------------.
1762 | yyabortlab -- YYABORT comes here. |
1763 `-----------------------------------*/
1764 yyabortlab:
1765 yyresult = 1;
1766 goto yyreturn;
1768 #ifndef yyoverflow
1769 /*----------------------------------------------.
1770 | yyoverflowlab -- parser overflow comes here. |
1771 `----------------------------------------------*/
1772 yyoverflowlab:
1773 yyerror ("parser stack overflow");
1774 yyresult = 2;
1775 /* Fall through. */
1776 #endif
1778 yyreturn:
1779 #ifndef yyoverflow
1780 if (yyss != yyssa)
1781 YYSTACK_FREE (yyss);
1782 #endif
1783 return yyresult;
1787 #line 444 "getdate.y"
1790 /* Include this file down here because bison inserts code above which
1791 may define-away `const'. We want the prototype for get_date to have
1792 the same signature as the function definition. */
1793 #include "modules/getdate.h"
1795 #ifndef gmtime
1796 struct tm *gmtime ();
1797 #endif
1798 #ifndef localtime
1799 struct tm *localtime ();
1800 #endif
1801 #ifndef mktime
1802 time_t mktime ();
1803 #endif
1805 static table const meridian_table[] =
1807 { "AM", tMERIDIAN, MERam },
1808 { "A.M.", tMERIDIAN, MERam },
1809 { "PM", tMERIDIAN, MERpm },
1810 { "P.M.", tMERIDIAN, MERpm },
1811 { 0, 0, 0 }
1814 static table const dst_table[] =
1816 { "DST", tDST, 0 }
1819 static table const month_and_day_table[] =
1821 { "JANUARY", tMONTH, 1 },
1822 { "FEBRUARY", tMONTH, 2 },
1823 { "MARCH", tMONTH, 3 },
1824 { "APRIL", tMONTH, 4 },
1825 { "MAY", tMONTH, 5 },
1826 { "JUNE", tMONTH, 6 },
1827 { "JULY", tMONTH, 7 },
1828 { "AUGUST", tMONTH, 8 },
1829 { "SEPTEMBER",tMONTH, 9 },
1830 { "SEPT", tMONTH, 9 },
1831 { "OCTOBER", tMONTH, 10 },
1832 { "NOVEMBER", tMONTH, 11 },
1833 { "DECEMBER", tMONTH, 12 },
1834 { "SUNDAY", tDAY, 0 },
1835 { "MONDAY", tDAY, 1 },
1836 { "TUESDAY", tDAY, 2 },
1837 { "TUES", tDAY, 2 },
1838 { "WEDNESDAY",tDAY, 3 },
1839 { "WEDNES", tDAY, 3 },
1840 { "THURSDAY", tDAY, 4 },
1841 { "THUR", tDAY, 4 },
1842 { "THURS", tDAY, 4 },
1843 { "FRIDAY", tDAY, 5 },
1844 { "SATURDAY", tDAY, 6 },
1845 { 0, 0, 0 }
1848 static table const time_units_table[] =
1850 { "YEAR", tYEAR_UNIT, 1 },
1851 { "MONTH", tMONTH_UNIT, 1 },
1852 { "FORTNIGHT",tDAY_UNIT, 14 },
1853 { "WEEK", tDAY_UNIT, 7 },
1854 { "DAY", tDAY_UNIT, 1 },
1855 { "HOUR", tHOUR_UNIT, 1 },
1856 { "MINUTE", tMINUTE_UNIT, 1 },
1857 { "MIN", tMINUTE_UNIT, 1 },
1858 { "SECOND", tSEC_UNIT, 1 },
1859 { "SEC", tSEC_UNIT, 1 },
1860 { 0, 0, 0 }
1863 /* Assorted relative-time words. */
1864 static table const relative_time_table[] =
1866 { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
1867 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
1868 { "TODAY", tMINUTE_UNIT, 0 },
1869 { "NOW", tMINUTE_UNIT, 0 },
1870 { "LAST", tUNUMBER, -1 },
1871 { "THIS", tUNUMBER, 0 },
1872 { "NEXT", tUNUMBER, 1 },
1873 { "FIRST", tUNUMBER, 1 },
1874 /*{ "SECOND", tUNUMBER, 2 }, */
1875 { "THIRD", tUNUMBER, 3 },
1876 { "FOURTH", tUNUMBER, 4 },
1877 { "FIFTH", tUNUMBER, 5 },
1878 { "SIXTH", tUNUMBER, 6 },
1879 { "SEVENTH", tUNUMBER, 7 },
1880 { "EIGHTH", tUNUMBER, 8 },
1881 { "NINTH", tUNUMBER, 9 },
1882 { "TENTH", tUNUMBER, 10 },
1883 { "ELEVENTH", tUNUMBER, 11 },
1884 { "TWELFTH", tUNUMBER, 12 },
1885 { "AGO", tAGO, 1 },
1886 { 0, 0, 0 }
1889 /* The time zone table. This table is necessarily incomplete, as time
1890 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1891 as Eastern time in Australia, not as US Eastern Standard Time.
1892 You cannot rely on getdate to handle arbitrary time zone
1893 abbreviations; use numeric abbreviations like `-0500' instead. */
1894 static table const time_zone_table[] =
1896 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1897 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1898 { "UTC", tZONE, HOUR ( 0) },
1899 { "WET", tZONE, HOUR ( 0) }, /* Western European */
1900 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
1901 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
1902 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
1903 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
1904 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1905 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1906 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1907 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
1908 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1909 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
1910 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1911 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
1912 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1913 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
1914 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1915 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
1916 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1917 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
1918 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1919 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
1920 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1921 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
1922 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1923 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1924 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
1925 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
1926 { "CET", tZONE, HOUR ( 1) }, /* Central European */
1927 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
1928 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
1929 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
1930 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1931 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1932 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
1933 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
1934 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
1935 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
1936 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
1937 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
1938 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
1939 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
1940 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
1941 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
1942 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
1943 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
1944 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
1945 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
1946 { 0, 0, 0 }
1949 /* Military time zone table. */
1950 static table const military_table[] =
1952 { "A", tZONE, -HOUR ( 1) },
1953 { "B", tZONE, -HOUR ( 2) },
1954 { "C", tZONE, -HOUR ( 3) },
1955 { "D", tZONE, -HOUR ( 4) },
1956 { "E", tZONE, -HOUR ( 5) },
1957 { "F", tZONE, -HOUR ( 6) },
1958 { "G", tZONE, -HOUR ( 7) },
1959 { "H", tZONE, -HOUR ( 8) },
1960 { "I", tZONE, -HOUR ( 9) },
1961 { "K", tZONE, -HOUR (10) },
1962 { "L", tZONE, -HOUR (11) },
1963 { "M", tZONE, -HOUR (12) },
1964 { "N", tZONE, HOUR ( 1) },
1965 { "O", tZONE, HOUR ( 2) },
1966 { "P", tZONE, HOUR ( 3) },
1967 { "Q", tZONE, HOUR ( 4) },
1968 { "R", tZONE, HOUR ( 5) },
1969 { "S", tZONE, HOUR ( 6) },
1970 { "T", tZONE, HOUR ( 7) },
1971 { "U", tZONE, HOUR ( 8) },
1972 { "V", tZONE, HOUR ( 9) },
1973 { "W", tZONE, HOUR (10) },
1974 { "X", tZONE, HOUR (11) },
1975 { "Y", tZONE, HOUR (12) },
1976 { "Z", tZONE, HOUR ( 0) },
1977 { 0, 0, 0 }
1982 static int
1983 to_hour (int hours, int meridian)
1985 switch (meridian)
1987 case MER24:
1988 return 0 <= hours && hours < 24 ? hours : -1;
1989 case MERam:
1990 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1991 case MERpm:
1992 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
1993 default:
1994 abort ();
1996 /* NOTREACHED */
1997 return 0;
2000 static int
2001 to_year (textint textyear)
2003 int year = textyear.value;
2005 if (year < 0)
2006 year = -year;
2008 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2009 years 69-99 map to 1969-1999. */
2010 if (textyear.digits == 2)
2011 year += year < 69 ? 2000 : 1900;
2013 return year;
2016 static table const *
2017 lookup_zone (parser_control const *pc, char const *name)
2019 table const *tp;
2021 /* Try local zone abbreviations first; they're more likely to be right. */
2022 for (tp = pc->local_time_zone_table; tp->name; tp++)
2023 if (strcmp (name, tp->name) == 0)
2024 return tp;
2026 for (tp = time_zone_table; tp->name; tp++)
2027 if (strcmp (name, tp->name) == 0)
2028 return tp;
2030 return 0;
2033 #if ! HAVE_TM_GMTOFF
2034 /* Yield the difference between *A and *B,
2035 measured in seconds, ignoring leap seconds.
2036 The body of this function is taken directly from the GNU C Library;
2037 see src/strftime.c. */
2038 static int
2039 tm_diff (struct tm const *a, struct tm const *b)
2041 /* Compute intervening leap days correctly even if year is negative.
2042 Take care to avoid int overflow in leap day calculations,
2043 but it's OK to assume that A and B are close to each other. */
2044 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2045 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2046 int a100 = a4 / 25 - (a4 % 25 < 0);
2047 int b100 = b4 / 25 - (b4 % 25 < 0);
2048 int a400 = a100 >> 2;
2049 int b400 = b100 >> 2;
2050 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2051 int years = a->tm_year - b->tm_year;
2052 int days = (365 * years + intervening_leap_days
2053 + (a->tm_yday - b->tm_yday));
2054 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2055 + (a->tm_min - b->tm_min))
2056 + (a->tm_sec - b->tm_sec));
2058 #endif /* ! HAVE_TM_GMTOFF */
2060 static table const *
2061 lookup_word (parser_control const *pc, char *word)
2063 char *p;
2064 char *q;
2065 size_t wordlen;
2066 table const *tp;
2067 int i;
2068 int abbrev;
2070 /* Make it uppercase. */
2071 for (p = word; *p; p++)
2072 if (ISLOWER ((unsigned char) *p))
2073 *p = toupper ((unsigned char) *p);
2075 for (tp = meridian_table; tp->name; tp++)
2076 if (strcmp (word, tp->name) == 0)
2077 return tp;
2079 /* See if we have an abbreviation for a month. */
2080 wordlen = strlen (word);
2081 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2083 for (tp = month_and_day_table; tp->name; tp++)
2084 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2085 return tp;
2087 if ((tp = lookup_zone (pc, word)))
2088 return tp;
2090 if (strcmp (word, dst_table[0].name) == 0)
2091 return dst_table;
2093 for (tp = time_units_table; tp->name; tp++)
2094 if (strcmp (word, tp->name) == 0)
2095 return tp;
2097 /* Strip off any plural and try the units table again. */
2098 if (word[wordlen - 1] == 'S')
2100 word[wordlen - 1] = '\0';
2101 for (tp = time_units_table; tp->name; tp++)
2102 if (strcmp (word, tp->name) == 0)
2103 return tp;
2104 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2107 for (tp = relative_time_table; tp->name; tp++)
2108 if (strcmp (word, tp->name) == 0)
2109 return tp;
2111 /* Military time zones. */
2112 if (wordlen == 1)
2113 for (tp = military_table; tp->name; tp++)
2114 if (word[0] == tp->name[0])
2115 return tp;
2117 /* Drop out any periods and try the time zone table again. */
2118 for (i = 0, p = q = word; (*p = *q); q++)
2119 if (*q == '.')
2120 i = 1;
2121 else
2122 p++;
2123 if (i && (tp = lookup_zone (pc, word)))
2124 return tp;
2126 return 0;
2129 static int
2130 yylex (YYSTYPE *lvalp, parser_control *pc)
2132 unsigned char c;
2133 int count;
2135 for (;;)
2137 while (c = *pc->input, ISSPACE (c))
2138 pc->input++;
2140 if (ISDIGIT (c) || c == '-' || c == '+')
2142 char const *p;
2143 int sign;
2144 int value;
2145 if (c == '-' || c == '+')
2147 sign = c == '-' ? -1 : 1;
2148 c = *++pc->input;
2149 if (! ISDIGIT (c))
2150 /* skip the '-' sign */
2151 continue;
2153 else
2154 sign = 0;
2155 p = pc->input;
2156 value = 0;
2159 value = 10 * value + c - '0';
2160 c = *++p;
2162 while (ISDIGIT (c));
2163 lvalp->textintval.value = sign < 0 ? -value : value;
2164 lvalp->textintval.digits = p - pc->input;
2165 pc->input = p;
2166 return sign ? tSNUMBER : tUNUMBER;
2169 if (ISALPHA (c))
2171 char buff[20];
2172 char *p = buff;
2173 table const *tp;
2177 if (p < buff + sizeof buff - 1)
2178 *p++ = c;
2179 c = *++pc->input;
2181 while (ISALPHA (c) || c == '.');
2183 *p = '\0';
2184 tp = lookup_word (pc, buff);
2185 if (! tp)
2186 return '?';
2187 lvalp->intval = tp->value;
2188 return tp->type;
2191 if (c != '(')
2192 return *pc->input++;
2193 count = 0;
2196 c = *pc->input++;
2197 if (c == '\0')
2198 return c;
2199 if (c == '(')
2200 count++;
2201 else if (c == ')')
2202 count--;
2204 while (count > 0);
2208 /* Do nothing if the parser reports an error. */
2209 static int
2210 yyerror (char *s ATTRIBUTE_UNUSED)
2212 return 0;
2215 /* Parse a date/time string P. Return the corresponding time_t value,
2216 or (time_t) -1 if there is an error. P can be an incomplete or
2217 relative time specification; if so, use *NOW as the basis for the
2218 returned time. */
2219 time_t
2220 get_date (const char *p, const time_t *now)
2222 time_t Start = now ? *now : time (0);
2223 struct tm *tmp = localtime (&Start);
2224 struct tm tm;
2225 struct tm tm0;
2226 parser_control pc;
2228 if (! tmp)
2229 return -1;
2231 pc.input = p;
2232 pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2233 pc.year.digits = 4;
2234 pc.month = tmp->tm_mon + 1;
2235 pc.day = tmp->tm_mday;
2236 pc.hour = tmp->tm_hour;
2237 pc.minutes = tmp->tm_min;
2238 pc.seconds = tmp->tm_sec;
2239 tm.tm_isdst = tmp->tm_isdst;
2241 pc.meridian = MER24;
2242 pc.rel_seconds = 0;
2243 pc.rel_minutes = 0;
2244 pc.rel_hour = 0;
2245 pc.rel_day = 0;
2246 pc.rel_month = 0;
2247 pc.rel_year = 0;
2248 pc.dates_seen = 0;
2249 pc.days_seen = 0;
2250 pc.rels_seen = 0;
2251 pc.times_seen = 0;
2252 pc.local_zones_seen = 0;
2253 pc.zones_seen = 0;
2255 #if HAVE_STRUCT_TM_TM_ZONE
2256 pc.local_time_zone_table[0].name = tmp->tm_zone;
2257 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2258 pc.local_time_zone_table[0].value = tmp->tm_isdst;
2259 pc.local_time_zone_table[1].name = 0;
2261 /* Probe the names used in the next three calendar quarters, looking
2262 for a tm_isdst different from the one we already have. */
2264 int quarter;
2265 for (quarter = 1; quarter <= 3; quarter++)
2267 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2268 struct tm *probe_tm = localtime (&probe);
2269 if (probe_tm && probe_tm->tm_zone
2270 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2273 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2274 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2275 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2276 pc.local_time_zone_table[2].name = 0;
2278 break;
2282 #else
2283 #if HAVE_TZNAME
2285 # ifndef tzname
2286 extern char *tzname[];
2287 # endif
2288 int i;
2289 for (i = 0; i < 2; i++)
2291 pc.local_time_zone_table[i].name = tzname[i];
2292 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2293 pc.local_time_zone_table[i].value = i;
2295 pc.local_time_zone_table[i].name = 0;
2297 #else
2298 pc.local_time_zone_table[0].name = 0;
2299 #endif
2300 #endif
2302 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2303 && ! strcmp (pc.local_time_zone_table[0].name,
2304 pc.local_time_zone_table[1].name))
2306 /* This locale uses the same abbrevation for standard and
2307 daylight times. So if we see that abbreviation, we don't
2308 know whether it's daylight time. */
2309 pc.local_time_zone_table[0].value = -1;
2310 pc.local_time_zone_table[1].name = 0;
2313 if (yyparse (&pc) != 0
2314 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2315 || 1 < (pc.local_zones_seen + pc.zones_seen)
2316 || (pc.local_zones_seen && 1 < pc.local_isdst))
2317 return -1;
2319 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2320 tm.tm_mon = pc.month - 1 + pc.rel_month;
2321 tm.tm_mday = pc.day + pc.rel_day;
2322 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2324 tm.tm_hour = to_hour (pc.hour, pc.meridian);
2325 if (tm.tm_hour < 0)
2326 return -1;
2327 tm.tm_min = pc.minutes;
2328 tm.tm_sec = pc.seconds;
2330 else
2332 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2335 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2336 or if the relative time stamp mentions days, months, or years. */
2337 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2338 | pc.rel_month | pc.rel_year)
2339 tm.tm_isdst = -1;
2341 /* But if the input explicitly specifies local time with or without
2342 DST, give mktime that information. */
2343 if (pc.local_zones_seen)
2344 tm.tm_isdst = pc.local_isdst;
2346 tm0 = tm;
2348 Start = mktime (&tm);
2350 if (Start == (time_t) -1)
2353 /* Guard against falsely reporting errors near the time_t boundaries
2354 when parsing times in other time zones. For example, if the min
2355 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2356 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2357 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2358 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2359 zone by 24 hours to compensate. This algorithm assumes that
2360 there is no DST transition within a day of the time_t boundaries. */
2361 if (pc.zones_seen)
2363 tm = tm0;
2364 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2366 tm.tm_mday++;
2367 pc.time_zone += 24 * 60;
2369 else
2371 tm.tm_mday--;
2372 pc.time_zone -= 24 * 60;
2374 Start = mktime (&tm);
2377 if (Start == (time_t) -1)
2378 return Start;
2381 if (pc.days_seen && ! pc.dates_seen)
2383 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2384 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2385 tm.tm_isdst = -1;
2386 Start = mktime (&tm);
2387 if (Start == (time_t) -1)
2388 return Start;
2391 if (pc.zones_seen)
2393 int delta = pc.time_zone * 60;
2394 #ifdef HAVE_TM_GMTOFF
2395 delta -= tm.tm_gmtoff;
2396 #else
2397 struct tm *gmt = gmtime (&Start);
2398 if (! gmt)
2399 return -1;
2400 delta -= tm_diff (&tm, gmt);
2401 #endif
2402 if ((Start < Start - delta) != (delta < 0))
2403 return -1; /* time_t overflow */
2404 Start -= delta;
2407 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2408 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2409 leap second. Typically this is not what the user wants, but it's
2410 too hard to do it the other way, because the time zone indicator
2411 must be applied before relative times, and if mktime is applied
2412 again the time zone will be lost. */
2414 time_t t0 = Start;
2415 long d1 = 60 * 60 * (long) pc.rel_hour;
2416 time_t t1 = t0 + d1;
2417 long d2 = 60 * (long) pc.rel_minutes;
2418 time_t t2 = t1 + d2;
2419 int d3 = pc.rel_seconds;
2420 time_t t3 = t2 + d3;
2421 if ((d1 / (60 * 60) ^ pc.rel_hour)
2422 | (d2 / 60 ^ pc.rel_minutes)
2423 | ((t0 + d1 < t0) ^ (d1 < 0))
2424 | ((t1 + d2 < t1) ^ (d2 < 0))
2425 | ((t2 + d3 < t2) ^ (d3 < 0)))
2426 return -1;
2427 Start = t3;
2430 return Start;
2433 #if TEST
2435 #include <stdio.h>
2438 main (int ac, char **av)
2440 char buff[BUFSIZ];
2441 time_t d;
2443 printf ("Enter date, or blank line to exit.\n\t> ");
2444 fflush (stdout);
2446 buff[BUFSIZ - 1] = 0;
2447 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2449 d = get_date (buff, 0);
2450 if (d == (time_t) -1)
2451 printf ("Bad format - couldn't convert.\n");
2452 else
2453 printf ("%s", ctime (&d));
2454 printf ("\t> ");
2455 fflush (stdout);
2457 return 0;
2459 #endif /* defined TEST */