Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / gpl2 / xcvs / dist / lib / getdate.c
bloba31ced1ee58f57c35b239665add72f220b830a11
2 /* A Bison parser, made by GNU Bison 2.4.1. */
4 /* Skeleton implementation for Bison's Yacc-like parsers in C
6 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
7 Free Software Foundation, Inc.
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 /* As a special exception, you may create a larger work that contains
23 part or all of the Bison parser skeleton and distribute that work
24 under terms of your choice, so long as that work isn't itself a
25 parser generator using the skeleton or a modified version thereof
26 as a parser skeleton. Alternatively, if you modify or redistribute
27 the parser skeleton itself, you may (at your option) remove this
28 special exception, which will cause the skeleton and the resulting
29 Bison output files to be licensed under the GNU General Public
30 License without this special exception.
32 This special exception was added by the Free Software Foundation in
33 version 2.2 of Bison. */
35 /* C LALR(1) parser skeleton written by Richard Stallman, by
36 simplifying the original so-called "semantic" parser. */
38 /* All symbols defined below should begin with yy or YY, to avoid
39 infringing on user name space. This should be done even for local
40 variables, as they might otherwise be expanded by user macros.
41 There are some unavoidable exceptions within include files to
42 define necessary library symbols; they are noted "INFRINGES ON
43 USER NAME SPACE" below. */
45 /* Identify Bison output. */
46 #define YYBISON 1
48 /* Bison version. */
49 #define YYBISON_VERSION "2.4.1"
51 /* Skeleton name. */
52 #define YYSKELETON_NAME "yacc.c"
54 /* Pure parsers. */
55 #define YYPURE 1
57 /* Push parsers. */
58 #define YYPUSH 0
60 /* Pull parsers. */
61 #define YYPULL 1
63 /* Using locations. */
64 #define YYLSP_NEEDED 0
68 /* Copy the first part of user declarations. */
70 /* Line 189 of yacc.c */
71 #line 1 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
73 /* Parse a string into an internal time stamp.
75 Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005 Free Software
76 Foundation, Inc.
78 This program is free software; you can redistribute it and/or modify
79 it under the terms of the GNU General Public License as published by
80 the Free Software Foundation; either version 2, or (at your option)
81 any later version.
83 This program is distributed in the hope that it will be useful,
84 but WITHOUT ANY WARRANTY; without even the implied warranty of
85 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
86 GNU General Public License for more details.
88 You should have received a copy of the GNU General Public License
89 along with this program; if not, write to the Free Software Foundation,
90 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
92 /* Originally written by Steven M. Bellovin <smb@research.att.com> while
93 at the University of North Carolina at Chapel Hill. Later tweaked by
94 a couple of people on Usenet. Completely overhauled by Rich $alz
95 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
97 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
98 the right thing about local DST. Also modified by Paul Eggert
99 <eggert@cs.ucla.edu> in February 2004 to support
100 nanosecond-resolution time stamps, and in October 2004 to support
101 TZ strings in dates. */
103 /* FIXME: Check for arithmetic overflow in all cases, not just
104 some of them. */
106 #ifdef HAVE_CONFIG_H
107 # include <config.h>
108 #endif
110 #include "getdate.h"
112 /* There's no need to extend the stack, so there's no need to involve
113 alloca. */
114 #define YYSTACK_USE_ALLOCA 0
116 /* Tell Bison how much stack space is needed. 20 should be plenty for
117 this grammar, which is not right recursive. Beware setting it too
118 high, since that might cause problems on machines whose
119 implementations have lame stack-overflow checking. */
120 #define YYMAXDEPTH 20
121 #define YYINITDEPTH YYMAXDEPTH
123 /* Since the code of getdate.y is not included in the Emacs executable
124 itself, there is no need to #define static in this file. Even if
125 the code were included in the Emacs executable, it probably
126 wouldn't do any harm to #undef it here; this will only cause
127 problems if we try to write to a static variable, which I don't
128 think this code needs to do. */
129 #ifdef emacs
130 # undef static
131 #endif
133 #include <ctype.h>
134 #include <limits.h>
135 #include <stdio.h>
136 #include <stdlib.h>
137 #include <string.h>
139 #include "setenv.h"
140 #include "xalloc.h"
142 #if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
143 # define IN_CTYPE_DOMAIN(c) 1
144 #else
145 # define IN_CTYPE_DOMAIN(c) isascii (c)
146 #endif
148 #define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
149 #define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
150 #define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
152 /* ISDIGIT differs from isdigit, as follows:
153 - Its arg may be any int or unsigned int; it need not be an unsigned char.
154 - It's guaranteed to evaluate its argument exactly once.
155 - It's typically faster.
156 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
157 isdigit unless it's important to use the locale's definition
158 of `digit' even when the host does not conform to POSIX. */
159 #define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
161 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
162 # define __attribute__(x)
163 #endif
165 #ifndef ATTRIBUTE_UNUSED
166 # define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
167 #endif
169 /* Shift A right by B bits portably, by dividing A by 2**B and
170 truncating towards minus infinity. A and B should be free of side
171 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
172 INT_BITS is the number of useful bits in an int. GNU code can
173 assume that INT_BITS is at least 32.
175 ISO C99 says that A >> B is implementation-defined if A < 0. Some
176 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
177 right in the usual way when A < 0, so SHR falls back on division if
178 ordinary A >> B doesn't seem to be the usual signed shift. */
179 #define SHR(a, b) \
180 (-1 >> 1 == -1 \
181 ? (a) >> (b) \
182 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
184 #define EPOCH_YEAR 1970
185 #define TM_YEAR_BASE 1900
187 #define HOUR(x) ((x) * 60)
189 /* An integer value, and the number of digits in its textual
190 representation. */
191 typedef struct
193 bool negative;
194 long int value;
195 size_t digits;
196 } textint;
198 /* An entry in the lexical lookup table. */
199 typedef struct
201 char const *name;
202 int type;
203 int value;
204 } table;
206 /* Meridian: am, pm, or 24-hour style. */
207 enum { MERam, MERpm, MER24 };
209 enum { BILLION = 1000000000, LOG10_BILLION = 9 };
211 /* Information passed to and from the parser. */
212 typedef struct
214 /* The input string remaining to be parsed. */
215 const char *input;
217 /* N, if this is the Nth Tuesday. */
218 long int day_ordinal;
220 /* Day of week; Sunday is 0. */
221 int day_number;
223 /* tm_isdst flag for the local zone. */
224 int local_isdst;
226 /* Time zone, in minutes east of UTC. */
227 long int time_zone;
229 /* Style used for time. */
230 int meridian;
232 /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */
233 textint year;
234 long int month;
235 long int day;
236 long int hour;
237 long int minutes;
238 struct timespec seconds; /* includes nanoseconds */
240 /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
241 long int rel_year;
242 long int rel_month;
243 long int rel_day;
244 long int rel_hour;
245 long int rel_minutes;
246 long int rel_seconds;
247 long int rel_ns;
249 /* Presence or counts of nonterminals of various flavors parsed so far. */
250 bool timespec_seen;
251 bool rels_seen;
252 size_t dates_seen;
253 size_t days_seen;
254 size_t local_zones_seen;
255 size_t dsts_seen;
256 size_t times_seen;
257 size_t zones_seen;
259 /* Table of local time zone abbrevations, terminated by a null entry. */
260 table local_time_zone_table[3];
261 } parser_control;
263 union YYSTYPE;
264 static int yylex (union YYSTYPE *, parser_control *);
265 static int yyerror (parser_control *, char *);
266 static long int time_zone_hhmm (textint, long int);
270 /* Line 189 of yacc.c */
271 #line 272 "getdate.c"
273 /* Enabling traces. */
274 #ifndef YYDEBUG
275 # define YYDEBUG 0
276 #endif
278 /* Enabling verbose error messages. */
279 #ifdef YYERROR_VERBOSE
280 # undef YYERROR_VERBOSE
281 # define YYERROR_VERBOSE 1
282 #else
283 # define YYERROR_VERBOSE 0
284 #endif
286 /* Enabling the token table. */
287 #ifndef YYTOKEN_TABLE
288 # define YYTOKEN_TABLE 0
289 #endif
292 /* Tokens. */
293 #ifndef YYTOKENTYPE
294 # define YYTOKENTYPE
295 /* Put the tokens into the symbol table, so that GDB and other debuggers
296 know about them. */
297 enum yytokentype {
298 tAGO = 258,
299 tDST = 259,
300 tDAY = 260,
301 tDAY_UNIT = 261,
302 tDAYZONE = 262,
303 tHOUR_UNIT = 263,
304 tLOCAL_ZONE = 264,
305 tMERIDIAN = 265,
306 tMINUTE_UNIT = 266,
307 tMONTH = 267,
308 tMONTH_UNIT = 268,
309 tORDINAL = 269,
310 tSEC_UNIT = 270,
311 tYEAR_UNIT = 271,
312 tZONE = 272,
313 tSNUMBER = 273,
314 tUNUMBER = 274,
315 tSDECIMAL_NUMBER = 275,
316 tUDECIMAL_NUMBER = 276
318 #endif
322 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
323 typedef union YYSTYPE
326 /* Line 214 of yacc.c */
327 #line 209 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
329 long int intval;
330 textint textintval;
331 struct timespec timespec;
335 /* Line 214 of yacc.c */
336 #line 337 "getdate.c"
337 } YYSTYPE;
338 # define YYSTYPE_IS_TRIVIAL 1
339 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
340 # define YYSTYPE_IS_DECLARED 1
341 #endif
344 /* Copy the second part of user declarations. */
347 /* Line 264 of yacc.c */
348 #line 349 "getdate.c"
350 #ifdef short
351 # undef short
352 #endif
354 #ifdef YYTYPE_UINT8
355 typedef YYTYPE_UINT8 yytype_uint8;
356 #else
357 typedef unsigned char yytype_uint8;
358 #endif
360 #ifdef YYTYPE_INT8
361 typedef YYTYPE_INT8 yytype_int8;
362 #elif (defined __STDC__ || defined __C99__FUNC__ \
363 || defined __cplusplus || defined _MSC_VER)
364 typedef signed char yytype_int8;
365 #else
366 typedef short int yytype_int8;
367 #endif
369 #ifdef YYTYPE_UINT16
370 typedef YYTYPE_UINT16 yytype_uint16;
371 #else
372 typedef unsigned short int yytype_uint16;
373 #endif
375 #ifdef YYTYPE_INT16
376 typedef YYTYPE_INT16 yytype_int16;
377 #else
378 typedef short int yytype_int16;
379 #endif
381 #ifndef YYSIZE_T
382 # ifdef __SIZE_TYPE__
383 # define YYSIZE_T __SIZE_TYPE__
384 # elif defined size_t
385 # define YYSIZE_T size_t
386 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
387 || defined __cplusplus || defined _MSC_VER)
388 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
389 # define YYSIZE_T size_t
390 # else
391 # define YYSIZE_T unsigned int
392 # endif
393 #endif
395 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
397 #ifndef YY_
398 # if YYENABLE_NLS
399 # if ENABLE_NLS
400 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
401 # define YY_(msgid) dgettext ("bison-runtime", msgid)
402 # endif
403 # endif
404 # ifndef YY_
405 # define YY_(msgid) msgid
406 # endif
407 #endif
409 /* Suppress unused-variable warnings by "using" E. */
410 #if ! defined lint || defined __GNUC__
411 # define YYUSE(e) ((void) (e))
412 #else
413 # define YYUSE(e) /* empty */
414 #endif
416 /* Identity function, used to suppress warnings about constant conditions. */
417 #ifndef lint
418 # define YYID(n) (n)
419 #else
420 #if (defined __STDC__ || defined __C99__FUNC__ \
421 || defined __cplusplus || defined _MSC_VER)
422 static int
423 YYID (int yyi)
424 #else
425 static int
426 YYID (yyi)
427 int yyi;
428 #endif
430 return yyi;
432 #endif
434 #if ! defined yyoverflow || YYERROR_VERBOSE
436 /* The parser invokes alloca or malloc; define the necessary symbols. */
438 # ifdef YYSTACK_USE_ALLOCA
439 # if YYSTACK_USE_ALLOCA
440 # ifdef __GNUC__
441 # define YYSTACK_ALLOC __builtin_alloca
442 # elif defined __BUILTIN_VA_ARG_INCR
443 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
444 # elif defined _AIX
445 # define YYSTACK_ALLOC __alloca
446 # elif defined _MSC_VER
447 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
448 # define alloca _alloca
449 # else
450 # define YYSTACK_ALLOC alloca
451 # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
452 || defined __cplusplus || defined _MSC_VER)
453 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
454 # ifndef _STDLIB_H
455 # define _STDLIB_H 1
456 # endif
457 # endif
458 # endif
459 # endif
460 # endif
462 # ifdef YYSTACK_ALLOC
463 /* Pacify GCC's `empty if-body' warning. */
464 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
465 # ifndef YYSTACK_ALLOC_MAXIMUM
466 /* The OS might guarantee only one guard page at the bottom of the stack,
467 and a page size can be as small as 4096 bytes. So we cannot safely
468 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
469 to allow for a few compiler-allocated temporary stack slots. */
470 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
471 # endif
472 # else
473 # define YYSTACK_ALLOC YYMALLOC
474 # define YYSTACK_FREE YYFREE
475 # ifndef YYSTACK_ALLOC_MAXIMUM
476 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
477 # endif
478 # if (defined __cplusplus && ! defined _STDLIB_H \
479 && ! ((defined YYMALLOC || defined malloc) \
480 && (defined YYFREE || defined free)))
481 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
482 # ifndef _STDLIB_H
483 # define _STDLIB_H 1
484 # endif
485 # endif
486 # ifndef YYMALLOC
487 # define YYMALLOC malloc
488 # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
489 || defined __cplusplus || defined _MSC_VER)
490 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
491 # endif
492 # endif
493 # ifndef YYFREE
494 # define YYFREE free
495 # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
496 || defined __cplusplus || defined _MSC_VER)
497 void free (void *); /* INFRINGES ON USER NAME SPACE */
498 # endif
499 # endif
500 # endif
501 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
504 #if (! defined yyoverflow \
505 && (! defined __cplusplus \
506 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
508 /* A type that is properly aligned for any stack member. */
509 union yyalloc
511 yytype_int16 yyss_alloc;
512 YYSTYPE yyvs_alloc;
515 /* The size of the maximum gap between one aligned stack and the next. */
516 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
518 /* The size of an array large to enough to hold all stacks, each with
519 N elements. */
520 # define YYSTACK_BYTES(N) \
521 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
522 + YYSTACK_GAP_MAXIMUM)
524 /* Copy COUNT objects from FROM to TO. The source and destination do
525 not overlap. */
526 # ifndef YYCOPY
527 # if defined __GNUC__ && 1 < __GNUC__
528 # define YYCOPY(To, From, Count) \
529 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
530 # else
531 # define YYCOPY(To, From, Count) \
532 do \
534 YYSIZE_T yyi; \
535 for (yyi = 0; yyi < (Count); yyi++) \
536 (To)[yyi] = (From)[yyi]; \
538 while (YYID (0))
539 # endif
540 # endif
542 /* Relocate STACK from its old location to the new one. The
543 local variables YYSIZE and YYSTACKSIZE give the old and new number of
544 elements in the stack, and YYPTR gives the new location of the
545 stack. Advance YYPTR to a properly aligned location for the next
546 stack. */
547 # define YYSTACK_RELOCATE(Stack_alloc, Stack) \
548 do \
550 YYSIZE_T yynewbytes; \
551 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
552 Stack = &yyptr->Stack_alloc; \
553 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
554 yyptr += yynewbytes / sizeof (*yyptr); \
556 while (YYID (0))
558 #endif
560 /* YYFINAL -- State number of the termination state. */
561 #define YYFINAL 12
562 /* YYLAST -- Last index in YYTABLE. */
563 #define YYLAST 92
565 /* YYNTOKENS -- Number of terminals. */
566 #define YYNTOKENS 27
567 /* YYNNTS -- Number of nonterminals. */
568 #define YYNNTS 20
569 /* YYNRULES -- Number of rules. */
570 #define YYNRULES 80
571 /* YYNRULES -- Number of states. */
572 #define YYNSTATES 101
574 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
575 #define YYUNDEFTOK 2
576 #define YYMAXUTOK 276
578 #define YYTRANSLATE(YYX) \
579 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
581 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
582 static const yytype_uint8 yytranslate[] =
584 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
585 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
586 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
587 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
588 2, 2, 2, 2, 25, 2, 23, 26, 2, 2,
589 2, 2, 2, 2, 2, 2, 2, 2, 24, 2,
590 2, 2, 2, 2, 22, 2, 2, 2, 2, 2,
591 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
592 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
593 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
594 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
595 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
596 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
597 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
598 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
599 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
600 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
601 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
602 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
603 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
604 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
605 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
606 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
607 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
608 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
609 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
610 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
611 15, 16, 17, 18, 19, 20, 21
614 #if YYDEBUG
615 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
616 YYRHS. */
617 static const yytype_uint8 yyprhs[] =
619 0, 0, 3, 5, 7, 10, 11, 14, 16, 18,
620 20, 22, 24, 26, 28, 30, 36, 39, 44, 50,
621 57, 65, 67, 70, 72, 75, 79, 81, 84, 86,
622 89, 92, 95, 99, 105, 109, 113, 117, 120, 125,
623 128, 132, 135, 137, 140, 143, 145, 148, 151, 153,
624 156, 159, 161, 164, 167, 169, 172, 175, 177, 180,
625 183, 186, 189, 191, 193, 196, 199, 202, 205, 208,
626 211, 213, 215, 217, 219, 221, 223, 225, 226, 229,
630 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
631 static const yytype_int8 yyrhs[] =
633 28, 0, -1, 29, -1, 30, -1, 22, 41, -1,
634 -1, 30, 31, -1, 33, -1, 34, -1, 35, -1,
635 37, -1, 36, -1, 38, -1, 32, -1, 44, -1,
636 21, 23, 21, 23, 21, -1, 19, 10, -1, 19,
637 24, 19, 46, -1, 19, 24, 19, 18, 45, -1,
638 19, 24, 19, 24, 43, 46, -1, 19, 24, 19,
639 24, 43, 18, 45, -1, 9, -1, 9, 4, -1,
640 17, -1, 17, 40, -1, 17, 18, 45, -1, 7,
641 -1, 17, 4, -1, 5, -1, 5, 25, -1, 14,
642 5, -1, 19, 5, -1, 19, 26, 19, -1, 19,
643 26, 19, 26, 19, -1, 19, 18, 18, -1, 19,
644 12, 18, -1, 12, 18, 18, -1, 12, 19, -1,
645 12, 19, 25, 19, -1, 19, 12, -1, 19, 12,
646 19, -1, 39, 3, -1, 39, -1, 14, 16, -1,
647 19, 16, -1, 16, -1, 14, 13, -1, 19, 13,
648 -1, 13, -1, 14, 6, -1, 19, 6, -1, 6,
649 -1, 14, 8, -1, 19, 8, -1, 8, -1, 14,
650 11, -1, 19, 11, -1, 11, -1, 14, 15, -1,
651 19, 15, -1, 20, 15, -1, 21, 15, -1, 15,
652 -1, 40, -1, 18, 16, -1, 18, 13, -1, 18,
653 6, -1, 18, 8, -1, 18, 11, -1, 18, 15,
654 -1, 42, -1, 43, -1, 20, -1, 18, -1, 21,
655 -1, 19, -1, 19, -1, -1, 24, 19, -1, -1,
656 10, -1
659 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
660 static const yytype_uint16 yyrline[] =
662 0, 230, 230, 231, 235, 242, 244, 248, 250, 252,
663 254, 256, 258, 260, 266, 269, 296, 304, 312, 322,
664 329, 341, 346, 354, 356, 358, 360, 362, 367, 372,
665 377, 382, 390, 395, 415, 422, 430, 438, 443, 449,
666 454, 463, 473, 477, 479, 481, 483, 485, 487, 489,
667 491, 493, 495, 497, 499, 501, 503, 505, 507, 509,
668 511, 513, 515, 517, 521, 523, 525, 527, 529, 531,
669 535, 535, 538, 539, 544, 545, 550, 588, 589, 595,
672 #endif
674 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
675 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
676 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
677 static const char *const yytname[] =
679 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
680 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
681 "tMONTH", "tMONTH_UNIT", "tORDINAL", "tSEC_UNIT", "tYEAR_UNIT", "tZONE",
682 "tSNUMBER", "tUNUMBER", "tSDECIMAL_NUMBER", "tUDECIMAL_NUMBER", "'@'",
683 "'.'", "':'", "','", "'/'", "$accept", "spec", "timespec", "items",
684 "item", "cvsstamp", "time", "local_zone", "zone", "day", "date", "rel",
685 "relunit", "relunit_snumber", "seconds", "signed_seconds",
686 "unsigned_seconds", "number", "o_colon_minutes", "o_merid", 0
688 #endif
690 # ifdef YYPRINT
691 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
692 token YYLEX-NUM. */
693 static const yytype_uint16 yytoknum[] =
695 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
696 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
697 275, 276, 64, 46, 58, 44, 47
699 # endif
701 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
702 static const yytype_uint8 yyr1[] =
704 0, 27, 28, 28, 29, 30, 30, 31, 31, 31,
705 31, 31, 31, 31, 31, 32, 33, 33, 33, 33,
706 33, 34, 34, 35, 35, 35, 35, 35, 36, 36,
707 36, 36, 37, 37, 37, 37, 37, 37, 37, 37,
708 37, 38, 38, 39, 39, 39, 39, 39, 39, 39,
709 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
710 39, 39, 39, 39, 40, 40, 40, 40, 40, 40,
711 41, 41, 42, 42, 43, 43, 44, 45, 45, 46,
715 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
716 static const yytype_uint8 yyr2[] =
718 0, 2, 1, 1, 2, 0, 2, 1, 1, 1,
719 1, 1, 1, 1, 1, 5, 2, 4, 5, 6,
720 7, 1, 2, 1, 2, 3, 1, 2, 1, 2,
721 2, 2, 3, 5, 3, 3, 3, 2, 4, 2,
722 3, 2, 1, 2, 2, 1, 2, 2, 1, 2,
723 2, 1, 2, 2, 1, 2, 2, 1, 2, 2,
724 2, 2, 1, 1, 2, 2, 2, 2, 2, 2,
725 1, 1, 1, 1, 1, 1, 1, 0, 2, 0,
729 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
730 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
731 means the default is an error. */
732 static const yytype_uint8 yydefact[] =
734 5, 0, 0, 2, 3, 73, 75, 72, 74, 4,
735 70, 71, 1, 28, 51, 26, 54, 21, 57, 0,
736 48, 0, 62, 45, 23, 0, 76, 0, 0, 6,
737 13, 7, 8, 9, 11, 10, 12, 42, 63, 14,
738 29, 22, 0, 37, 30, 49, 52, 55, 46, 58,
739 43, 27, 77, 24, 66, 67, 68, 65, 69, 64,
740 31, 50, 53, 16, 56, 39, 47, 59, 44, 0,
741 0, 0, 60, 61, 0, 41, 36, 0, 0, 25,
742 35, 40, 34, 79, 32, 0, 38, 78, 80, 77,
743 0, 17, 0, 0, 18, 79, 33, 15, 77, 19,
747 /* YYDEFGOTO[NTERM-NUM]. */
748 static const yytype_int8 yydefgoto[] =
750 -1, 2, 3, 4, 29, 30, 31, 32, 33, 34,
751 35, 36, 37, 38, 9, 10, 11, 39, 79, 91
754 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
755 STATE-NUM. */
756 #define YYPACT_NINF -76
757 static const yytype_int8 yypact[] =
759 -13, 45, 67, -76, 23, -76, -76, -76, -76, -76,
760 -76, -76, -76, 47, -76, -76, -76, 69, -76, 8,
761 -76, 40, -76, -76, -2, 46, -5, 56, 35, -76,
762 -76, -76, -76, -76, -76, -76, -76, 71, -76, -76,
763 -76, -76, 57, 52, -76, -76, -76, -76, -76, -76,
764 -76, -76, 9, -76, -76, -76, -76, -76, -76, -76,
765 -76, -76, -76, -76, -76, 51, -76, -76, -76, 58,
766 59, 60, -76, -76, 61, -76, -76, 62, 64, -76,
767 -76, -76, -76, -6, 54, 63, -76, -76, -76, 65,
768 28, -76, 66, 70, -76, 50, -76, -76, 65, -76,
772 /* YYPGOTO[NTERM-NUM]. */
773 static const yytype_int8 yypgoto[] =
775 -76, -76, -76, -76, -76, -76, -76, -76, -76, -76,
776 -76, -76, -76, 68, -76, -76, -3, -76, -75, -11
779 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
780 positive, shift that token. If negative, reduce the rule which
781 number is the opposite. If zero, do what YYDEFACT says.
782 If YYTABLE_NINF, syntax error. */
783 #define YYTABLE_NINF -1
784 static const yytype_uint8 yytable[] =
786 60, 61, 51, 62, 88, 63, 64, 65, 66, 1,
787 67, 68, 89, 69, 94, 54, 52, 55, 90, 70,
788 56, 71, 57, 100, 58, 59, 42, 43, 13, 14,
789 15, 16, 17, 78, 18, 19, 20, 21, 22, 23,
790 24, 25, 26, 27, 28, 44, 45, 6, 46, 8,
791 73, 47, 54, 48, 55, 49, 50, 56, 74, 57,
792 88, 58, 59, 5, 6, 7, 8, 12, 98, 80,
793 81, 72, 40, 41, 75, 76, 82, 77, 83, 84,
794 92, 86, 85, 87, 99, 96, 93, 95, 0, 78,
795 0, 97, 53
798 static const yytype_int8 yycheck[] =
800 5, 6, 4, 8, 10, 10, 11, 12, 13, 22,
801 15, 16, 18, 18, 89, 6, 18, 8, 24, 24,
802 11, 26, 13, 98, 15, 16, 18, 19, 5, 6,
803 7, 8, 9, 24, 11, 12, 13, 14, 15, 16,
804 17, 18, 19, 20, 21, 5, 6, 19, 8, 21,
805 15, 11, 6, 13, 8, 15, 16, 11, 23, 13,
806 10, 15, 16, 18, 19, 20, 21, 0, 18, 18,
807 19, 15, 25, 4, 3, 18, 18, 25, 19, 19,
808 26, 19, 21, 19, 95, 19, 23, 90, -1, 24,
809 -1, 21, 24
812 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
813 symbol of state STATE-NUM. */
814 static const yytype_uint8 yystos[] =
816 0, 22, 28, 29, 30, 18, 19, 20, 21, 41,
817 42, 43, 0, 5, 6, 7, 8, 9, 11, 12,
818 13, 14, 15, 16, 17, 18, 19, 20, 21, 31,
819 32, 33, 34, 35, 36, 37, 38, 39, 40, 44,
820 25, 4, 18, 19, 5, 6, 8, 11, 13, 15,
821 16, 4, 18, 40, 6, 8, 11, 13, 15, 16,
822 5, 6, 8, 10, 11, 12, 13, 15, 16, 18,
823 24, 26, 15, 15, 23, 3, 18, 25, 24, 45,
824 18, 19, 18, 19, 19, 21, 19, 19, 10, 18,
825 24, 46, 26, 23, 45, 43, 19, 21, 18, 46,
829 #define yyerrok (yyerrstatus = 0)
830 #define yyclearin (yychar = YYEMPTY)
831 #define YYEMPTY (-2)
832 #define YYEOF 0
834 #define YYACCEPT goto yyacceptlab
835 #define YYABORT goto yyabortlab
836 #define YYERROR goto yyerrorlab
839 /* Like YYERROR except do call yyerror. This remains here temporarily
840 to ease the transition to the new meaning of YYERROR, for GCC.
841 Once GCC version 2 has supplanted version 1, this can go. */
843 #define YYFAIL goto yyerrlab
845 #define YYRECOVERING() (!!yyerrstatus)
847 #define YYBACKUP(Token, Value) \
848 do \
849 if (yychar == YYEMPTY && yylen == 1) \
851 yychar = (Token); \
852 yylval = (Value); \
853 yytoken = YYTRANSLATE (yychar); \
854 YYPOPSTACK (1); \
855 goto yybackup; \
857 else \
859 yyerror (pc, YY_("syntax error: cannot back up")); \
860 YYERROR; \
862 while (YYID (0))
865 #define YYTERROR 1
866 #define YYERRCODE 256
869 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
870 If N is 0, then set CURRENT to the empty location which ends
871 the previous symbol: RHS[0] (always defined). */
873 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
874 #ifndef YYLLOC_DEFAULT
875 # define YYLLOC_DEFAULT(Current, Rhs, N) \
876 do \
877 if (YYID (N)) \
879 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
880 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
881 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
882 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
884 else \
886 (Current).first_line = (Current).last_line = \
887 YYRHSLOC (Rhs, 0).last_line; \
888 (Current).first_column = (Current).last_column = \
889 YYRHSLOC (Rhs, 0).last_column; \
891 while (YYID (0))
892 #endif
895 /* YY_LOCATION_PRINT -- Print the location on the stream.
896 This macro was not mandated originally: define only if we know
897 we won't break user code: when these are the locations we know. */
899 #ifndef YY_LOCATION_PRINT
900 # if YYLTYPE_IS_TRIVIAL
901 # define YY_LOCATION_PRINT(File, Loc) \
902 fprintf (File, "%d.%d-%d.%d", \
903 (Loc).first_line, (Loc).first_column, \
904 (Loc).last_line, (Loc).last_column)
905 # else
906 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
907 # endif
908 #endif
911 /* YYLEX -- calling `yylex' with the right arguments. */
913 #ifdef YYLEX_PARAM
914 # define YYLEX yylex (&yylval, YYLEX_PARAM)
915 #else
916 # define YYLEX yylex (&yylval, pc)
917 #endif
919 /* Enable debugging if requested. */
920 #if YYDEBUG
922 # ifndef YYFPRINTF
923 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
924 # define YYFPRINTF fprintf
925 # endif
927 # define YYDPRINTF(Args) \
928 do { \
929 if (yydebug) \
930 YYFPRINTF Args; \
931 } while (YYID (0))
933 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
934 do { \
935 if (yydebug) \
937 YYFPRINTF (stderr, "%s ", Title); \
938 yy_symbol_print (stderr, \
939 Type, Value, pc); \
940 YYFPRINTF (stderr, "\n"); \
942 } while (YYID (0))
945 /*--------------------------------.
946 | Print this symbol on YYOUTPUT. |
947 `--------------------------------*/
949 /*ARGSUSED*/
950 #if (defined __STDC__ || defined __C99__FUNC__ \
951 || defined __cplusplus || defined _MSC_VER)
952 static void
953 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)
954 #else
955 static void
956 yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc)
957 FILE *yyoutput;
958 int yytype;
959 YYSTYPE const * const yyvaluep;
960 parser_control *pc;
961 #endif
963 if (!yyvaluep)
964 return;
965 YYUSE (pc);
966 # ifdef YYPRINT
967 if (yytype < YYNTOKENS)
968 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
969 # else
970 YYUSE (yyoutput);
971 # endif
972 switch (yytype)
974 default:
975 break;
980 /*--------------------------------.
981 | Print this symbol on YYOUTPUT. |
982 `--------------------------------*/
984 #if (defined __STDC__ || defined __C99__FUNC__ \
985 || defined __cplusplus || defined _MSC_VER)
986 static void
987 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)
988 #else
989 static void
990 yy_symbol_print (yyoutput, yytype, yyvaluep, pc)
991 FILE *yyoutput;
992 int yytype;
993 YYSTYPE const * const yyvaluep;
994 parser_control *pc;
995 #endif
997 if (yytype < YYNTOKENS)
998 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
999 else
1000 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
1002 yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc);
1003 YYFPRINTF (yyoutput, ")");
1006 /*------------------------------------------------------------------.
1007 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
1008 | TOP (included). |
1009 `------------------------------------------------------------------*/
1011 #if (defined __STDC__ || defined __C99__FUNC__ \
1012 || defined __cplusplus || defined _MSC_VER)
1013 static void
1014 yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1015 #else
1016 static void
1017 yy_stack_print (yybottom, yytop)
1018 yytype_int16 *yybottom;
1019 yytype_int16 *yytop;
1020 #endif
1022 YYFPRINTF (stderr, "Stack now");
1023 for (; yybottom <= yytop; yybottom++)
1025 int yybot = *yybottom;
1026 YYFPRINTF (stderr, " %d", yybot);
1028 YYFPRINTF (stderr, "\n");
1031 # define YY_STACK_PRINT(Bottom, Top) \
1032 do { \
1033 if (yydebug) \
1034 yy_stack_print ((Bottom), (Top)); \
1035 } while (YYID (0))
1038 /*------------------------------------------------.
1039 | Report that the YYRULE is going to be reduced. |
1040 `------------------------------------------------*/
1042 #if (defined __STDC__ || defined __C99__FUNC__ \
1043 || defined __cplusplus || defined _MSC_VER)
1044 static void
1045 yy_reduce_print (YYSTYPE *yyvsp, int yyrule, parser_control *pc)
1046 #else
1047 static void
1048 yy_reduce_print (yyvsp, yyrule, pc)
1049 YYSTYPE *yyvsp;
1050 int yyrule;
1051 parser_control *pc;
1052 #endif
1054 int yynrhs = yyr2[yyrule];
1055 int yyi;
1056 unsigned long int yylno = yyrline[yyrule];
1057 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1058 yyrule - 1, yylno);
1059 /* The symbols being reduced. */
1060 for (yyi = 0; yyi < yynrhs; yyi++)
1062 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1063 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
1064 &(yyvsp[(yyi + 1) - (yynrhs)])
1065 , pc);
1066 YYFPRINTF (stderr, "\n");
1070 # define YY_REDUCE_PRINT(Rule) \
1071 do { \
1072 if (yydebug) \
1073 yy_reduce_print (yyvsp, Rule, pc); \
1074 } while (YYID (0))
1076 /* Nonzero means print parse trace. It is left uninitialized so that
1077 multiple parsers can coexist. */
1078 int yydebug;
1079 #else /* !YYDEBUG */
1080 # define YYDPRINTF(Args)
1081 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1082 # define YY_STACK_PRINT(Bottom, Top)
1083 # define YY_REDUCE_PRINT(Rule)
1084 #endif /* !YYDEBUG */
1087 /* YYINITDEPTH -- initial size of the parser's stacks. */
1088 #ifndef YYINITDEPTH
1089 # define YYINITDEPTH 200
1090 #endif
1092 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1093 if the built-in stack extension method is used).
1095 Do not make this value too large; the results are undefined if
1096 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1097 evaluated with infinite-precision integer arithmetic. */
1099 #ifndef YYMAXDEPTH
1100 # define YYMAXDEPTH 10000
1101 #endif
1105 #if YYERROR_VERBOSE
1107 # ifndef yystrlen
1108 # if defined __GLIBC__ && defined _STRING_H
1109 # define yystrlen strlen
1110 # else
1111 /* Return the length of YYSTR. */
1112 #if (defined __STDC__ || defined __C99__FUNC__ \
1113 || defined __cplusplus || defined _MSC_VER)
1114 static YYSIZE_T
1115 yystrlen (const char *yystr)
1116 #else
1117 static YYSIZE_T
1118 yystrlen (yystr)
1119 const char *yystr;
1120 #endif
1122 YYSIZE_T yylen;
1123 for (yylen = 0; yystr[yylen]; yylen++)
1124 continue;
1125 return yylen;
1127 # endif
1128 # endif
1130 # ifndef yystpcpy
1131 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1132 # define yystpcpy stpcpy
1133 # else
1134 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1135 YYDEST. */
1136 #if (defined __STDC__ || defined __C99__FUNC__ \
1137 || defined __cplusplus || defined _MSC_VER)
1138 static char *
1139 yystpcpy (char *yydest, const char *yysrc)
1140 #else
1141 static char *
1142 yystpcpy (yydest, yysrc)
1143 char *yydest;
1144 const char *yysrc;
1145 #endif
1147 char *yyd = yydest;
1148 const char *yys = yysrc;
1150 while ((*yyd++ = *yys++) != '\0')
1151 continue;
1153 return yyd - 1;
1155 # endif
1156 # endif
1158 # ifndef yytnamerr
1159 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1160 quotes and backslashes, so that it's suitable for yyerror. The
1161 heuristic is that double-quoting is unnecessary unless the string
1162 contains an apostrophe, a comma, or backslash (other than
1163 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1164 null, do not copy; instead, return the length of what the result
1165 would have been. */
1166 static YYSIZE_T
1167 yytnamerr (char *yyres, const char *yystr)
1169 if (*yystr == '"')
1171 YYSIZE_T yyn = 0;
1172 char const *yyp = yystr;
1174 for (;;)
1175 switch (*++yyp)
1177 case '\'':
1178 case ',':
1179 goto do_not_strip_quotes;
1181 case '\\':
1182 if (*++yyp != '\\')
1183 goto do_not_strip_quotes;
1184 /* Fall through. */
1185 default:
1186 if (yyres)
1187 yyres[yyn] = *yyp;
1188 yyn++;
1189 break;
1191 case '"':
1192 if (yyres)
1193 yyres[yyn] = '\0';
1194 return yyn;
1196 do_not_strip_quotes: ;
1199 if (! yyres)
1200 return yystrlen (yystr);
1202 return yystpcpy (yyres, yystr) - yyres;
1204 # endif
1206 /* Copy into YYRESULT an error message about the unexpected token
1207 YYCHAR while in state YYSTATE. Return the number of bytes copied,
1208 including the terminating null byte. If YYRESULT is null, do not
1209 copy anything; just return the number of bytes that would be
1210 copied. As a special case, return 0 if an ordinary "syntax error"
1211 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1212 size calculation. */
1213 static YYSIZE_T
1214 yysyntax_error (char *yyresult, int yystate, int yychar)
1216 int yyn = yypact[yystate];
1218 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1219 return 0;
1220 else
1222 int yytype = YYTRANSLATE (yychar);
1223 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1224 YYSIZE_T yysize = yysize0;
1225 YYSIZE_T yysize1;
1226 int yysize_overflow = 0;
1227 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1228 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1229 int yyx;
1231 # if 0
1232 /* This is so xgettext sees the translatable formats that are
1233 constructed on the fly. */
1234 YY_("syntax error, unexpected %s");
1235 YY_("syntax error, unexpected %s, expecting %s");
1236 YY_("syntax error, unexpected %s, expecting %s or %s");
1237 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1238 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1239 # endif
1240 char *yyfmt;
1241 char const *yyf;
1242 static char const yyunexpected[] = "syntax error, unexpected %s";
1243 static char const yyexpecting[] = ", expecting %s";
1244 static char const yyor[] = " or %s";
1245 char yyformat[sizeof yyunexpected
1246 + sizeof yyexpecting - 1
1247 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1248 * (sizeof yyor - 1))];
1249 char const *yyprefix = yyexpecting;
1251 /* Start YYX at -YYN if negative to avoid negative indexes in
1252 YYCHECK. */
1253 int yyxbegin = yyn < 0 ? -yyn : 0;
1255 /* Stay within bounds of both yycheck and yytname. */
1256 int yychecklim = YYLAST - yyn + 1;
1257 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1258 int yycount = 1;
1260 yyarg[0] = yytname[yytype];
1261 yyfmt = yystpcpy (yyformat, yyunexpected);
1263 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1264 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1266 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1268 yycount = 1;
1269 yysize = yysize0;
1270 yyformat[sizeof yyunexpected - 1] = '\0';
1271 break;
1273 yyarg[yycount++] = yytname[yyx];
1274 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1275 yysize_overflow |= (yysize1 < yysize);
1276 yysize = yysize1;
1277 yyfmt = yystpcpy (yyfmt, yyprefix);
1278 yyprefix = yyor;
1281 yyf = YY_(yyformat);
1282 yysize1 = yysize + yystrlen (yyf);
1283 yysize_overflow |= (yysize1 < yysize);
1284 yysize = yysize1;
1286 if (yysize_overflow)
1287 return YYSIZE_MAXIMUM;
1289 if (yyresult)
1291 /* Avoid sprintf, as that infringes on the user's name space.
1292 Don't have undefined behavior even if the translation
1293 produced a string with the wrong number of "%s"s. */
1294 char *yyp = yyresult;
1295 int yyi = 0;
1296 while ((*yyp = *yyf) != '\0')
1298 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1300 yyp += yytnamerr (yyp, yyarg[yyi++]);
1301 yyf += 2;
1303 else
1305 yyp++;
1306 yyf++;
1310 return yysize;
1313 #endif /* YYERROR_VERBOSE */
1316 /*-----------------------------------------------.
1317 | Release the memory associated to this symbol. |
1318 `-----------------------------------------------*/
1320 /*ARGSUSED*/
1321 #if (defined __STDC__ || defined __C99__FUNC__ \
1322 || defined __cplusplus || defined _MSC_VER)
1323 static void
1324 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_control *pc)
1325 #else
1326 static void
1327 yydestruct (yymsg, yytype, yyvaluep, pc)
1328 const char *yymsg;
1329 int yytype;
1330 YYSTYPE *yyvaluep;
1331 parser_control *pc;
1332 #endif
1334 YYUSE (yyvaluep);
1335 YYUSE (pc);
1337 if (!yymsg)
1338 yymsg = "Deleting";
1339 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1341 switch (yytype)
1344 default:
1345 break;
1349 /* Prevent warnings from -Wmissing-prototypes. */
1350 #ifdef YYPARSE_PARAM
1351 #if defined __STDC__ || defined __cplusplus
1352 int yyparse (void *YYPARSE_PARAM);
1353 #else
1354 int yyparse ();
1355 #endif
1356 #else /* ! YYPARSE_PARAM */
1357 #if defined __STDC__ || defined __cplusplus
1358 int yyparse (parser_control *pc);
1359 #else
1360 int yyparse ();
1361 #endif
1362 #endif /* ! YYPARSE_PARAM */
1368 /*-------------------------.
1369 | yyparse or yypush_parse. |
1370 `-------------------------*/
1372 #ifdef YYPARSE_PARAM
1373 #if (defined __STDC__ || defined __C99__FUNC__ \
1374 || defined __cplusplus || defined _MSC_VER)
1376 yyparse (void *YYPARSE_PARAM)
1377 #else
1379 yyparse (YYPARSE_PARAM)
1380 void *YYPARSE_PARAM;
1381 #endif
1382 #else /* ! YYPARSE_PARAM */
1383 #if (defined __STDC__ || defined __C99__FUNC__ \
1384 || defined __cplusplus || defined _MSC_VER)
1386 yyparse (parser_control *pc)
1387 #else
1389 yyparse (pc)
1390 parser_control *pc;
1391 #endif
1392 #endif
1394 /* The lookahead symbol. */
1395 int yychar;
1397 /* The semantic value of the lookahead symbol. */
1398 YYSTYPE yylval;
1400 /* Number of syntax errors so far. */
1401 int yynerrs;
1403 int yystate;
1404 /* Number of tokens to shift before error messages enabled. */
1405 int yyerrstatus;
1407 /* The stacks and their tools:
1408 `yyss': related to states.
1409 `yyvs': related to semantic values.
1411 Refer to the stacks thru separate pointers, to allow yyoverflow
1412 to reallocate them elsewhere. */
1414 /* The state stack. */
1415 yytype_int16 yyssa[YYINITDEPTH];
1416 yytype_int16 *yyss;
1417 yytype_int16 *yyssp;
1419 /* The semantic value stack. */
1420 YYSTYPE yyvsa[YYINITDEPTH];
1421 YYSTYPE *yyvs;
1422 YYSTYPE *yyvsp;
1424 YYSIZE_T yystacksize;
1426 int yyn;
1427 int yyresult;
1428 /* Lookahead token as an internal (translated) token number. */
1429 int yytoken;
1430 /* The variables used to return semantic value and location from the
1431 action routines. */
1432 YYSTYPE yyval;
1434 #if YYERROR_VERBOSE
1435 /* Buffer for error messages, and its allocated size. */
1436 char yymsgbuf[128];
1437 char *yymsg = yymsgbuf;
1438 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1439 #endif
1441 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1443 /* The number of symbols on the RHS of the reduced rule.
1444 Keep to zero when no symbol should be popped. */
1445 int yylen = 0;
1447 yytoken = 0;
1448 yyss = yyssa;
1449 yyvs = yyvsa;
1450 yystacksize = YYINITDEPTH;
1452 YYDPRINTF ((stderr, "Starting parse\n"));
1454 yystate = 0;
1455 yyerrstatus = 0;
1456 yynerrs = 0;
1457 yychar = YYEMPTY; /* Cause a token to be read. */
1459 /* Initialize stack pointers.
1460 Waste one element of value and location stack
1461 so that they stay on the same level as the state stack.
1462 The wasted elements are never initialized. */
1463 yyssp = yyss;
1464 yyvsp = yyvs;
1466 goto yysetstate;
1468 /*------------------------------------------------------------.
1469 | yynewstate -- Push a new state, which is found in yystate. |
1470 `------------------------------------------------------------*/
1471 yynewstate:
1472 /* In all cases, when you get here, the value and location stacks
1473 have just been pushed. So pushing a state here evens the stacks. */
1474 yyssp++;
1476 yysetstate:
1477 *yyssp = yystate;
1479 if (yyss + yystacksize - 1 <= yyssp)
1481 /* Get the current used size of the three stacks, in elements. */
1482 YYSIZE_T yysize = yyssp - yyss + 1;
1484 #ifdef yyoverflow
1486 /* Give user a chance to reallocate the stack. Use copies of
1487 these so that the &'s don't force the real ones into
1488 memory. */
1489 YYSTYPE *yyvs1 = yyvs;
1490 yytype_int16 *yyss1 = yyss;
1492 /* Each stack pointer address is followed by the size of the
1493 data in use in that stack, in bytes. This used to be a
1494 conditional around just the two extra args, but that might
1495 be undefined if yyoverflow is a macro. */
1496 yyoverflow (YY_("memory exhausted"),
1497 &yyss1, yysize * sizeof (*yyssp),
1498 &yyvs1, yysize * sizeof (*yyvsp),
1499 &yystacksize);
1501 yyss = yyss1;
1502 yyvs = yyvs1;
1504 #else /* no yyoverflow */
1505 # ifndef YYSTACK_RELOCATE
1506 goto yyexhaustedlab;
1507 # else
1508 /* Extend the stack our own way. */
1509 if (YYMAXDEPTH <= yystacksize)
1510 goto yyexhaustedlab;
1511 yystacksize *= 2;
1512 if (YYMAXDEPTH < yystacksize)
1513 yystacksize = YYMAXDEPTH;
1516 yytype_int16 *yyss1 = yyss;
1517 union yyalloc *yyptr =
1518 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1519 if (! yyptr)
1520 goto yyexhaustedlab;
1521 YYSTACK_RELOCATE (yyss_alloc, yyss);
1522 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1523 # undef YYSTACK_RELOCATE
1524 if (yyss1 != yyssa)
1525 YYSTACK_FREE (yyss1);
1527 # endif
1528 #endif /* no yyoverflow */
1530 yyssp = yyss + yysize - 1;
1531 yyvsp = yyvs + yysize - 1;
1533 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1534 (unsigned long int) yystacksize));
1536 if (yyss + yystacksize - 1 <= yyssp)
1537 YYABORT;
1540 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1542 if (yystate == YYFINAL)
1543 YYACCEPT;
1545 goto yybackup;
1547 /*-----------.
1548 | yybackup. |
1549 `-----------*/
1550 yybackup:
1552 /* Do appropriate processing given the current state. Read a
1553 lookahead token if we need one and don't already have one. */
1555 /* First try to decide what to do without reference to lookahead token. */
1556 yyn = yypact[yystate];
1557 if (yyn == YYPACT_NINF)
1558 goto yydefault;
1560 /* Not known => get a lookahead token if don't already have one. */
1562 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1563 if (yychar == YYEMPTY)
1565 YYDPRINTF ((stderr, "Reading a token: "));
1566 yychar = YYLEX;
1569 if (yychar <= YYEOF)
1571 yychar = yytoken = YYEOF;
1572 YYDPRINTF ((stderr, "Now at end of input.\n"));
1574 else
1576 yytoken = YYTRANSLATE (yychar);
1577 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1580 /* If the proper action on seeing token YYTOKEN is to reduce or to
1581 detect an error, take that action. */
1582 yyn += yytoken;
1583 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1584 goto yydefault;
1585 yyn = yytable[yyn];
1586 if (yyn <= 0)
1588 if (yyn == 0 || yyn == YYTABLE_NINF)
1589 goto yyerrlab;
1590 yyn = -yyn;
1591 goto yyreduce;
1594 /* Count tokens shifted since error; after three, turn off error
1595 status. */
1596 if (yyerrstatus)
1597 yyerrstatus--;
1599 /* Shift the lookahead token. */
1600 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1602 /* Discard the shifted token. */
1603 yychar = YYEMPTY;
1605 yystate = yyn;
1606 *++yyvsp = yylval;
1608 goto yynewstate;
1611 /*-----------------------------------------------------------.
1612 | yydefault -- do the default action for the current state. |
1613 `-----------------------------------------------------------*/
1614 yydefault:
1615 yyn = yydefact[yystate];
1616 if (yyn == 0)
1617 goto yyerrlab;
1618 goto yyreduce;
1621 /*-----------------------------.
1622 | yyreduce -- Do a reduction. |
1623 `-----------------------------*/
1624 yyreduce:
1625 /* yyn is the number of a rule to reduce with. */
1626 yylen = yyr2[yyn];
1628 /* If YYLEN is nonzero, implement the default value of the action:
1629 `$$ = $1'.
1631 Otherwise, the following line sets YYVAL to garbage.
1632 This behavior is undocumented and Bison
1633 users should not rely upon it. Assigning to YYVAL
1634 unconditionally makes the parser a bit smaller, and it avoids a
1635 GCC warning that YYVAL may be used uninitialized. */
1636 yyval = yyvsp[1-yylen];
1639 YY_REDUCE_PRINT (yyn);
1640 switch (yyn)
1642 case 4:
1644 /* Line 1455 of yacc.c */
1645 #line 236 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1647 pc->seconds = (yyvsp[(2) - (2)].timespec);
1648 pc->timespec_seen = true;
1650 break;
1652 case 7:
1654 /* Line 1455 of yacc.c */
1655 #line 249 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1656 { pc->times_seen++; ;}
1657 break;
1659 case 8:
1661 /* Line 1455 of yacc.c */
1662 #line 251 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1663 { pc->local_zones_seen++; ;}
1664 break;
1666 case 9:
1668 /* Line 1455 of yacc.c */
1669 #line 253 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1670 { pc->zones_seen++; ;}
1671 break;
1673 case 10:
1675 /* Line 1455 of yacc.c */
1676 #line 255 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1677 { pc->dates_seen++; ;}
1678 break;
1680 case 11:
1682 /* Line 1455 of yacc.c */
1683 #line 257 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1684 { pc->days_seen++; ;}
1685 break;
1687 case 12:
1689 /* Line 1455 of yacc.c */
1690 #line 259 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1691 { pc->rels_seen = true; ;}
1692 break;
1694 case 13:
1696 /* Line 1455 of yacc.c */
1697 #line 261 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1699 pc->dates_seen++;
1700 pc->zones_seen++;
1701 pc->times_seen++;
1703 break;
1705 case 15:
1707 /* Line 1455 of yacc.c */
1708 #line 270 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1710 int i;
1711 pc->year.negative = 0;
1712 pc->year.value = (yyvsp[(1) - (5)].timespec).tv_sec;
1714 if (pc->year.value < 70)
1715 pc->year.value += 2000;
1716 else if (pc->year.value < 100)
1717 pc->year.value += 1900;
1719 for (i = pc->year.value, pc->year.digits = 0; i; i /= 10, pc->year.digits++)
1720 continue;
1721 if (pc->year.digits == 0)
1722 pc->year.digits++;
1724 pc->month = (yyvsp[(1) - (5)].timespec).tv_nsec / 10000000;
1725 pc->day = (yyvsp[(3) - (5)].timespec).tv_sec;
1726 pc->hour = (yyvsp[(3) - (5)].timespec).tv_nsec / 10000000;
1727 pc->minutes = (yyvsp[(5) - (5)].timespec).tv_sec;
1728 pc->seconds.tv_sec = (yyvsp[(5) - (5)].timespec).tv_nsec / 10000000;
1729 pc->seconds.tv_nsec = 0;
1730 pc->meridian = MER24;
1731 pc->time_zone = 0;
1733 break;
1735 case 16:
1737 /* Line 1455 of yacc.c */
1738 #line 297 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1740 pc->hour = (yyvsp[(1) - (2)].textintval).value;
1741 pc->minutes = 0;
1742 pc->seconds.tv_sec = 0;
1743 pc->seconds.tv_nsec = 0;
1744 pc->meridian = (yyvsp[(2) - (2)].intval);
1746 break;
1748 case 17:
1750 /* Line 1455 of yacc.c */
1751 #line 305 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1753 pc->hour = (yyvsp[(1) - (4)].textintval).value;
1754 pc->minutes = (yyvsp[(3) - (4)].textintval).value;
1755 pc->seconds.tv_sec = 0;
1756 pc->seconds.tv_nsec = 0;
1757 pc->meridian = (yyvsp[(4) - (4)].intval);
1759 break;
1761 case 18:
1763 /* Line 1455 of yacc.c */
1764 #line 313 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1766 pc->hour = (yyvsp[(1) - (5)].textintval).value;
1767 pc->minutes = (yyvsp[(3) - (5)].textintval).value;
1768 pc->seconds.tv_sec = 0;
1769 pc->seconds.tv_nsec = 0;
1770 pc->meridian = MER24;
1771 pc->zones_seen++;
1772 pc->time_zone = time_zone_hhmm ((yyvsp[(4) - (5)].textintval), (yyvsp[(5) - (5)].intval));
1774 break;
1776 case 19:
1778 /* Line 1455 of yacc.c */
1779 #line 323 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1781 pc->hour = (yyvsp[(1) - (6)].textintval).value;
1782 pc->minutes = (yyvsp[(3) - (6)].textintval).value;
1783 pc->seconds = (yyvsp[(5) - (6)].timespec);
1784 pc->meridian = (yyvsp[(6) - (6)].intval);
1786 break;
1788 case 20:
1790 /* Line 1455 of yacc.c */
1791 #line 330 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1793 pc->hour = (yyvsp[(1) - (7)].textintval).value;
1794 pc->minutes = (yyvsp[(3) - (7)].textintval).value;
1795 pc->seconds = (yyvsp[(5) - (7)].timespec);
1796 pc->meridian = MER24;
1797 pc->zones_seen++;
1798 pc->time_zone = time_zone_hhmm ((yyvsp[(6) - (7)].textintval), (yyvsp[(7) - (7)].intval));
1800 break;
1802 case 21:
1804 /* Line 1455 of yacc.c */
1805 #line 342 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1807 pc->local_isdst = (yyvsp[(1) - (1)].intval);
1808 pc->dsts_seen += (0 < (yyvsp[(1) - (1)].intval));
1810 break;
1812 case 22:
1814 /* Line 1455 of yacc.c */
1815 #line 347 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1817 pc->local_isdst = 1;
1818 pc->dsts_seen += (0 < (yyvsp[(1) - (2)].intval)) + 1;
1820 break;
1822 case 23:
1824 /* Line 1455 of yacc.c */
1825 #line 355 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1826 { pc->time_zone = (yyvsp[(1) - (1)].intval); ;}
1827 break;
1829 case 24:
1831 /* Line 1455 of yacc.c */
1832 #line 357 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1833 { pc->time_zone = (yyvsp[(1) - (2)].intval); pc->rels_seen = true; ;}
1834 break;
1836 case 25:
1838 /* Line 1455 of yacc.c */
1839 #line 359 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1840 { pc->time_zone = (yyvsp[(1) - (3)].intval) + time_zone_hhmm ((yyvsp[(2) - (3)].textintval), (yyvsp[(3) - (3)].intval)); ;}
1841 break;
1843 case 26:
1845 /* Line 1455 of yacc.c */
1846 #line 361 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1847 { pc->time_zone = (yyvsp[(1) - (1)].intval) + 60; ;}
1848 break;
1850 case 27:
1852 /* Line 1455 of yacc.c */
1853 #line 363 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1854 { pc->time_zone = (yyvsp[(1) - (2)].intval) + 60; ;}
1855 break;
1857 case 28:
1859 /* Line 1455 of yacc.c */
1860 #line 368 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1862 pc->day_ordinal = 1;
1863 pc->day_number = (yyvsp[(1) - (1)].intval);
1865 break;
1867 case 29:
1869 /* Line 1455 of yacc.c */
1870 #line 373 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1872 pc->day_ordinal = 1;
1873 pc->day_number = (yyvsp[(1) - (2)].intval);
1875 break;
1877 case 30:
1879 /* Line 1455 of yacc.c */
1880 #line 378 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1882 pc->day_ordinal = (yyvsp[(1) - (2)].intval);
1883 pc->day_number = (yyvsp[(2) - (2)].intval);
1885 break;
1887 case 31:
1889 /* Line 1455 of yacc.c */
1890 #line 383 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1892 pc->day_ordinal = (yyvsp[(1) - (2)].textintval).value;
1893 pc->day_number = (yyvsp[(2) - (2)].intval);
1895 break;
1897 case 32:
1899 /* Line 1455 of yacc.c */
1900 #line 391 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1902 pc->month = (yyvsp[(1) - (3)].textintval).value;
1903 pc->day = (yyvsp[(3) - (3)].textintval).value;
1905 break;
1907 case 33:
1909 /* Line 1455 of yacc.c */
1910 #line 396 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1912 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1913 otherwise as MM/DD/YY.
1914 The goal in recognizing YYYY/MM/DD is solely to support legacy
1915 machine-generated dates like those in an RCS log listing. If
1916 you want portability, use the ISO 8601 format. */
1917 if (4 <= (yyvsp[(1) - (5)].textintval).digits)
1919 pc->year = (yyvsp[(1) - (5)].textintval);
1920 pc->month = (yyvsp[(3) - (5)].textintval).value;
1921 pc->day = (yyvsp[(5) - (5)].textintval).value;
1923 else
1925 pc->month = (yyvsp[(1) - (5)].textintval).value;
1926 pc->day = (yyvsp[(3) - (5)].textintval).value;
1927 pc->year = (yyvsp[(5) - (5)].textintval);
1930 break;
1932 case 34:
1934 /* Line 1455 of yacc.c */
1935 #line 416 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1937 /* ISO 8601 format. YYYY-MM-DD. */
1938 pc->year = (yyvsp[(1) - (3)].textintval);
1939 pc->month = -(yyvsp[(2) - (3)].textintval).value;
1940 pc->day = -(yyvsp[(3) - (3)].textintval).value;
1942 break;
1944 case 35:
1946 /* Line 1455 of yacc.c */
1947 #line 423 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1949 /* e.g. 17-JUN-1992. */
1950 pc->day = (yyvsp[(1) - (3)].textintval).value;
1951 pc->month = (yyvsp[(2) - (3)].intval);
1952 pc->year.value = -(yyvsp[(3) - (3)].textintval).value;
1953 pc->year.digits = (yyvsp[(3) - (3)].textintval).digits;
1955 break;
1957 case 36:
1959 /* Line 1455 of yacc.c */
1960 #line 431 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1962 /* e.g. JUN-17-1992. */
1963 pc->month = (yyvsp[(1) - (3)].intval);
1964 pc->day = -(yyvsp[(2) - (3)].textintval).value;
1965 pc->year.value = -(yyvsp[(3) - (3)].textintval).value;
1966 pc->year.digits = (yyvsp[(3) - (3)].textintval).digits;
1968 break;
1970 case 37:
1972 /* Line 1455 of yacc.c */
1973 #line 439 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1975 pc->month = (yyvsp[(1) - (2)].intval);
1976 pc->day = (yyvsp[(2) - (2)].textintval).value;
1978 break;
1980 case 38:
1982 /* Line 1455 of yacc.c */
1983 #line 444 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1985 pc->month = (yyvsp[(1) - (4)].intval);
1986 pc->day = (yyvsp[(2) - (4)].textintval).value;
1987 pc->year = (yyvsp[(4) - (4)].textintval);
1989 break;
1991 case 39:
1993 /* Line 1455 of yacc.c */
1994 #line 450 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
1996 pc->day = (yyvsp[(1) - (2)].textintval).value;
1997 pc->month = (yyvsp[(2) - (2)].intval);
1999 break;
2001 case 40:
2003 /* Line 1455 of yacc.c */
2004 #line 455 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2006 pc->day = (yyvsp[(1) - (3)].textintval).value;
2007 pc->month = (yyvsp[(2) - (3)].intval);
2008 pc->year = (yyvsp[(3) - (3)].textintval);
2010 break;
2012 case 41:
2014 /* Line 1455 of yacc.c */
2015 #line 464 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2017 pc->rel_ns = -pc->rel_ns;
2018 pc->rel_seconds = -pc->rel_seconds;
2019 pc->rel_minutes = -pc->rel_minutes;
2020 pc->rel_hour = -pc->rel_hour;
2021 pc->rel_day = -pc->rel_day;
2022 pc->rel_month = -pc->rel_month;
2023 pc->rel_year = -pc->rel_year;
2025 break;
2027 case 43:
2029 /* Line 1455 of yacc.c */
2030 #line 478 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2031 { pc->rel_year += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2032 break;
2034 case 44:
2036 /* Line 1455 of yacc.c */
2037 #line 480 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2038 { pc->rel_year += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2039 break;
2041 case 45:
2043 /* Line 1455 of yacc.c */
2044 #line 482 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2045 { pc->rel_year += (yyvsp[(1) - (1)].intval); ;}
2046 break;
2048 case 46:
2050 /* Line 1455 of yacc.c */
2051 #line 484 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2052 { pc->rel_month += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2053 break;
2055 case 47:
2057 /* Line 1455 of yacc.c */
2058 #line 486 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2059 { pc->rel_month += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2060 break;
2062 case 48:
2064 /* Line 1455 of yacc.c */
2065 #line 488 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2066 { pc->rel_month += (yyvsp[(1) - (1)].intval); ;}
2067 break;
2069 case 49:
2071 /* Line 1455 of yacc.c */
2072 #line 490 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2073 { pc->rel_day += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2074 break;
2076 case 50:
2078 /* Line 1455 of yacc.c */
2079 #line 492 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2080 { pc->rel_day += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2081 break;
2083 case 51:
2085 /* Line 1455 of yacc.c */
2086 #line 494 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2087 { pc->rel_day += (yyvsp[(1) - (1)].intval); ;}
2088 break;
2090 case 52:
2092 /* Line 1455 of yacc.c */
2093 #line 496 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2094 { pc->rel_hour += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2095 break;
2097 case 53:
2099 /* Line 1455 of yacc.c */
2100 #line 498 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2101 { pc->rel_hour += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2102 break;
2104 case 54:
2106 /* Line 1455 of yacc.c */
2107 #line 500 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2108 { pc->rel_hour += (yyvsp[(1) - (1)].intval); ;}
2109 break;
2111 case 55:
2113 /* Line 1455 of yacc.c */
2114 #line 502 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2115 { pc->rel_minutes += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2116 break;
2118 case 56:
2120 /* Line 1455 of yacc.c */
2121 #line 504 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2122 { pc->rel_minutes += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2123 break;
2125 case 57:
2127 /* Line 1455 of yacc.c */
2128 #line 506 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2129 { pc->rel_minutes += (yyvsp[(1) - (1)].intval); ;}
2130 break;
2132 case 58:
2134 /* Line 1455 of yacc.c */
2135 #line 508 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2136 { pc->rel_seconds += (yyvsp[(1) - (2)].intval) * (yyvsp[(2) - (2)].intval); ;}
2137 break;
2139 case 59:
2141 /* Line 1455 of yacc.c */
2142 #line 510 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2143 { pc->rel_seconds += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2144 break;
2146 case 60:
2148 /* Line 1455 of yacc.c */
2149 #line 512 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2150 { pc->rel_seconds += (yyvsp[(1) - (2)].timespec).tv_sec * (yyvsp[(2) - (2)].intval); pc->rel_ns += (yyvsp[(1) - (2)].timespec).tv_nsec * (yyvsp[(2) - (2)].intval); ;}
2151 break;
2153 case 61:
2155 /* Line 1455 of yacc.c */
2156 #line 514 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2157 { pc->rel_seconds += (yyvsp[(1) - (2)].timespec).tv_sec * (yyvsp[(2) - (2)].intval); pc->rel_ns += (yyvsp[(1) - (2)].timespec).tv_nsec * (yyvsp[(2) - (2)].intval); ;}
2158 break;
2160 case 62:
2162 /* Line 1455 of yacc.c */
2163 #line 516 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2164 { pc->rel_seconds += (yyvsp[(1) - (1)].intval); ;}
2165 break;
2167 case 64:
2169 /* Line 1455 of yacc.c */
2170 #line 522 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2171 { pc->rel_year += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2172 break;
2174 case 65:
2176 /* Line 1455 of yacc.c */
2177 #line 524 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2178 { pc->rel_month += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2179 break;
2181 case 66:
2183 /* Line 1455 of yacc.c */
2184 #line 526 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2185 { pc->rel_day += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2186 break;
2188 case 67:
2190 /* Line 1455 of yacc.c */
2191 #line 528 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2192 { pc->rel_hour += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2193 break;
2195 case 68:
2197 /* Line 1455 of yacc.c */
2198 #line 530 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2199 { pc->rel_minutes += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2200 break;
2202 case 69:
2204 /* Line 1455 of yacc.c */
2205 #line 532 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2206 { pc->rel_seconds += (yyvsp[(1) - (2)].textintval).value * (yyvsp[(2) - (2)].intval); ;}
2207 break;
2209 case 73:
2211 /* Line 1455 of yacc.c */
2212 #line 540 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2213 { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; ;}
2214 break;
2216 case 75:
2218 /* Line 1455 of yacc.c */
2219 #line 546 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2220 { (yyval.timespec).tv_sec = (yyvsp[(1) - (1)].textintval).value; (yyval.timespec).tv_nsec = 0; ;}
2221 break;
2223 case 76:
2225 /* Line 1455 of yacc.c */
2226 #line 551 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2228 if (pc->dates_seen && ! pc->year.digits
2229 && ! pc->rels_seen && (pc->times_seen || 2 < (yyvsp[(1) - (1)].textintval).digits))
2230 pc->year = (yyvsp[(1) - (1)].textintval);
2231 else
2233 if (4 < (yyvsp[(1) - (1)].textintval).digits)
2235 pc->dates_seen++;
2236 pc->day = (yyvsp[(1) - (1)].textintval).value % 100;
2237 pc->month = ((yyvsp[(1) - (1)].textintval).value / 100) % 100;
2238 pc->year.value = (yyvsp[(1) - (1)].textintval).value / 10000;
2239 pc->year.digits = (yyvsp[(1) - (1)].textintval).digits - 4;
2241 else
2243 pc->times_seen++;
2244 if ((yyvsp[(1) - (1)].textintval).digits <= 2)
2246 pc->hour = (yyvsp[(1) - (1)].textintval).value;
2247 pc->minutes = 0;
2249 else
2251 pc->hour = (yyvsp[(1) - (1)].textintval).value / 100;
2252 pc->minutes = (yyvsp[(1) - (1)].textintval).value % 100;
2254 pc->seconds.tv_sec = 0;
2255 pc->seconds.tv_nsec = 0;
2256 pc->meridian = MER24;
2260 break;
2262 case 77:
2264 /* Line 1455 of yacc.c */
2265 #line 588 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2266 { (yyval.intval) = -1; ;}
2267 break;
2269 case 78:
2271 /* Line 1455 of yacc.c */
2272 #line 590 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2273 { (yyval.intval) = (yyvsp[(2) - (2)].textintval).value; ;}
2274 break;
2276 case 79:
2278 /* Line 1455 of yacc.c */
2279 #line 595 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2280 { (yyval.intval) = MER24; ;}
2281 break;
2283 case 80:
2285 /* Line 1455 of yacc.c */
2286 #line 597 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2287 { (yyval.intval) = (yyvsp[(1) - (1)].intval); ;}
2288 break;
2292 /* Line 1455 of yacc.c */
2293 #line 2294 "getdate.c"
2294 default: break;
2296 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
2298 YYPOPSTACK (yylen);
2299 yylen = 0;
2300 YY_STACK_PRINT (yyss, yyssp);
2302 *++yyvsp = yyval;
2304 /* Now `shift' the result of the reduction. Determine what state
2305 that goes to, based on the state we popped back to and the rule
2306 number reduced by. */
2308 yyn = yyr1[yyn];
2310 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2311 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2312 yystate = yytable[yystate];
2313 else
2314 yystate = yydefgoto[yyn - YYNTOKENS];
2316 goto yynewstate;
2319 /*------------------------------------.
2320 | yyerrlab -- here on detecting error |
2321 `------------------------------------*/
2322 yyerrlab:
2323 /* If not already recovering from an error, report this error. */
2324 if (!yyerrstatus)
2326 ++yynerrs;
2327 #if ! YYERROR_VERBOSE
2328 yyerror (pc, YY_("syntax error"));
2329 #else
2331 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
2332 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
2334 YYSIZE_T yyalloc = 2 * yysize;
2335 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
2336 yyalloc = YYSTACK_ALLOC_MAXIMUM;
2337 if (yymsg != yymsgbuf)
2338 YYSTACK_FREE (yymsg);
2339 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
2340 if (yymsg)
2341 yymsg_alloc = yyalloc;
2342 else
2344 yymsg = yymsgbuf;
2345 yymsg_alloc = sizeof yymsgbuf;
2349 if (0 < yysize && yysize <= yymsg_alloc)
2351 (void) yysyntax_error (yymsg, yystate, yychar);
2352 yyerror (pc, yymsg);
2354 else
2356 yyerror (pc, YY_("syntax error"));
2357 if (yysize != 0)
2358 goto yyexhaustedlab;
2361 #endif
2366 if (yyerrstatus == 3)
2368 /* If just tried and failed to reuse lookahead token after an
2369 error, discard it. */
2371 if (yychar <= YYEOF)
2373 /* Return failure if at end of input. */
2374 if (yychar == YYEOF)
2375 YYABORT;
2377 else
2379 yydestruct ("Error: discarding",
2380 yytoken, &yylval, pc);
2381 yychar = YYEMPTY;
2385 /* Else will try to reuse lookahead token after shifting the error
2386 token. */
2387 goto yyerrlab1;
2390 /*---------------------------------------------------.
2391 | yyerrorlab -- error raised explicitly by YYERROR. |
2392 `---------------------------------------------------*/
2393 yyerrorlab:
2395 /* Pacify compilers like GCC when the user code never invokes
2396 YYERROR and the label yyerrorlab therefore never appears in user
2397 code. */
2398 if (/*CONSTCOND*/ 0)
2399 goto yyerrorlab;
2401 /* Do not reclaim the symbols of the rule which action triggered
2402 this YYERROR. */
2403 YYPOPSTACK (yylen);
2404 yylen = 0;
2405 YY_STACK_PRINT (yyss, yyssp);
2406 yystate = *yyssp;
2407 goto yyerrlab1;
2410 /*-------------------------------------------------------------.
2411 | yyerrlab1 -- common code for both syntax error and YYERROR. |
2412 `-------------------------------------------------------------*/
2413 yyerrlab1:
2414 yyerrstatus = 3; /* Each real token shifted decrements this. */
2416 for (;;)
2418 yyn = yypact[yystate];
2419 if (yyn != YYPACT_NINF)
2421 yyn += YYTERROR;
2422 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
2424 yyn = yytable[yyn];
2425 if (0 < yyn)
2426 break;
2430 /* Pop the current state because it cannot handle the error token. */
2431 if (yyssp == yyss)
2432 YYABORT;
2435 yydestruct ("Error: popping",
2436 yystos[yystate], yyvsp, pc);
2437 YYPOPSTACK (1);
2438 yystate = *yyssp;
2439 YY_STACK_PRINT (yyss, yyssp);
2442 *++yyvsp = yylval;
2445 /* Shift the error token. */
2446 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
2448 yystate = yyn;
2449 goto yynewstate;
2452 /*-------------------------------------.
2453 | yyacceptlab -- YYACCEPT comes here. |
2454 `-------------------------------------*/
2455 yyacceptlab:
2456 yyresult = 0;
2457 goto yyreturn;
2459 /*-----------------------------------.
2460 | yyabortlab -- YYABORT comes here. |
2461 `-----------------------------------*/
2462 yyabortlab:
2463 yyresult = 1;
2464 goto yyreturn;
2466 #if !defined(yyoverflow) || YYERROR_VERBOSE
2467 /*-------------------------------------------------.
2468 | yyexhaustedlab -- memory exhaustion comes here. |
2469 `-------------------------------------------------*/
2470 yyexhaustedlab:
2471 yyerror (pc, YY_("memory exhausted"));
2472 yyresult = 2;
2473 /* Fall through. */
2474 #endif
2476 yyreturn:
2477 if (yychar != YYEMPTY)
2478 yydestruct ("Cleanup: discarding lookahead",
2479 yytoken, &yylval, pc);
2480 /* Do not reclaim the symbols of the rule which action triggered
2481 this YYABORT or YYACCEPT. */
2482 YYPOPSTACK (yylen);
2483 YY_STACK_PRINT (yyss, yyssp);
2484 while (yyssp != yyss)
2486 yydestruct ("Cleanup: popping",
2487 yystos[*yyssp], yyvsp, pc);
2488 YYPOPSTACK (1);
2490 #ifndef yyoverflow
2491 if (yyss != yyssa)
2492 YYSTACK_FREE (yyss);
2493 #endif
2494 #if YYERROR_VERBOSE
2495 if (yymsg != yymsgbuf)
2496 YYSTACK_FREE (yymsg);
2497 #endif
2498 /* Make sure YYID is used. */
2499 return YYID (yyresult);
2504 /* Line 1675 of yacc.c */
2505 #line 600 "/usr/src/external/gpl2/xcvs/dist/lib/getdate.y"
2508 static table const meridian_table[] =
2510 { "AM", tMERIDIAN, MERam },
2511 { "A.M.", tMERIDIAN, MERam },
2512 { "PM", tMERIDIAN, MERpm },
2513 { "P.M.", tMERIDIAN, MERpm },
2514 { NULL, 0, 0 }
2517 static table const dst_table[] =
2519 { "DST", tDST, 0 }
2522 static table const month_and_day_table[] =
2524 { "JANUARY", tMONTH, 1 },
2525 { "FEBRUARY", tMONTH, 2 },
2526 { "MARCH", tMONTH, 3 },
2527 { "APRIL", tMONTH, 4 },
2528 { "MAY", tMONTH, 5 },
2529 { "JUNE", tMONTH, 6 },
2530 { "JULY", tMONTH, 7 },
2531 { "AUGUST", tMONTH, 8 },
2532 { "SEPTEMBER",tMONTH, 9 },
2533 { "SEPT", tMONTH, 9 },
2534 { "OCTOBER", tMONTH, 10 },
2535 { "NOVEMBER", tMONTH, 11 },
2536 { "DECEMBER", tMONTH, 12 },
2537 { "SUNDAY", tDAY, 0 },
2538 { "MONDAY", tDAY, 1 },
2539 { "TUESDAY", tDAY, 2 },
2540 { "TUES", tDAY, 2 },
2541 { "WEDNESDAY",tDAY, 3 },
2542 { "WEDNES", tDAY, 3 },
2543 { "THURSDAY", tDAY, 4 },
2544 { "THUR", tDAY, 4 },
2545 { "THURS", tDAY, 4 },
2546 { "FRIDAY", tDAY, 5 },
2547 { "SATURDAY", tDAY, 6 },
2548 { NULL, 0, 0 }
2551 static table const time_units_table[] =
2553 { "YEAR", tYEAR_UNIT, 1 },
2554 { "MONTH", tMONTH_UNIT, 1 },
2555 { "FORTNIGHT",tDAY_UNIT, 14 },
2556 { "WEEK", tDAY_UNIT, 7 },
2557 { "DAY", tDAY_UNIT, 1 },
2558 { "HOUR", tHOUR_UNIT, 1 },
2559 { "MINUTE", tMINUTE_UNIT, 1 },
2560 { "MIN", tMINUTE_UNIT, 1 },
2561 { "SECOND", tSEC_UNIT, 1 },
2562 { "SEC", tSEC_UNIT, 1 },
2563 { NULL, 0, 0 }
2566 /* Assorted relative-time words. */
2567 static table const relative_time_table[] =
2569 { "TOMORROW", tDAY_UNIT, 1 },
2570 { "YESTERDAY",tDAY_UNIT, -1 },
2571 { "TODAY", tDAY_UNIT, 0 },
2572 { "NOW", tDAY_UNIT, 0 },
2573 { "LAST", tORDINAL, -1 },
2574 { "THIS", tORDINAL, 0 },
2575 { "NEXT", tORDINAL, 1 },
2576 { "FIRST", tORDINAL, 1 },
2577 /*{ "SECOND", tORDINAL, 2 }, */
2578 { "THIRD", tORDINAL, 3 },
2579 { "FOURTH", tORDINAL, 4 },
2580 { "FIFTH", tORDINAL, 5 },
2581 { "SIXTH", tORDINAL, 6 },
2582 { "SEVENTH", tORDINAL, 7 },
2583 { "EIGHTH", tORDINAL, 8 },
2584 { "NINTH", tORDINAL, 9 },
2585 { "TENTH", tORDINAL, 10 },
2586 { "ELEVENTH", tORDINAL, 11 },
2587 { "TWELFTH", tORDINAL, 12 },
2588 { "AGO", tAGO, 1 },
2589 { NULL, 0, 0 }
2592 /* The universal time zone table. These labels can be used even for
2593 time stamps that would not otherwise be valid, e.g., GMT time
2594 stamps in London during summer. */
2595 static table const universal_time_zone_table[] =
2597 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
2598 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
2599 { "UTC", tZONE, HOUR ( 0) },
2600 { NULL, 0, 0 }
2603 /* The time zone table. This table is necessarily incomplete, as time
2604 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
2605 as Eastern time in Australia, not as US Eastern Standard Time.
2606 You cannot rely on getdate to handle arbitrary time zone
2607 abbreviations; use numeric abbreviations like `-0500' instead. */
2608 static table const time_zone_table[] =
2610 { "WET", tZONE, HOUR ( 0) }, /* Western European */
2611 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
2612 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
2613 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */
2614 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
2615 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
2616 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
2617 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
2618 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
2619 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
2620 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */
2621 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
2622 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
2623 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
2624 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
2625 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
2626 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
2627 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
2628 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
2629 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
2630 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
2631 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
2632 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
2633 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
2634 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
2635 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
2636 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */
2637 { "CET", tZONE, HOUR ( 1) }, /* Central European */
2638 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
2639 { "MET", tZONE, HOUR ( 1) }, /* Middle European */
2640 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
2641 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
2642 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
2643 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */
2644 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
2645 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
2646 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
2647 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */
2648 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */
2649 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
2650 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
2651 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */
2652 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
2653 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
2654 { "GST", tZONE, HOUR (10) }, /* Guam Standard */
2655 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
2656 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
2657 { NULL, 0, 0 }
2660 /* Military time zone table. */
2661 static table const military_table[] =
2663 { "A", tZONE, -HOUR ( 1) },
2664 { "B", tZONE, -HOUR ( 2) },
2665 { "C", tZONE, -HOUR ( 3) },
2666 { "D", tZONE, -HOUR ( 4) },
2667 { "E", tZONE, -HOUR ( 5) },
2668 { "F", tZONE, -HOUR ( 6) },
2669 { "G", tZONE, -HOUR ( 7) },
2670 { "H", tZONE, -HOUR ( 8) },
2671 { "I", tZONE, -HOUR ( 9) },
2672 { "K", tZONE, -HOUR (10) },
2673 { "L", tZONE, -HOUR (11) },
2674 { "M", tZONE, -HOUR (12) },
2675 { "N", tZONE, HOUR ( 1) },
2676 { "O", tZONE, HOUR ( 2) },
2677 { "P", tZONE, HOUR ( 3) },
2678 { "Q", tZONE, HOUR ( 4) },
2679 { "R", tZONE, HOUR ( 5) },
2680 { "S", tZONE, HOUR ( 6) },
2681 { "T", tZONE, HOUR ( 7) },
2682 { "U", tZONE, HOUR ( 8) },
2683 { "V", tZONE, HOUR ( 9) },
2684 { "W", tZONE, HOUR (10) },
2685 { "X", tZONE, HOUR (11) },
2686 { "Y", tZONE, HOUR (12) },
2687 { "Z", tZONE, HOUR ( 0) },
2688 { NULL, 0, 0 }
2693 /* Convert a time zone expressed as HH:MM into an integer count of
2694 minutes. If MM is negative, then S is of the form HHMM and needs
2695 to be picked apart; otherwise, S is of the form HH. */
2697 static long int
2698 time_zone_hhmm (textint s, long int mm)
2700 if (mm < 0)
2701 return (s.value / 100) * 60 + s.value % 100;
2702 else
2703 return s.value * 60 + (s.negative ? -mm : mm);
2706 static int
2707 to_hour (long int hours, int meridian)
2709 switch (meridian)
2711 default: /* Pacify GCC. */
2712 case MER24:
2713 return 0 <= hours && hours < 24 ? hours : -1;
2714 case MERam:
2715 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
2716 case MERpm:
2717 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
2721 static long int
2722 to_year (textint textyear)
2724 long int year = textyear.value;
2726 if (year < 0)
2727 year = -year;
2729 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2730 years 69-99 map to 1969-1999. */
2731 else if (textyear.digits == 2)
2732 year += year < 69 ? 2000 : 1900;
2734 return year;
2737 static table const *
2738 lookup_zone (parser_control const *pc, char const *name)
2740 table const *tp;
2742 for (tp = universal_time_zone_table; tp->name; tp++)
2743 if (strcmp (name, tp->name) == 0)
2744 return tp;
2746 /* Try local zone abbreviations before those in time_zone_table, as
2747 the local ones are more likely to be right. */
2748 for (tp = pc->local_time_zone_table; tp->name; tp++)
2749 if (strcmp (name, tp->name) == 0)
2750 return tp;
2752 for (tp = time_zone_table; tp->name; tp++)
2753 if (strcmp (name, tp->name) == 0)
2754 return tp;
2756 return NULL;
2759 #if ! HAVE_TM_GMTOFF
2760 /* Yield the difference between *A and *B,
2761 measured in seconds, ignoring leap seconds.
2762 The body of this function is taken directly from the GNU C Library;
2763 see src/strftime.c. */
2764 static long int
2765 tm_diff (struct tm const *a, struct tm const *b)
2767 /* Compute intervening leap days correctly even if year is negative.
2768 Take care to avoid int overflow in leap day calculations. */
2769 int a4 = SHR (a->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (a->tm_year & 3);
2770 int b4 = SHR (b->tm_year, 2) + SHR (TM_YEAR_BASE, 2) - ! (b->tm_year & 3);
2771 int a100 = a4 / 25 - (a4 % 25 < 0);
2772 int b100 = b4 / 25 - (b4 % 25 < 0);
2773 int a400 = SHR (a100, 2);
2774 int b400 = SHR (b100, 2);
2775 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2776 long int ayear = a->tm_year;
2777 long int years = ayear - b->tm_year;
2778 long int days = (365 * years + intervening_leap_days
2779 + (a->tm_yday - b->tm_yday));
2780 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2781 + (a->tm_min - b->tm_min))
2782 + (a->tm_sec - b->tm_sec));
2784 #endif /* ! HAVE_TM_GMTOFF */
2786 static table const *
2787 lookup_word (parser_control const *pc, char *word)
2789 char *p;
2790 char *q;
2791 size_t wordlen;
2792 table const *tp;
2793 bool period_found;
2794 bool abbrev;
2796 /* Make it uppercase. */
2797 for (p = word; *p; p++)
2799 unsigned char ch = *p;
2800 if (ISLOWER (ch))
2801 *p = toupper (ch);
2804 for (tp = meridian_table; tp->name; tp++)
2805 if (strcmp (word, tp->name) == 0)
2806 return tp;
2808 /* See if we have an abbreviation for a month. */
2809 wordlen = strlen (word);
2810 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2812 for (tp = month_and_day_table; tp->name; tp++)
2813 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2814 return tp;
2816 if ((tp = lookup_zone (pc, word)))
2817 return tp;
2819 if (strcmp (word, dst_table[0].name) == 0)
2820 return dst_table;
2822 for (tp = time_units_table; tp->name; tp++)
2823 if (strcmp (word, tp->name) == 0)
2824 return tp;
2826 /* Strip off any plural and try the units table again. */
2827 if (word[wordlen - 1] == 'S')
2829 word[wordlen - 1] = '\0';
2830 for (tp = time_units_table; tp->name; tp++)
2831 if (strcmp (word, tp->name) == 0)
2832 return tp;
2833 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2836 for (tp = relative_time_table; tp->name; tp++)
2837 if (strcmp (word, tp->name) == 0)
2838 return tp;
2840 /* Military time zones. */
2841 if (wordlen == 1)
2842 for (tp = military_table; tp->name; tp++)
2843 if (word[0] == tp->name[0])
2844 return tp;
2846 /* Drop out any periods and try the time zone table again. */
2847 for (period_found = false, p = q = word; (*p = *q); q++)
2848 if (*q == '.')
2849 period_found = true;
2850 else
2851 p++;
2852 if (period_found && (tp = lookup_zone (pc, word)))
2853 return tp;
2855 return NULL;
2858 static int
2859 yylex (YYSTYPE *lvalp, parser_control *pc)
2861 unsigned char c;
2862 size_t count;
2864 for (;;)
2866 while (c = *pc->input, ISSPACE (c))
2867 pc->input++;
2869 if (ISDIGIT (c) || c == '-' || c == '+')
2871 char const *p;
2872 int sign;
2873 unsigned long int value;
2874 if (c == '-' || c == '+')
2876 sign = c == '-' ? -1 : 1;
2877 while (c = *++pc->input, ISSPACE (c))
2878 continue;
2879 if (! ISDIGIT (c))
2880 /* skip the '-' sign */
2881 continue;
2883 else
2884 sign = 0;
2885 p = pc->input;
2886 for (value = 0; ; value *= 10)
2888 unsigned long int value1 = value + (c - '0');
2889 if (value1 < value)
2890 return '?';
2891 value = value1;
2892 c = *++p;
2893 if (! ISDIGIT (c))
2894 break;
2895 if (ULONG_MAX / 10 < value)
2896 return '?';
2898 if ((c == '.' || c == ',') && ISDIGIT (p[1]))
2900 time_t s;
2901 int ns;
2902 int digits;
2903 unsigned long int value1;
2905 /* Check for overflow when converting value to time_t. */
2906 if (sign < 0)
2908 s = - value;
2909 if (0 < s)
2910 return '?';
2911 value1 = -s;
2913 else
2915 s = value;
2916 if (s < 0)
2917 return '?';
2918 value1 = s;
2920 if (value != value1)
2921 return '?';
2923 /* Accumulate fraction, to ns precision. */
2924 p++;
2925 ns = *p++ - '0';
2926 for (digits = 2; digits <= LOG10_BILLION; digits++)
2928 ns *= 10;
2929 if (ISDIGIT (*p))
2930 ns += *p++ - '0';
2933 /* Skip excess digits, truncating toward -Infinity. */
2934 if (sign < 0)
2935 for (; ISDIGIT (*p); p++)
2936 if (*p != '0')
2938 ns++;
2939 break;
2941 while (ISDIGIT (*p))
2942 p++;
2944 /* Adjust to the timespec convention, which is that
2945 tv_nsec is always a positive offset even if tv_sec is
2946 negative. */
2947 if (sign < 0 && ns)
2949 s--;
2950 if (! (s < 0))
2951 return '?';
2952 ns = BILLION - ns;
2955 lvalp->timespec.tv_sec = s;
2956 lvalp->timespec.tv_nsec = ns;
2957 pc->input = p;
2958 return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;
2960 else
2962 lvalp->textintval.negative = sign < 0;
2963 if (sign < 0)
2965 lvalp->textintval.value = - value;
2966 if (0 < lvalp->textintval.value)
2967 return '?';
2969 else
2971 lvalp->textintval.value = value;
2972 if (lvalp->textintval.value < 0)
2973 return '?';
2975 lvalp->textintval.digits = p - pc->input;
2976 pc->input = p;
2977 return sign ? tSNUMBER : tUNUMBER;
2981 if (ISALPHA (c))
2983 char buff[20];
2984 char *p = buff;
2985 table const *tp;
2989 if (p < buff + sizeof buff - 1)
2990 *p++ = c;
2991 c = *++pc->input;
2993 while (ISALPHA (c) || c == '.');
2995 *p = '\0';
2996 tp = lookup_word (pc, buff);
2997 if (! tp)
2998 return '?';
2999 lvalp->intval = tp->value;
3000 return tp->type;
3003 if (c != '(')
3004 return *pc->input++;
3005 count = 0;
3008 c = *pc->input++;
3009 if (c == '\0')
3010 return c;
3011 if (c == '(')
3012 count++;
3013 else if (c == ')')
3014 count--;
3016 while (count != 0);
3020 /* Do nothing if the parser reports an error. */
3021 static int
3022 yyerror (parser_control *pc ATTRIBUTE_UNUSED, char *s ATTRIBUTE_UNUSED)
3024 return 0;
3027 /* If *TM0 is the old and *TM1 is the new value of a struct tm after
3028 passing it to mktime, return true if it's OK that mktime returned T.
3029 It's not OK if *TM0 has out-of-range members. */
3031 static bool
3032 mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)
3034 if (t == (time_t) -1)
3036 /* Guard against falsely reporting an error when parsing a time
3037 stamp that happens to equal (time_t) -1, on a host that
3038 supports such a time stamp. */
3039 tm1 = localtime (&t);
3040 if (!tm1)
3041 return false;
3044 return ! ((tm0->tm_sec ^ tm1->tm_sec)
3045 | (tm0->tm_min ^ tm1->tm_min)
3046 | (tm0->tm_hour ^ tm1->tm_hour)
3047 | (tm0->tm_mday ^ tm1->tm_mday)
3048 | (tm0->tm_mon ^ tm1->tm_mon)
3049 | (tm0->tm_year ^ tm1->tm_year));
3052 /* A reasonable upper bound for the size of ordinary TZ strings.
3053 Use heap allocation if TZ's length exceeds this. */
3054 enum { TZBUFSIZE = 100 };
3056 /* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
3057 otherwise. */
3058 static char *
3059 get_tz (char tzbuf[TZBUFSIZE])
3061 char *tz = getenv ("TZ");
3062 if (tz)
3064 size_t tzsize = strlen (tz) + 1;
3065 tz = (tzsize <= TZBUFSIZE
3066 ? memcpy (tzbuf, tz, tzsize)
3067 : xmemdup (tz, tzsize));
3069 return tz;
3072 /* Parse a date/time string, storing the resulting time value into *RESULT.
3073 The string itself is pointed to by P. Return true if successful.
3074 P can be an incomplete or relative time specification; if so, use
3075 *NOW as the basis for the returned time. */
3076 bool
3077 get_date (struct timespec *result, char const *p, struct timespec const *now)
3079 time_t Start;
3080 long int Start_ns;
3081 struct tm const *tmp;
3082 struct tm tm;
3083 struct tm tm0;
3084 parser_control pc;
3085 struct timespec gettime_buffer;
3086 unsigned char c;
3087 bool tz_was_altered = false;
3088 char *tz0 = NULL;
3089 char tz0buf[TZBUFSIZE];
3090 bool ok = true;
3092 if (! now)
3094 gettime (&gettime_buffer);
3095 now = &gettime_buffer;
3098 Start = now->tv_sec;
3099 Start_ns = now->tv_nsec;
3101 tmp = localtime (&now->tv_sec);
3102 if (! tmp)
3103 return false;
3105 while (c = *p, ISSPACE (c))
3106 p++;
3108 if (strncmp (p, "TZ=\"", 4) == 0)
3110 char const *tzbase = p + 4;
3111 size_t tzsize = 1;
3112 char const *s;
3114 for (s = tzbase; *s; s++, tzsize++)
3115 if (*s == '\\')
3117 s++;
3118 if (! (*s == '\\' || *s == '"'))
3119 break;
3121 else if (*s == '"')
3123 char *z;
3124 char *tz1;
3125 char tz1buf[TZBUFSIZE];
3126 bool large_tz = TZBUFSIZE < tzsize;
3127 bool setenv_ok;
3128 tz0 = get_tz (tz0buf);
3129 z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf;
3130 for (s = tzbase; *s != '"'; s++)
3131 *z++ = *(s += *s == '\\');
3132 *z = '\0';
3133 setenv_ok = setenv ("TZ", tz1, 1) == 0;
3134 if (large_tz)
3135 free (tz1);
3136 if (!setenv_ok)
3137 goto fail;
3138 tz_was_altered = true;
3139 p = s + 1;
3143 pc.input = p;
3144 pc.year.value = tmp->tm_year;
3145 pc.year.value += TM_YEAR_BASE;
3146 pc.year.digits = 0;
3147 pc.month = tmp->tm_mon + 1;
3148 pc.day = tmp->tm_mday;
3149 pc.hour = tmp->tm_hour;
3150 pc.minutes = tmp->tm_min;
3151 pc.seconds.tv_sec = tmp->tm_sec;
3152 pc.seconds.tv_nsec = Start_ns;
3153 tm.tm_isdst = tmp->tm_isdst;
3155 pc.meridian = MER24;
3156 pc.rel_ns = 0;
3157 pc.rel_seconds = 0;
3158 pc.rel_minutes = 0;
3159 pc.rel_hour = 0;
3160 pc.rel_day = 0;
3161 pc.rel_month = 0;
3162 pc.rel_year = 0;
3163 pc.timespec_seen = false;
3164 pc.rels_seen = false;
3165 pc.dates_seen = 0;
3166 pc.days_seen = 0;
3167 pc.times_seen = 0;
3168 pc.local_zones_seen = 0;
3169 pc.dsts_seen = 0;
3170 pc.zones_seen = 0;
3172 #if HAVE_STRUCT_TM_TM_ZONE
3173 pc.local_time_zone_table[0].name = tmp->tm_zone;
3174 pc.local_time_zone_table[0].type = tLOCAL_ZONE;
3175 pc.local_time_zone_table[0].value = tmp->tm_isdst;
3176 pc.local_time_zone_table[1].name = NULL;
3178 /* Probe the names used in the next three calendar quarters, looking
3179 for a tm_isdst different from the one we already have. */
3181 int quarter;
3182 for (quarter = 1; quarter <= 3; quarter++)
3184 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
3185 struct tm const *probe_tm = localtime (&probe);
3186 if (probe_tm && probe_tm->tm_zone
3187 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
3190 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
3191 pc.local_time_zone_table[1].type = tLOCAL_ZONE;
3192 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
3193 pc.local_time_zone_table[2].name = NULL;
3195 break;
3199 #else
3200 #if HAVE_TZNAME
3202 # ifndef tzname
3203 extern char *tzname[];
3204 # endif
3205 int i;
3206 for (i = 0; i < 2; i++)
3208 pc.local_time_zone_table[i].name = tzname[i];
3209 pc.local_time_zone_table[i].type = tLOCAL_ZONE;
3210 pc.local_time_zone_table[i].value = i;
3212 pc.local_time_zone_table[i].name = NULL;
3214 #else
3215 pc.local_time_zone_table[0].name = NULL;
3216 #endif
3217 #endif
3219 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
3220 && ! strcmp (pc.local_time_zone_table[0].name,
3221 pc.local_time_zone_table[1].name))
3223 /* This locale uses the same abbrevation for standard and
3224 daylight times. So if we see that abbreviation, we don't
3225 know whether it's daylight time. */
3226 pc.local_time_zone_table[0].value = -1;
3227 pc.local_time_zone_table[1].name = NULL;
3230 if (yyparse (&pc) != 0)
3231 goto fail;
3233 if (pc.timespec_seen)
3234 *result = pc.seconds;
3235 else
3237 if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
3238 | (pc.local_zones_seen + pc.zones_seen)))
3239 goto fail;
3241 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE;
3242 tm.tm_mon = pc.month - 1;
3243 tm.tm_mday = pc.day;
3244 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
3246 tm.tm_hour = to_hour (pc.hour, pc.meridian);
3247 if (tm.tm_hour < 0)
3248 goto fail;
3249 tm.tm_min = pc.minutes;
3250 tm.tm_sec = pc.seconds.tv_sec;
3252 else
3254 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
3255 pc.seconds.tv_nsec = 0;
3258 /* Let mktime deduce tm_isdst if we have an absolute time stamp. */
3259 if (!pc.rels_seen)
3260 tm.tm_isdst = -1;
3262 /* But if the input explicitly specifies local time with or without
3263 DST, give mktime that information. */
3264 if (pc.local_zones_seen)
3265 tm.tm_isdst = pc.local_isdst;
3267 tm0 = tm;
3269 Start = mktime (&tm);
3271 if (! mktime_ok (&tm0, &tm, Start))
3273 if (! pc.zones_seen)
3274 goto fail;
3275 else
3277 /* Guard against falsely reporting errors near the time_t
3278 boundaries when parsing times in other time zones. For
3279 example, suppose the input string "1969-12-31 23:00:00 -0100",
3280 the current time zone is 8 hours ahead of UTC, and the min
3281 time_t value is 1970-01-01 00:00:00 UTC. Then the min
3282 localtime value is 1970-01-01 08:00:00, and mktime will
3283 therefore fail on 1969-12-31 23:00:00. To work around the
3284 problem, set the time zone to 1 hour behind UTC temporarily
3285 by setting TZ="XXX1:00" and try mktime again. */
3287 long int time_zone = pc.time_zone;
3288 long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
3289 long int abs_time_zone_hour = abs_time_zone / 60;
3290 int abs_time_zone_min = abs_time_zone % 60;
3291 char tz1buf[sizeof "XXX+0:00"
3292 + sizeof pc.time_zone * CHAR_BIT / 3];
3293 if (!tz_was_altered)
3294 tz0 = get_tz (tz0buf);
3295 sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0),
3296 abs_time_zone_hour, abs_time_zone_min);
3297 if (setenv ("TZ", tz1buf, 1) != 0)
3298 goto fail;
3299 tz_was_altered = true;
3300 tm = tm0;
3301 Start = mktime (&tm);
3302 if (! mktime_ok (&tm0, &tm, Start))
3303 goto fail;
3307 if (pc.days_seen && ! pc.dates_seen)
3309 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
3310 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
3311 tm.tm_isdst = -1;
3312 Start = mktime (&tm);
3313 if (Start == (time_t) -1)
3314 goto fail;
3317 if (pc.zones_seen)
3319 long int delta = pc.time_zone * 60;
3320 time_t t1;
3321 #ifdef HAVE_TM_GMTOFF
3322 delta -= tm.tm_gmtoff;
3323 #else
3324 time_t t = Start;
3325 struct tm const *gmt = gmtime (&t);
3326 if (! gmt)
3327 goto fail;
3328 delta -= tm_diff (&tm, gmt);
3329 #endif
3330 t1 = Start - delta;
3331 if ((Start < t1) != (delta < 0))
3332 goto fail; /* time_t overflow */
3333 Start = t1;
3336 /* Add relative date. */
3337 if (pc.rel_year | pc.rel_month | pc.rel_day)
3339 int year = tm.tm_year + pc.rel_year;
3340 int month = tm.tm_mon + pc.rel_month;
3341 int day = tm.tm_mday + pc.rel_day;
3342 if (((year < tm.tm_year) ^ (pc.rel_year < 0))
3343 | ((month < tm.tm_mon) ^ (pc.rel_month < 0))
3344 | ((day < tm.tm_mday) ^ (pc.rel_day < 0)))
3345 goto fail;
3346 tm.tm_year = year;
3347 tm.tm_mon = month;
3348 tm.tm_mday = day;
3349 Start = mktime (&tm);
3350 if (Start == (time_t) -1)
3351 goto fail;
3354 /* Add relative hours, minutes, and seconds. On hosts that support
3355 leap seconds, ignore the possibility of leap seconds; e.g.,
3356 "+ 10 minutes" adds 600 seconds, even if one of them is a
3357 leap second. Typically this is not what the user wants, but it's
3358 too hard to do it the other way, because the time zone indicator
3359 must be applied before relative times, and if mktime is applied
3360 again the time zone will be lost. */
3362 long int sum_ns = pc.seconds.tv_nsec + pc.rel_ns;
3363 long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
3364 time_t t0 = Start;
3365 long int d1 = 60 * 60 * pc.rel_hour;
3366 time_t t1 = t0 + d1;
3367 long int d2 = 60 * pc.rel_minutes;
3368 time_t t2 = t1 + d2;
3369 long int d3 = pc.rel_seconds;
3370 time_t t3 = t2 + d3;
3371 long int d4 = (sum_ns - normalized_ns) / BILLION;
3372 time_t t4 = t3 + d4;
3374 if ((d1 / (60 * 60) ^ pc.rel_hour)
3375 | (d2 / 60 ^ pc.rel_minutes)
3376 | ((t1 < t0) ^ (d1 < 0))
3377 | ((t2 < t1) ^ (d2 < 0))
3378 | ((t3 < t2) ^ (d3 < 0))
3379 | ((t4 < t3) ^ (d4 < 0)))
3380 goto fail;
3382 result->tv_sec = t4;
3383 result->tv_nsec = normalized_ns;
3387 goto done;
3389 fail:
3390 ok = false;
3391 done:
3392 if (tz_was_altered)
3393 ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;
3394 if (tz0 != tz0buf)
3395 free (tz0);
3396 return ok;
3399 #if TEST
3402 main (int ac, char **av)
3404 char buff[BUFSIZ];
3406 printf ("Enter date, or blank line to exit.\n\t> ");
3407 fflush (stdout);
3409 buff[BUFSIZ - 1] = '\0';
3410 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
3412 struct timespec d;
3413 struct tm const *tm;
3414 if (! get_date (&d, buff, NULL))
3415 printf ("Bad format - couldn't convert.\n");
3416 else if (! (tm = localtime (&d.tv_sec)))
3418 long int sec = d.tv_sec;
3419 printf ("localtime (%ld) failed\n", sec);
3421 else
3423 int ns = d.tv_nsec;
3424 printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",
3425 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
3426 tm->tm_hour, tm->tm_min, tm->tm_sec, ns);
3428 printf ("\t> ");
3429 fflush (stdout);
3431 return 0;
3433 #endif /* TEST */