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@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@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
126
127 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
128 the right thing about local DST. Also modified by Paul Eggert
129 <eggert@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
yy_stack_print(short * bottom,short * top)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
yy_reduce_print(int yyrule)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
890 #if YYERROR_VERBOSE
891
892 # ifndef yystrlen
893 # if defined (__GLIBC__) && defined (_STRING_H)
894 # define yystrlen strlen
895 # else
896 /* Return the length of YYSTR. */
897 static YYSIZE_T
898 # if defined (__STDC__) || defined (__cplusplus)
yystrlen(const char * yystr)899 yystrlen (const char *yystr)
900 # else
901 yystrlen (yystr)
902 const char *yystr;
903 # endif
904 {
905 register const char *yys = yystr;
906
907 while (*yys++ != '\0')
908 continue;
909
910 return yys - yystr - 1;
911 }
912 # endif
913 # endif
914
915 # ifndef yystpcpy
916 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
917 # define yystpcpy stpcpy
918 # else
919 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
920 YYDEST. */
921 static char *
922 # if defined (__STDC__) || defined (__cplusplus)
yystpcpy(char * yydest,const char * yysrc)923 yystpcpy (char *yydest, const char *yysrc)
924 # else
925 yystpcpy (yydest, yysrc)
926 char *yydest;
927 const char *yysrc;
928 # endif
929 {
930 register char *yyd = yydest;
931 register const char *yys = yysrc;
932
933 while ((*yyd++ = *yys++) != '\0')
934 continue;
935
936 return yyd - 1;
937 }
938 # endif
939 # endif
940
941 #endif /* !YYERROR_VERBOSE */
942
943
944
945 #if YYDEBUG
946 /*--------------------------------.
947 | Print this symbol on YYOUTPUT. |
948 `--------------------------------*/
949
950 #if defined (__STDC__) || defined (__cplusplus)
951 static void
yysymprint(FILE * yyoutput,int yytype,YYSTYPE * yyvaluep)952 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
953 #else
954 static void
955 yysymprint (yyoutput, yytype, yyvaluep)
956 FILE *yyoutput;
957 int yytype;
958 YYSTYPE *yyvaluep;
959 #endif
960 {
961 /* Pacify ``unused variable'' warnings. */
962 (void) yyvaluep;
963
964 if (yytype < YYNTOKENS)
965 {
966 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
967 # ifdef YYPRINT
968 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
969 # endif
970 }
971 else
972 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
973
974 switch (yytype)
975 {
976 default:
977 break;
978 }
979 YYFPRINTF (yyoutput, ")");
980 }
981
982 #endif /* ! YYDEBUG */
983 /*-----------------------------------------------.
984 | Release the memory associated to this symbol. |
985 `-----------------------------------------------*/
986
987 #if defined (__STDC__) || defined (__cplusplus)
988 static void
yydestruct(int yytype,YYSTYPE * yyvaluep)989 yydestruct (int yytype, YYSTYPE *yyvaluep)
990 #else
991 static void
992 yydestruct (yytype, yyvaluep)
993 int yytype;
994 YYSTYPE *yyvaluep;
995 #endif
996 {
997 /* Pacify ``unused variable'' warnings. */
998 (void) yyvaluep;
999
1000 switch (yytype)
1001 {
1002
1003 default:
1004 break;
1005 }
1006 }
1007
1008
1009 /* Prevent warnings from -Wmissing-prototypes. */
1010
1011 #ifdef YYPARSE_PARAM
1012 # if defined (__STDC__) || defined (__cplusplus)
1013 int yyparse (void *YYPARSE_PARAM);
1014 # else
1015 int yyparse ();
1016 # endif
1017 #else /* ! YYPARSE_PARAM */
1018 #if defined (__STDC__) || defined (__cplusplus)
1019 int yyparse ( parser_control *pc );
1020 #else
1021 int yyparse ();
1022 #endif
1023 #endif /* ! YYPARSE_PARAM */
1024
1025
1026
1027
1028
1029
1030 /*----------.
1031 | yyparse. |
1032 `----------*/
1033
1034 #ifdef YYPARSE_PARAM
1035 # if defined (__STDC__) || defined (__cplusplus)
yyparse(void * YYPARSE_PARAM)1036 int yyparse (void *YYPARSE_PARAM)
1037 # else
1038 int yyparse (YYPARSE_PARAM)
1039 void *YYPARSE_PARAM;
1040 # endif
1041 #else /* ! YYPARSE_PARAM */
1042 #if defined (__STDC__) || defined (__cplusplus)
1043 int
1044 yyparse ( parser_control *pc )
1045 #else
1046 int
1047 yyparse (pc)
1048 parser_control *pc ;
1049 #endif
1050 #endif
1051 {
1052 /* The lookahead symbol. */
1053 int yychar;
1054
1055 /* The semantic value of the lookahead symbol. */
1056 YYSTYPE yylval;
1057
1058 /* Number of syntax errors so far. */
1059 int yynerrs;
1060
1061 register int yystate;
1062 register int yyn;
1063 int yyresult;
1064 /* Number of tokens to shift before error messages enabled. */
1065 int yyerrstatus;
1066 /* Lookahead token as an internal (translated) token number. */
1067 int yytoken = 0;
1068
1069 /* Three stacks and their tools:
1070 `yyss': related to states,
1071 `yyvs': related to semantic values,
1072 `yyls': related to locations.
1073
1074 Refer to the stacks thru separate pointers, to allow yyoverflow
1075 to reallocate them elsewhere. */
1076
1077 /* The state stack. */
1078 short yyssa[YYINITDEPTH];
1079 short *yyss = yyssa;
1080 register short *yyssp;
1081
1082 /* The semantic value stack. */
1083 YYSTYPE yyvsa[YYINITDEPTH];
1084 YYSTYPE *yyvs = yyvsa;
1085 register YYSTYPE *yyvsp;
1086
1087
1088
1089 #define YYPOPSTACK (yyvsp--, yyssp--)
1090
1091 YYSIZE_T yystacksize = YYINITDEPTH;
1092
1093 /* The variables used to return semantic value and location from the
1094 action routines. */
1095 YYSTYPE yyval;
1096
1097
1098 /* When reducing, the number of symbols on the RHS of the reduced
1099 rule. */
1100 int yylen;
1101
1102 YYDPRINTF ((stderr, "Starting parse\n"));
1103
1104 yystate = 0;
1105 yyerrstatus = 0;
1106 yynerrs = 0;
1107 yychar = YYEMPTY; /* Cause a token to be read. */
1108
1109 /* Initialize stack pointers.
1110 Waste one element of value and location stack
1111 so that they stay on the same level as the state stack.
1112 The wasted elements are never initialized. */
1113
1114 yyssp = yyss;
1115 yyvsp = yyvs;
1116
1117 goto yysetstate;
1118
1119 /*------------------------------------------------------------.
1120 | yynewstate -- Push a new state, which is found in yystate. |
1121 `------------------------------------------------------------*/
1122 yynewstate:
1123 /* In all cases, when you get here, the value and location stacks
1124 have just been pushed. so pushing a state here evens the stacks.
1125 */
1126 yyssp++;
1127
1128 yysetstate:
1129 *yyssp = yystate;
1130
1131 if (yyss + yystacksize - 1 <= yyssp)
1132 {
1133 /* Get the current used size of the three stacks, in elements. */
1134 YYSIZE_T yysize = yyssp - yyss + 1;
1135
1136 #ifdef yyoverflow
1137 {
1138 /* Give user a chance to reallocate the stack. Use copies of
1139 these so that the &'s don't force the real ones into
1140 memory. */
1141 YYSTYPE *yyvs1 = yyvs;
1142 short *yyss1 = yyss;
1143
1144
1145 /* Each stack pointer address is followed by the size of the
1146 data in use in that stack, in bytes. This used to be a
1147 conditional around just the two extra args, but that might
1148 be undefined if yyoverflow is a macro. */
1149 yyoverflow ("parser stack overflow",
1150 &yyss1, yysize * sizeof (*yyssp),
1151 &yyvs1, yysize * sizeof (*yyvsp),
1152
1153 &yystacksize);
1154
1155 yyss = yyss1;
1156 yyvs = yyvs1;
1157 }
1158 #else /* no yyoverflow */
1159 # ifndef YYSTACK_RELOCATE
1160 goto yyoverflowlab;
1161 # else
1162 /* Extend the stack our own way. */
1163 if (YYMAXDEPTH <= yystacksize)
1164 goto yyoverflowlab;
1165 yystacksize *= 2;
1166 if (YYMAXDEPTH < yystacksize)
1167 yystacksize = YYMAXDEPTH;
1168
1169 {
1170 short *yyss1 = yyss;
1171 union yyalloc *yyptr =
1172 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1173 if (! yyptr)
1174 goto yyoverflowlab;
1175 YYSTACK_RELOCATE (yyss);
1176 YYSTACK_RELOCATE (yyvs);
1177
1178 # undef YYSTACK_RELOCATE
1179 if (yyss1 != yyssa)
1180 YYSTACK_FREE (yyss1);
1181 }
1182 # endif
1183 #endif /* no yyoverflow */
1184
1185 yyssp = yyss + yysize - 1;
1186 yyvsp = yyvs + yysize - 1;
1187
1188
1189 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1190 (unsigned long int) yystacksize));
1191
1192 if (yyss + yystacksize - 1 <= yyssp)
1193 YYABORT;
1194 }
1195
1196 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1197
1198 goto yybackup;
1199
1200 /*-----------.
1201 | yybackup. |
1202 `-----------*/
1203 yybackup:
1204
1205 /* Do appropriate processing given the current state. */
1206 /* Read a lookahead token if we need one and don't already have one. */
1207 /* yyresume: */
1208
1209 /* First try to decide what to do without reference to lookahead token. */
1210
1211 yyn = yypact[yystate];
1212 if (yyn == YYPACT_NINF)
1213 goto yydefault;
1214
1215 /* Not known => get a lookahead token if don't already have one. */
1216
1217 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1218 if (yychar == YYEMPTY)
1219 {
1220 YYDPRINTF ((stderr, "Reading a token: "));
1221 yychar = YYLEX;
1222 }
1223
1224 if (yychar <= YYEOF)
1225 {
1226 yychar = yytoken = YYEOF;
1227 YYDPRINTF ((stderr, "Now at end of input.\n"));
1228 }
1229 else
1230 {
1231 yytoken = YYTRANSLATE (yychar);
1232 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1233 }
1234
1235 /* If the proper action on seeing token YYTOKEN is to reduce or to
1236 detect an error, take that action. */
1237 yyn += yytoken;
1238 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1239 goto yydefault;
1240 yyn = yytable[yyn];
1241 if (yyn <= 0)
1242 {
1243 if (yyn == 0 || yyn == YYTABLE_NINF)
1244 goto yyerrlab;
1245 yyn = -yyn;
1246 goto yyreduce;
1247 }
1248
1249 if (yyn == YYFINAL)
1250 YYACCEPT;
1251
1252 /* Shift the lookahead token. */
1253 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1254
1255 /* Discard the token being shifted unless it is eof. */
1256 if (yychar != YYEOF)
1257 yychar = YYEMPTY;
1258
1259 *++yyvsp = yylval;
1260
1261
1262 /* Count tokens shifted since error; after three, turn off error
1263 status. */
1264 if (yyerrstatus)
1265 yyerrstatus--;
1266
1267 yystate = yyn;
1268 goto yynewstate;
1269
1270
1271 /*-----------------------------------------------------------.
1272 | yydefault -- do the default action for the current state. |
1273 `-----------------------------------------------------------*/
1274 yydefault:
1275 yyn = yydefact[yystate];
1276 if (yyn == 0)
1277 goto yyerrlab;
1278 goto yyreduce;
1279
1280
1281 /*-----------------------------.
1282 | yyreduce -- Do a reduction. |
1283 `-----------------------------*/
1284 yyreduce:
1285 /* yyn is the number of a rule to reduce with. */
1286 yylen = yyr2[yyn];
1287
1288 /* If YYLEN is nonzero, implement the default value of the action:
1289 `$$ = $1'.
1290
1291 Otherwise, the following line sets YYVAL to garbage.
1292 This behavior is undocumented and Bison
1293 users should not rely upon it. Assigning to YYVAL
1294 unconditionally makes the parser a bit smaller, and it avoids a
1295 GCC warning that YYVAL may be used uninitialized. */
1296 yyval = yyvsp[1-yylen];
1297
1298
1299 YY_REDUCE_PRINT (yyn);
1300 switch (yyn)
1301 {
1302 case 4:
1303 #line 236 "getdate.y"
1304 {
1305 pc->seconds = yyvsp[0].timespec;
1306 pc->timespec_seen = true;
1307 }
1308 break;
1309
1310 case 7:
1311 #line 249 "getdate.y"
1312 { pc->times_seen++; }
1313 break;
1314
1315 case 8:
1316 #line 251 "getdate.y"
1317 { pc->local_zones_seen++; }
1318 break;
1319
1320 case 9:
1321 #line 253 "getdate.y"
1322 { pc->zones_seen++; }
1323 break;
1324
1325 case 10:
1326 #line 255 "getdate.y"
1327 { pc->dates_seen++; }
1328 break;
1329
1330 case 11:
1331 #line 257 "getdate.y"
1332 { pc->days_seen++; }
1333 break;
1334
1335 case 12:
1336 #line 259 "getdate.y"
1337 { pc->rels_seen = true; }
1338 break;
1339
1340 case 14:
1341 #line 265 "getdate.y"
1342 {
1343 pc->hour = yyvsp[-1].textintval.value;
1344 pc->minutes = 0;
1345 pc->seconds.tv_sec = 0;
1346 pc->seconds.tv_nsec = 0;
1347 pc->meridian = yyvsp[0].intval;
1348 }
1349 break;
1350
1351 case 15:
1352 #line 273 "getdate.y"
1353 {
1354 pc->hour = yyvsp[-3].textintval.value;
1355 pc->minutes = yyvsp[-1].textintval.value;
1356 pc->seconds.tv_sec = 0;
1357 pc->seconds.tv_nsec = 0;
1358 pc->meridian = yyvsp[0].intval;
1359 }
1360 break;
1361
1362 case 16:
1363 #line 281 "getdate.y"
1364 {
1365 pc->hour = yyvsp[-4].textintval.value;
1366 pc->minutes = yyvsp[-2].textintval.value;
1367 pc->seconds.tv_sec = 0;
1368 pc->seconds.tv_nsec = 0;
1369 pc->meridian = MER24;
1370 pc->zones_seen++;
1371 pc->time_zone = time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval);
1372 }
1373 break;
1374
1375 case 17:
1376 #line 291 "getdate.y"
1377 {
1378 pc->hour = yyvsp[-5].textintval.value;
1379 pc->minutes = yyvsp[-3].textintval.value;
1380 pc->seconds = yyvsp[-1].timespec;
1381 pc->meridian = yyvsp[0].intval;
1382 }
1383 break;
1384
1385 case 18:
1386 #line 298 "getdate.y"
1387 {
1388 pc->hour = yyvsp[-6].textintval.value;
1389 pc->minutes = yyvsp[-4].textintval.value;
1390 pc->seconds = yyvsp[-2].timespec;
1391 pc->meridian = MER24;
1392 pc->zones_seen++;
1393 pc->time_zone = time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval);
1394 }
1395 break;
1396
1397 case 19:
1398 #line 310 "getdate.y"
1399 {
1400 pc->local_isdst = yyvsp[0].intval;
1401 pc->dsts_seen += (0 < yyvsp[0].intval);
1402 }
1403 break;
1404
1405 case 20:
1406 #line 315 "getdate.y"
1407 {
1408 pc->local_isdst = 1;
1409 pc->dsts_seen += (0 < yyvsp[-1].intval) + 1;
1410 }
1411 break;
1412
1413 case 21:
1414 #line 323 "getdate.y"
1415 { pc->time_zone = yyvsp[0].intval; }
1416 break;
1417
1418 case 22:
1419 #line 325 "getdate.y"
1420 { pc->time_zone = yyvsp[-1].intval; pc->rels_seen = true; }
1421 break;
1422
1423 case 23:
1424 #line 327 "getdate.y"
1425 { pc->time_zone = yyvsp[-2].intval + time_zone_hhmm (yyvsp[-1].textintval, yyvsp[0].intval); }
1426 break;
1427
1428 case 24:
1429 #line 329 "getdate.y"
1430 { pc->time_zone = yyvsp[0].intval + 60; }
1431 break;
1432
1433 case 25:
1434 #line 331 "getdate.y"
1435 { pc->time_zone = yyvsp[-1].intval + 60; }
1436 break;
1437
1438 case 26:
1439 #line 336 "getdate.y"
1440 {
1441 pc->day_ordinal = 1;
1442 pc->day_number = yyvsp[0].intval;
1443 }
1444 break;
1445
1446 case 27:
1447 #line 341 "getdate.y"
1448 {
1449 pc->day_ordinal = 1;
1450 pc->day_number = yyvsp[-1].intval;
1451 }
1452 break;
1453
1454 case 28:
1455 #line 346 "getdate.y"
1456 {
1457 pc->day_ordinal = yyvsp[-1].intval;
1458 pc->day_number = yyvsp[0].intval;
1459 }
1460 break;
1461
1462 case 29:
1463 #line 351 "getdate.y"
1464 {
1465 pc->day_ordinal = yyvsp[-1].textintval.value;
1466 pc->day_number = yyvsp[0].intval;
1467 }
1468 break;
1469
1470 case 30:
1471 #line 359 "getdate.y"
1472 {
1473 pc->month = yyvsp[-2].textintval.value;
1474 pc->day = yyvsp[0].textintval.value;
1475 }
1476 break;
1477
1478 case 31:
1479 #line 364 "getdate.y"
1480 {
1481 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1482 otherwise as MM/DD/YY.
1483 The goal in recognizing YYYY/MM/DD is solely to support legacy
1484 machine-generated dates like those in an RCS log listing. If
1485 you want portability, use the ISO 8601 format. */
1486 if (4 <= yyvsp[-4].textintval.digits)
1487 {
1488 pc->year = yyvsp[-4].textintval;
1489 pc->month = yyvsp[-2].textintval.value;
1490 pc->day = yyvsp[0].textintval.value;
1491 }
1492 else
1493 {
1494 pc->month = yyvsp[-4].textintval.value;
1495 pc->day = yyvsp[-2].textintval.value;
1496 pc->year = yyvsp[0].textintval;
1497 }
1498 }
1499 break;
1500
1501 case 32:
1502 #line 384 "getdate.y"
1503 {
1504 /* ISO 8601 format. YYYY-MM-DD. */
1505 pc->year = yyvsp[-2].textintval;
1506 pc->month = -yyvsp[-1].textintval.value;
1507 pc->day = -yyvsp[0].textintval.value;
1508 }
1509 break;
1510
1511 case 33:
1512 #line 391 "getdate.y"
1513 {
1514 /* e.g. 17-JUN-1992. */
1515 pc->day = yyvsp[-2].textintval.value;
1516 pc->month = yyvsp[-1].intval;
1517 pc->year.value = -yyvsp[0].textintval.value;
1518 pc->year.digits = yyvsp[0].textintval.digits;
1519 }
1520 break;
1521
1522 case 34:
1523 #line 399 "getdate.y"
1524 {
1525 /* e.g. JUN-17-1992. */
1526 pc->month = yyvsp[-2].intval;
1527 pc->day = -yyvsp[-1].textintval.value;
1528 pc->year.value = -yyvsp[0].textintval.value;
1529 pc->year.digits = yyvsp[0].textintval.digits;
1530 }
1531 break;
1532
1533 case 35:
1534 #line 407 "getdate.y"
1535 {
1536 pc->month = yyvsp[-1].intval;
1537 pc->day = yyvsp[0].textintval.value;
1538 }
1539 break;
1540
1541 case 36:
1542 #line 412 "getdate.y"
1543 {
1544 pc->month = yyvsp[-3].intval;
1545 pc->day = yyvsp[-2].textintval.value;
1546 pc->year = yyvsp[0].textintval;
1547 }
1548 break;
1549
1550 case 37:
1551 #line 418 "getdate.y"
1552 {
1553 pc->day = yyvsp[-1].textintval.value;
1554 pc->month = yyvsp[0].intval;
1555 }
1556 break;
1557
1558 case 38:
1559 #line 423 "getdate.y"
1560 {
1561 pc->day = yyvsp[-2].textintval.value;
1562 pc->month = yyvsp[-1].intval;
1563 pc->year = yyvsp[0].textintval;
1564 }
1565 break;
1566
1567 case 39:
1568 #line 432 "getdate.y"
1569 {
1570 pc->rel_ns = -pc->rel_ns;
1571 pc->rel_seconds = -pc->rel_seconds;
1572 pc->rel_minutes = -pc->rel_minutes;
1573 pc->rel_hour = -pc->rel_hour;
1574 pc->rel_day = -pc->rel_day;
1575 pc->rel_month = -pc->rel_month;
1576 pc->rel_year = -pc->rel_year;
1577 }
1578 break;
1579
1580 case 41:
1581 #line 446 "getdate.y"
1582 { pc->rel_year += yyvsp[-1].intval * yyvsp[0].intval; }
1583 break;
1584
1585 case 42:
1586 #line 448 "getdate.y"
1587 { pc->rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1588 break;
1589
1590 case 43:
1591 #line 450 "getdate.y"
1592 { pc->rel_year += yyvsp[0].intval; }
1593 break;
1594
1595 case 44:
1596 #line 452 "getdate.y"
1597 { pc->rel_month += yyvsp[-1].intval * yyvsp[0].intval; }
1598 break;
1599
1600 case 45:
1601 #line 454 "getdate.y"
1602 { pc->rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1603 break;
1604
1605 case 46:
1606 #line 456 "getdate.y"
1607 { pc->rel_month += yyvsp[0].intval; }
1608 break;
1609
1610 case 47:
1611 #line 458 "getdate.y"
1612 { pc->rel_day += yyvsp[-1].intval * yyvsp[0].intval; }
1613 break;
1614
1615 case 48:
1616 #line 460 "getdate.y"
1617 { pc->rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1618 break;
1619
1620 case 49:
1621 #line 462 "getdate.y"
1622 { pc->rel_day += yyvsp[0].intval; }
1623 break;
1624
1625 case 50:
1626 #line 464 "getdate.y"
1627 { pc->rel_hour += yyvsp[-1].intval * yyvsp[0].intval; }
1628 break;
1629
1630 case 51:
1631 #line 466 "getdate.y"
1632 { pc->rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1633 break;
1634
1635 case 52:
1636 #line 468 "getdate.y"
1637 { pc->rel_hour += yyvsp[0].intval; }
1638 break;
1639
1640 case 53:
1641 #line 470 "getdate.y"
1642 { pc->rel_minutes += yyvsp[-1].intval * yyvsp[0].intval; }
1643 break;
1644
1645 case 54:
1646 #line 472 "getdate.y"
1647 { pc->rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1648 break;
1649
1650 case 55:
1651 #line 474 "getdate.y"
1652 { pc->rel_minutes += yyvsp[0].intval; }
1653 break;
1654
1655 case 56:
1656 #line 476 "getdate.y"
1657 { pc->rel_seconds += yyvsp[-1].intval * yyvsp[0].intval; }
1658 break;
1659
1660 case 57:
1661 #line 478 "getdate.y"
1662 { pc->rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1663 break;
1664
1665 case 58:
1666 #line 480 "getdate.y"
1667 { pc->rel_seconds += yyvsp[-1].timespec.tv_sec * yyvsp[0].intval; pc->rel_ns += yyvsp[-1].timespec.tv_nsec * yyvsp[0].intval; }
1668 break;
1669
1670 case 59:
1671 #line 482 "getdate.y"
1672 { pc->rel_seconds += yyvsp[-1].timespec.tv_sec * yyvsp[0].intval; pc->rel_ns += yyvsp[-1].timespec.tv_nsec * yyvsp[0].intval; }
1673 break;
1674
1675 case 60:
1676 #line 484 "getdate.y"
1677 { pc->rel_seconds += yyvsp[0].intval; }
1678 break;
1679
1680 case 62:
1681 #line 490 "getdate.y"
1682 { pc->rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1683 break;
1684
1685 case 63:
1686 #line 492 "getdate.y"
1687 { pc->rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1688 break;
1689
1690 case 64:
1691 #line 494 "getdate.y"
1692 { pc->rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1693 break;
1694
1695 case 65:
1696 #line 496 "getdate.y"
1697 { pc->rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1698 break;
1699
1700 case 66:
1701 #line 498 "getdate.y"
1702 { pc->rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1703 break;
1704
1705 case 67:
1706 #line 500 "getdate.y"
1707 { pc->rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1708 break;
1709
1710 case 71:
1711 #line 508 "getdate.y"
1712 { yyval.timespec.tv_sec = yyvsp[0].textintval.value; yyval.timespec.tv_nsec = 0; }
1713 break;
1714
1715 case 73:
1716 #line 514 "getdate.y"
1717 { yyval.timespec.tv_sec = yyvsp[0].textintval.value; yyval.timespec.tv_nsec = 0; }
1718 break;
1719
1720 case 74:
1721 #line 519 "getdate.y"
1722 {
1723 if (pc->dates_seen && ! pc->year.digits
1724 && ! pc->rels_seen && (pc->times_seen || 2 < yyvsp[0].textintval.digits))
1725 pc->year = yyvsp[0].textintval;
1726 else
1727 {
1728 if (4 < yyvsp[0].textintval.digits)
1729 {
1730 pc->dates_seen++;
1731 pc->day = yyvsp[0].textintval.value % 100;
1732 pc->month = (yyvsp[0].textintval.value / 100) % 100;
1733 pc->year.value = yyvsp[0].textintval.value / 10000;
1734 pc->year.digits = yyvsp[0].textintval.digits - 4;
1735 }
1736 else
1737 {
1738 pc->times_seen++;
1739 if (yyvsp[0].textintval.digits <= 2)
1740 {
1741 pc->hour = yyvsp[0].textintval.value;
1742 pc->minutes = 0;
1743 }
1744 else
1745 {
1746 pc->hour = yyvsp[0].textintval.value / 100;
1747 pc->minutes = yyvsp[0].textintval.value % 100;
1748 }
1749 pc->seconds.tv_sec = 0;
1750 pc->seconds.tv_nsec = 0;
1751 pc->meridian = MER24;
1752 }
1753 }
1754 }
1755 break;
1756
1757 case 75:
1758 #line 556 "getdate.y"
1759 { yyval.intval = -1; }
1760 break;
1761
1762 case 76:
1763 #line 558 "getdate.y"
1764 { yyval.intval = yyvsp[0].textintval.value; }
1765 break;
1766
1767 case 77:
1768 #line 563 "getdate.y"
1769 { yyval.intval = MER24; }
1770 break;
1771
1772 case 78:
1773 #line 565 "getdate.y"
1774 { yyval.intval = yyvsp[0].intval; }
1775 break;
1776
1777
1778 }
1779
1780 /* Line 1000 of yacc.c. */
1781 #line 1782 "getdate.c"
1782
1783 yyvsp -= yylen;
1784 yyssp -= yylen;
1785
1786
1787 YY_STACK_PRINT (yyss, yyssp);
1788
1789 *++yyvsp = yyval;
1790
1791
1792 /* Now `shift' the result of the reduction. Determine what state
1793 that goes to, based on the state we popped back to and the rule
1794 number reduced by. */
1795
1796 yyn = yyr1[yyn];
1797
1798 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1799 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1800 yystate = yytable[yystate];
1801 else
1802 yystate = yydefgoto[yyn - YYNTOKENS];
1803
1804 goto yynewstate;
1805
1806
1807 /*------------------------------------.
1808 | yyerrlab -- here on detecting error |
1809 `------------------------------------*/
1810 yyerrlab:
1811 /* If not already recovering from an error, report this error. */
1812 if (!yyerrstatus)
1813 {
1814 ++yynerrs;
1815 #if YYERROR_VERBOSE
1816 yyn = yypact[yystate];
1817
1818 if (YYPACT_NINF < yyn && yyn < YYLAST)
1819 {
1820 YYSIZE_T yysize = 0;
1821 int yytype = YYTRANSLATE (yychar);
1822 const char* yyprefix;
1823 char *yymsg;
1824 int yyx;
1825
1826 /* Start YYX at -YYN if negative to avoid negative indexes in
1827 YYCHECK. */
1828 int yyxbegin = yyn < 0 ? -yyn : 0;
1829
1830 /* Stay within bounds of both yycheck and yytname. */
1831 int yychecklim = YYLAST - yyn;
1832 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1833 int yycount = 0;
1834
1835 yyprefix = ", expecting ";
1836 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1837 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1838 {
1839 yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
1840 yycount += 1;
1841 if (yycount == 5)
1842 {
1843 yysize = 0;
1844 break;
1845 }
1846 }
1847 yysize += (sizeof ("syntax error, unexpected ")
1848 + yystrlen (yytname[yytype]));
1849 yymsg = (char *) YYSTACK_ALLOC (yysize);
1850 if (yymsg != 0)
1851 {
1852 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1853 yyp = yystpcpy (yyp, yytname[yytype]);
1854
1855 if (yycount < 5)
1856 {
1857 yyprefix = ", expecting ";
1858 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1859 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1860 {
1861 yyp = yystpcpy (yyp, yyprefix);
1862 yyp = yystpcpy (yyp, yytname[yyx]);
1863 yyprefix = " or ";
1864 }
1865 }
1866 yyerror (pc, yymsg);
1867 YYSTACK_FREE (yymsg);
1868 }
1869 else
1870 yyerror (pc, "syntax error; also virtual memory exhausted");
1871 }
1872 else
1873 #endif /* YYERROR_VERBOSE */
1874 yyerror (pc, "syntax error");
1875 }
1876
1877
1878
1879 if (yyerrstatus == 3)
1880 {
1881 /* If just tried and failed to reuse lookahead token after an
1882 error, discard it. */
1883
1884 if (yychar <= YYEOF)
1885 {
1886 /* If at end of input, pop the error token,
1887 then the rest of the stack, then return failure. */
1888 if (yychar == YYEOF)
1889 for (;;)
1890 {
1891 YYPOPSTACK;
1892 if (yyssp == yyss)
1893 YYABORT;
1894 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1895 yydestruct (yystos[*yyssp], yyvsp);
1896 }
1897 }
1898 else
1899 {
1900 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1901 yydestruct (yytoken, &yylval);
1902 yychar = YYEMPTY;
1903
1904 }
1905 }
1906
1907 /* Else will try to reuse lookahead token after shifting the error
1908 token. */
1909 goto yyerrlab1;
1910
1911
1912 /*---------------------------------------------------.
1913 | yyerrorlab -- error raised explicitly by YYERROR. |
1914 `---------------------------------------------------*/
1915 yyerrorlab:
1916
1917 #ifdef __GNUC__
1918 /* Pacify GCC when the user code never invokes YYERROR and the label
1919 yyerrorlab therefore never appears in user code. */
1920 if (0)
1921 goto yyerrorlab;
1922 #endif
1923
1924 yyvsp -= yylen;
1925 yyssp -= yylen;
1926 yystate = *yyssp;
1927 goto yyerrlab1;
1928
1929
1930 /*-------------------------------------------------------------.
1931 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1932 `-------------------------------------------------------------*/
1933 yyerrlab1:
1934 yyerrstatus = 3; /* Each real token shifted decrements this. */
1935
1936 for (;;)
1937 {
1938 yyn = yypact[yystate];
1939 if (yyn != YYPACT_NINF)
1940 {
1941 yyn += YYTERROR;
1942 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1943 {
1944 yyn = yytable[yyn];
1945 if (0 < yyn)
1946 break;
1947 }
1948 }
1949
1950 /* Pop the current state because it cannot handle the error token. */
1951 if (yyssp == yyss)
1952 YYABORT;
1953
1954 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1955 yydestruct (yystos[yystate], yyvsp);
1956 YYPOPSTACK;
1957 yystate = *yyssp;
1958 YY_STACK_PRINT (yyss, yyssp);
1959 }
1960
1961 if (yyn == YYFINAL)
1962 YYACCEPT;
1963
1964 YYDPRINTF ((stderr, "Shifting error token, "));
1965
1966 *++yyvsp = yylval;
1967
1968
1969 yystate = yyn;
1970 goto yynewstate;
1971
1972
1973 /*-------------------------------------.
1974 | yyacceptlab -- YYACCEPT comes here. |
1975 `-------------------------------------*/
1976 yyacceptlab:
1977 yyresult = 0;
1978 goto yyreturn;
1979
1980 /*-----------------------------------.
1981 | yyabortlab -- YYABORT comes here. |
1982 `-----------------------------------*/
1983 yyabortlab:
1984 yyresult = 1;
1985 goto yyreturn;
1986
1987 #ifndef yyoverflow
1988 /*----------------------------------------------.
1989 | yyoverflowlab -- parser overflow comes here. |
1990 `----------------------------------------------*/
1991 yyoverflowlab:
1992 yyerror (pc, "parser stack overflow");
1993 yyresult = 2;
1994 /* Fall through. */
1995 #endif
1996
1997 yyreturn:
1998 #ifndef yyoverflow
1999 if (yyss != yyssa)
2000 YYSTACK_FREE (yyss);
2001 #endif
2002 return yyresult;
2003 }
2004
2005
2006 #line 568 "getdate.y"
2007
2008
2009 static table const meridian_table[] =
2010 {
2011 { "AM", tMERIDIAN, MERam },
2012 { "A.M.", tMERIDIAN, MERam },
2013 { "PM", tMERIDIAN, MERpm },
2014 { "P.M.", tMERIDIAN, MERpm },
2015 { NULL, 0, 0 }
2016 };
2017
2018 static table const dst_table[] =
2019 {
2020 { "DST", tDST, 0 }
2021 };
2022
2023 static table const month_and_day_table[] =
2024 {
2025 { "JANUARY", tMONTH, 1 },
2026 { "FEBRUARY", tMONTH, 2 },
2027 { "MARCH", tMONTH, 3 },
2028 { "APRIL", tMONTH, 4 },
2029 { "MAY", tMONTH, 5 },
2030 { "JUNE", tMONTH, 6 },
2031 { "JULY", tMONTH, 7 },
2032 { "AUGUST", tMONTH, 8 },
2033 { "SEPTEMBER",tMONTH, 9 },
2034 { "SEPT", tMONTH, 9 },
2035 { "OCTOBER", tMONTH, 10 },
2036 { "NOVEMBER", tMONTH, 11 },
2037 { "DECEMBER", tMONTH, 12 },
2038 { "SUNDAY", tDAY, 0 },
2039 { "MONDAY", tDAY, 1 },
2040 { "TUESDAY", tDAY, 2 },
2041 { "TUES", tDAY, 2 },
2042 { "WEDNESDAY",tDAY, 3 },
2043 { "WEDNES", tDAY, 3 },
2044 { "THURSDAY", tDAY, 4 },
2045 { "THUR", tDAY, 4 },
2046 { "THURS", tDAY, 4 },
2047 { "FRIDAY", tDAY, 5 },
2048 { "SATURDAY", tDAY, 6 },
2049 { NULL, 0, 0 }
2050 };
2051
2052 static table const time_units_table[] =
2053 {
2054 { "YEAR", tYEAR_UNIT, 1 },
2055 { "MONTH", tMONTH_UNIT, 1 },
2056 { "FORTNIGHT",tDAY_UNIT, 14 },
2057 { "WEEK", tDAY_UNIT, 7 },
2058 { "DAY", tDAY_UNIT, 1 },
2059 { "HOUR", tHOUR_UNIT, 1 },
2060 { "MINUTE", tMINUTE_UNIT, 1 },
2061 { "MIN", tMINUTE_UNIT, 1 },
2062 { "SECOND", tSEC_UNIT, 1 },
2063 { "SEC", tSEC_UNIT, 1 },
2064 { NULL, 0, 0 }
2065 };
2066
2067 /* Assorted relative-time words. */
2068 static table const relative_time_table[] =
2069 {
2070 { "TOMORROW", tDAY_UNIT, 1 },
2071 { "YESTERDAY",tDAY_UNIT, -1 },
2072 { "TODAY", tDAY_UNIT, 0 },
2073 { "NOW", tDAY_UNIT, 0 },
2074 { "LAST", tORDINAL, -1 },
2075 { "THIS", tORDINAL, 0 },
2076 { "NEXT", tORDINAL, 1 },
2077 { "FIRST", tORDINAL, 1 },
2078 /*{ "SECOND", tORDINAL, 2 }, */
2079 { "THIRD", tORDINAL, 3 },
2080 { "FOURTH", tORDINAL, 4 },
2081 { "FIFTH", tORDINAL, 5 },
2082 { "SIXTH", tORDINAL, 6 },
2083 { "SEVENTH", tORDINAL, 7 },
2084 { "EIGHTH", tORDINAL, 8 },
2085 { "NINTH", tORDINAL, 9 },
2086 { "TENTH", tORDINAL, 10 },
2087 { "ELEVENTH", tORDINAL, 11 },
2088 { "TWELFTH", tORDINAL, 12 },
2089 { "AGO", tAGO, 1 },
2090 { NULL, 0, 0 }
2091 };
2092
2093 /* The universal time zone table. These labels can be used even for
2094 time stamps that would not otherwise be valid, e.g., GMT time
2095 stamps in London during summer. */
2096 static table const universal_time_zone_table[] =
2097 {
2098 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
2099 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
2100 { "UTC", tZONE, HOUR ( 0) },
2101 { NULL, 0, 0 }
2102 };
2103
2104 /* The time zone table. This table is necessarily incomplete, as time
2105 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
2106 as Eastern time in Australia, not as US Eastern Standard Time.
2107 You cannot rely on getdate to handle arbitrary time zone
2108 abbreviations; use numeric abbreviations like `-0500' instead. */
2109 static table const time_zone_table[] =
2110 {
2111 { "WET", tZONE, HOUR ( 0) }, /* Western European */
2112 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
2113 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
2114 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
2115 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
2116 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
2117 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
2118 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
2119 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
2120 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
2121 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
2122 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
2123 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
2124 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
2125 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
2126 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
2127 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
2128 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
2129 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
2130 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
2131 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
2132 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
2133 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
2134 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
2135 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
2136 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
2137 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
2138 { "CET", tZONE, HOUR ( 1) }, /* Central European */
2139 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
2140 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
2141 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
2142 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
2143 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
2144 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
2145 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
2146 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
2147 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
2148 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
2149 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
2150 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
2151 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
2152 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
2153 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
2154 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
2155 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
2156 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
2157 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
2158 { NULL, 0, 0 }
2159 };
2160
2161 /* Military time zone table. */
2162 static table const military_table[] =
2163 {
2164 { "A", tZONE, -HOUR ( 1) },
2165 { "B", tZONE, -HOUR ( 2) },
2166 { "C", tZONE, -HOUR ( 3) },
2167 { "D", tZONE, -HOUR ( 4) },
2168 { "E", tZONE, -HOUR ( 5) },
2169 { "F", tZONE, -HOUR ( 6) },
2170 { "G", tZONE, -HOUR ( 7) },
2171 { "H", tZONE, -HOUR ( 8) },
2172 { "I", tZONE, -HOUR ( 9) },
2173 { "K", tZONE, -HOUR (10) },
2174 { "L", tZONE, -HOUR (11) },
2175 { "M", tZONE, -HOUR (12) },
2176 { "N", tZONE, HOUR ( 1) },
2177 { "O", tZONE, HOUR ( 2) },
2178 { "P", tZONE, HOUR ( 3) },
2179 { "Q", tZONE, HOUR ( 4) },
2180 { "R", tZONE, HOUR ( 5) },
2181 { "S", tZONE, HOUR ( 6) },
2182 { "T", tZONE, HOUR ( 7) },
2183 { "U", tZONE, HOUR ( 8) },
2184 { "V", tZONE, HOUR ( 9) },
2185 { "W", tZONE, HOUR (10) },
2186 { "X", tZONE, HOUR (11) },
2187 { "Y", tZONE, HOUR (12) },
2188 { "Z", tZONE, HOUR ( 0) },
2189 { NULL, 0, 0 }
2190 };
2191
2192
2193
2194 /* Convert a time zone expressed as HH:MM into an integer count of
2195 minutes. If MM is negative, then S is of the form HHMM and needs
2196 to be picked apart; otherwise, S is of the form HH. */
2197
2198 static long int
time_zone_hhmm(textint s,long int mm)2199 time_zone_hhmm (textint s, long int mm)
2200 {
2201 if (mm < 0)
2202 return (s.value / 100) * 60 + s.value % 100;
2203 else
2204 return s.value * 60 + (s.negative ? -mm : mm);
2205 }
2206
2207 static int
to_hour(long int hours,int meridian)2208 to_hour (long int hours, int meridian)
2209 {
2210 switch (meridian)
2211 {
2212 default: /* Pacify GCC. */
2213 case MER24:
2214 return 0 <= hours && hours < 24 ? hours : -1;
2215 case MERam:
2216 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
2217 case MERpm:
2218 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
2219 }
2220 }
2221
2222 static long int
to_year(textint textyear)2223 to_year (textint textyear)
2224 {
2225 long int year = textyear.value;
2226
2227 if (year < 0)
2228 year = -year;
2229
2230 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2231 years 69-99 map to 1969-1999. */
2232 else if (textyear.digits == 2)
2233 year += year < 69 ? 2000 : 1900;
2234
2235 return year;
2236 }
2237
2238 static table const *
lookup_zone(parser_control const * pc,char const * name)2239 lookup_zone (parser_control const *pc, char const *name)
2240 {
2241 table const *tp;
2242
2243 for (tp = universal_time_zone_table; tp->name; tp++)
2244 if (strcmp (name, tp->name) == 0)
2245 return tp;
2246
2247 /* Try local zone abbreviations before those in time_zone_table, as
2248 the local ones are more likely to be right. */
2249 for (tp = pc->local_time_zone_table; tp->name; tp++)
2250 if (strcmp (name, tp->name) == 0)
2251 return tp;
2252
2253 for (tp = time_zone_table; tp->name; tp++)
2254 if (strcmp (name, tp->name) == 0)
2255 return tp;
2256
2257 return NULL;
2258 }
2259
2260 #if ! HAVE_TM_GMTOFF
2261 /* Yield the difference between *A and *B,
2262 measured in seconds, ignoring leap seconds.
2263 The body of this function is taken directly from the GNU C Library;
2264 see src/strftime.c. */
2265 static long int
tm_diff(struct tm const * a,struct tm const * b)2266 tm_diff (struct tm const *a, struct tm const *b)
2267 {
2268 /* Compute intervening leap days correctly even if year is negative.
2269 Take care to avoid int overflow in leap day calculations. */
2270 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
2271 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
2272 int a100 = a4 / 25 - (a4 % 25 < 0);
2273 int b100 = b4 / 25 - (b4 % 25 < 0);
2274 int a400 = SHR (a100, 2);
2275 int b400 = SHR (b100, 2);
2276 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2277 long int ayear = a->tm_year;
2278 long int years = ayear - b->tm_year;
2279 long int days = (365 * years + intervening_leap_days
2280 + (a->tm_yday - b->tm_yday));
2281 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2282 + (a->tm_min - b->tm_min))
2283 + (a->tm_sec - b->tm_sec));
2284 }
2285 #endif /* ! HAVE_TM_GMTOFF */
2286
2287 static table const *
lookup_word(parser_control const * pc,char * word)2288 lookup_word (parser_control const *pc, char *word)
2289 {
2290 char *p;
2291 char *q;
2292 size_t wordlen;
2293 table const *tp;
2294 bool period_found;
2295 bool abbrev;
2296
2297 /* Make it uppercase. */
2298 for (p = word; *p; p++)
2299 {
2300 unsigned char ch = *p;
2301 if (ISLOWER (ch))
2302 *p = toupper (ch);
2303 }
2304
2305 for (tp = meridian_table; tp->name; tp++)
2306 if (strcmp (word, tp->name) == 0)
2307 return tp;
2308
2309 /* See if we have an abbreviation for a month. */
2310 wordlen = strlen (word);
2311 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2312
2313 for (tp = month_and_day_table; tp->name; tp++)
2314 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2315 return tp;
2316
2317 if ((tp = lookup_zone (pc, word)))
2318 return tp;
2319
2320 if (strcmp (word, dst_table[0].name) == 0)
2321 return dst_table;
2322
2323 for (tp = time_units_table; tp->name; tp++)
2324 if (strcmp (word, tp->name) == 0)
2325 return tp;
2326
2327 /* Strip off any plural and try the units table again. */
2328 if (word[wordlen - 1] == 'S')
2329 {
2330 word[wordlen - 1] = '\0';
2331 for (tp = time_units_table; tp->name; tp++)
2332 if (strcmp (word, tp->name) == 0)
2333 return tp;
2334 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2335 }
2336
2337 for (tp = relative_time_table; tp->name; tp++)
2338 if (strcmp (word, tp->name) == 0)
2339 return tp;
2340
2341 /* Military time zones. */
2342 if (wordlen == 1)
2343 for (tp = military_table; tp->name; tp++)
2344 if (word[0] == tp->name[0])
2345 return tp;
2346
2347 /* Drop out any periods and try the time zone table again. */
2348 for (period_found = false, p = q = word; (*p = *q); q++)
2349 if (*q == '.')
2350 period_found = true;
2351 else
2352 p++;
2353 if (period_found && (tp = lookup_zone (pc, word)))
2354 return tp;
2355
2356 return NULL;
2357 }
2358
2359 static int
yylex(YYSTYPE * lvalp,parser_control * pc)2360 yylex (YYSTYPE *lvalp, parser_control *pc)
2361 {
2362 unsigned char c;
2363 size_t count;
2364
2365 for (;;)
2366 {
2367 while (c = *pc->input, ISSPACE (c))
2368 pc->input++;
2369
2370 if (ISDIGIT (c) || c == '-' || c == '+')
2371 {
2372 char const *p;
2373 int sign;
2374 unsigned long int value;
2375 if (c == '-' || c == '+')
2376 {
2377 sign = c == '-' ? -1 : 1;
2378 while (c = *++pc->input, ISSPACE (c))
2379 continue;
2380 if (! ISDIGIT (c))
2381 /* skip the '-' sign */
2382 continue;
2383 }
2384 else
2385 sign = 0;
2386 p = pc->input;
2387 for (value = 0; ; value *= 10)
2388 {
2389 unsigned long int value1 = value + (c - '0');
2390 if (value1 < value)
2391 return '?';
2392 value = value1;
2393 c = *++p;
2394 if (! ISDIGIT (c))
2395 break;
2396 if (ULONG_MAX / 10 < value)
2397 return '?';
2398 }
2399 if ((c == '.' || c == ',') && ISDIGIT (p[1]))
2400 {
2401 time_t s;
2402 int ns;
2403 int digits;
2404 unsigned long int value1;
2405
2406 /* Check for overflow when converting value to time_t. */
2407 if (sign < 0)
2408 {
2409 s = - value;
2410 if (0 < s)
2411 return '?';
2412 value1 = -s;
2413 }
2414 else
2415 {
2416 s = value;
2417 if (s < 0)
2418 return '?';
2419 value1 = s;
2420 }
2421 if (value != value1)
2422 return '?';
2423
2424 /* Accumulate fraction, to ns precision. */
2425 p++;
2426 ns = *p++ - '0';
2427 for (digits = 2; digits <= LOG10_BILLION; digits++)
2428 {
2429 ns *= 10;
2430 if (ISDIGIT (*p))
2431 ns += *p++ - '0';
2432 }
2433
2434 /* Skip excess digits, truncating toward -Infinity. */
2435 if (sign < 0)
2436 for (; ISDIGIT (*p); p++)
2437 if (*p != '0')
2438 {
2439 ns++;
2440 break;
2441 }
2442 while (ISDIGIT (*p))
2443 p++;
2444
2445 /* Adjust to the timespec convention, which is that
2446 tv_nsec is always a positive offset even if tv_sec is
2447 negative. */
2448 if (sign < 0 && ns)
2449 {
2450 s--;
2451 if (! (s < 0))
2452 return '?';
2453 ns = BILLION - ns;
2454 }
2455
2456 lvalp->timespec.tv_sec = s;
2457 lvalp->timespec.tv_nsec = ns;
2458 pc->input = p;
2459 return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;
2460 }
2461 else
2462 {
2463 lvalp->textintval.negative = sign < 0;
2464 if (sign < 0)
2465 {
2466 lvalp->textintval.value = - value;
2467 if (0 < lvalp->textintval.value)
2468 return '?';
2469 }
2470 else
2471 {
2472 lvalp->textintval.value = value;
2473 if (lvalp->textintval.value < 0)
2474 return '?';
2475 }
2476 lvalp->textintval.digits = p - pc->input;
2477 pc->input = p;
2478 return sign ? tSNUMBER : tUNUMBER;
2479 }
2480 }
2481
2482 if (ISALPHA (c))
2483 {
2484 char buff[20];
2485 char *p = buff;
2486 table const *tp;
2487
2488 do
2489 {
2490 if (p < buff + sizeof buff - 1)
2491 *p++ = c;
2492 c = *++pc->input;
2493 }
2494 while (ISALPHA (c) || c == '.');
2495
2496 *p = '\0';
2497 tp = lookup_word (pc, buff);
2498 if (! tp)
2499 return '?';
2500 lvalp->intval = tp->value;
2501 return tp->type;
2502 }
2503
2504 if (c != '(')
2505 return *pc->input++;
2506 count = 0;
2507 do
2508 {
2509 c = *pc->input++;
2510 if (c == '\0')
2511 return c;
2512 if (c == '(')
2513 count++;
2514 else if (c == ')')
2515 count--;
2516 }
2517 while (count != 0);
2518 }
2519 }
2520
2521 /* Do nothing if the parser reports an error. */
2522 static int
yyerror(parser_control * pc ATTRIBUTE_UNUSED,char * s ATTRIBUTE_UNUSED)2523 yyerror (parser_control *pc ATTRIBUTE_UNUSED, char *s ATTRIBUTE_UNUSED)
2524 {
2525 return 0;
2526 }
2527
2528 /* If *TM0 is the old and *TM1 is the new value of a struct tm after
2529 passing it to mktime, return true if it's OK that mktime returned T.
2530 It's not OK if *TM0 has out-of-range members. */
2531
2532 static bool
mktime_ok(struct tm const * tm0,struct tm const * tm1,time_t t)2533 mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)
2534 {
2535 if (t == (time_t) -1)
2536 {
2537 /* Guard against falsely reporting an error when parsing a time
2538 stamp that happens to equal (time_t) -1, on a host that
2539 supports such a time stamp. */
2540 tm1 = localtime (&t);
2541 if (!tm1)
2542 return false;
2543 }
2544
2545 return ! ((tm0->tm_sec ^ tm1->tm_sec)
2546 | (tm0->tm_min ^ tm1->tm_min)
2547 | (tm0->tm_hour ^ tm1->tm_hour)
2548 | (tm0->tm_mday ^ tm1->tm_mday)
2549 | (tm0->tm_mon ^ tm1->tm_mon)
2550 | (tm0->tm_year ^ tm1->tm_year));
2551 }
2552
2553 /* A reasonable upper bound for the size of ordinary TZ strings.
2554 Use heap allocation if TZ's length exceeds this. */
2555 enum { TZBUFSIZE = 100 };
2556
2557 /* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
2558 otherwise. */
2559 static char *
get_tz(char tzbuf[TZBUFSIZE])2560 get_tz (char tzbuf[TZBUFSIZE])
2561 {
2562 char *tz = getenv ("TZ");
2563 if (tz)
2564 {
2565 size_t tzsize = strlen (tz) + 1;
2566 tz = (tzsize <= TZBUFSIZE
2567 ? memcpy (tzbuf, tz, tzsize)
2568 : xmemdup (tz, tzsize));
2569 }
2570 return tz;
2571 }
2572
2573 /* Parse a date/time string, storing the resulting time value into *RESULT.
2574 The string itself is pointed to by P. Return true if successful.
2575 P can be an incomplete or relative time specification; if so, use
2576 *NOW as the basis for the returned time. */
2577 bool
get_date(struct timespec * result,char const * p,struct timespec const * now)2578 get_date (struct timespec *result, char const *p, struct timespec const *now)
2579 {
2580 time_t Start;
2581 long int Start_ns;
2582 struct tm const *tmp;
2583 struct tm tm;
2584 struct tm tm0;
2585 parser_control pc;
2586 struct timespec gettime_buffer;
2587 unsigned char c;
2588 bool tz_was_altered = false;
2589 char *tz0 = NULL;
2590 char tz0buf[TZBUFSIZE];
2591 bool ok = true;
2592
2593 if (! now)
2594 {
2595 gettime (&gettime_buffer);
2596 now = &gettime_buffer;
2597 }
2598
2599 Start = now->tv_sec;
2600 Start_ns = now->tv_nsec;
2601
2602 tmp = localtime (&now->tv_sec);
2603 if (! tmp)
2604 return false;
2605
2606 while (c = *p, ISSPACE (c))
2607 p++;
2608
2609 if (strncmp (p, "TZ=\"", 4) == 0)
2610 {
2611 char const *tzbase = p + 4;
2612 size_t tzsize = 1;
2613 char const *s;
2614
2615 for (s = tzbase; *s; s++, tzsize++)
2616 if (*s == '\\')
2617 {
2618 s++;
2619 if (! (*s == '\\' || *s == '"'))
2620 break;
2621 }
2622 else if (*s == '"')
2623 {
2624 char *z;
2625 char *tz1;
2626 char tz1buf[TZBUFSIZE];
2627 bool large_tz = TZBUFSIZE < tzsize;
2628 bool setenv_ok;
2629 tz0 = get_tz (tz0buf);
2630 z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf;
2631 for (s = tzbase; *s != '"'; s++)
2632 *z++ = *(s += *s == '\\');
2633 *z = '\0';
2634 setenv_ok = setenv ("TZ", tz1, 1) == 0;
2635 if (large_tz)
2636 free (tz1);
2637 if (!setenv_ok)
2638 goto fail;
2639 tz_was_altered = true;
2640 p = s + 1;
2641 }
2642 }
2643
2644 pc.input = p;
2645 pc.year.value = tmp->tm_year;
2646 pc.year.value += TM_YEAR_BASE;
2647 pc.year.digits = 0;
2648 pc.month = tmp->tm_mon + 1;
2649 pc.day = tmp->tm_mday;
2650 pc.hour = tmp->tm_hour;
2651 pc.minutes = tmp->tm_min;
2652 pc.seconds.tv_sec = tmp->tm_sec;
2653 pc.seconds.tv_nsec = Start_ns;
2654 tm.tm_isdst = tmp->tm_isdst;
2655
2656 pc.meridian = MER24;
2657 pc.rel_ns = 0;
2658 pc.rel_seconds = 0;
2659 pc.rel_minutes = 0;
2660 pc.rel_hour = 0;
2661 pc.rel_day = 0;
2662 pc.rel_month = 0;
2663 pc.rel_year = 0;
2664 pc.timespec_seen = false;
2665 pc.rels_seen = false;
2666 pc.dates_seen = 0;
2667 pc.days_seen = 0;
2668 pc.times_seen = 0;
2669 pc.local_zones_seen = 0;
2670 pc.dsts_seen = 0;
2671 pc.zones_seen = 0;
2672
2673 #if HAVE_STRUCT_TM_TM_ZONE
2674 pc.local_time_zone_table[0].name = tmp->tm_zone;
2675 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2676 pc.local_time_zone_table[0].value = tmp->tm_isdst;
2677 pc.local_time_zone_table[1].name = NULL;
2678
2679 /* Probe the names used in the next three calendar quarters, looking
2680 for a tm_isdst different from the one we already have. */
2681 {
2682 int quarter;
2683 for (quarter = 1; quarter <= 3; quarter++)
2684 {
2685 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2686 struct tm const *probe_tm = localtime (&probe);
2687 if (probe_tm && probe_tm->tm_zone
2688 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2689 {
2690 {
2691 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2692 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2693 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2694 pc.local_time_zone_table[2].name = NULL;
2695 }
2696 break;
2697 }
2698 }
2699 }
2700 #else
2701 #if HAVE_TZNAME
2702 {
2703 # ifndef tzname
2704 extern char *tzname[];
2705 # endif
2706 int i;
2707 for (i = 0; i < 2; i++)
2708 {
2709 pc.local_time_zone_table[i].name = tzname[i];
2710 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2711 pc.local_time_zone_table[i].value = i;
2712 }
2713 pc.local_time_zone_table[i].name = NULL;
2714 }
2715 #else
2716 pc.local_time_zone_table[0].name = NULL;
2717 #endif
2718 #endif
2719
2720 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2721 && ! strcmp (pc.local_time_zone_table[0].name,
2722 pc.local_time_zone_table[1].name))
2723 {
2724 /* This locale uses the same abbrevation for standard and
2725 daylight times. So if we see that abbreviation, we don't
2726 know whether it's daylight time. */
2727 pc.local_time_zone_table[0].value = -1;
2728 pc.local_time_zone_table[1].name = NULL;
2729 }
2730
2731 if (yyparse (&pc) != 0)
2732 goto fail;
2733
2734 if (pc.timespec_seen)
2735 *result = pc.seconds;
2736 else
2737 {
2738 if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
2739 | (pc.local_zones_seen + pc.zones_seen)))
2740 goto fail;
2741
2742 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;
2743 tm.tm_mon = pc.month - 1;
2744 tm.tm_mday = pc.day;
2745 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2746 {
2747 tm.tm_hour = to_hour (pc.hour, pc.meridian);
2748 if (tm.tm_hour < 0)
2749 goto fail;
2750 tm.tm_min = pc.minutes;
2751 tm.tm_sec = pc.seconds.tv_sec;
2752 }
2753 else
2754 {
2755 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2756 pc.seconds.tv_nsec = 0;
2757 }
2758
2759 /* Let mktime deduce tm_isdst if we have an absolute time stamp. */
2760 if (!pc.rels_seen)
2761 tm.tm_isdst = -1;
2762
2763 /* But if the input explicitly specifies local time with or without
2764 DST, give mktime that information. */
2765 if (pc.local_zones_seen)
2766 tm.tm_isdst = pc.local_isdst;
2767
2768 tm0 = tm;
2769
2770 Start = mktime (&tm);
2771
2772 if (! mktime_ok (&tm0, &tm, Start))
2773 {
2774 if (! pc.zones_seen)
2775 goto fail;
2776 else
2777 {
2778 /* Guard against falsely reporting errors near the time_t
2779 boundaries when parsing times in other time zones. For
2780 example, suppose the input string "1969-12-31 23:00:00 -0100",
2781 the current time zone is 8 hours ahead of UTC, and the min
2782 time_t value is 1970-01-01 00:00:00 UTC. Then the min
2783 localtime value is 1970-01-01 08:00:00, and mktime will
2784 therefore fail on 1969-12-31 23:00:00. To work around the
2785 problem, set the time zone to 1 hour behind UTC temporarily
2786 by setting TZ="XXX1:00" and try mktime again. */
2787
2788 long int time_zone = pc.time_zone;
2789 long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
2790 long int abs_time_zone_hour = abs_time_zone / 60;
2791 int abs_time_zone_min = abs_time_zone % 60;
2792 char tz1buf[sizeof "XXX+0:00"
2793 + sizeof pc.time_zone * CHAR_BIT / 3];
2794 if (!tz_was_altered)
2795 tz0 = get_tz (tz0buf);
2796 sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0),
2797 abs_time_zone_hour, abs_time_zone_min);
2798 if (setenv ("TZ", tz1buf, 1) != 0)
2799 goto fail;
2800 tz_was_altered = true;
2801 tm = tm0;
2802 Start = mktime (&tm);
2803 if (! mktime_ok (&tm0, &tm, Start))
2804 goto fail;
2805 }
2806 }
2807
2808 if (pc.days_seen && ! pc.dates_seen)
2809 {
2810 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2811 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2812 tm.tm_isdst = -1;
2813 Start = mktime (&tm);
2814 if (Start == (time_t) -1)
2815 goto fail;
2816 }
2817
2818 if (pc.zones_seen)
2819 {
2820 long int delta = pc.time_zone * 60;
2821 time_t t1;
2822 #ifdef HAVE_TM_GMTOFF
2823 delta -= tm.tm_gmtoff;
2824 #else
2825 time_t t = Start;
2826 struct tm const *gmt = gmtime (&t);
2827 if (! gmt)
2828 goto fail;
2829 delta -= tm_diff (&tm, gmt);
2830 #endif
2831 t1 = Start - delta;
2832 if ((Start < t1) != (delta < 0))
2833 goto fail; /* time_t overflow */
2834 Start = t1;
2835 }
2836
2837 /* Add relative date. */
2838 if (pc.rel_year | pc.rel_month | pc.rel_day)
2839 {
2840 int year = tm.tm_year + pc.rel_year;
2841 int month = tm.tm_mon + pc.rel_month;
2842 int day = tm.tm_mday + pc.rel_day;
2843 if (((year < tm.tm_year) ^ (pc.rel_year < 0))
2844 | ((month < tm.tm_mon) ^ (pc.rel_month < 0))
2845 | ((day < tm.tm_mday) ^ (pc.rel_day < 0)))
2846 goto fail;
2847 tm.tm_year = year;
2848 tm.tm_mon = month;
2849 tm.tm_mday = day;
2850 Start = mktime (&tm);
2851 if (Start == (time_t) -1)
2852 goto fail;
2853 }
2854
2855 /* Add relative hours, minutes, and seconds. On hosts that support
2856 leap seconds, ignore the possibility of leap seconds; e.g.,
2857 "+ 10 minutes" adds 600 seconds, even if one of them is a
2858 leap second. Typically this is not what the user wants, but it's
2859 too hard to do it the other way, because the time zone indicator
2860 must be applied before relative times, and if mktime is applied
2861 again the time zone will be lost. */
2862 {
2863 long int sum_ns = pc.seconds.tv_nsec + pc.rel_ns;
2864 long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
2865 time_t t0 = Start;
2866 long int d1 = 60 * 60 * pc.rel_hour;
2867 time_t t1 = t0 + d1;
2868 long int d2 = 60 * pc.rel_minutes;
2869 time_t t2 = t1 + d2;
2870 long int d3 = pc.rel_seconds;
2871 time_t t3 = t2 + d3;
2872 long int d4 = (sum_ns - normalized_ns) / BILLION;
2873 time_t t4 = t3 + d4;
2874
2875 if ((d1 / (60 * 60) ^ pc.rel_hour)
2876 | (d2 / 60 ^ pc.rel_minutes)
2877 | ((t1 < t0) ^ (d1 < 0))
2878 | ((t2 < t1) ^ (d2 < 0))
2879 | ((t3 < t2) ^ (d3 < 0))
2880 | ((t4 < t3) ^ (d4 < 0)))
2881 goto fail;
2882
2883 result->tv_sec = t4;
2884 result->tv_nsec = normalized_ns;
2885 }
2886 }
2887
2888 goto done;
2889
2890 fail:
2891 ok = false;
2892 done:
2893 if (tz_was_altered)
2894 ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;
2895 if (tz0 != tz0buf)
2896 free (tz0);
2897 return ok;
2898 }
2899
2900 #if TEST
2901
2902 int
main(int ac,char ** av)2903 main (int ac, char **av)
2904 {
2905 char buff[BUFSIZ];
2906
2907 printf ("Enter date, or blank line to exit.\n\t> ");
2908 fflush (stdout);
2909
2910 buff[BUFSIZ - 1] = '\0';
2911 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2912 {
2913 struct timespec d;
2914 struct tm const *tm;
2915 if (! get_date (&d, buff, NULL))
2916 printf ("Bad format - couldn't convert.\n");
2917 else if (! (tm = localtime (&d.tv_sec)))
2918 {
2919 long int sec = d.tv_sec;
2920 printf ("localtime (%ld) failed\n", sec);
2921 }
2922 else
2923 {
2924 int ns = d.tv_nsec;
2925 printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",
2926 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
2927 tm->tm_hour, tm->tm_min, tm->tm_sec, ns);
2928 }
2929 printf ("\t> ");
2930 fflush (stdout);
2931 }
2932 return 0;
2933 }
2934 #endif /* TEST */
2935
2936
2937