A fix to allow configure to find iconv on a number of systems including those
[Samba/gebeck_regimport.git] / source3 / modules / getdate.c
blob491c51294e9ca0e68704250b126865671c7229e8
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>
142 #if HAVE_STDLIB_H
143 # include <stdlib.h> /* for `free'; used by Bison 1.27 */
144 #endif
146 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
147 # define IN_CTYPE_DOMAIN(c) 1
148 #else
149 # define IN_CTYPE_DOMAIN(c) isascii (c)
150 #endif
152 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
153 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
154 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
155 #define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
157 /* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
158 - Its arg may be any int or unsigned int; it need not be an unsigned char.
159 - It's guaranteed to evaluate its argument exactly once.
160 - It's typically faster.
161 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
162 ISDIGIT_LOCALE unless it's important to use the locale's definition
163 of `digit' even when the host does not conform to POSIX. */
164 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
166 #if STDC_HEADERS || HAVE_STRING_H
167 # include <string.h>
168 #endif
170 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
171 # define __attribute__(x)
172 #endif
174 #ifndef ATTRIBUTE_UNUSED
175 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
176 #endif
178 #define EPOCH_YEAR 1970
179 #define TM_YEAR_BASE 1900
181 #define HOUR(x) ((x) * 60)
183 /* An integer value, and the number of digits in its textual
184 representation. */
185 typedef struct
187 int value;
188 int digits;
189 } textint;
191 /* An entry in the lexical lookup table. */
192 typedef struct
194 char const *name;
195 int type;
196 int value;
197 } table;
199 /* Meridian: am, pm, or 24-hour style. */
200 enum { MERam, MERpm, MER24 };
202 /* Information passed to and from the parser. */
203 typedef struct
205 /* The input string remaining to be parsed. */
206 const char *input;
208 /* N, if this is the Nth Tuesday. */
209 int day_ordinal;
211 /* Day of week; Sunday is 0. */
212 int day_number;
214 /* tm_isdst flag for the local zone. */
215 int local_isdst;
217 /* Time zone, in minutes east of UTC. */
218 int time_zone;
220 /* Style used for time. */
221 int meridian;
223 /* Gregorian year, month, day, hour, minutes, and seconds. */
224 textint year;
225 int month;
226 int day;
227 int hour;
228 int minutes;
229 int seconds;
231 /* Relative year, month, day, hour, minutes, and seconds. */
232 int rel_year;
233 int rel_month;
234 int rel_day;
235 int rel_hour;
236 int rel_minutes;
237 int rel_seconds;
239 /* Counts of nonterminals of various flavors parsed so far. */
240 int dates_seen;
241 int days_seen;
242 int local_zones_seen;
243 int rels_seen;
244 int times_seen;
245 int zones_seen;
247 /* Table of local time zone abbrevations, terminated by a null entry. */
248 table local_time_zone_table[3];
249 } parser_control;
251 #define PC (* (parser_control *) parm)
252 #define YYLEX_PARAM parm
253 #define YYPARSE_PARAM parm
255 static int yyerror ();
256 static int yylex ();
260 /* Enabling traces. */
261 #ifndef YYDEBUG
262 # define YYDEBUG 0
263 #endif
265 /* Enabling verbose error messages. */
266 #ifdef YYERROR_VERBOSE
267 # undef YYERROR_VERBOSE
268 # define YYERROR_VERBOSE 1
269 #else
270 # define YYERROR_VERBOSE 0
271 #endif
273 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
274 #line 172 "getdate.y"
275 typedef union YYSTYPE {
276 int intval;
277 textint textintval;
278 } YYSTYPE;
279 /* Line 191 of yacc.c. */
280 #line 281 "getdate.c"
281 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
282 # define YYSTYPE_IS_DECLARED 1
283 # define YYSTYPE_IS_TRIVIAL 1
284 #endif
288 /* Copy the second part of user declarations. */
291 /* Line 214 of yacc.c. */
292 #line 293 "getdate.c"
294 #if ! defined (yyoverflow) || YYERROR_VERBOSE
296 /* The parser invokes alloca or malloc; define the necessary symbols. */
298 # if YYSTACK_USE_ALLOCA
299 # define YYSTACK_ALLOC alloca
300 # else
301 # ifndef YYSTACK_USE_ALLOCA
302 # if defined (alloca) || defined (_ALLOCA_H)
303 # define YYSTACK_ALLOC alloca
304 # else
305 # ifdef __GNUC__
306 # define YYSTACK_ALLOC __builtin_alloca
307 # endif
308 # endif
309 # endif
310 # endif
312 # ifdef YYSTACK_ALLOC
313 /* Pacify GCC's `empty if-body' warning. */
314 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
315 # else
316 # if defined (__STDC__) || defined (__cplusplus)
317 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
318 # define YYSIZE_T size_t
319 # endif
320 # define YYSTACK_ALLOC malloc
321 # define YYSTACK_FREE free
322 # endif
323 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
326 #if (! defined (yyoverflow) \
327 && (! defined (__cplusplus) \
328 || (YYSTYPE_IS_TRIVIAL)))
330 /* A type that is properly aligned for any stack member. */
331 union yyalloc
333 short yyss;
334 YYSTYPE yyvs;
337 /* The size of the maximum gap between one aligned stack and the next. */
338 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
340 /* The size of an array large to enough to hold all stacks, each with
341 N elements. */
342 # define YYSTACK_BYTES(N) \
343 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
344 + YYSTACK_GAP_MAXIMUM)
346 /* Copy COUNT objects from FROM to TO. The source and destination do
347 not overlap. */
348 # ifndef YYCOPY
349 # if 1 < __GNUC__
350 # define YYCOPY(To, From, Count) \
351 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
352 # else
353 # define YYCOPY(To, From, Count) \
354 do \
356 register YYSIZE_T yyi; \
357 for (yyi = 0; yyi < (Count); yyi++) \
358 (To)[yyi] = (From)[yyi]; \
360 while (0)
361 # endif
362 # endif
364 /* Relocate STACK from its old location to the new one. The
365 local variables YYSIZE and YYSTACKSIZE give the old and new number of
366 elements in the stack, and YYPTR gives the new location of the
367 stack. Advance YYPTR to a properly aligned location for the next
368 stack. */
369 # define YYSTACK_RELOCATE(Stack) \
370 do \
372 YYSIZE_T yynewbytes; \
373 YYCOPY (&yyptr->Stack, Stack, yysize); \
374 Stack = &yyptr->Stack; \
375 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
376 yyptr += yynewbytes / sizeof (*yyptr); \
378 while (0)
380 #endif
382 #if defined (__STDC__) || defined (__cplusplus)
383 typedef signed char yysigned_char;
384 #else
385 typedef short yysigned_char;
386 #endif
388 /* YYFINAL -- State number of the termination state. */
389 #define YYFINAL 2
390 /* YYLAST -- Last index in YYTABLE. */
391 #define YYLAST 52
393 /* YYNTOKENS -- Number of terminals. */
394 #define YYNTOKENS 22
395 /* YYNNTS -- Number of nonterminals. */
396 #define YYNNTS 12
397 /* YYNRULES -- Number of rules. */
398 #define YYNRULES 54
399 /* YYNRULES -- Number of states. */
400 #define YYNSTATES 64
402 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
403 #define YYUNDEFTOK 2
404 #define YYMAXUTOK 273
406 #define YYTRANSLATE(YYX) \
407 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
409 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
410 static const unsigned char yytranslate[] =
412 0, 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, 2, 2, 2, 2, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
416 2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 19, 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, 2, 2, 2, 2,
436 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
437 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
438 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
439 15, 16, 17, 18
442 #if YYDEBUG
443 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
444 YYRHS. */
445 static const unsigned char yyprhs[] =
447 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
448 19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
449 57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
450 94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
451 122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
452 149, 152, 154, 156, 157
455 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
456 static const yysigned_char yyrhs[] =
458 23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
459 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
460 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
461 19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
462 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
463 9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
464 5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
465 18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
466 17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
467 18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
468 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
469 15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
470 13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
471 18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
472 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
473 14, -1, 14, -1, 18, -1, -1, 10, -1
476 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
477 static const unsigned short yyrline[] =
479 0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
480 206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
481 262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
482 336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
483 375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
484 395, 397, 402, 439, 440
486 #endif
488 #if YYDEBUG || YYERROR_VERBOSE
489 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
490 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
491 static const char *const yytname[] =
493 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
494 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
495 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
496 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
497 "local_zone", "zone", "day", "date", "rel", "relunit", "number",
498 "o_merid", 0
500 #endif
502 # ifdef YYPRINT
503 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
504 token YYLEX-NUM. */
505 static const unsigned short yytoknum[] =
507 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
508 265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
509 44, 47
511 # endif
513 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
514 static const unsigned char yyr1[] =
516 0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
517 24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
518 27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
519 29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
520 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
521 31, 31, 32, 33, 33
524 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
525 static const unsigned char yyr2[] =
527 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
528 1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
529 2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
530 2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
531 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
532 2, 1, 1, 0, 1
535 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
536 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
537 means the default is an error. */
538 static const unsigned char yydefact[] =
540 2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
541 39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
542 8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
543 44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
544 30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
545 31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
546 53, 25, 15, 14
549 /* YYDEFGOTO[NTERM-NUM]. */
550 static const yysigned_char yydefgoto[] =
552 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
553 24, 58
556 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
557 STATE-NUM. */
558 #define YYPACT_NINF -17
559 static const yysigned_char yypact[] =
561 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
562 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
563 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
564 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
565 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
566 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
567 -7, -17, -17, -17
570 /* YYPGOTO[NTERM-NUM]. */
571 static const yysigned_char yypgoto[] =
573 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
574 -17, -10
577 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
578 positive, shift that token. If negative, reduce the rule which
579 number is the opposite. If zero, do what YYDEFACT says.
580 If YYTABLE_NINF, syntax error. */
581 #define YYTABLE_NINF -1
582 static const unsigned char yytable[] =
584 2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
585 62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
586 36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
587 47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
588 33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
589 63, 60, 61
592 static const unsigned char yycheck[] =
594 0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
595 17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
596 6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
597 3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
598 14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
599 60, 18, 18
602 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
603 symbol of state STATE-NUM. */
604 static const unsigned char yystos[] =
606 0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
607 13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
608 28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
609 8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
610 12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
611 18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
612 18, 18, 17, 33
615 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
616 # define YYSIZE_T __SIZE_TYPE__
617 #endif
618 #if ! defined (YYSIZE_T) && defined (size_t)
619 # define YYSIZE_T size_t
620 #endif
621 #if ! defined (YYSIZE_T)
622 # if defined (__STDC__) || defined (__cplusplus)
623 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
624 # define YYSIZE_T size_t
625 # endif
626 #endif
627 #if ! defined (YYSIZE_T)
628 # define YYSIZE_T unsigned int
629 #endif
631 #define yyerrok (yyerrstatus = 0)
632 #define yyclearin (yychar = YYEMPTY)
633 #define YYEMPTY (-2)
634 #define YYEOF 0
636 #define YYACCEPT goto yyacceptlab
637 #define YYABORT goto yyabortlab
638 #define YYERROR goto yyerrlab1
641 /* Like YYERROR except do call yyerror. This remains here temporarily
642 to ease the transition to the new meaning of YYERROR, for GCC.
643 Once GCC version 2 has supplanted version 1, this can go. */
645 #define YYFAIL goto yyerrlab
647 #define YYRECOVERING() (!!yyerrstatus)
649 #define YYBACKUP(Token, Value) \
650 do \
651 if (yychar == YYEMPTY && yylen == 1) \
653 yychar = (Token); \
654 yylval = (Value); \
655 yytoken = YYTRANSLATE (yychar); \
656 YYPOPSTACK; \
657 goto yybackup; \
659 else \
661 yyerror ("syntax error: cannot back up");\
662 YYERROR; \
664 while (0)
666 #define YYTERROR 1
667 #define YYERRCODE 256
669 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
670 are run). */
672 #ifndef YYLLOC_DEFAULT
673 # define YYLLOC_DEFAULT(Current, Rhs, N) \
674 Current.first_line = Rhs[1].first_line; \
675 Current.first_column = Rhs[1].first_column; \
676 Current.last_line = Rhs[N].last_line; \
677 Current.last_column = Rhs[N].last_column;
678 #endif
680 /* YYLEX -- calling `yylex' with the right arguments. */
682 #ifdef YYLEX_PARAM
683 # define YYLEX yylex (&yylval, YYLEX_PARAM)
684 #else
685 # define YYLEX yylex (&yylval)
686 #endif
688 /* Enable debugging if requested. */
689 #if YYDEBUG
691 # ifndef YYFPRINTF
692 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
693 # define YYFPRINTF fprintf
694 # endif
696 # define YYDPRINTF(Args) \
697 do { \
698 if (yydebug) \
699 YYFPRINTF Args; \
700 } while (0)
702 # define YYDSYMPRINT(Args) \
703 do { \
704 if (yydebug) \
705 yysymprint Args; \
706 } while (0)
708 # define YYDSYMPRINTF(Title, Token, Value, Location) \
709 do { \
710 if (yydebug) \
712 YYFPRINTF (stderr, "%s ", Title); \
713 yysymprint (stderr, \
714 Token, Value); \
715 YYFPRINTF (stderr, "\n"); \
717 } while (0)
719 /*------------------------------------------------------------------.
720 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
721 | TOP (cinluded). |
722 `------------------------------------------------------------------*/
724 #if defined (__STDC__) || defined (__cplusplus)
725 static void
726 yy_stack_print (short *bottom, short *top)
727 #else
728 static void
729 yy_stack_print (bottom, top)
730 short *bottom;
731 short *top;
732 #endif
734 YYFPRINTF (stderr, "Stack now");
735 for (/* Nothing. */; bottom <= top; ++bottom)
736 YYFPRINTF (stderr, " %d", *bottom);
737 YYFPRINTF (stderr, "\n");
740 # define YY_STACK_PRINT(Bottom, Top) \
741 do { \
742 if (yydebug) \
743 yy_stack_print ((Bottom), (Top)); \
744 } while (0)
747 /*------------------------------------------------.
748 | Report that the YYRULE is going to be reduced. |
749 `------------------------------------------------*/
751 #if defined (__STDC__) || defined (__cplusplus)
752 static void
753 yy_reduce_print (int yyrule)
754 #else
755 static void
756 yy_reduce_print (yyrule)
757 int yyrule;
758 #endif
760 int yyi;
761 unsigned int yylineno = yyrline[yyrule];
762 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
763 yyrule - 1, yylineno);
764 /* Print the symbols being reduced, and their result. */
765 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
766 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
767 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
770 # define YY_REDUCE_PRINT(Rule) \
771 do { \
772 if (yydebug) \
773 yy_reduce_print (Rule); \
774 } while (0)
776 /* Nonzero means print parse trace. It is left uninitialized so that
777 multiple parsers can coexist. */
778 int yydebug;
779 #else /* !YYDEBUG */
780 # define YYDPRINTF(Args)
781 # define YYDSYMPRINT(Args)
782 # define YYDSYMPRINTF(Title, Token, Value, Location)
783 # define YY_STACK_PRINT(Bottom, Top)
784 # define YY_REDUCE_PRINT(Rule)
785 #endif /* !YYDEBUG */
788 /* YYINITDEPTH -- initial size of the parser's stacks. */
789 #ifndef YYINITDEPTH
790 # define YYINITDEPTH 200
791 #endif
793 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
794 if the built-in stack extension method is used).
796 Do not make this value too large; the results are undefined if
797 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
798 evaluated with infinite-precision integer arithmetic. */
800 #if YYMAXDEPTH == 0
801 # undef YYMAXDEPTH
802 #endif
804 #ifndef YYMAXDEPTH
805 # define YYMAXDEPTH 10000
806 #endif
810 #if YYERROR_VERBOSE
812 # ifndef yystrlen
813 # if defined (__GLIBC__) && defined (_STRING_H)
814 # define yystrlen strlen
815 # else
816 /* Return the length of YYSTR. */
817 static YYSIZE_T
818 # if defined (__STDC__) || defined (__cplusplus)
819 yystrlen (const char *yystr)
820 # else
821 yystrlen (yystr)
822 const char *yystr;
823 # endif
825 register const char *yys = yystr;
827 while (*yys++ != '\0')
828 continue;
830 return yys - yystr - 1;
832 # endif
833 # endif
835 # ifndef yystpcpy
836 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
837 # define yystpcpy stpcpy
838 # else
839 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
840 YYDEST. */
841 static char *
842 # if defined (__STDC__) || defined (__cplusplus)
843 yystpcpy (char *yydest, const char *yysrc)
844 # else
845 yystpcpy (yydest, yysrc)
846 char *yydest;
847 const char *yysrc;
848 # endif
850 register char *yyd = yydest;
851 register const char *yys = yysrc;
853 while ((*yyd++ = *yys++) != '\0')
854 continue;
856 return yyd - 1;
858 # endif
859 # endif
861 #endif /* !YYERROR_VERBOSE */
865 #if YYDEBUG
866 /*--------------------------------.
867 | Print this symbol on YYOUTPUT. |
868 `--------------------------------*/
870 #if defined (__STDC__) || defined (__cplusplus)
871 static void
872 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
873 #else
874 static void
875 yysymprint (yyoutput, yytype, yyvaluep)
876 FILE *yyoutput;
877 int yytype;
878 YYSTYPE *yyvaluep;
879 #endif
881 /* Pacify ``unused variable'' warnings. */
882 (void) yyvaluep;
884 if (yytype < YYNTOKENS)
886 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
887 # ifdef YYPRINT
888 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
889 # endif
891 else
892 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
894 switch (yytype)
896 default:
897 break;
899 YYFPRINTF (yyoutput, ")");
902 #endif /* ! YYDEBUG */
903 /*-----------------------------------------------.
904 | Release the memory associated to this symbol. |
905 `-----------------------------------------------*/
907 #if defined (__STDC__) || defined (__cplusplus)
908 static void
909 yydestruct (int yytype, YYSTYPE *yyvaluep)
910 #else
911 static void
912 yydestruct (yytype, yyvaluep)
913 int yytype;
914 YYSTYPE *yyvaluep;
915 #endif
917 /* Pacify ``unused variable'' warnings. */
918 (void) yyvaluep;
920 switch (yytype)
923 default:
924 break;
929 /* Prevent warnings from -Wmissing-prototypes. */
931 #ifdef YYPARSE_PARAM
932 # if defined (__STDC__) || defined (__cplusplus)
933 int yyparse (void *YYPARSE_PARAM);
934 # else
935 int yyparse ();
936 # endif
937 #else /* ! YYPARSE_PARAM */
938 #if defined (__STDC__) || defined (__cplusplus)
939 int yyparse (void);
940 #else
941 int yyparse ();
942 #endif
943 #endif /* ! YYPARSE_PARAM */
950 /*----------.
951 | yyparse. |
952 `----------*/
954 #ifdef YYPARSE_PARAM
955 # if defined (__STDC__) || defined (__cplusplus)
956 int yyparse (void *YYPARSE_PARAM)
957 # else
958 int yyparse (YYPARSE_PARAM)
959 void *YYPARSE_PARAM;
960 # endif
961 #else /* ! YYPARSE_PARAM */
962 #if defined (__STDC__) || defined (__cplusplus)
964 yyparse (void)
965 #else
967 yyparse ()
969 #endif
970 #endif
972 /* The lookahead symbol. */
973 int yychar;
975 /* The semantic value of the lookahead symbol. */
976 YYSTYPE yylval;
978 /* Number of syntax errors so far. */
979 int yynerrs;
981 register int yystate;
982 register int yyn;
983 int yyresult;
984 /* Number of tokens to shift before error messages enabled. */
985 int yyerrstatus;
986 /* Lookahead token as an internal (translated) token number. */
987 int yytoken = 0;
989 /* Three stacks and their tools:
990 `yyss': related to states,
991 `yyvs': related to semantic values,
992 `yyls': related to locations.
994 Refer to the stacks thru separate pointers, to allow yyoverflow
995 to reallocate them elsewhere. */
997 /* The state stack. */
998 short yyssa[YYINITDEPTH];
999 short *yyss = yyssa;
1000 register short *yyssp;
1002 /* The semantic value stack. */
1003 YYSTYPE yyvsa[YYINITDEPTH];
1004 YYSTYPE *yyvs = yyvsa;
1005 register YYSTYPE *yyvsp;
1009 #define YYPOPSTACK (yyvsp--, yyssp--)
1011 YYSIZE_T yystacksize = YYINITDEPTH;
1013 /* The variables used to return semantic value and location from the
1014 action routines. */
1015 YYSTYPE yyval;
1018 /* When reducing, the number of symbols on the RHS of the reduced
1019 rule. */
1020 int yylen;
1022 YYDPRINTF ((stderr, "Starting parse\n"));
1024 yystate = 0;
1025 yyerrstatus = 0;
1026 yynerrs = 0;
1027 yychar = YYEMPTY; /* Cause a token to be read. */
1029 /* Initialize stack pointers.
1030 Waste one element of value and location stack
1031 so that they stay on the same level as the state stack.
1032 The wasted elements are never initialized. */
1034 yyssp = yyss;
1035 yyvsp = yyvs;
1037 goto yysetstate;
1039 /*------------------------------------------------------------.
1040 | yynewstate -- Push a new state, which is found in yystate. |
1041 `------------------------------------------------------------*/
1042 yynewstate:
1043 /* In all cases, when you get here, the value and location stacks
1044 have just been pushed. so pushing a state here evens the stacks.
1046 yyssp++;
1048 yysetstate:
1049 *yyssp = yystate;
1051 if (yyss + yystacksize - 1 <= yyssp)
1053 /* Get the current used size of the three stacks, in elements. */
1054 YYSIZE_T yysize = yyssp - yyss + 1;
1056 #ifdef yyoverflow
1058 /* Give user a chance to reallocate the stack. Use copies of
1059 these so that the &'s don't force the real ones into
1060 memory. */
1061 YYSTYPE *yyvs1 = yyvs;
1062 short *yyss1 = yyss;
1065 /* Each stack pointer address is followed by the size of the
1066 data in use in that stack, in bytes. This used to be a
1067 conditional around just the two extra args, but that might
1068 be undefined if yyoverflow is a macro. */
1069 yyoverflow ("parser stack overflow",
1070 &yyss1, yysize * sizeof (*yyssp),
1071 &yyvs1, yysize * sizeof (*yyvsp),
1073 &yystacksize);
1075 yyss = yyss1;
1076 yyvs = yyvs1;
1078 #else /* no yyoverflow */
1079 # ifndef YYSTACK_RELOCATE
1080 goto yyoverflowlab;
1081 # else
1082 /* Extend the stack our own way. */
1083 if (YYMAXDEPTH <= yystacksize)
1084 goto yyoverflowlab;
1085 yystacksize *= 2;
1086 if (YYMAXDEPTH < yystacksize)
1087 yystacksize = YYMAXDEPTH;
1090 short *yyss1 = yyss;
1091 union yyalloc *yyptr =
1092 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1093 if (! yyptr)
1094 goto yyoverflowlab;
1095 YYSTACK_RELOCATE (yyss);
1096 YYSTACK_RELOCATE (yyvs);
1098 # undef YYSTACK_RELOCATE
1099 if (yyss1 != yyssa)
1100 YYSTACK_FREE (yyss1);
1102 # endif
1103 #endif /* no yyoverflow */
1105 yyssp = yyss + yysize - 1;
1106 yyvsp = yyvs + yysize - 1;
1109 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1110 (unsigned long int) yystacksize));
1112 if (yyss + yystacksize - 1 <= yyssp)
1113 YYABORT;
1116 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1118 goto yybackup;
1120 /*-----------.
1121 | yybackup. |
1122 `-----------*/
1123 yybackup:
1125 /* Do appropriate processing given the current state. */
1126 /* Read a lookahead token if we need one and don't already have one. */
1127 /* yyresume: */
1129 /* First try to decide what to do without reference to lookahead token. */
1131 yyn = yypact[yystate];
1132 if (yyn == YYPACT_NINF)
1133 goto yydefault;
1135 /* Not known => get a lookahead token if don't already have one. */
1137 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1138 if (yychar == YYEMPTY)
1140 YYDPRINTF ((stderr, "Reading a token: "));
1141 yychar = YYLEX;
1144 if (yychar <= YYEOF)
1146 yychar = yytoken = YYEOF;
1147 YYDPRINTF ((stderr, "Now at end of input.\n"));
1149 else
1151 yytoken = YYTRANSLATE (yychar);
1152 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1155 /* If the proper action on seeing token YYTOKEN is to reduce or to
1156 detect an error, take that action. */
1157 yyn += yytoken;
1158 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1159 goto yydefault;
1160 yyn = yytable[yyn];
1161 if (yyn <= 0)
1163 if (yyn == 0 || yyn == YYTABLE_NINF)
1164 goto yyerrlab;
1165 yyn = -yyn;
1166 goto yyreduce;
1169 if (yyn == YYFINAL)
1170 YYACCEPT;
1172 /* Shift the lookahead token. */
1173 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1175 /* Discard the token being shifted unless it is eof. */
1176 if (yychar != YYEOF)
1177 yychar = YYEMPTY;
1179 *++yyvsp = yylval;
1182 /* Count tokens shifted since error; after three, turn off error
1183 status. */
1184 if (yyerrstatus)
1185 yyerrstatus--;
1187 yystate = yyn;
1188 goto yynewstate;
1191 /*-----------------------------------------------------------.
1192 | yydefault -- do the default action for the current state. |
1193 `-----------------------------------------------------------*/
1194 yydefault:
1195 yyn = yydefact[yystate];
1196 if (yyn == 0)
1197 goto yyerrlab;
1198 goto yyreduce;
1201 /*-----------------------------.
1202 | yyreduce -- Do a reduction. |
1203 `-----------------------------*/
1204 yyreduce:
1205 /* yyn is the number of a rule to reduce with. */
1206 yylen = yyr2[yyn];
1208 /* If YYLEN is nonzero, implement the default value of the action:
1209 `$$ = $1'.
1211 Otherwise, the following line sets YYVAL to garbage.
1212 This behavior is undocumented and Bison
1213 users should not rely upon it. Assigning to YYVAL
1214 unconditionally makes the parser a bit smaller, and it avoids a
1215 GCC warning that YYVAL may be used uninitialized. */
1216 yyval = yyvsp[1-yylen];
1219 YY_REDUCE_PRINT (yyn);
1220 switch (yyn)
1222 case 4:
1223 #line 195 "getdate.y"
1224 { PC.times_seen++; }
1225 break;
1227 case 5:
1228 #line 197 "getdate.y"
1229 { PC.local_zones_seen++; }
1230 break;
1232 case 6:
1233 #line 199 "getdate.y"
1234 { PC.zones_seen++; }
1235 break;
1237 case 7:
1238 #line 201 "getdate.y"
1239 { PC.dates_seen++; }
1240 break;
1242 case 8:
1243 #line 203 "getdate.y"
1244 { PC.days_seen++; }
1245 break;
1247 case 9:
1248 #line 205 "getdate.y"
1249 { PC.rels_seen++; }
1250 break;
1252 case 11:
1253 #line 211 "getdate.y"
1255 PC.hour = yyvsp[-1].textintval.value;
1256 PC.minutes = 0;
1257 PC.seconds = 0;
1258 PC.meridian = yyvsp[0].intval;
1260 break;
1262 case 12:
1263 #line 218 "getdate.y"
1265 PC.hour = yyvsp[-3].textintval.value;
1266 PC.minutes = yyvsp[-1].textintval.value;
1267 PC.seconds = 0;
1268 PC.meridian = yyvsp[0].intval;
1270 break;
1272 case 13:
1273 #line 225 "getdate.y"
1275 PC.hour = yyvsp[-3].textintval.value;
1276 PC.minutes = yyvsp[-1].textintval.value;
1277 PC.meridian = MER24;
1278 PC.zones_seen++;
1279 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1281 break;
1283 case 14:
1284 #line 233 "getdate.y"
1286 PC.hour = yyvsp[-5].textintval.value;
1287 PC.minutes = yyvsp[-3].textintval.value;
1288 PC.seconds = yyvsp[-1].textintval.value;
1289 PC.meridian = yyvsp[0].intval;
1291 break;
1293 case 15:
1294 #line 240 "getdate.y"
1296 PC.hour = yyvsp[-5].textintval.value;
1297 PC.minutes = yyvsp[-3].textintval.value;
1298 PC.seconds = yyvsp[-1].textintval.value;
1299 PC.meridian = MER24;
1300 PC.zones_seen++;
1301 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1303 break;
1305 case 16:
1306 #line 252 "getdate.y"
1307 { PC.local_isdst = yyvsp[0].intval; }
1308 break;
1310 case 17:
1311 #line 254 "getdate.y"
1312 { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1313 break;
1315 case 18:
1316 #line 259 "getdate.y"
1317 { PC.time_zone = yyvsp[0].intval; }
1318 break;
1320 case 19:
1321 #line 261 "getdate.y"
1322 { PC.time_zone = yyvsp[0].intval + 60; }
1323 break;
1325 case 20:
1326 #line 263 "getdate.y"
1327 { PC.time_zone = yyvsp[-1].intval + 60; }
1328 break;
1330 case 21:
1331 #line 268 "getdate.y"
1333 PC.day_ordinal = 1;
1334 PC.day_number = yyvsp[0].intval;
1336 break;
1338 case 22:
1339 #line 273 "getdate.y"
1341 PC.day_ordinal = 1;
1342 PC.day_number = yyvsp[-1].intval;
1344 break;
1346 case 23:
1347 #line 278 "getdate.y"
1349 PC.day_ordinal = yyvsp[-1].textintval.value;
1350 PC.day_number = yyvsp[0].intval;
1352 break;
1354 case 24:
1355 #line 286 "getdate.y"
1357 PC.month = yyvsp[-2].textintval.value;
1358 PC.day = yyvsp[0].textintval.value;
1360 break;
1362 case 25:
1363 #line 291 "getdate.y"
1365 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1366 otherwise as MM/DD/YY.
1367 The goal in recognizing YYYY/MM/DD is solely to support legacy
1368 machine-generated dates like those in an RCS log listing. If
1369 you want portability, use the ISO 8601 format. */
1370 if (4 <= yyvsp[-4].textintval.digits)
1372 PC.year = yyvsp[-4].textintval;
1373 PC.month = yyvsp[-2].textintval.value;
1374 PC.day = yyvsp[0].textintval.value;
1376 else
1378 PC.month = yyvsp[-4].textintval.value;
1379 PC.day = yyvsp[-2].textintval.value;
1380 PC.year = yyvsp[0].textintval;
1383 break;
1385 case 26:
1386 #line 311 "getdate.y"
1388 /* ISO 8601 format. YYYY-MM-DD. */
1389 PC.year = yyvsp[-2].textintval;
1390 PC.month = -yyvsp[-1].textintval.value;
1391 PC.day = -yyvsp[0].textintval.value;
1393 break;
1395 case 27:
1396 #line 318 "getdate.y"
1398 /* e.g. 17-JUN-1992. */
1399 PC.day = yyvsp[-2].textintval.value;
1400 PC.month = yyvsp[-1].intval;
1401 PC.year.value = -yyvsp[0].textintval.value;
1402 PC.year.digits = yyvsp[0].textintval.digits;
1404 break;
1406 case 28:
1407 #line 326 "getdate.y"
1409 PC.month = yyvsp[-1].intval;
1410 PC.day = yyvsp[0].textintval.value;
1412 break;
1414 case 29:
1415 #line 331 "getdate.y"
1417 PC.month = yyvsp[-3].intval;
1418 PC.day = yyvsp[-2].textintval.value;
1419 PC.year = yyvsp[0].textintval;
1421 break;
1423 case 30:
1424 #line 337 "getdate.y"
1426 PC.day = yyvsp[-1].textintval.value;
1427 PC.month = yyvsp[0].intval;
1429 break;
1431 case 31:
1432 #line 342 "getdate.y"
1434 PC.day = yyvsp[-2].textintval.value;
1435 PC.month = yyvsp[-1].intval;
1436 PC.year = yyvsp[0].textintval;
1438 break;
1440 case 32:
1441 #line 351 "getdate.y"
1443 PC.rel_seconds = -PC.rel_seconds;
1444 PC.rel_minutes = -PC.rel_minutes;
1445 PC.rel_hour = -PC.rel_hour;
1446 PC.rel_day = -PC.rel_day;
1447 PC.rel_month = -PC.rel_month;
1448 PC.rel_year = -PC.rel_year;
1450 break;
1452 case 34:
1453 #line 364 "getdate.y"
1454 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1455 break;
1457 case 35:
1458 #line 366 "getdate.y"
1459 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1460 break;
1462 case 36:
1463 #line 368 "getdate.y"
1464 { PC.rel_year += yyvsp[0].intval; }
1465 break;
1467 case 37:
1468 #line 370 "getdate.y"
1469 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1470 break;
1472 case 38:
1473 #line 372 "getdate.y"
1474 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1475 break;
1477 case 39:
1478 #line 374 "getdate.y"
1479 { PC.rel_month += yyvsp[0].intval; }
1480 break;
1482 case 40:
1483 #line 376 "getdate.y"
1484 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1485 break;
1487 case 41:
1488 #line 378 "getdate.y"
1489 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1490 break;
1492 case 42:
1493 #line 380 "getdate.y"
1494 { PC.rel_day += yyvsp[0].intval; }
1495 break;
1497 case 43:
1498 #line 382 "getdate.y"
1499 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1500 break;
1502 case 44:
1503 #line 384 "getdate.y"
1504 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1505 break;
1507 case 45:
1508 #line 386 "getdate.y"
1509 { PC.rel_hour += yyvsp[0].intval; }
1510 break;
1512 case 46:
1513 #line 388 "getdate.y"
1514 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1515 break;
1517 case 47:
1518 #line 390 "getdate.y"
1519 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1520 break;
1522 case 48:
1523 #line 392 "getdate.y"
1524 { PC.rel_minutes += yyvsp[0].intval; }
1525 break;
1527 case 49:
1528 #line 394 "getdate.y"
1529 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1530 break;
1532 case 50:
1533 #line 396 "getdate.y"
1534 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1535 break;
1537 case 51:
1538 #line 398 "getdate.y"
1539 { PC.rel_seconds += yyvsp[0].intval; }
1540 break;
1542 case 52:
1543 #line 403 "getdate.y"
1545 if (PC.dates_seen
1546 && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
1547 PC.year = yyvsp[0].textintval;
1548 else
1550 if (4 < yyvsp[0].textintval.digits)
1552 PC.dates_seen++;
1553 PC.day = yyvsp[0].textintval.value % 100;
1554 PC.month = (yyvsp[0].textintval.value / 100) % 100;
1555 PC.year.value = yyvsp[0].textintval.value / 10000;
1556 PC.year.digits = yyvsp[0].textintval.digits - 4;
1558 else
1560 PC.times_seen++;
1561 if (yyvsp[0].textintval.digits <= 2)
1563 PC.hour = yyvsp[0].textintval.value;
1564 PC.minutes = 0;
1566 else
1568 PC.hour = yyvsp[0].textintval.value / 100;
1569 PC.minutes = yyvsp[0].textintval.value % 100;
1571 PC.seconds = 0;
1572 PC.meridian = MER24;
1576 break;
1578 case 53:
1579 #line 439 "getdate.y"
1580 { yyval.intval = MER24; }
1581 break;
1583 case 54:
1584 #line 441 "getdate.y"
1585 { yyval.intval = yyvsp[0].intval; }
1586 break;
1591 /* Line 999 of yacc.c. */
1592 #line 1593 "getdate.c"
1594 yyvsp -= yylen;
1595 yyssp -= yylen;
1598 YY_STACK_PRINT (yyss, yyssp);
1600 *++yyvsp = yyval;
1603 /* Now `shift' the result of the reduction. Determine what state
1604 that goes to, based on the state we popped back to and the rule
1605 number reduced by. */
1607 yyn = yyr1[yyn];
1609 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1610 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1611 yystate = yytable[yystate];
1612 else
1613 yystate = yydefgoto[yyn - YYNTOKENS];
1615 goto yynewstate;
1618 /*------------------------------------.
1619 | yyerrlab -- here on detecting error |
1620 `------------------------------------*/
1621 yyerrlab:
1622 /* If not already recovering from an error, report this error. */
1623 if (!yyerrstatus)
1625 ++yynerrs;
1626 #if YYERROR_VERBOSE
1627 yyn = yypact[yystate];
1629 if (YYPACT_NINF < yyn && yyn < YYLAST)
1631 YYSIZE_T yysize = 0;
1632 int yytype = YYTRANSLATE (yychar);
1633 char *yymsg;
1634 int yyx, yycount;
1636 yycount = 0;
1637 /* Start YYX at -YYN if negative to avoid negative indexes in
1638 YYCHECK. */
1639 for (yyx = yyn < 0 ? -yyn : 0;
1640 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1641 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1642 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1643 yysize += yystrlen ("syntax error, unexpected ") + 1;
1644 yysize += yystrlen (yytname[yytype]);
1645 yymsg = (char *) YYSTACK_ALLOC (yysize);
1646 if (yymsg != 0)
1648 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1649 yyp = yystpcpy (yyp, yytname[yytype]);
1651 if (yycount < 5)
1653 yycount = 0;
1654 for (yyx = yyn < 0 ? -yyn : 0;
1655 yyx < (int) (sizeof (yytname) / sizeof (char *));
1656 yyx++)
1657 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1659 const char *yyq = ! yycount ? ", expecting " : " or ";
1660 yyp = yystpcpy (yyp, yyq);
1661 yyp = yystpcpy (yyp, yytname[yyx]);
1662 yycount++;
1665 yyerror (yymsg);
1666 YYSTACK_FREE (yymsg);
1668 else
1669 yyerror ("syntax error; also virtual memory exhausted");
1671 else
1672 #endif /* YYERROR_VERBOSE */
1673 yyerror ("syntax error");
1678 if (yyerrstatus == 3)
1680 /* If just tried and failed to reuse lookahead token after an
1681 error, discard it. */
1683 /* Return failure if at end of input. */
1684 if (yychar == YYEOF)
1686 /* Pop the error token. */
1687 YYPOPSTACK;
1688 /* Pop the rest of the stack. */
1689 while (yyss < yyssp)
1691 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1692 yydestruct (yystos[*yyssp], yyvsp);
1693 YYPOPSTACK;
1695 YYABORT;
1698 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1699 yydestruct (yytoken, &yylval);
1700 yychar = YYEMPTY;
1704 /* Else will try to reuse lookahead token after shifting the error
1705 token. */
1706 goto yyerrlab1;
1709 /*----------------------------------------------------.
1710 | yyerrlab1 -- error raised explicitly by an action. |
1711 `----------------------------------------------------*/
1712 yyerrlab1:
1713 yyerrstatus = 3; /* Each real token shifted decrements this. */
1715 for (;;)
1717 yyn = yypact[yystate];
1718 if (yyn != YYPACT_NINF)
1720 yyn += YYTERROR;
1721 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1723 yyn = yytable[yyn];
1724 if (0 < yyn)
1725 break;
1729 /* Pop the current state because it cannot handle the error token. */
1730 if (yyssp == yyss)
1731 YYABORT;
1733 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1734 yydestruct (yystos[yystate], yyvsp);
1735 yyvsp--;
1736 yystate = *--yyssp;
1738 YY_STACK_PRINT (yyss, yyssp);
1741 if (yyn == YYFINAL)
1742 YYACCEPT;
1744 YYDPRINTF ((stderr, "Shifting error token, "));
1746 *++yyvsp = yylval;
1749 yystate = yyn;
1750 goto yynewstate;
1753 /*-------------------------------------.
1754 | yyacceptlab -- YYACCEPT comes here. |
1755 `-------------------------------------*/
1756 yyacceptlab:
1757 yyresult = 0;
1758 goto yyreturn;
1760 /*-----------------------------------.
1761 | yyabortlab -- YYABORT comes here. |
1762 `-----------------------------------*/
1763 yyabortlab:
1764 yyresult = 1;
1765 goto yyreturn;
1767 #ifndef yyoverflow
1768 /*----------------------------------------------.
1769 | yyoverflowlab -- parser overflow comes here. |
1770 `----------------------------------------------*/
1771 yyoverflowlab:
1772 yyerror ("parser stack overflow");
1773 yyresult = 2;
1774 /* Fall through. */
1775 #endif
1777 yyreturn:
1778 #ifndef yyoverflow
1779 if (yyss != yyssa)
1780 YYSTACK_FREE (yyss);
1781 #endif
1782 return yyresult;
1786 #line 444 "getdate.y"
1789 /* Include this file down here because bison inserts code above which
1790 may define-away `const'. We want the prototype for get_date to have
1791 the same signature as the function definition. */
1792 #include "modules/getdate.h"
1794 #ifndef gmtime
1795 struct tm *gmtime ();
1796 #endif
1797 #ifndef localtime
1798 struct tm *localtime ();
1799 #endif
1800 #ifndef mktime
1801 time_t mktime ();
1802 #endif
1804 static table const meridian_table[] =
1806 { "AM", tMERIDIAN, MERam },
1807 { "A.M.", tMERIDIAN, MERam },
1808 { "PM", tMERIDIAN, MERpm },
1809 { "P.M.", tMERIDIAN, MERpm },
1810 { 0, 0, 0 }
1813 static table const dst_table[] =
1815 { "DST", tDST, 0 }
1818 static table const month_and_day_table[] =
1820 { "JANUARY", tMONTH, 1 },
1821 { "FEBRUARY", tMONTH, 2 },
1822 { "MARCH", tMONTH, 3 },
1823 { "APRIL", tMONTH, 4 },
1824 { "MAY", tMONTH, 5 },
1825 { "JUNE", tMONTH, 6 },
1826 { "JULY", tMONTH, 7 },
1827 { "AUGUST", tMONTH, 8 },
1828 { "SEPTEMBER",tMONTH, 9 },
1829 { "SEPT", tMONTH, 9 },
1830 { "OCTOBER", tMONTH, 10 },
1831 { "NOVEMBER", tMONTH, 11 },
1832 { "DECEMBER", tMONTH, 12 },
1833 { "SUNDAY", tDAY, 0 },
1834 { "MONDAY", tDAY, 1 },
1835 { "TUESDAY", tDAY, 2 },
1836 { "TUES", tDAY, 2 },
1837 { "WEDNESDAY",tDAY, 3 },
1838 { "WEDNES", tDAY, 3 },
1839 { "THURSDAY", tDAY, 4 },
1840 { "THUR", tDAY, 4 },
1841 { "THURS", tDAY, 4 },
1842 { "FRIDAY", tDAY, 5 },
1843 { "SATURDAY", tDAY, 6 },
1844 { 0, 0, 0 }
1847 static table const time_units_table[] =
1849 { "YEAR", tYEAR_UNIT, 1 },
1850 { "MONTH", tMONTH_UNIT, 1 },
1851 { "FORTNIGHT",tDAY_UNIT, 14 },
1852 { "WEEK", tDAY_UNIT, 7 },
1853 { "DAY", tDAY_UNIT, 1 },
1854 { "HOUR", tHOUR_UNIT, 1 },
1855 { "MINUTE", tMINUTE_UNIT, 1 },
1856 { "MIN", tMINUTE_UNIT, 1 },
1857 { "SECOND", tSEC_UNIT, 1 },
1858 { "SEC", tSEC_UNIT, 1 },
1859 { 0, 0, 0 }
1862 /* Assorted relative-time words. */
1863 static table const relative_time_table[] =
1865 { "TOMORROW", tMINUTE_UNIT, 24 * 60 },
1866 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
1867 { "TODAY", tMINUTE_UNIT, 0 },
1868 { "NOW", tMINUTE_UNIT, 0 },
1869 { "LAST", tUNUMBER, -1 },
1870 { "THIS", tUNUMBER, 0 },
1871 { "NEXT", tUNUMBER, 1 },
1872 { "FIRST", tUNUMBER, 1 },
1873 /*{ "SECOND", tUNUMBER, 2 }, */
1874 { "THIRD", tUNUMBER, 3 },
1875 { "FOURTH", tUNUMBER, 4 },
1876 { "FIFTH", tUNUMBER, 5 },
1877 { "SIXTH", tUNUMBER, 6 },
1878 { "SEVENTH", tUNUMBER, 7 },
1879 { "EIGHTH", tUNUMBER, 8 },
1880 { "NINTH", tUNUMBER, 9 },
1881 { "TENTH", tUNUMBER, 10 },
1882 { "ELEVENTH", tUNUMBER, 11 },
1883 { "TWELFTH", tUNUMBER, 12 },
1884 { "AGO", tAGO, 1 },
1885 { 0, 0, 0 }
1888 /* The time zone table. This table is necessarily incomplete, as time
1889 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1890 as Eastern time in Australia, not as US Eastern Standard Time.
1891 You cannot rely on getdate to handle arbitrary time zone
1892 abbreviations; use numeric abbreviations like `-0500' instead. */
1893 static table const time_zone_table[] =
1895 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1896 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1897 { "UTC", tZONE, HOUR ( 0) },
1898 { "WET", tZONE, HOUR ( 0) }, /* Western European */
1899 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
1900 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
1901 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
1902 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
1903 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1904 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1905 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1906 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
1907 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1908 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
1909 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1910 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
1911 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1912 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
1913 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1914 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
1915 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1916 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
1917 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1918 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
1919 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1920 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
1921 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1922 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1923 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
1924 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
1925 { "CET", tZONE, HOUR ( 1) }, /* Central European */
1926 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
1927 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
1928 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
1929 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1930 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1931 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
1932 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
1933 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
1934 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
1935 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
1936 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
1937 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
1938 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
1939 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
1940 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
1941 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
1942 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
1943 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
1944 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
1945 { 0, 0, 0 }
1948 /* Military time zone table. */
1949 static table const military_table[] =
1951 { "A", tZONE, -HOUR ( 1) },
1952 { "B", tZONE, -HOUR ( 2) },
1953 { "C", tZONE, -HOUR ( 3) },
1954 { "D", tZONE, -HOUR ( 4) },
1955 { "E", tZONE, -HOUR ( 5) },
1956 { "F", tZONE, -HOUR ( 6) },
1957 { "G", tZONE, -HOUR ( 7) },
1958 { "H", tZONE, -HOUR ( 8) },
1959 { "I", tZONE, -HOUR ( 9) },
1960 { "K", tZONE, -HOUR (10) },
1961 { "L", tZONE, -HOUR (11) },
1962 { "M", tZONE, -HOUR (12) },
1963 { "N", tZONE, HOUR ( 1) },
1964 { "O", tZONE, HOUR ( 2) },
1965 { "P", tZONE, HOUR ( 3) },
1966 { "Q", tZONE, HOUR ( 4) },
1967 { "R", tZONE, HOUR ( 5) },
1968 { "S", tZONE, HOUR ( 6) },
1969 { "T", tZONE, HOUR ( 7) },
1970 { "U", tZONE, HOUR ( 8) },
1971 { "V", tZONE, HOUR ( 9) },
1972 { "W", tZONE, HOUR (10) },
1973 { "X", tZONE, HOUR (11) },
1974 { "Y", tZONE, HOUR (12) },
1975 { "Z", tZONE, HOUR ( 0) },
1976 { 0, 0, 0 }
1981 static int
1982 to_hour (int hours, int meridian)
1984 switch (meridian)
1986 case MER24:
1987 return 0 <= hours && hours < 24 ? hours : -1;
1988 case MERam:
1989 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1990 case MERpm:
1991 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
1992 default:
1993 abort ();
1995 /* NOTREACHED */
1996 return 0;
1999 static int
2000 to_year (textint textyear)
2002 int year = textyear.value;
2004 if (year < 0)
2005 year = -year;
2007 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2008 years 69-99 map to 1969-1999. */
2009 if (textyear.digits == 2)
2010 year += year < 69 ? 2000 : 1900;
2012 return year;
2015 static table const *
2016 lookup_zone (parser_control const *pc, char const *name)
2018 table const *tp;
2020 /* Try local zone abbreviations first; they're more likely to be right. */
2021 for (tp = pc->local_time_zone_table; tp->name; tp++)
2022 if (strcmp (name, tp->name) == 0)
2023 return tp;
2025 for (tp = time_zone_table; tp->name; tp++)
2026 if (strcmp (name, tp->name) == 0)
2027 return tp;
2029 return 0;
2032 #if ! HAVE_TM_GMTOFF
2033 /* Yield the difference between *A and *B,
2034 measured in seconds, ignoring leap seconds.
2035 The body of this function is taken directly from the GNU C Library;
2036 see src/strftime.c. */
2037 static int
2038 tm_diff (struct tm const *a, struct tm const *b)
2040 /* Compute intervening leap days correctly even if year is negative.
2041 Take care to avoid int overflow in leap day calculations,
2042 but it's OK to assume that A and B are close to each other. */
2043 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2044 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2045 int a100 = a4 / 25 - (a4 % 25 < 0);
2046 int b100 = b4 / 25 - (b4 % 25 < 0);
2047 int a400 = a100 >> 2;
2048 int b400 = b100 >> 2;
2049 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2050 int years = a->tm_year - b->tm_year;
2051 int days = (365 * years + intervening_leap_days
2052 + (a->tm_yday - b->tm_yday));
2053 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2054 + (a->tm_min - b->tm_min))
2055 + (a->tm_sec - b->tm_sec));
2057 #endif /* ! HAVE_TM_GMTOFF */
2059 static table const *
2060 lookup_word (parser_control const *pc, char *word)
2062 char *p;
2063 char *q;
2064 size_t wordlen;
2065 table const *tp;
2066 int i;
2067 int abbrev;
2069 /* Make it uppercase. */
2070 for (p = word; *p; p++)
2071 if (ISLOWER ((unsigned char) *p))
2072 *p = toupper ((unsigned char) *p);
2074 for (tp = meridian_table; tp->name; tp++)
2075 if (strcmp (word, tp->name) == 0)
2076 return tp;
2078 /* See if we have an abbreviation for a month. */
2079 wordlen = strlen (word);
2080 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2082 for (tp = month_and_day_table; tp->name; tp++)
2083 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2084 return tp;
2086 if ((tp = lookup_zone (pc, word)))
2087 return tp;
2089 if (strcmp (word, dst_table[0].name) == 0)
2090 return dst_table;
2092 for (tp = time_units_table; tp->name; tp++)
2093 if (strcmp (word, tp->name) == 0)
2094 return tp;
2096 /* Strip off any plural and try the units table again. */
2097 if (word[wordlen - 1] == 'S')
2099 word[wordlen - 1] = '\0';
2100 for (tp = time_units_table; tp->name; tp++)
2101 if (strcmp (word, tp->name) == 0)
2102 return tp;
2103 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2106 for (tp = relative_time_table; tp->name; tp++)
2107 if (strcmp (word, tp->name) == 0)
2108 return tp;
2110 /* Military time zones. */
2111 if (wordlen == 1)
2112 for (tp = military_table; tp->name; tp++)
2113 if (word[0] == tp->name[0])
2114 return tp;
2116 /* Drop out any periods and try the time zone table again. */
2117 for (i = 0, p = q = word; (*p = *q); q++)
2118 if (*q == '.')
2119 i = 1;
2120 else
2121 p++;
2122 if (i && (tp = lookup_zone (pc, word)))
2123 return tp;
2125 return 0;
2128 static int
2129 yylex (YYSTYPE *lvalp, parser_control *pc)
2131 unsigned char c;
2132 int count;
2134 for (;;)
2136 while (c = *pc->input, ISSPACE (c))
2137 pc->input++;
2139 if (ISDIGIT (c) || c == '-' || c == '+')
2141 char const *p;
2142 int sign;
2143 int value;
2144 if (c == '-' || c == '+')
2146 sign = c == '-' ? -1 : 1;
2147 c = *++pc->input;
2148 if (! ISDIGIT (c))
2149 /* skip the '-' sign */
2150 continue;
2152 else
2153 sign = 0;
2154 p = pc->input;
2155 value = 0;
2158 value = 10 * value + c - '0';
2159 c = *++p;
2161 while (ISDIGIT (c));
2162 lvalp->textintval.value = sign < 0 ? -value : value;
2163 lvalp->textintval.digits = p - pc->input;
2164 pc->input = p;
2165 return sign ? tSNUMBER : tUNUMBER;
2168 if (ISALPHA (c))
2170 char buff[20];
2171 char *p = buff;
2172 table const *tp;
2176 if (p < buff + sizeof buff - 1)
2177 *p++ = c;
2178 c = *++pc->input;
2180 while (ISALPHA (c) || c == '.');
2182 *p = '\0';
2183 tp = lookup_word (pc, buff);
2184 if (! tp)
2185 return '?';
2186 lvalp->intval = tp->value;
2187 return tp->type;
2190 if (c != '(')
2191 return *pc->input++;
2192 count = 0;
2195 c = *pc->input++;
2196 if (c == '\0')
2197 return c;
2198 if (c == '(')
2199 count++;
2200 else if (c == ')')
2201 count--;
2203 while (count > 0);
2207 /* Do nothing if the parser reports an error. */
2208 static int
2209 yyerror (char *s ATTRIBUTE_UNUSED)
2211 return 0;
2214 /* Parse a date/time string P. Return the corresponding time_t value,
2215 or (time_t) -1 if there is an error. P can be an incomplete or
2216 relative time specification; if so, use *NOW as the basis for the
2217 returned time. */
2218 time_t
2219 get_date (const char *p, const time_t *now)
2221 time_t Start = now ? *now : time (0);
2222 struct tm *tmp = localtime (&Start);
2223 struct tm tm;
2224 struct tm tm0;
2225 parser_control pc;
2227 if (! tmp)
2228 return -1;
2230 pc.input = p;
2231 pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2232 pc.year.digits = 4;
2233 pc.month = tmp->tm_mon + 1;
2234 pc.day = tmp->tm_mday;
2235 pc.hour = tmp->tm_hour;
2236 pc.minutes = tmp->tm_min;
2237 pc.seconds = tmp->tm_sec;
2238 tm.tm_isdst = tmp->tm_isdst;
2240 pc.meridian = MER24;
2241 pc.rel_seconds = 0;
2242 pc.rel_minutes = 0;
2243 pc.rel_hour = 0;
2244 pc.rel_day = 0;
2245 pc.rel_month = 0;
2246 pc.rel_year = 0;
2247 pc.dates_seen = 0;
2248 pc.days_seen = 0;
2249 pc.rels_seen = 0;
2250 pc.times_seen = 0;
2251 pc.local_zones_seen = 0;
2252 pc.zones_seen = 0;
2254 #if HAVE_STRUCT_TM_TM_ZONE
2255 pc.local_time_zone_table[0].name = tmp->tm_zone;
2256 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2257 pc.local_time_zone_table[0].value = tmp->tm_isdst;
2258 pc.local_time_zone_table[1].name = 0;
2260 /* Probe the names used in the next three calendar quarters, looking
2261 for a tm_isdst different from the one we already have. */
2263 int quarter;
2264 for (quarter = 1; quarter <= 3; quarter++)
2266 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2267 struct tm *probe_tm = localtime (&probe);
2268 if (probe_tm && probe_tm->tm_zone
2269 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2272 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2273 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2274 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2275 pc.local_time_zone_table[2].name = 0;
2277 break;
2281 #else
2282 #if HAVE_TZNAME
2284 # ifndef tzname
2285 extern char *tzname[];
2286 # endif
2287 int i;
2288 for (i = 0; i < 2; i++)
2290 pc.local_time_zone_table[i].name = tzname[i];
2291 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2292 pc.local_time_zone_table[i].value = i;
2294 pc.local_time_zone_table[i].name = 0;
2296 #else
2297 pc.local_time_zone_table[0].name = 0;
2298 #endif
2299 #endif
2301 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2302 && ! strcmp (pc.local_time_zone_table[0].name,
2303 pc.local_time_zone_table[1].name))
2305 /* This locale uses the same abbrevation for standard and
2306 daylight times. So if we see that abbreviation, we don't
2307 know whether it's daylight time. */
2308 pc.local_time_zone_table[0].value = -1;
2309 pc.local_time_zone_table[1].name = 0;
2312 if (yyparse (&pc) != 0
2313 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2314 || 1 < (pc.local_zones_seen + pc.zones_seen)
2315 || (pc.local_zones_seen && 1 < pc.local_isdst))
2316 return -1;
2318 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2319 tm.tm_mon = pc.month - 1 + pc.rel_month;
2320 tm.tm_mday = pc.day + pc.rel_day;
2321 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2323 tm.tm_hour = to_hour (pc.hour, pc.meridian);
2324 if (tm.tm_hour < 0)
2325 return -1;
2326 tm.tm_min = pc.minutes;
2327 tm.tm_sec = pc.seconds;
2329 else
2331 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2334 /* Let mktime deduce tm_isdst if we have an absolute time stamp,
2335 or if the relative time stamp mentions days, months, or years. */
2336 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2337 | pc.rel_month | pc.rel_year)
2338 tm.tm_isdst = -1;
2340 /* But if the input explicitly specifies local time with or without
2341 DST, give mktime that information. */
2342 if (pc.local_zones_seen)
2343 tm.tm_isdst = pc.local_isdst;
2345 tm0 = tm;
2347 Start = mktime (&tm);
2349 if (Start == (time_t) -1)
2352 /* Guard against falsely reporting errors near the time_t boundaries
2353 when parsing times in other time zones. For example, if the min
2354 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2355 of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2356 we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2357 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2358 zone by 24 hours to compensate. This algorithm assumes that
2359 there is no DST transition within a day of the time_t boundaries. */
2360 if (pc.zones_seen)
2362 tm = tm0;
2363 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2365 tm.tm_mday++;
2366 pc.time_zone += 24 * 60;
2368 else
2370 tm.tm_mday--;
2371 pc.time_zone -= 24 * 60;
2373 Start = mktime (&tm);
2376 if (Start == (time_t) -1)
2377 return Start;
2380 if (pc.days_seen && ! pc.dates_seen)
2382 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2383 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2384 tm.tm_isdst = -1;
2385 Start = mktime (&tm);
2386 if (Start == (time_t) -1)
2387 return Start;
2390 if (pc.zones_seen)
2392 int delta = pc.time_zone * 60;
2393 #ifdef HAVE_TM_GMTOFF
2394 delta -= tm.tm_gmtoff;
2395 #else
2396 struct tm *gmt = gmtime (&Start);
2397 if (! gmt)
2398 return -1;
2399 delta -= tm_diff (&tm, gmt);
2400 #endif
2401 if ((Start < Start - delta) != (delta < 0))
2402 return -1; /* time_t overflow */
2403 Start -= delta;
2406 /* Add relative hours, minutes, and seconds. Ignore leap seconds;
2407 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2408 leap second. Typically this is not what the user wants, but it's
2409 too hard to do it the other way, because the time zone indicator
2410 must be applied before relative times, and if mktime is applied
2411 again the time zone will be lost. */
2413 time_t t0 = Start;
2414 long d1 = 60 * 60 * (long) pc.rel_hour;
2415 time_t t1 = t0 + d1;
2416 long d2 = 60 * (long) pc.rel_minutes;
2417 time_t t2 = t1 + d2;
2418 int d3 = pc.rel_seconds;
2419 time_t t3 = t2 + d3;
2420 if ((d1 / (60 * 60) ^ pc.rel_hour)
2421 | (d2 / 60 ^ pc.rel_minutes)
2422 | ((t0 + d1 < t0) ^ (d1 < 0))
2423 | ((t1 + d2 < t1) ^ (d2 < 0))
2424 | ((t2 + d3 < t2) ^ (d3 < 0)))
2425 return -1;
2426 Start = t3;
2429 return Start;
2432 #if TEST
2434 #include <stdio.h>
2437 main (int ac, char **av)
2439 char buff[BUFSIZ];
2440 time_t d;
2442 printf ("Enter date, or blank line to exit.\n\t> ");
2443 fflush (stdout);
2445 buff[BUFSIZ - 1] = 0;
2446 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2448 d = get_date (buff, 0);
2449 if (d == (time_t) -1)
2450 printf ("Bad format - couldn't convert.\n");
2451 else
2452 printf ("%s", ctime (&d));
2453 printf ("\t> ");
2454 fflush (stdout);
2456 return 0;
2458 #endif /* defined TEST */