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