source: branches/samba-3.5.x/source3/modules/getdate.c@ 836

Last change on this file since 836 was 414, checked in by Herwig Bauernfeind, 15 years ago

Samba 3.5.0: Initial import

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