source: trunk/essentials/app-arch/tar/lib/getdate.c

Last change on this file was 3342, checked in by bird, 18 years ago

tar 1.16.1

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