Bug Summary

File:oathtool/gl/parse-datetime.c
Location:line 449, column 7
Description:Size argument is greater than the free space in the destination buffer

Annotated Source Code

1/* A Bison parser, made by GNU Bison 3.0.2. */
2
3/* Bison implementation for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33/* C LALR(1) parser skeleton written by Richard Stallman, by
34 simplifying the original so-called "semantic" parser. */
35
36/* All symbols defined below should begin with yy or YY, to avoid
37 infringing on user name space. This should be done even for local
38 variables, as they might otherwise be expanded by user macros.
39 There are some unavoidable exceptions within include files to
40 define necessary library symbols; they are noted "INFRINGES ON
41 USER NAME SPACE" below. */
42
43/* Identify Bison output. */
44#define YYBISON1 1
45
46/* Bison version. */
47#define YYBISON_VERSION"3.0.2" "3.0.2"
48
49/* Skeleton name. */
50#define YYSKELETON_NAME"yacc.c" "yacc.c"
51
52/* Pure parsers. */
53#define YYPURE1 1
54
55/* Push parsers. */
56#define YYPUSH0 0
57
58/* Pull parsers. */
59#define YYPULL1 1
60
61
62
63
64/* Copy the first part of user declarations. */
65#line 1 "./parse-datetime.y" /* yacc.c:339 */
66
67/* Parse a string into an internal time stamp.
68
69 Copyright (C) 1999-2000, 2002-2016 Free Software Foundation, Inc.
70
71 This program is free software: you can redistribute it and/or modify
72 it under the terms of the GNU General Public License as published by
73 the Free Software Foundation; either version 3 of the License, or
74 (at your option) any later version.
75
76 This program is distributed in the hope that it will be useful,
77 but WITHOUT ANY WARRANTY; without even the implied warranty of
78 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79 GNU General Public License for more details.
80
81 You should have received a copy of the GNU General Public License
82 along with this program. If not, see <http://www.gnu.org/licenses/>. */
83
84/* Originally written by Steven M. Bellovin <smb@research.att.com> while
85 at the University of North Carolina at Chapel Hill. Later tweaked by
86 a couple of people on Usenet. Completely overhauled by Rich $alz
87 <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
88
89 Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
90 the right thing about local DST. Also modified by Paul Eggert
91 <eggert@cs.ucla.edu> in February 2004 to support
92 nanosecond-resolution time stamps, and in October 2004 to support
93 TZ strings in dates. */
94
95/* FIXME: Check for arithmetic overflow in all cases, not just
96 some of them. */
97
98#include <config.h>
99
100#include "parse-datetime.h"
101
102#include "intprops.h"
103#include "timespec.h"
104#include "verify.h"
105#include "strftime.h"
106
107/* There's no need to extend the stack, so there's no need to involve
108 alloca. */
109#define YYSTACK_USE_ALLOCA0 0
110
111/* Tell Bison how much stack space is needed. 20 should be plenty for
112 this grammar, which is not right recursive. Beware setting it too
113 high, since that might cause problems on machines whose
114 implementations have lame stack-overflow checking. */
115#define YYMAXDEPTH20 20
116#define YYINITDEPTH20 YYMAXDEPTH20
117
118/* Since the code of parse-datetime.y is not included in the Emacs executable
119 itself, there is no need to #define static in this file. Even if
120 the code were included in the Emacs executable, it probably
121 wouldn't do any harm to #undef it here; this will only cause
122 problems if we try to write to a static variable, which I don't
123 think this code needs to do. */
124#ifdef emacs
125# undef static
126#endif
127
128#include <inttypes.h>
129#include <c-ctype.h>
130#include <limits.h>
131#include <stdio.h>
132#include <stdlib.h>
133#include <string.h>
134
135#include "gettext.h"
136#include "xalloc.h"
137
138#define _(str)((const char *) (str)) gettext (str)((const char *) (str))
139
140/* Bison's skeleton tests _STDLIB_H, while some stdlib.h headers
141 use _STDLIB_H_ as witness. Map the latter to the one bison uses. */
142/* FIXME: this is temporary. Remove when we have a mechanism to ensure
143 that the version we're using is fixed, too. */
144#ifdef _STDLIB_H_
145# undef _STDLIB_H1
146# define _STDLIB_H1 1
147#endif
148
149/* ISDIGIT differs from isdigit, as follows:
150 - Its arg may be any int or unsigned int; it need not be an unsigned char
151 or EOF.
152 - It's typically faster.
153 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
154 isdigit unless it's important to use the locale's definition
155 of "digit" even when the host does not conform to POSIX. */
156#define ISDIGIT(c)((unsigned int) (c) - '0' <= 9) ((unsigned int) (c) - '0' <= 9)
157
158/* Shift A right by B bits portably, by dividing A by 2**B and
159 truncating towards minus infinity. A and B should be free of side
160 effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
161 INT_BITS is the number of useful bits in an int. GNU code can
162 assume that INT_BITS is at least 32.
163
164 ISO C99 says that A >> B is implementation-defined if A < 0. Some
165 implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
166 right in the usual way when A < 0, so SHR falls back on division if
167 ordinary A >> B doesn't seem to be the usual signed shift. */
168#define SHR(a, b)(-1 >> 1 == -1 ? (a) >> (b) : (a) / (1 << (
b)) - ((a) % (1 << (b)) < 0))
\
169 (-1 >> 1 == -1 \
170 ? (a) >> (b) \
171 : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
172
173#define EPOCH_YEAR1970 1970
174#define TM_YEAR_BASE1900 1900
175
176#define HOUR(x)((x) * 60) ((x) * 60)
177
178#define STREQ(a, b)(__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a) && __builtin_constant_p (b) && (__s1_len
= __builtin_strlen (a), __s2_len = __builtin_strlen (b), (!(
(size_t)(const void *)((a) + 1) - (size_t)(const void *)(a) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((b) + 1) - (size_t)(const void *)(b) == 1) || __s2_len >=
4)) ? __builtin_strcmp (a, b) : (__builtin_constant_p (a) &&
((size_t)(const void *)((a) + 1) - (size_t)(const void *)(a)
== 1) && (__s1_len = __builtin_strlen (a), __s1_len <
4) ? (__builtin_constant_p (b) && ((size_t)(const void
*)((b) + 1) - (size_t)(const void *)(b) == 1) ? __builtin_strcmp
(a, b) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (b); int __result = (((const
unsigned char *) (const char *) (a))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (a))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (a))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(b) && ((size_t)(const void *)((b) + 1) - (size_t)(const
void *)(b) == 1) && (__s2_len = __builtin_strlen (b)
, __s2_len < 4) ? (__builtin_constant_p (a) && ((size_t
)(const void *)((a) + 1) - (size_t)(const void *)(a) == 1) ? __builtin_strcmp
(a, b) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (a); int __result = (((const
unsigned char *) (const char *) (b))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (b))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (b))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (b))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(a, b)))); }) == 0)
(strcmp (a, b)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(a) && __builtin_constant_p (b) && (__s1_len
= __builtin_strlen (a), __s2_len = __builtin_strlen (b), (!(
(size_t)(const void *)((a) + 1) - (size_t)(const void *)(a) ==
1) || __s1_len >= 4) && (!((size_t)(const void *)
((b) + 1) - (size_t)(const void *)(b) == 1) || __s2_len >=
4)) ? __builtin_strcmp (a, b) : (__builtin_constant_p (a) &&
((size_t)(const void *)((a) + 1) - (size_t)(const void *)(a)
== 1) && (__s1_len = __builtin_strlen (a), __s1_len <
4) ? (__builtin_constant_p (b) && ((size_t)(const void
*)((b) + 1) - (size_t)(const void *)(b) == 1) ? __builtin_strcmp
(a, b) : (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (b); int __result = (((const
unsigned char *) (const char *) (a))[0] - __s2[0]); if (__s1_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (a))[1] - __s2[1]); if (__s1_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (a))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (a))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(b) && ((size_t)(const void *)((b) + 1) - (size_t)(const
void *)(b) == 1) && (__s2_len = __builtin_strlen (b)
, __s2_len < 4) ? (__builtin_constant_p (a) && ((size_t
)(const void *)((a) + 1) - (size_t)(const void *)(a) == 1) ? __builtin_strcmp
(a, b) : (- (__extension__ ({ const unsigned char *__s2 = (const
unsigned char *) (const char *) (a); int __result = (((const
unsigned char *) (const char *) (b))[0] - __s2[0]); if (__s2_len
> 0 && __result == 0) { __result = (((const unsigned
char *) (const char *) (b))[1] - __s2[1]); if (__s2_len >
1 && __result == 0) { __result = (((const unsigned char
*) (const char *) (b))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (b))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(a, b)))); })
== 0)
179
180/* long_time_t is a signed integer type that contains all time_t values. */
181verify (TYPE_IS_INTEGER (time_t))extern int (*_gl_verify_function14 (void)) [(!!sizeof (struct
{ unsigned int _gl_verify_error_if_negative: (((time_t) 1.5 ==
1)) ? 1 : -1; }))]
;
182#if TIME_T_FITS_IN_LONG_INT1
183typedef long int long_time_t;
184#else
185typedef time_t long_time_t;
186#endif
187
188/* Convert a possibly-signed character to an unsigned character. This is
189 a bit safer than casting to unsigned char, since it catches some type
190 errors that the cast doesn't. */
191static unsigned char to_uchar (char ch) { return ch; }
192
193static void
194dbg_printf (const char *msg,...)
195{
196 va_list args;
197 /* TODO: use gnulib's 'program_name' instead? */
198 fputs ("date: ", stderrstderr);
199
200 va_start (args, msg)__builtin_va_start(args, msg);
201 vfprintf (stderrstderr, msg, args);
202 va_end (args)__builtin_va_end(args);
203}
204
205
206
207/* Lots of this code assumes time_t and time_t-like values fit into
208 long_time_t. */
209verify (TYPE_MINIMUM (long_time_t) <= TYPE_MINIMUM (time_t)extern int (*_gl_verify_function15 (void)) [(!!sizeof (struct
{ unsigned int _gl_verify_error_if_negative: (((long_time_t)
~ ((long_time_t) (! (! ((long_time_t) 0 < (long_time_t) -
1)) ? (long_time_t) -1 : ((((long_time_t) 1 << (sizeof (
long_time_t) * 8 - 2)) - 1) * 2 + 1)))) <= ((time_t) ~ ((time_t
) (! (! ((time_t) 0 < (time_t) -1)) ? (time_t) -1 : ((((time_t
) 1 << (sizeof (time_t) * 8 - 2)) - 1) * 2 + 1)))) &&
((time_t) (! (! ((time_t) 0 < (time_t) -1)) ? (time_t) -1
: ((((time_t) 1 << (sizeof (time_t) * 8 - 2)) - 1) * 2
+ 1))) <= ((long_time_t) (! (! ((long_time_t) 0 < (long_time_t
) -1)) ? (long_time_t) -1 : ((((long_time_t) 1 << (sizeof
(long_time_t) * 8 - 2)) - 1) * 2 + 1)))) ? 1 : -1; }))]
210 && TYPE_MAXIMUM (time_t) <= TYPE_MAXIMUM (long_time_t))extern int (*_gl_verify_function15 (void)) [(!!sizeof (struct
{ unsigned int _gl_verify_error_if_negative: (((long_time_t)
~ ((long_time_t) (! (! ((long_time_t) 0 < (long_time_t) -
1)) ? (long_time_t) -1 : ((((long_time_t) 1 << (sizeof (
long_time_t) * 8 - 2)) - 1) * 2 + 1)))) <= ((time_t) ~ ((time_t
) (! (! ((time_t) 0 < (time_t) -1)) ? (time_t) -1 : ((((time_t
) 1 << (sizeof (time_t) * 8 - 2)) - 1) * 2 + 1)))) &&
((time_t) (! (! ((time_t) 0 < (time_t) -1)) ? (time_t) -1
: ((((time_t) 1 << (sizeof (time_t) * 8 - 2)) - 1) * 2
+ 1))) <= ((long_time_t) (! (! ((long_time_t) 0 < (long_time_t
) -1)) ? (long_time_t) -1 : ((((long_time_t) 1 << (sizeof
(long_time_t) * 8 - 2)) - 1) * 2 + 1)))) ? 1 : -1; }))]
;
211
212/* FIXME: It also assumes that signed integer overflow silently wraps around,
213 but this is not true any more with recent versions of GCC 4. */
214
215/* An integer value, and the number of digits in its textual
216 representation. */
217typedef struct
218{
219 bool_Bool negative;
220 long int value;
221 size_t digits;
222} textint;
223
224/* An entry in the lexical lookup table. */
225typedef struct
226{
227 char const *name;
228 int type;
229 int value;
230} table;
231
232/* Meridian: am, pm, or 24-hour style. */
233enum { MERam, MERpm, MER24 };
234
235enum { BILLION = 1000000000, LOG10_BILLION = 9 };
236
237/* Relative times. */
238typedef struct
239{
240 /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
241 long int year;
242 long int month;
243 long int day;
244 long int hour;
245 long int minutes;
246 long_time_t seconds;
247 long int ns;
248} relative_time;
249
250#if HAVE_COMPOUND_LITERALS1
251# define RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }) ((relative_time) { 0, 0, 0, 0, 0, 0, 0 })
252#else
253static relative_time const RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 });
254#endif
255
256/* Information passed to and from the parser. */
257typedef struct
258{
259 /* The input string remaining to be parsed. */
260 const char *input;
261
262 /* N, if this is the Nth Tuesday. */
263 long int day_ordinal;
264
265 /* Day of week; Sunday is 0. */
266 int day_number;
267
268 /* tm_isdst flag for the local zone. */
269 int local_isdst;
270
271 /* Time zone, in minutes east of UTC. */
272 long int time_zone;
273
274 /* Style used for time. */
275 int meridian;
276
277 /* Gregorian year, month, day, hour, minutes, seconds, and nanoseconds. */
278 textint year;
279 long int month;
280 long int day;
281 long int hour;
282 long int minutes;
283 struct timespec seconds; /* includes nanoseconds */
284
285 /* Relative year, month, day, hour, minutes, seconds, and nanoseconds. */
286 relative_time rel;
287
288 /* Presence or counts of nonterminals of various flavors parsed so far. */
289 bool_Bool timespec_seen;
290 bool_Bool rels_seen;
291 size_t dates_seen;
292 size_t days_seen;
293 size_t local_zones_seen;
294 size_t dsts_seen;
295 size_t times_seen;
296 size_t zones_seen;
297
298 /* if true, print debugging output to stderr */
299 bool_Bool parse_datetime_debug;
300
301 /* which of the 'seen' parts has been printed when debugging */
302 size_t debug_dates_seen;
303 size_t debug_days_seen;
304 size_t debug_local_zones_seen;
305 size_t debug_dsts_seen;
306 size_t debug_times_seen;
307 size_t debug_zones_seen;
308
309 /* true if the user specified explicit ordinal day value, */
310 bool_Bool debug_ordinal_day_seen;
311
312 /* the default input timezone, set by TZ value */
313 long int debug_default_input_timezone;
314
315 /* Table of local time zone abbreviations, terminated by a null entry. */
316 table local_time_zone_table[3];
317} parser_control;
318
319union YYSTYPE;
320static int yylex (union YYSTYPE *, parser_control *);
321static int yyerror (parser_control const *, char const *);
322static long int time_zone_hhmm (parser_control *, textint, long int);
323
324/* Extract into *PC any date and time info from a string of digits
325 of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
326 YYYY, ...). */
327static void
328digits_to_date_time (parser_control *pc, textint text_int)
329{
330 if (pc->dates_seen && ! pc->year.digits
331 && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))
332 pc->year = text_int;
333 else
334 {
335 if (4 < text_int.digits)
336 {
337 pc->dates_seen++;
338 pc->day = text_int.value % 100;
339 pc->month = (text_int.value / 100) % 100;
340 pc->year.value = text_int.value / 10000;
341 pc->year.digits = text_int.digits - 4;
342 }
343 else
344 {
345 pc->times_seen++;
346 if (text_int.digits <= 2)
347 {
348 pc->hour = text_int.value;
349 pc->minutes = 0;
350 }
351 else
352 {
353 pc->hour = text_int.value / 100;
354 pc->minutes = text_int.value % 100;
355 }
356 pc->seconds.tv_sec = 0;
357 pc->seconds.tv_nsec = 0;
358 pc->meridian = MER24;
359 }
360 }
361}
362
363/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1). */
364static void
365apply_relative_time (parser_control *pc, relative_time rel, int factor)
366{
367 pc->rel.ns += factor * rel.ns;
368 pc->rel.seconds += factor * rel.seconds;
369 pc->rel.minutes += factor * rel.minutes;
370 pc->rel.hour += factor * rel.hour;
371 pc->rel.day += factor * rel.day;
372 pc->rel.month += factor * rel.month;
373 pc->rel.year += factor * rel.year;
374 pc->rels_seen = true1;
375}
376
377/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */
378static void
379set_hhmmss (parser_control *pc, long int hour, long int minutes,
380 time_t sec, long int nsec)
381{
382 pc->hour = hour;
383 pc->minutes = minutes;
384 pc->seconds.tv_sec = sec;
385 pc->seconds.tv_nsec = nsec;
386}
387
388/* returns a textual representation of the day ordinal/number values
389 in the parser_control struct (e.g. 'last wed', 'this tues', 'thu') */
390static const char*
391str_days (parser_control *pc, char* /*output*/ buffer, size_t n)
392{
393 /* TODO: use the relative_time_table[] for reverse lookup */
394 static const char* ordinal_values[] = {
395 "last",
396 "this",
397 "next/first",
398 "(SECOND)", /* SECOND is commented out in relative_time_table[] */
399 "third",
400 "fourth",
401 "fifth",
402 "sixth",
403 "seventh",
404 "eight",
405 "ninth",
406 "tenth",
407 "eleventh",
408 "twelfth"};
409
410 static const char* days_values[] = {
411 "Sun",
412 "Mon",
413 "Tue",
414 "Wed",
415 "Thu",
416 "Fri",
417 "Sat"
418 };
419
420 /* don't add an ordinal prefix if the user didn't specify it
421 (e.g., "this wed" vs "wed") */
422 if (pc->debug_ordinal_day_seen)
65
Taking false branch
423 {
424 /* use word description of possible (e.g. -1 = last, 3 = third) */
425 if (pc->day_ordinal>=-1 && pc->day_ordinal <=12)
426 {
427 strncpy (buffer, ordinal_values[ pc->day_ordinal+1 ], n)__builtin_strncpy (buffer, ordinal_values[ pc->day_ordinal
+1 ], n)
;
428 buffer[n-1]='\0';
429 }
430 else
431 {
432 snprintf (buffer,n,"%ld",pc->day_ordinal);
433 }
434 }
435 else
436 {
437 buffer[0] = '\0';
438 }
439
440 /* Add the day name */
441 if (pc->day_number>=0 && pc->day_number<=6)
66
Taking true branch
442 {
443 size_t l = strlen (buffer);
444 if (l>0)
67
Assuming 'l' is <= 0
68
Taking false branch
445 {
446 strncat (buffer," ",n-l)__builtin_strncat (buffer, " ", n-l);
447 ++l;
448 }
449 strncat (buffer,days_values[pc->day_number],n-l)__builtin_strncat (buffer, days_values[pc->day_number], n-
l)
;
69
Within the expansion of the macro 'strncat':
a
Size argument is greater than the free space in the destination buffer
450 }
451 else
452 {
453 /* invalid day_number value - should never happen */
454 }
455 return buffer;
456}
457
458/* debugging: print the current time in the parser_control structure.
459 The parser will increment "*_seen" members for those which were parsed.
460 This function will print only newly seen parts. */
461static void
462debug_print_current_time (const char* item, parser_control *pc)
463{
464 char tmp[100] = {0};
465 int space = 0; /* if true, add space delimiter */
466
467 if (!pc->parse_datetime_debug)
59
Taking false branch
468 return;
469
470 /* no newline, more items printed below */
471 dbg_printf (_("parsed %s part: ")((const char *) ("parsed %s part: ")), item);
472
473 if (pc->dates_seen != pc->debug_dates_seen)
60
Taking false branch
474 {
475 /*TODO: use pc->year.negative? */
476 fprintf (stderrstderr,"(Y-M-D) %04ld-%02ld-%02ld",
477 pc->year.value, pc->month, pc->day);
478 pc->debug_dates_seen = pc->dates_seen;
479 space = 1;
480 }
481
482 if (pc->times_seen != pc->debug_times_seen)
61
Taking false branch
483 {
484 if (space)
485 fputc (' ',stderrstderr);
486 fprintf (stderrstderr,"%02ld:%02ld:%02ld",
487 pc->hour, pc->minutes, pc->seconds.tv_sec);
488 if (pc->seconds.tv_nsec!=0)
489 fprintf (stderrstderr,"%09ld", pc->seconds.tv_nsec);
490 if (pc->meridian==MERpm)
491 fputs ("pm",stderrstderr);
492
493 pc->debug_times_seen = pc->times_seen;
494 space = 1;
495 }
496
497 if (pc->days_seen != pc->debug_days_seen)
62
Taking true branch
498 {
499 if (space)
63
Taking false branch
500 fputc (' ',stderrstderr);
501 fprintf (stderrstderr,_("%s (day ordinal=%ld number=%d)")((const char *) ("%s (day ordinal=%ld number=%d)")),
502 str_days (pc,tmp,sizeof (tmp)),
64
Calling 'str_days'
503 pc->day_ordinal, pc->day_number);
504 pc->debug_days_seen = pc->days_seen ;
505 space = 1;
506 }
507
508 if (pc->dsts_seen != pc->debug_dsts_seen)
509 {
510 if (space)
511 fputc (' ',stderrstderr);
512 fprintf (stderrstderr,_("is-dst=%d")((const char *) ("is-dst=%d")), pc->local_isdst);
513 pc->dsts_seen = pc->debug_dsts_seen;
514 space = 1;
515 }
516
517 /* TODO: fix incorrect display of EST=2:08h? */
518 if (pc->zones_seen != pc->debug_zones_seen)
519 {
520 if (space)
521 fputc (' ',stderrstderr);
522 fprintf (stderrstderr,_("TZ=%+03d:%02d")((const char *) ("TZ=%+03d:%02d")), (int)(pc->time_zone/60),
523 abs ((int)pc->time_zone%60));
524 pc->debug_zones_seen = pc->zones_seen;
525 space = 1;
526 }
527
528 if (pc->local_zones_seen != pc->debug_local_zones_seen)
529 {
530 if (space)
531 fputc (' ',stderrstderr);
532 fprintf (stderrstderr,_("Local-TZ=%+03d:%02d")((const char *) ("Local-TZ=%+03d:%02d")), (int)(pc->time_zone/60),
533 abs ((int)pc->time_zone%60));
534 pc->debug_local_zones_seen = pc->local_zones_seen;
535 space = 1;
536 }
537
538 if (pc->timespec_seen)
539 {
540 if (space)
541 fputc (' ',stderrstderr);
542 fprintf (stderrstderr,_("number of seconds: %ld")((const char *) ("number of seconds: %ld")), pc->seconds.tv_sec);
543 }
544
545 fputc ('\n', stderrstderr);
546}
547
548/* debugging: print the current relative values. */
549static void
550debug_print_relative_time (const char* item, const parser_control *pc)
551{
552 int space = 0; /* if true, add space delimiter */
553
554 if (!pc->parse_datetime_debug)
555 return;
556
557 /* no newline, more items printed below */
558 dbg_printf (_("parsed %s part: ")((const char *) ("parsed %s part: ")), item);
559
560 if (pc->rel.year==0 && pc->rel.month==0 && pc->rel.day==0
561 && pc->rel.hour==0 && pc->rel.minutes==00 && pc->rel.seconds == 0
562 && pc->rel.ns==0)
563 {
564 /* Special case: relative time of this/today/now */
565 fputs (_("today/this/now\n")((const char *) ("today/this/now\n")),stderrstderr);
566 return ;
567 }
568
569#define PRINT_REL_PART(x,name)do { if ( (pc->rel.x) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.x, name); space = 1;
} } while (0)
\
570 do { \
571 if ( (pc->rel.x) != 0 ) \
572 { \
573 if (space) \
574 fputc (' ',stderrstderr); \
575 fprintf (stderrstderr,"%+ld %s", pc->rel.x, name); \
576 space = 1; \
577 } \
578 } while (0)
579
580 PRINT_REL_PART (year,"year(s)")do { if ( (pc->rel.year) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.year, "year(s)"); space
= 1; } } while (0)
;
581 PRINT_REL_PART (month,"month(s)")do { if ( (pc->rel.month) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.month, "month(s)"); space
= 1; } } while (0)
;
582 PRINT_REL_PART (day,"day(s)")do { if ( (pc->rel.day) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.day, "day(s)"); space
= 1; } } while (0)
;
583 PRINT_REL_PART (hour,"hour(s)")do { if ( (pc->rel.hour) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.hour, "hour(s)"); space
= 1; } } while (0)
;
584 PRINT_REL_PART (minutes,"minutes")do { if ( (pc->rel.minutes) != 0 ) { if (space) fputc (' '
,stderr); fprintf (stderr,"%+ld %s", pc->rel.minutes, "minutes"
); space = 1; } } while (0)
;
585 PRINT_REL_PART (seconds,"seconds")do { if ( (pc->rel.seconds) != 0 ) { if (space) fputc (' '
,stderr); fprintf (stderr,"%+ld %s", pc->rel.seconds, "seconds"
); space = 1; } } while (0)
;
586 PRINT_REL_PART (ns,"nanoseconds")do { if ( (pc->rel.ns) != 0 ) { if (space) fputc (' ',stderr
); fprintf (stderr,"%+ld %s", pc->rel.ns, "nanoseconds"); space
= 1; } } while (0)
;
587
588 fputc ('\n',stderrstderr);
589}
590
591
592
593
594#line 595 "parse-datetime.c" /* yacc.c:339 */
595
596# ifndef YY_NULLPTR0
597# if defined __cplusplus && 201103L <= __cplusplus
598# define YY_NULLPTR0 nullptr
599# else
600# define YY_NULLPTR0 0
601# endif
602# endif
603
604/* Enabling verbose error messages. */
605#ifdef YYERROR_VERBOSE0
606# undef YYERROR_VERBOSE0
607# define YYERROR_VERBOSE0 1
608#else
609# define YYERROR_VERBOSE0 0
610#endif
611
612
613/* Debug traces. */
614#ifndef YYDEBUG0
615# define YYDEBUG0 0
616#endif
617#if YYDEBUG0
618extern int yydebug;
619#endif
620
621/* Token type. */
622#ifndef YYTOKENTYPE
623# define YYTOKENTYPE
624 enum yytokentype
625 {
626 tAGO258 = 258,
627 tDST259 = 259,
628 tYEAR_UNIT260 = 260,
629 tMONTH_UNIT261 = 261,
630 tHOUR_UNIT262 = 262,
631 tMINUTE_UNIT263 = 263,
632 tSEC_UNIT264 = 264,
633 tDAY_UNIT265 = 265,
634 tDAY_SHIFT266 = 266,
635 tDAY267 = 267,
636 tDAYZONE268 = 268,
637 tLOCAL_ZONE269 = 269,
638 tMERIDIAN270 = 270,
639 tMONTH271 = 271,
640 tORDINAL272 = 272,
641 tZONE273 = 273,
642 tSNUMBER274 = 274,
643 tUNUMBER275 = 275,
644 tSDECIMAL_NUMBER276 = 276,
645 tUDECIMAL_NUMBER277 = 277
646 };
647#endif
648/* Tokens. */
649#define tAGO258 258
650#define tDST259 259
651#define tYEAR_UNIT260 260
652#define tMONTH_UNIT261 261
653#define tHOUR_UNIT262 262
654#define tMINUTE_UNIT263 263
655#define tSEC_UNIT264 264
656#define tDAY_UNIT265 265
657#define tDAY_SHIFT266 266
658#define tDAY267 267
659#define tDAYZONE268 268
660#define tLOCAL_ZONE269 269
661#define tMERIDIAN270 270
662#define tMONTH271 271
663#define tORDINAL272 272
664#define tZONE273 273
665#define tSNUMBER274 274
666#define tUNUMBER275 275
667#define tSDECIMAL_NUMBER276 276
668#define tUDECIMAL_NUMBER277 277
669
670/* Value type. */
671#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED1
672typedef union YYSTYPE YYSTYPE;
673union YYSTYPE
674{
675#line 540 "./parse-datetime.y" /* yacc.c:355 */
676
677 long int intval;
678 textint textintval;
679 struct timespec timespec;
680 relative_time rel;
681
682#line 683 "parse-datetime.c" /* yacc.c:355 */
683};
684# define YYSTYPE_IS_TRIVIAL1 1
685# define YYSTYPE_IS_DECLARED1 1
686#endif
687
688
689
690int yyparse (parser_control *pc);
691
692
693
694/* Copy the second part of user declarations. */
695
696#line 697 "parse-datetime.c" /* yacc.c:358 */
697
698#ifdef short
699# undef short
700#endif
701
702#ifdef YYTYPE_UINT8
703typedef YYTYPE_UINT8 yytype_uint8;
704#else
705typedef unsigned char yytype_uint8;
706#endif
707
708#ifdef YYTYPE_INT8
709typedef YYTYPE_INT8 yytype_int8;
710#else
711typedef signed char yytype_int8;
712#endif
713
714#ifdef YYTYPE_UINT16
715typedef YYTYPE_UINT16 yytype_uint16;
716#else
717typedef unsigned short int yytype_uint16;
718#endif
719
720#ifdef YYTYPE_INT16
721typedef YYTYPE_INT16 yytype_int16;
722#else
723typedef short int yytype_int16;
724#endif
725
726#ifndef YYSIZE_Tlong unsigned int
727# ifdef __SIZE_TYPE__long unsigned int
728# define YYSIZE_Tlong unsigned int __SIZE_TYPE__long unsigned int
729# elif defined size_t
730# define YYSIZE_Tlong unsigned int size_t
731# elif ! defined YYSIZE_Tlong unsigned int
732# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
733# define YYSIZE_Tlong unsigned int size_t
734# else
735# define YYSIZE_Tlong unsigned int unsigned int
736# endif
737#endif
738
739#define YYSIZE_MAXIMUM((long unsigned int) -1) ((YYSIZE_Tlong unsigned int) -1)
740
741#ifndef YY_
742# if defined YYENABLE_NLS && YYENABLE_NLS
743# if ENABLE_NLS
744# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
745# define YY_(Msgid)Msgid dgettext ("bison-runtime", Msgid)((void) ("bison-runtime"), ((const char *) (Msgid)))
746# endif
747# endif
748# ifndef YY_
749# define YY_(Msgid)Msgid Msgid
750# endif
751#endif
752
753#ifndef YY_ATTRIBUTE
754# if (defined __GNUC__4 \
755 && (2 < __GNUC__4 || (__GNUC__4 == 2 && 96 <= __GNUC_MINOR__2))) \
756 || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
757# define YY_ATTRIBUTE(Spec)__attribute__(Spec) __attribute__(Spec)
758# else
759# define YY_ATTRIBUTE(Spec)__attribute__(Spec) /* empty */
760# endif
761#endif
762
763#ifndef YY_ATTRIBUTE_PURE__attribute__((__pure__))
764# define YY_ATTRIBUTE_PURE__attribute__((__pure__)) YY_ATTRIBUTE ((__pure__))__attribute__((__pure__))
765#endif
766
767#ifndef YY_ATTRIBUTE_UNUSED__attribute__((__unused__))
768# define YY_ATTRIBUTE_UNUSED__attribute__((__unused__)) YY_ATTRIBUTE ((__unused__))__attribute__((__unused__))
769#endif
770
771#if !defined _Noreturn__attribute__ ((__noreturn__)) \
772 && (!defined __STDC_VERSION__199901L || __STDC_VERSION__199901L < 201112)
773# if defined _MSC_VER && 1200 <= _MSC_VER
774# define _Noreturn__attribute__ ((__noreturn__)) __declspec (noreturn)
775# else
776# define _Noreturn__attribute__ ((__noreturn__)) YY_ATTRIBUTE ((__noreturn__))__attribute__((__noreturn__))
777# endif
778#endif
779
780/* Suppress unused-variable warnings by "using" E. */
781#if ! defined lint || defined __GNUC__4
782# define YYUSE(E)((void) (E)) ((void) (E))
783#else
784# define YYUSE(E)((void) (E)) /* empty */
785#endif
786
787#if defined __GNUC__4 && 407 <= __GNUC__4 * 100 + __GNUC_MINOR__2
788/* Suppress an incorrect diagnostic about yylval being uninitialized. */
789# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
790 _Pragma ("GCC diagnostic push")GCC diagnostic push \
791 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")GCC diagnostic ignored "-Wuninitialized" \
792 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")GCC diagnostic ignored "-Wmaybe-uninitialized"
793# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
794 _Pragma ("GCC diagnostic pop")GCC diagnostic pop
795#else
796# define YY_INITIAL_VALUE(Value)Value Value
797#endif
798#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
799# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
800# define YY_IGNORE_MAYBE_UNINITIALIZED_END
801#endif
802#ifndef YY_INITIAL_VALUE
803# define YY_INITIAL_VALUE(Value)Value /* Nothing. */
804#endif
805
806
807#if ! defined yyoverflow || YYERROR_VERBOSE0
808
809/* The parser invokes alloca or malloc; define the necessary symbols. */
810
811# ifdef YYSTACK_USE_ALLOCA0
812# if YYSTACK_USE_ALLOCA0
813# ifdef __GNUC__4
814# define YYSTACK_ALLOCmalloc __builtin_alloca
815# elif defined __BUILTIN_VA_ARG_INCR
816# include <alloca__builtin_alloca.h> /* INFRINGES ON USER NAME SPACE */
817# elif defined _AIX
818# define YYSTACK_ALLOCmalloc __alloca
819# elif defined _MSC_VER
820# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
821# define alloca__builtin_alloca _alloca
822# else
823# define YYSTACK_ALLOCmalloc alloca__builtin_alloca
824# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS0
825# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
826 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
827# ifndef EXIT_SUCCESS0
828# define EXIT_SUCCESS0 0
829# endif
830# endif
831# endif
832# endif
833# endif
834
835# ifdef YYSTACK_ALLOCmalloc
836 /* Pacify GCC's 'empty if-body' warning. */
837# define YYSTACK_FREEfree(Ptr) do { /* empty */; } while (0)
838# ifndef YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1)
839 /* The OS might guarantee only one guard page at the bottom of the stack,
840 and a page size can be as small as 4096 bytes. So we cannot safely
841 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
842 to allow for a few compiler-allocated temporary stack slots. */
843# define YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1) 4032 /* reasonable circa 2006 */
844# endif
845# else
846# define YYSTACK_ALLOCmalloc YYMALLOCmalloc
847# define YYSTACK_FREEfree YYFREEfree
848# ifndef YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1)
849# define YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1) YYSIZE_MAXIMUM((long unsigned int) -1)
850# endif
851# if (defined __cplusplus && ! defined EXIT_SUCCESS0 \
852 && ! ((defined YYMALLOCmalloc || defined malloc) \
853 && (defined YYFREEfree || defined free)))
854# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
855# ifndef EXIT_SUCCESS0
856# define EXIT_SUCCESS0 0
857# endif
858# endif
859# ifndef YYMALLOCmalloc
860# define YYMALLOCmalloc malloc
861# if ! defined malloc && ! defined EXIT_SUCCESS0
862void *malloc (YYSIZE_Tlong unsigned int); /* INFRINGES ON USER NAME SPACE */
863# endif
864# endif
865# ifndef YYFREEfree
866# define YYFREEfree free
867# if ! defined free && ! defined EXIT_SUCCESS0
868void free (void *); /* INFRINGES ON USER NAME SPACE */
869# endif
870# endif
871# endif
872#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
873
874
875#if (! defined yyoverflow \
876 && (! defined __cplusplus \
877 || (defined YYSTYPE_IS_TRIVIAL1 && YYSTYPE_IS_TRIVIAL1)))
878
879/* A type that is properly aligned for any stack member. */
880union yyalloc
881{
882 yytype_int16 yyss_alloc;
883 YYSTYPE yyvs_alloc;
884};
885
886/* The size of the maximum gap between one aligned stack and the next. */
887# define YYSTACK_GAP_MAXIMUM(sizeof (union yyalloc) - 1) (sizeof (union yyalloc) - 1)
888
889/* The size of an array large to enough to hold all stacks, each with
890 N elements. */
891# define YYSTACK_BYTES(N)((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) + (sizeof (
union yyalloc) - 1))
\
892 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
893 + YYSTACK_GAP_MAXIMUM(sizeof (union yyalloc) - 1))
894
895# define YYCOPY_NEEDED1 1
896
897/* Relocate STACK from its old location to the new one. The
898 local variables YYSIZE and YYSTACKSIZE give the old and new number of
899 elements in the stack, and YYPTR gives the new location of the
900 stack. Advance YYPTR to a properly aligned location for the next
901 stack. */
902# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
903 do \
904 { \
905 YYSIZE_Tlong unsigned int yynewbytes; \
906 YYCOPY (&yyptr->Stack_alloc, Stack, yysize)__builtin_memcpy (&yyptr->Stack_alloc, Stack, (yysize)
* sizeof (*(Stack)))
; \
907 Stack = &yyptr->Stack_alloc; \
908 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM(sizeof (union yyalloc) - 1); \
909 yyptr += yynewbytes / sizeof (*yyptr); \
910 } \
911 while (0)
912
913#endif
914
915#if defined YYCOPY_NEEDED1 && YYCOPY_NEEDED1
916/* Copy COUNT objects from SRC to DST. The source and destination do
917 not overlap. */
918# ifndef YYCOPY
919# if defined __GNUC__4 && 1 < __GNUC__4
920# define YYCOPY(Dst, Src, Count)__builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) \
921 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
922# else
923# define YYCOPY(Dst, Src, Count)__builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) \
924 do \
925 { \
926 YYSIZE_Tlong unsigned int yyi; \
927 for (yyi = 0; yyi < (Count); yyi++) \
928 (Dst)[yyi] = (Src)[yyi]; \
929 } \
930 while (0)
931# endif
932# endif
933#endif /* !YYCOPY_NEEDED */
934
935/* YYFINAL -- State number of the termination state. */
936#define YYFINAL12 12
937/* YYLAST -- Last index in YYTABLE. */
938#define YYLAST112 112
939
940/* YYNTOKENS -- Number of terminals. */
941#define YYNTOKENS28 28
942/* YYNNTS -- Number of nonterminals. */
943#define YYNNTS26 26
944/* YYNRULES -- Number of rules. */
945#define YYNRULES91 91
946/* YYNSTATES -- Number of states. */
947#define YYNSTATES114 114
948
949/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
950 by yylex, with out-of-bounds checking. */
951#define YYUNDEFTOK2 2
952#define YYMAXUTOK277 277
953
954#define YYTRANSLATE(YYX)((unsigned int) (YYX) <= 277 ? yytranslate[YYX] : 2) \
955 ((unsigned int) (YYX) <= YYMAXUTOK277 ? yytranslate[YYX] : YYUNDEFTOK2)
956
957/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
958 as returned by yylex, without out-of-bounds checking. */
959static const yytype_uint8 yytranslate[] =
960{
961 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
962 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
963 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
964 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
965 2, 2, 2, 2, 26, 2, 2, 27, 2, 2,
966 2, 2, 2, 2, 2, 2, 2, 2, 25, 2,
967 2, 2, 2, 2, 23, 2, 2, 2, 2, 2,
968 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
969 2, 2, 2, 2, 24, 2, 2, 2, 2, 2,
970 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
971 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
972 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
973 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
974 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
975 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
976 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
977 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
978 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
979 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
980 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
981 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
982 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
983 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
984 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
985 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
986 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
987 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
988 15, 16, 17, 18, 19, 20, 21, 22
989};
990
991#if YYDEBUG0
992 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
993static const yytype_uint16 yyrline[] =
994{
995 0, 567, 567, 568, 572, 580, 582, 586, 591, 596,
996 601, 606, 611, 616, 620, 624, 631, 635, 639, 644,
997 649, 654, 658, 663, 668, 675, 677, 681, 689, 694,
998 704, 706, 708, 711, 714, 716, 718, 723, 728, 733,
999 739, 748, 753, 781, 789, 797, 802, 808, 813, 819,
1000 823, 833, 835, 837, 842, 844, 846, 848, 850, 852,
1001 854, 856, 858, 860, 862, 864, 866, 868, 870, 872,
1002 874, 876, 878, 880, 882, 886, 888, 890, 892, 894,
1003 896, 901, 905, 905, 908, 909, 914, 915, 920, 925,
1004 936, 937
1005};
1006#endif
1007
1008#if YYDEBUG0 || YYERROR_VERBOSE0 || 0
1009/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
1010 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
1011static const char *const yytname[] =
1012{
1013 "$end", "error", "$undefined", "tAGO", "tDST", "tYEAR_UNIT",
1014 "tMONTH_UNIT", "tHOUR_UNIT", "tMINUTE_UNIT", "tSEC_UNIT", "tDAY_UNIT",
1015 "tDAY_SHIFT", "tDAY", "tDAYZONE", "tLOCAL_ZONE", "tMERIDIAN", "tMONTH",
1016 "tORDINAL", "tZONE", "tSNUMBER", "tUNUMBER", "tSDECIMAL_NUMBER",
1017 "tUDECIMAL_NUMBER", "'@'", "'T'", "':'", "','", "'/'", "$accept", "spec",
1018 "timespec", "items", "item", "datetime", "iso_8601_datetime", "time",
1019 "iso_8601_time", "o_zone_offset", "zone_offset", "local_zone", "zone",
1020 "day", "date", "iso_8601_date", "rel", "relunit", "relunit_snumber",
1021 "dayshift", "seconds", "signed_seconds", "unsigned_seconds", "number",
1022 "hybrid", "o_colon_minutes", YY_NULLPTR0
1023};
1024#endif
1025
1026# ifdef YYPRINT
1027/* YYTOKNUM[NUM] -- (External) token number corresponding to the
1028 (internal) symbol number NUM (which must be that of a token). */
1029static const yytype_uint16 yytoknum[] =
1030{
1031 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
1032 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
1033 275, 276, 277, 64, 84, 58, 44, 47
1034};
1035# endif
1036
1037#define YYPACT_NINF-93 -93
1038
1039#define yypact_value_is_default(Yystate)(!!((Yystate) == (-93))) \
1040 (!!((Yystate) == (-93)))
1041
1042#define YYTABLE_NINF-1 -1
1043
1044#define yytable_value_is_error(Yytable_value)0 \
1045 0
1046
1047 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
1048 STATE-NUM. */
1049static const yytype_int8 yypact[] =
1050{
1051 38, 27, 77, -93, 46, -93, -93, -93, -93, -93,
1052 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1053 62, -93, 82, -3, 66, 3, 74, -4, 83, 84,
1054 75, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1055 71, -93, 93, -93, -93, -93, -93, -93, -93, 78,
1056 72, -93, -93, -93, -93, -93, -93, -93, -93, 25,
1057 -93, -93, -93, -93, -93, -93, -93, -93, -93, -93,
1058 -93, -93, -93, -93, -93, 21, 19, 79, 80, -93,
1059 -93, -93, -93, -93, 81, -93, -93, 85, 86, -93,
1060 -93, -93, -93, -93, -6, 76, 17, -93, -93, -93,
1061 -93, 87, 69, -93, -93, 88, 89, -1, -93, 18,
1062 -93, -93, 69, 91
1063};
1064
1065 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
1066 Performed when YYTABLE does not specify something else to do. Zero
1067 means the default is an error. */
1068static const yytype_uint8 yydefact[] =
1069{
1070 5, 0, 0, 2, 3, 85, 87, 84, 86, 4,
1071 82, 83, 1, 56, 59, 65, 68, 73, 62, 81,
1072 37, 35, 28, 0, 0, 30, 0, 88, 0, 0,
1073 31, 6, 7, 16, 8, 21, 9, 10, 12, 11,
1074 49, 13, 52, 74, 53, 14, 15, 38, 29, 0,
1075 45, 54, 57, 63, 66, 69, 60, 39, 36, 90,
1076 32, 75, 76, 78, 79, 80, 77, 55, 58, 64,
1077 67, 70, 61, 40, 18, 47, 90, 0, 0, 22,
1078 89, 71, 72, 33, 0, 51, 44, 0, 0, 34,
1079 43, 48, 50, 27, 25, 41, 0, 17, 46, 91,
1080 19, 90, 0, 23, 26, 0, 0, 25, 42, 25,
1081 20, 24, 0, 25
1082};
1083
1084 /* YYPGOTO[NTERM-NUM]. */
1085static const yytype_int8 yypgoto[] =
1086{
1087 -93, -93, -93, -93, -93, -93, -93, -93, 20, -68,
1088 -27, -93, -93, -93, -93, -93, -93, -93, 60, -93,
1089 -93, -93, -92, -93, -93, 43
1090};
1091
1092 /* YYDEFGOTO[NTERM-NUM]. */
1093static const yytype_int8 yydefgoto[] =
1094{
1095 -1, 2, 3, 4, 31, 32, 33, 34, 35, 103,
1096 104, 36, 37, 38, 39, 40, 41, 42, 43, 44,
1097 9, 10, 11, 45, 46, 93
1098};
1099
1100 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
1101 positive, shift that token. If negative, reduce the rule whose
1102 number is the opposite. If YYTABLE_NINF, syntax error. */
1103static const yytype_uint8 yytable[] =
1104{
1105 79, 67, 68, 69, 70, 71, 72, 58, 73, 100,
1106 107, 74, 75, 101, 110, 76, 49, 50, 101, 102,
1107 113, 77, 59, 78, 61, 62, 63, 64, 65, 66,
1108 61, 62, 63, 64, 65, 66, 101, 101, 92, 111,
1109 90, 91, 106, 112, 88, 111, 5, 6, 7, 8,
1110 88, 13, 14, 15, 16, 17, 18, 19, 20, 21,
1111 22, 1, 23, 24, 25, 26, 27, 28, 29, 79,
1112 30, 51, 52, 53, 54, 55, 56, 12, 57, 61,
1113 62, 63, 64, 65, 66, 60, 48, 80, 47, 6,
1114 83, 8, 81, 82, 26, 84, 85, 86, 87, 94,
1115 95, 96, 89, 105, 97, 98, 99, 0, 108, 109,
1116 101, 0, 88
1117};
1118
1119static const yytype_int8 yycheck[] =
1120{
1121 27, 5, 6, 7, 8, 9, 10, 4, 12, 15,
1122 102, 15, 16, 19, 15, 19, 19, 20, 19, 25,
1123 112, 25, 19, 27, 5, 6, 7, 8, 9, 10,
1124 5, 6, 7, 8, 9, 10, 19, 19, 19, 107,
1125 19, 20, 25, 25, 25, 113, 19, 20, 21, 22,
1126 25, 5, 6, 7, 8, 9, 10, 11, 12, 13,
1127 14, 23, 16, 17, 18, 19, 20, 21, 22, 96,
1128 24, 5, 6, 7, 8, 9, 10, 0, 12, 5,
1129 6, 7, 8, 9, 10, 25, 4, 27, 26, 20,
1130 30, 22, 9, 9, 19, 24, 3, 19, 26, 20,
1131 20, 20, 59, 27, 84, 20, 20, -1, 20, 20,
1132 19, -1, 25
1133};
1134
1135 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1136 symbol of state STATE-NUM. */
1137static const yytype_uint8 yystos[] =
1138{
1139 0, 23, 29, 30, 31, 19, 20, 21, 22, 48,
1140 49, 50, 0, 5, 6, 7, 8, 9, 10, 11,
1141 12, 13, 14, 16, 17, 18, 19, 20, 21, 22,
1142 24, 32, 33, 34, 35, 36, 39, 40, 41, 42,
1143 43, 44, 45, 46, 47, 51, 52, 26, 4, 19,
1144 20, 5, 6, 7, 8, 9, 10, 12, 4, 19,
1145 46, 5, 6, 7, 8, 9, 10, 5, 6, 7,
1146 8, 9, 10, 12, 15, 16, 19, 25, 27, 38,
1147 46, 9, 9, 46, 24, 3, 19, 26, 25, 53,
1148 19, 20, 19, 53, 20, 20, 20, 36, 20, 20,
1149 15, 19, 25, 37, 38, 27, 25, 50, 20, 20,
1150 15, 37, 25, 50
1151};
1152
1153 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
1154static const yytype_uint8 yyr1[] =
1155{
1156 0, 28, 29, 29, 30, 31, 31, 32, 32, 32,
1157 32, 32, 32, 32, 32, 32, 33, 34, 35, 35,
1158 35, 35, 36, 36, 36, 37, 37, 38, 39, 39,
1159 40, 40, 40, 40, 40, 40, 40, 41, 41, 41,
1160 41, 42, 42, 42, 42, 42, 42, 42, 42, 42,
1161 43, 44, 44, 44, 45, 45, 45, 45, 45, 45,
1162 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
1163 45, 45, 45, 45, 45, 46, 46, 46, 46, 46,
1164 46, 47, 48, 48, 49, 49, 50, 50, 51, 52,
1165 53, 53
1166};
1167
1168 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
1169static const yytype_uint8 yyr2[] =
1170{
1171 0, 2, 1, 1, 2, 0, 2, 1, 1, 1,
1172 1, 1, 1, 1, 1, 1, 1, 3, 2, 4,
1173 6, 1, 2, 4, 6, 0, 1, 2, 1, 2,
1174 1, 1, 2, 2, 3, 1, 2, 1, 2, 2,
1175 2, 3, 5, 3, 3, 2, 4, 2, 3, 1,
1176 3, 2, 1, 1, 2, 2, 1, 2, 2, 1,
1177 2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
1178 2, 2, 2, 1, 1, 2, 2, 2, 2, 2,
1179 2, 1, 1, 1, 1, 1, 1, 1, 1, 2,
1180 0, 2
1181};
1182
1183
1184#define yyerrok(yyerrstatus = 0) (yyerrstatus = 0)
1185#define yyclearin(yychar = (-2)) (yychar = YYEMPTY(-2))
1186#define YYEMPTY(-2) (-2)
1187#define YYEOF0 0
1188
1189#define YYACCEPTgoto yyacceptlab goto yyacceptlab
1190#define YYABORTgoto yyabortlab goto yyabortlab
1191#define YYERRORgoto yyerrorlab goto yyerrorlab
1192
1193
1194#define YYRECOVERING()(!!yyerrstatus) (!!yyerrstatus)
1195
1196#define YYBACKUP(Token, Value)do if (yychar == (-2)) { yychar = (Token); yylval = (Value); (
yyvsp -= (yylen), yyssp -= (yylen)); yystate = *yyssp; goto yybackup
; } else { yyerror (pc, "syntax error: cannot back up"); goto
yyerrorlab; } while (0)
\
1197do \
1198 if (yychar == YYEMPTY(-2)) \
1199 { \
1200 yychar = (Token); \
1201 yylval = (Value); \
1202 YYPOPSTACK (yylen)(yyvsp -= (yylen), yyssp -= (yylen)); \
1203 yystate = *yyssp; \
1204 goto yybackup; \
1205 } \
1206 else \
1207 { \
1208 yyerror (pc, YY_("syntax error: cannot back up")"syntax error: cannot back up"); \
1209 YYERRORgoto yyerrorlab; \
1210 } \
1211while (0)
1212
1213/* Error token number */
1214#define YYTERROR1 1
1215#define YYERRCODE256 256
1216
1217
1218
1219/* Enable debugging if requested. */
1220#if YYDEBUG0
1221
1222# ifndef YYFPRINTF
1223# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1224# define YYFPRINTF fprintf
1225# endif
1226
1227# define YYDPRINTF(Args) \
1228do { \
1229 if (yydebug) \
1230 YYFPRINTF Args; \
1231} while (0)
1232
1233/* This macro is provided for backward compatibility. */
1234#ifndef YY_LOCATION_PRINT
1235# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1236#endif
1237
1238
1239# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1240do { \
1241 if (yydebug) \
1242 { \
1243 YYFPRINTF (stderrstderr, "%s ", Title); \
1244 yy_symbol_print (stderrstderr, \
1245 Type, Value, pc); \
1246 YYFPRINTF (stderrstderr, "\n"); \
1247 } \
1248} while (0)
1249
1250
1251/*----------------------------------------.
1252| Print this symbol's value on YYOUTPUT. |
1253`----------------------------------------*/
1254
1255static void
1256yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)
1257{
1258 FILE *yyo = yyoutput;
1259 YYUSE (yyo)((void) (yyo));
1260 YYUSE (pc)((void) (pc));
1261 if (!yyvaluep)
1262 return;
1263# ifdef YYPRINT
1264 if (yytype < YYNTOKENS28)
1265 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1266# endif
1267 YYUSE (yytype)((void) (yytype));
1268}
1269
1270
1271/*--------------------------------.
1272| Print this symbol on YYOUTPUT. |
1273`--------------------------------*/
1274
1275static void
1276yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, parser_control *pc)
1277{
1278 YYFPRINTF (yyoutput, "%s %s (",
1279 yytype < YYNTOKENS28 ? "token" : "nterm", yytname[yytype]);
1280
1281 yy_symbol_value_print (yyoutput, yytype, yyvaluep, pc);
1282 YYFPRINTF (yyoutput, ")");
1283}
1284
1285/*------------------------------------------------------------------.
1286| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1287| TOP (included). |
1288`------------------------------------------------------------------*/
1289
1290static void
1291yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1292{
1293 YYFPRINTF (stderrstderr, "Stack now");
1294 for (; yybottom <= yytop; yybottom++)
1295 {
1296 int yybot = *yybottom;
1297 YYFPRINTF (stderrstderr, " %d", yybot);
1298 }
1299 YYFPRINTF (stderrstderr, "\n");
1300}
1301
1302# define YY_STACK_PRINT(Bottom, Top) \
1303do { \
1304 if (yydebug) \
1305 yy_stack_print ((Bottom), (Top)); \
1306} while (0)
1307
1308
1309/*------------------------------------------------.
1310| Report that the YYRULE is going to be reduced. |
1311`------------------------------------------------*/
1312
1313static void
1314yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, parser_control *pc)
1315{
1316 unsigned long int yylno = yyrline[yyrule];
1317 int yynrhs = yyr2[yyrule];
1318 int yyi;
1319 YYFPRINTF (stderrstderr, "Reducing stack by rule %d (line %lu):\n",
1320 yyrule - 1, yylno);
1321 /* The symbols being reduced. */
1322 for (yyi = 0; yyi < yynrhs; yyi++)
1323 {
1324 YYFPRINTF (stderrstderr, " $%d = ", yyi + 1);
1325 yy_symbol_print (stderrstderr,
1326 yystos[yyssp[yyi + 1 - yynrhs]],
1327 &(yyvsp[(yyi + 1) - (yynrhs)])
1328 , pc);
1329 YYFPRINTF (stderrstderr, "\n");
1330 }
1331}
1332
1333# define YY_REDUCE_PRINT(Rule) \
1334do { \
1335 if (yydebug) \
1336 yy_reduce_print (yyssp, yyvsp, Rule, pc); \
1337} while (0)
1338
1339/* Nonzero means print parse trace. It is left uninitialized so that
1340 multiple parsers can coexist. */
1341int yydebug;
1342#else /* !YYDEBUG */
1343# define YYDPRINTF(Args)
1344# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1345# define YY_STACK_PRINT(Bottom, Top)
1346# define YY_REDUCE_PRINT(Rule)
1347#endif /* !YYDEBUG */
1348
1349
1350/* YYINITDEPTH -- initial size of the parser's stacks. */
1351#ifndef YYINITDEPTH20
1352# define YYINITDEPTH20 200
1353#endif
1354
1355/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1356 if the built-in stack extension method is used).
1357
1358 Do not make this value too large; the results are undefined if
1359 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1360 evaluated with infinite-precision integer arithmetic. */
1361
1362#ifndef YYMAXDEPTH20
1363# define YYMAXDEPTH20 10000
1364#endif
1365
1366
1367#if YYERROR_VERBOSE0
1368
1369# ifndef yystrlen
1370# if defined __GLIBC__2 && defined _STRING_H1
1371# define yystrlen strlen
1372# else
1373/* Return the length of YYSTR. */
1374static YYSIZE_Tlong unsigned int
1375yystrlen (const char *yystr)
1376{
1377 YYSIZE_Tlong unsigned int yylen;
1378 for (yylen = 0; yystr[yylen]; yylen++)
1379 continue;
1380 return yylen;
1381}
1382# endif
1383# endif
1384
1385# ifndef yystpcpy
1386# if defined __GLIBC__2 && defined _STRING_H1 && defined _GNU_SOURCE1
1387# define yystpcpy stpcpy
1388# else
1389/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1390 YYDEST. */
1391static char *
1392yystpcpy (char *yydest, const char *yysrc)
1393{
1394 char *yyd = yydest;
1395 const char *yys = yysrc;
1396
1397 while ((*yyd++ = *yys++) != '\0')
1398 continue;
1399
1400 return yyd - 1;
1401}
1402# endif
1403# endif
1404
1405# ifndef yytnamerr
1406/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1407 quotes and backslashes, so that it's suitable for yyerror. The
1408 heuristic is that double-quoting is unnecessary unless the string
1409 contains an apostrophe, a comma, or backslash (other than
1410 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1411 null, do not copy; instead, return the length of what the result
1412 would have been. */
1413static YYSIZE_Tlong unsigned int
1414yytnamerr (char *yyres, const char *yystr)
1415{
1416 if (*yystr == '"')
1417 {
1418 YYSIZE_Tlong unsigned int yyn = 0;
1419 char const *yyp = yystr;
1420
1421 for (;;)
1422 switch (*++yyp)
1423 {
1424 case '\'':
1425 case ',':
1426 goto do_not_strip_quotes;
1427
1428 case '\\':
1429 if (*++yyp != '\\')
1430 goto do_not_strip_quotes;
1431 /* Fall through. */
1432 default:
1433 if (yyres)
1434 yyres[yyn] = *yyp;
1435 yyn++;
1436 break;
1437
1438 case '"':
1439 if (yyres)
1440 yyres[yyn] = '\0';
1441 return yyn;
1442 }
1443 do_not_strip_quotes: ;
1444 }
1445
1446 if (! yyres)
1447 return yystrlen (yystr);
1448
1449 return yystpcpy (yyres, yystr) - yyres;
1450}
1451# endif
1452
1453/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1454 about the unexpected token YYTOKEN for the state stack whose top is
1455 YYSSP.
1456
1457 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1458 not large enough to hold the message. In that case, also set
1459 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1460 required number of bytes is too large to store. */
1461static int
1462yysyntax_error (YYSIZE_Tlong unsigned int *yymsg_alloc, char **yymsg,
1463 yytype_int16 *yyssp, int yytoken)
1464{
1465 YYSIZE_Tlong unsigned int yysize0 = yytnamerr (YY_NULLPTR0, yytname[yytoken]);
1466 YYSIZE_Tlong unsigned int yysize = yysize0;
1467 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1468 /* Internationalized format string. */
1469 const char *yyformat = YY_NULLPTR0;
1470 /* Arguments of yyformat. */
1471 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1472 /* Number of reported tokens (one for the "unexpected", one per
1473 "expected"). */
1474 int yycount = 0;
1475
1476 /* There are many possibilities here to consider:
1477 - If this state is a consistent state with a default action, then
1478 the only way this function was invoked is if the default action
1479 is an error action. In that case, don't check for expected
1480 tokens because there are none.
1481 - The only way there can be no lookahead present (in yychar) is if
1482 this state is a consistent state with a default action. Thus,
1483 detecting the absence of a lookahead is sufficient to determine
1484 that there is no unexpected or expected token to report. In that
1485 case, just report a simple "syntax error".
1486 - Don't assume there isn't a lookahead just because this state is a
1487 consistent state with a default action. There might have been a
1488 previous inconsistent state, consistent state with a non-default
1489 action, or user semantic action that manipulated yychar.
1490 - Of course, the expected token list depends on states to have
1491 correct lookahead information, and it depends on the parser not
1492 to perform extra reductions after fetching a lookahead from the
1493 scanner and before detecting a syntax error. Thus, state merging
1494 (from LALR or IELR) and default reductions corrupt the expected
1495 token list. However, the list is correct for canonical LR with
1496 one exception: it will still contain any token that will not be
1497 accepted due to an error action in a later state.
1498 */
1499 if (yytoken != YYEMPTY(-2))
1500 {
1501 int yyn = yypact[*yyssp];
1502 yyarg[yycount++] = yytname[yytoken];
1503 if (!yypact_value_is_default (yyn)(!!((yyn) == (-93))))
1504 {
1505 /* Start YYX at -YYN if negative to avoid negative indexes in
1506 YYCHECK. In other words, skip the first -YYN actions for
1507 this state because they are default actions. */
1508 int yyxbegin = yyn < 0 ? -yyn : 0;
1509 /* Stay within bounds of both yycheck and yytname. */
1510 int yychecklim = YYLAST112 - yyn + 1;
1511 int yyxend = yychecklim < YYNTOKENS28 ? yychecklim : YYNTOKENS28;
1512 int yyx;
1513
1514 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1515 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR1
1516 && !yytable_value_is_error (yytable[yyx + yyn])0)
1517 {
1518 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1519 {
1520 yycount = 1;
1521 yysize = yysize0;
1522 break;
1523 }
1524 yyarg[yycount++] = yytname[yyx];
1525 {
1526 YYSIZE_Tlong unsigned int yysize1 = yysize + yytnamerr (YY_NULLPTR0, yytname[yyx]);
1527 if (! (yysize <= yysize1
1528 && yysize1 <= YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1)))
1529 return 2;
1530 yysize = yysize1;
1531 }
1532 }
1533 }
1534 }
1535
1536 switch (yycount)
1537 {
1538# define YYCASE_(N, S) \
1539 case N: \
1540 yyformat = S; \
1541 break
1542 YYCASE_(0, YY_("syntax error")"syntax error");
1543 YYCASE_(1, YY_("syntax error, unexpected %s")"syntax error, unexpected %s");
1544 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")"syntax error, unexpected %s, expecting %s");
1545 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")"syntax error, unexpected %s, expecting %s or %s");
1546 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")"syntax error, unexpected %s, expecting %s or %s or %s");
1547 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")"syntax error, unexpected %s, expecting %s or %s or %s or %s");
1548# undef YYCASE_
1549 }
1550
1551 {
1552 YYSIZE_Tlong unsigned int yysize1 = yysize + yystrlen (yyformat);
1553 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1)))
1554 return 2;
1555 yysize = yysize1;
1556 }
1557
1558 if (*yymsg_alloc < yysize)
1559 {
1560 *yymsg_alloc = 2 * yysize;
1561 if (! (yysize <= *yymsg_alloc
1562 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1)))
1563 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM((long unsigned int) -1);
1564 return 1;
1565 }
1566
1567 /* Avoid sprintf, as that infringes on the user's name space.
1568 Don't have undefined behavior even if the translation
1569 produced a string with the wrong number of "%s"s. */
1570 {
1571 char *yyp = *yymsg;
1572 int yyi = 0;
1573 while ((*yyp = *yyformat) != '\0')
1574 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1575 {
1576 yyp += yytnamerr (yyp, yyarg[yyi++]);
1577 yyformat += 2;
1578 }
1579 else
1580 {
1581 yyp++;
1582 yyformat++;
1583 }
1584 }
1585 return 0;
1586}
1587#endif /* YYERROR_VERBOSE */
1588
1589/*-----------------------------------------------.
1590| Release the memory associated to this symbol. |
1591`-----------------------------------------------*/
1592
1593static void
1594yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, parser_control *pc)
1595{
1596 YYUSE (yyvaluep)((void) (yyvaluep));
1597 YYUSE (pc)((void) (pc));
1598 if (!yymsg)
1599 yymsg = "Deleting";
1600 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1601
1602 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1603 YYUSE (yytype)((void) (yytype));
1604 YY_IGNORE_MAYBE_UNINITIALIZED_END
1605}
1606
1607
1608
1609
1610/*----------.
1611| yyparse. |
1612`----------*/
1613
1614int
1615yyparse (parser_control *pc)
1616{
1617/* The lookahead symbol. */
1618int yychar;
1619
1620
1621/* The semantic value of the lookahead symbol. */
1622/* Default value used for initialization, for pacifying older GCCs
1623 or non-GCC compilers. */
1624YY_INITIAL_VALUE (static YYSTYPE yyval_default;)static YYSTYPE yyval_default;
1625YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default)= yyval_default;
1626
1627 /* Number of syntax errors so far. */
1628 int yynerrs;
1629
1630 int yystate;
1631 /* Number of tokens to shift before error messages enabled. */
1632 int yyerrstatus;
1633
1634 /* The stacks and their tools:
1635 'yyss': related to states.
1636 'yyvs': related to semantic values.
1637
1638 Refer to the stacks through separate pointers, to allow yyoverflow
1639 to reallocate them elsewhere. */
1640
1641 /* The state stack. */
1642 yytype_int16 yyssa[YYINITDEPTH20];
1643 yytype_int16 *yyss;
1644 yytype_int16 *yyssp;
1645
1646 /* The semantic value stack. */
1647 YYSTYPE yyvsa[YYINITDEPTH20];
1648 YYSTYPE *yyvs;
1649 YYSTYPE *yyvsp;
1650
1651 YYSIZE_Tlong unsigned int yystacksize;
1652
1653 int yyn;
1654 int yyresult;
1655 /* Lookahead token as an internal (translated) token number. */
1656 int yytoken = 0;
1657 /* The variables used to return semantic value and location from the
1658 action routines. */
1659 YYSTYPE yyval;
1660
1661#if YYERROR_VERBOSE0
1662 /* Buffer for error messages, and its allocated size. */
1663 char yymsgbuf[128];
1664 char *yymsg = yymsgbuf;
1665 YYSIZE_Tlong unsigned int yymsg_alloc = sizeof yymsgbuf;
1666#endif
1667
1668#define YYPOPSTACK(N)(yyvsp -= (N), yyssp -= (N)) (yyvsp -= (N), yyssp -= (N))
1669
1670 /* The number of symbols on the RHS of the reduced rule.
1671 Keep to zero when no symbol should be popped. */
1672 int yylen = 0;
1673
1674 yyssp = yyss = yyssa;
1675 yyvsp = yyvs = yyvsa;
1676 yystacksize = YYINITDEPTH20;
1677
1678 YYDPRINTF ((stderr, "Starting parse\n"));
1679
1680 yystate = 0;
1681 yyerrstatus = 0;
1682 yynerrs = 0;
1683 yychar = YYEMPTY(-2); /* Cause a token to be read. */
1684 goto yysetstate;
1
Control jumps to line 1695
1685
1686/*------------------------------------------------------------.
1687| yynewstate -- Push a new state, which is found in yystate. |
1688`------------------------------------------------------------*/
1689 yynewstate:
1690 /* In all cases, when you get here, the value and location stacks
1691 have just been pushed. So pushing a state here evens the stacks. */
1692 yyssp++;
1693
1694 yysetstate:
1695 *yyssp = yystate;
1696
1697 if (yyss + yystacksize - 1 <= yyssp)
2
Taking false branch
15
Taking false branch
29
Taking false branch
43
Taking false branch
1698 {
1699 /* Get the current used size of the three stacks, in elements. */
1700 YYSIZE_Tlong unsigned int yysize = yyssp - yyss + 1;
1701
1702#ifdef yyoverflow
1703 {
1704 /* Give user a chance to reallocate the stack. Use copies of
1705 these so that the &'s don't force the real ones into
1706 memory. */
1707 YYSTYPE *yyvs1 = yyvs;
1708 yytype_int16 *yyss1 = yyss;
1709
1710 /* Each stack pointer address is followed by the size of the
1711 data in use in that stack, in bytes. This used to be a
1712 conditional around just the two extra args, but that might
1713 be undefined if yyoverflow is a macro. */
1714 yyoverflow (YY_("memory exhausted")"memory exhausted",
1715 &yyss1, yysize * sizeof (*yyssp),
1716 &yyvs1, yysize * sizeof (*yyvsp),
1717 &yystacksize);
1718
1719 yyss = yyss1;
1720 yyvs = yyvs1;
1721 }
1722#else /* no yyoverflow */
1723# ifndef YYSTACK_RELOCATE
1724 goto yyexhaustedlab;
1725# else
1726 /* Extend the stack our own way. */
1727 if (YYMAXDEPTH20 <= yystacksize)
1728 goto yyexhaustedlab;
1729 yystacksize *= 2;
1730 if (YYMAXDEPTH20 < yystacksize)
1731 yystacksize = YYMAXDEPTH20;
1732
1733 {
1734 yytype_int16 *yyss1 = yyss;
1735 union yyalloc *yyptr =
1736 (union yyalloc *) YYSTACK_ALLOCmalloc (YYSTACK_BYTES (yystacksize)((yystacksize) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) +
(sizeof (union yyalloc) - 1))
);
1737 if (! yyptr)
1738 goto yyexhaustedlab;
1739 YYSTACK_RELOCATE (yyss_alloc, yyss);
1740 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1741# undef YYSTACK_RELOCATE
1742 if (yyss1 != yyssa)
1743 YYSTACK_FREEfree (yyss1);
1744 }
1745# endif
1746#endif /* no yyoverflow */
1747
1748 yyssp = yyss + yysize - 1;
1749 yyvsp = yyvs + yysize - 1;
1750
1751 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1752 (unsigned long int) yystacksize));
1753
1754 if (yyss + yystacksize - 1 <= yyssp)
1755 YYABORTgoto yyabortlab;
1756 }
1757
1758 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1759
1760 if (yystate == YYFINAL12)
3
Taking false branch
16
Assuming 'yystate' is not equal to 12
17
Taking false branch
30
Assuming 'yystate' is not equal to 12
31
Taking false branch
44
Assuming 'yystate' is not equal to 12
45
Taking false branch
1761 YYACCEPTgoto yyacceptlab;
1762
1763 goto yybackup;
4
Control jumps to line 1774
18
Control jumps to line 1774
32
Control jumps to line 1774
46
Control jumps to line 1774
1764
1765/*-----------.
1766| yybackup. |
1767`-----------*/
1768yybackup:
1769
1770 /* Do appropriate processing given the current state. Read a
1771 lookahead token if we need one and don't already have one. */
1772
1773 /* First try to decide what to do without reference to lookahead token. */
1774 yyn = yypact[yystate];
1775 if (yypact_value_is_default (yyn)(!!((yyn) == (-93))))
5
Taking false branch
19
Taking false branch
33
Taking false branch
47
Taking false branch
1776 goto yydefault;
1777
1778 /* Not known => get a lookahead token if don't already have one. */
1779
1780 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1781 if (yychar == YYEMPTY(-2))
6
Taking true branch
20
Taking true branch
34
Taking true branch
48
Taking true branch
1782 {
1783 YYDPRINTF ((stderr, "Reading a token: "));
1784 yychar = yylex (&yylval, pc);
1785 }
1786
1787 if (yychar <= YYEOF0)
7
Assuming 'yychar' is > 0
8
Taking false branch
21
Assuming 'yychar' is > 0
22
Taking false branch
35
Assuming 'yychar' is > 0
36
Taking false branch
49
Assuming 'yychar' is > 0
50
Taking false branch
1788 {
1789 yychar = yytoken = YYEOF0;
1790 YYDPRINTF ((stderr, "Now at end of input.\n"));
1791 }
1792 else
1793 {
1794 yytoken = YYTRANSLATE (yychar)((unsigned int) (yychar) <= 277 ? yytranslate[yychar] : 2);
1795 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1796 }
1797
1798 /* If the proper action on seeing token YYTOKEN is to reduce or to
1799 detect an error, take that action. */
1800 yyn += yytoken;
1801 if (yyn < 0 || YYLAST112 < yyn || yycheck[yyn] != yytoken)
9
Assuming 'yyn' is >= 0
10
Taking false branch
23
Assuming 'yyn' is >= 0
24
Taking false branch
37
Assuming 'yyn' is >= 0
38
Taking false branch
51
Assuming 'yyn' is >= 0
52
Taking false branch
1802 goto yydefault;
1803 yyn = yytable[yyn];
1804 if (yyn <= 0)
11
Assuming 'yyn' is > 0
12
Taking false branch
25
Assuming 'yyn' is > 0
26
Taking false branch
39
Assuming 'yyn' is > 0
40
Taking false branch
53
Assuming 'yyn' is <= 0
54
Taking true branch
1805 {
1806 if (yytable_value_is_error (yyn)0)
55
Taking false branch
1807 goto yyerrlab;
1808 yyn = -yyn;
1809 goto yyreduce;
56
Control jumps to line 1846
1810 }
1811
1812 /* Count tokens shifted since error; after three, turn off error
1813 status. */
1814 if (yyerrstatus)
13
Taking false branch
27
Taking false branch
41
Taking false branch
1815 yyerrstatus--;
1816
1817 /* Shift the lookahead token. */
1818 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1819
1820 /* Discard the shifted token. */
1821 yychar = YYEMPTY(-2);
1822
1823 yystate = yyn;
1824 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1825 *++yyvsp = yylval;
1826 YY_IGNORE_MAYBE_UNINITIALIZED_END
1827
1828 goto yynewstate;
14
Control jumps to line 1692
28
Control jumps to line 1692
42
Control jumps to line 1692
1829
1830
1831/*-----------------------------------------------------------.
1832| yydefault -- do the default action for the current state. |
1833`-----------------------------------------------------------*/
1834yydefault:
1835 yyn = yydefact[yystate];
1836 if (yyn == 0)
1837 goto yyerrlab;
1838 goto yyreduce;
1839
1840
1841/*-----------------------------.
1842| yyreduce -- Do a reduction. |
1843`-----------------------------*/
1844yyreduce:
1845 /* yyn is the number of a rule to reduce with. */
1846 yylen = yyr2[yyn];
1847
1848 /* If YYLEN is nonzero, implement the default value of the action:
1849 '$$ = $1'.
1850
1851 Otherwise, the following line sets YYVAL to garbage.
1852 This behavior is undocumented and Bison
1853 users should not rely upon it. Assigning to YYVAL
1854 unconditionally makes the parser a bit smaller, and it avoids a
1855 GCC warning that YYVAL may be used uninitialized. */
1856 yyval = yyvsp[1-yylen];
1857
1858
1859 YY_REDUCE_PRINT (yyn);
1860 switch (yyn)
57
Control jumps to 'case 12:' at line 1917
1861 {
1862 case 4:
1863#line 573 "./parse-datetime.y" /* yacc.c:1646 */
1864 {
1865 pc->seconds = (yyvsp[0].timespec);
1866 pc->timespec_seen = true1;
1867 debug_print_current_time (_("number of seconds")((const char *) ("number of seconds")), pc);
1868 }
1869#line 1870 "parse-datetime.c" /* yacc.c:1646 */
1870 break;
1871
1872 case 7:
1873#line 587 "./parse-datetime.y" /* yacc.c:1646 */
1874 {
1875 pc->times_seen++; pc->dates_seen++;
1876 debug_print_current_time (_("datetime")((const char *) ("datetime")), pc);
1877 }
1878#line 1879 "parse-datetime.c" /* yacc.c:1646 */
1879 break;
1880
1881 case 8:
1882#line 592 "./parse-datetime.y" /* yacc.c:1646 */
1883 {
1884 pc->times_seen++;
1885 debug_print_current_time (_("time")((const char *) ("time")), pc);
1886 }
1887#line 1888 "parse-datetime.c" /* yacc.c:1646 */
1888 break;
1889
1890 case 9:
1891#line 597 "./parse-datetime.y" /* yacc.c:1646 */
1892 {
1893 pc->local_zones_seen++;
1894 debug_print_current_time (_("local_zone")((const char *) ("local_zone")), pc);
1895 }
1896#line 1897 "parse-datetime.c" /* yacc.c:1646 */
1897 break;
1898
1899 case 10:
1900#line 602 "./parse-datetime.y" /* yacc.c:1646 */
1901 {
1902 pc->zones_seen++;
1903 debug_print_current_time (_("zone")((const char *) ("zone")), pc);
1904 }
1905#line 1906 "parse-datetime.c" /* yacc.c:1646 */
1906 break;
1907
1908 case 11:
1909#line 607 "./parse-datetime.y" /* yacc.c:1646 */
1910 {
1911 pc->dates_seen++;
1912 debug_print_current_time (_("date")((const char *) ("date")), pc);
1913 }
1914#line 1915 "parse-datetime.c" /* yacc.c:1646 */
1915 break;
1916
1917 case 12:
1918#line 612 "./parse-datetime.y" /* yacc.c:1646 */
1919 {
1920 pc->days_seen++;
1921 debug_print_current_time (_("day")((const char *) ("day")), pc);
58
Calling 'debug_print_current_time'
1922 }
1923#line 1924 "parse-datetime.c" /* yacc.c:1646 */
1924 break;
1925
1926 case 13:
1927#line 617 "./parse-datetime.y" /* yacc.c:1646 */
1928 {
1929 debug_print_relative_time (_("relative")((const char *) ("relative")), pc);
1930 }
1931#line 1932 "parse-datetime.c" /* yacc.c:1646 */
1932 break;
1933
1934 case 14:
1935#line 621 "./parse-datetime.y" /* yacc.c:1646 */
1936 {
1937 debug_print_relative_time (_("number")((const char *) ("number")), pc);
1938 }
1939#line 1940 "parse-datetime.c" /* yacc.c:1646 */
1940 break;
1941
1942 case 15:
1943#line 625 "./parse-datetime.y" /* yacc.c:1646 */
1944 {
1945 debug_print_relative_time (_("hybrid")((const char *) ("hybrid")), pc);
1946 }
1947#line 1948 "parse-datetime.c" /* yacc.c:1646 */
1948 break;
1949
1950 case 18:
1951#line 640 "./parse-datetime.y" /* yacc.c:1646 */
1952 {
1953 set_hhmmss (pc, (yyvsp[-1].textintval).value, 0, 0, 0);
1954 pc->meridian = (yyvsp[0].intval);
1955 }
1956#line 1957 "parse-datetime.c" /* yacc.c:1646 */
1957 break;
1958
1959 case 19:
1960#line 645 "./parse-datetime.y" /* yacc.c:1646 */
1961 {
1962 set_hhmmss (pc, (yyvsp[-3].textintval).value, (yyvsp[-1].textintval).value, 0, 0);
1963 pc->meridian = (yyvsp[0].intval);
1964 }
1965#line 1966 "parse-datetime.c" /* yacc.c:1646 */
1966 break;
1967
1968 case 20:
1969#line 650 "./parse-datetime.y" /* yacc.c:1646 */
1970 {
1971 set_hhmmss (pc, (yyvsp[-5].textintval).value, (yyvsp[-3].textintval).value, (yyvsp[-1].timespec).tv_sec, (yyvsp[-1].timespec).tv_nsec);
1972 pc->meridian = (yyvsp[0].intval);
1973 }
1974#line 1975 "parse-datetime.c" /* yacc.c:1646 */
1975 break;
1976
1977 case 22:
1978#line 659 "./parse-datetime.y" /* yacc.c:1646 */
1979 {
1980 set_hhmmss (pc, (yyvsp[-1].textintval).value, 0, 0, 0);
1981 pc->meridian = MER24;
1982 }
1983#line 1984 "parse-datetime.c" /* yacc.c:1646 */
1984 break;
1985
1986 case 23:
1987#line 664 "./parse-datetime.y" /* yacc.c:1646 */
1988 {
1989 set_hhmmss (pc, (yyvsp[-3].textintval).value, (yyvsp[-1].textintval).value, 0, 0);
1990 pc->meridian = MER24;
1991 }
1992#line 1993 "parse-datetime.c" /* yacc.c:1646 */
1993 break;
1994
1995 case 24:
1996#line 669 "./parse-datetime.y" /* yacc.c:1646 */
1997 {
1998 set_hhmmss (pc, (yyvsp[-5].textintval).value, (yyvsp[-3].textintval).value, (yyvsp[-1].timespec).tv_sec, (yyvsp[-1].timespec).tv_nsec);
1999 pc->meridian = MER24;
2000 }
2001#line 2002 "parse-datetime.c" /* yacc.c:1646 */
2002 break;
2003
2004 case 27:
2005#line 682 "./parse-datetime.y" /* yacc.c:1646 */
2006 {
2007 pc->zones_seen++;
2008 pc->time_zone = time_zone_hhmm (pc, (yyvsp[-1].textintval), (yyvsp[0].intval));
2009 }
2010#line 2011 "parse-datetime.c" /* yacc.c:1646 */
2011 break;
2012
2013 case 28:
2014#line 690 "./parse-datetime.y" /* yacc.c:1646 */
2015 {
2016 pc->local_isdst = (yyvsp[0].intval);
2017 pc->dsts_seen += (0 < (yyvsp[0].intval));
2018 }
2019#line 2020 "parse-datetime.c" /* yacc.c:1646 */
2020 break;
2021
2022 case 29:
2023#line 695 "./parse-datetime.y" /* yacc.c:1646 */
2024 {
2025 pc->local_isdst = 1;
2026 pc->dsts_seen += (0 < (yyvsp[-1].intval)) + 1;
2027 }
2028#line 2029 "parse-datetime.c" /* yacc.c:1646 */
2029 break;
2030
2031 case 30:
2032#line 705 "./parse-datetime.y" /* yacc.c:1646 */
2033 { pc->time_zone = (yyvsp[0].intval); }
2034#line 2035 "parse-datetime.c" /* yacc.c:1646 */
2035 break;
2036
2037 case 31:
2038#line 707 "./parse-datetime.y" /* yacc.c:1646 */
2039 { pc->time_zone = HOUR(7)((7) * 60); }
2040#line 2041 "parse-datetime.c" /* yacc.c:1646 */
2041 break;
2042
2043 case 32:
2044#line 709 "./parse-datetime.y" /* yacc.c:1646 */
2045 { pc->time_zone = (yyvsp[-1].intval);
2046 apply_relative_time (pc, (yyvsp[0].rel), 1); }
2047#line 2048 "parse-datetime.c" /* yacc.c:1646 */
2048 break;
2049
2050 case 33:
2051#line 712 "./parse-datetime.y" /* yacc.c:1646 */
2052 { pc->time_zone = HOUR(7)((7) * 60);
2053 apply_relative_time (pc, (yyvsp[0].rel), 1); }
2054#line 2055 "parse-datetime.c" /* yacc.c:1646 */
2055 break;
2056
2057 case 34:
2058#line 715 "./parse-datetime.y" /* yacc.c:1646 */
2059 { pc->time_zone = (yyvsp[-2].intval) + time_zone_hhmm (pc, (yyvsp[-1].textintval), (yyvsp[0].intval)); }
2060#line 2061 "parse-datetime.c" /* yacc.c:1646 */
2061 break;
2062
2063 case 35:
2064#line 717 "./parse-datetime.y" /* yacc.c:1646 */
2065 { pc->time_zone = (yyvsp[0].intval) + 60; }
2066#line 2067 "parse-datetime.c" /* yacc.c:1646 */
2067 break;
2068
2069 case 36:
2070#line 719 "./parse-datetime.y" /* yacc.c:1646 */
2071 { pc->time_zone = (yyvsp[-1].intval) + 60; }
2072#line 2073 "parse-datetime.c" /* yacc.c:1646 */
2073 break;
2074
2075 case 37:
2076#line 724 "./parse-datetime.y" /* yacc.c:1646 */
2077 {
2078 pc->day_ordinal = 0;
2079 pc->day_number = (yyvsp[0].intval);
2080 }
2081#line 2082 "parse-datetime.c" /* yacc.c:1646 */
2082 break;
2083
2084 case 38:
2085#line 729 "./parse-datetime.y" /* yacc.c:1646 */
2086 {
2087 pc->day_ordinal = 0;
2088 pc->day_number = (yyvsp[-1].intval);
2089 }
2090#line 2091 "parse-datetime.c" /* yacc.c:1646 */
2091 break;
2092
2093 case 39:
2094#line 734 "./parse-datetime.y" /* yacc.c:1646 */
2095 {
2096 pc->day_ordinal = (yyvsp[-1].intval);
2097 pc->day_number = (yyvsp[0].intval);
2098 pc->debug_ordinal_day_seen = true1;
2099 }
2100#line 2101 "parse-datetime.c" /* yacc.c:1646 */
2101 break;
2102
2103 case 40:
2104#line 740 "./parse-datetime.y" /* yacc.c:1646 */
2105 {
2106 pc->day_ordinal = (yyvsp[-1].textintval).value;
2107 pc->day_number = (yyvsp[0].intval);
2108 pc->debug_ordinal_day_seen = true1;
2109 }
2110#line 2111 "parse-datetime.c" /* yacc.c:1646 */
2111 break;
2112
2113 case 41:
2114#line 749 "./parse-datetime.y" /* yacc.c:1646 */
2115 {
2116 pc->month = (yyvsp[-2].textintval).value;
2117 pc->day = (yyvsp[0].textintval).value;
2118 }
2119#line 2120 "parse-datetime.c" /* yacc.c:1646 */
2120 break;
2121
2122 case 42:
2123#line 754 "./parse-datetime.y" /* yacc.c:1646 */
2124 {
2125 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
2126 otherwise as MM/DD/YY.
2127 The goal in recognizing YYYY/MM/DD is solely to support legacy
2128 machine-generated dates like those in an RCS log listing. If
2129 you want portability, use the ISO 8601 format. */
2130 if (4 <= (yyvsp[-4].textintval).digits)
2131 {
2132 if (pc->parse_datetime_debug)
2133 dbg_printf (_("warning: value %ld has %"PRIuMAX" digits. " \((const char *) ("warning: value %ld has %""l" "u"" digits. "
"Assuming YYYY/MM/DD\n"))
2134 "Assuming YYYY/MM/DD\n")((const char *) ("warning: value %ld has %""l" "u"" digits. "
"Assuming YYYY/MM/DD\n"))
, (yyvsp[-4].textintval).value, (yyvsp[-4].textintval).digits);
2135
2136 pc->year = (yyvsp[-4].textintval);
2137 pc->month = (yyvsp[-2].textintval).value;
2138 pc->day = (yyvsp[0].textintval).value;
2139 }
2140 else
2141 {
2142 if (pc->parse_datetime_debug)
2143 dbg_printf (_("warning: value %ld has less than 4 digits. " \((const char *) ("warning: value %ld has less than 4 digits. "
"Assuming MM/DD/YY[YY]\n"))
2144 "Assuming MM/DD/YY[YY]\n")((const char *) ("warning: value %ld has less than 4 digits. "
"Assuming MM/DD/YY[YY]\n"))
, (yyvsp[-4].textintval).value);
2145
2146 pc->month = (yyvsp[-4].textintval).value;
2147 pc->day = (yyvsp[-2].textintval).value;
2148 pc->year = (yyvsp[0].textintval);
2149 }
2150 }
2151#line 2152 "parse-datetime.c" /* yacc.c:1646 */
2152 break;
2153
2154 case 43:
2155#line 782 "./parse-datetime.y" /* yacc.c:1646 */
2156 {
2157 /* e.g. 17-JUN-1992. */
2158 pc->day = (yyvsp[-2].textintval).value;
2159 pc->month = (yyvsp[-1].intval);
2160 pc->year.value = -(yyvsp[0].textintval).value;
2161 pc->year.digits = (yyvsp[0].textintval).digits;
2162 }
2163#line 2164 "parse-datetime.c" /* yacc.c:1646 */
2164 break;
2165
2166 case 44:
2167#line 790 "./parse-datetime.y" /* yacc.c:1646 */
2168 {
2169 /* e.g. JUN-17-1992. */
2170 pc->month = (yyvsp[-2].intval);
2171 pc->day = -(yyvsp[-1].textintval).value;
2172 pc->year.value = -(yyvsp[0].textintval).value;
2173 pc->year.digits = (yyvsp[0].textintval).digits;
2174 }
2175#line 2176 "parse-datetime.c" /* yacc.c:1646 */
2176 break;
2177
2178 case 45:
2179#line 798 "./parse-datetime.y" /* yacc.c:1646 */
2180 {
2181 pc->month = (yyvsp[-1].intval);
2182 pc->day = (yyvsp[0].textintval).value;
2183 }
2184#line 2185 "parse-datetime.c" /* yacc.c:1646 */
2185 break;
2186
2187 case 46:
2188#line 803 "./parse-datetime.y" /* yacc.c:1646 */
2189 {
2190 pc->month = (yyvsp[-3].intval);
2191 pc->day = (yyvsp[-2].textintval).value;
2192 pc->year = (yyvsp[0].textintval);
2193 }
2194#line 2195 "parse-datetime.c" /* yacc.c:1646 */
2195 break;
2196
2197 case 47:
2198#line 809 "./parse-datetime.y" /* yacc.c:1646 */
2199 {
2200 pc->day = (yyvsp[-1].textintval).value;
2201 pc->month = (yyvsp[0].intval);
2202 }
2203#line 2204 "parse-datetime.c" /* yacc.c:1646 */
2204 break;
2205
2206 case 48:
2207#line 814 "./parse-datetime.y" /* yacc.c:1646 */
2208 {
2209 pc->day = (yyvsp[-2].textintval).value;
2210 pc->month = (yyvsp[-1].intval);
2211 pc->year = (yyvsp[0].textintval);
2212 }
2213#line 2214 "parse-datetime.c" /* yacc.c:1646 */
2214 break;
2215
2216 case 50:
2217#line 824 "./parse-datetime.y" /* yacc.c:1646 */
2218 {
2219 /* ISO 8601 format. YYYY-MM-DD. */
2220 pc->year = (yyvsp[-2].textintval);
2221 pc->month = -(yyvsp[-1].textintval).value;
2222 pc->day = -(yyvsp[0].textintval).value;
2223 }
2224#line 2225 "parse-datetime.c" /* yacc.c:1646 */
2225 break;
2226
2227 case 51:
2228#line 834 "./parse-datetime.y" /* yacc.c:1646 */
2229 { apply_relative_time (pc, (yyvsp[-1].rel), (yyvsp[0].intval)); }
2230#line 2231 "parse-datetime.c" /* yacc.c:1646 */
2231 break;
2232
2233 case 52:
2234#line 836 "./parse-datetime.y" /* yacc.c:1646 */
2235 { apply_relative_time (pc, (yyvsp[0].rel), 1); }
2236#line 2237 "parse-datetime.c" /* yacc.c:1646 */
2237 break;
2238
2239 case 53:
2240#line 838 "./parse-datetime.y" /* yacc.c:1646 */
2241 { apply_relative_time (pc, (yyvsp[0].rel), 1); }
2242#line 2243 "parse-datetime.c" /* yacc.c:1646 */
2243 break;
2244
2245 case 54:
2246#line 843 "./parse-datetime.y" /* yacc.c:1646 */
2247 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).year = (yyvsp[-1].intval); }
2248#line 2249 "parse-datetime.c" /* yacc.c:1646 */
2249 break;
2250
2251 case 55:
2252#line 845 "./parse-datetime.y" /* yacc.c:1646 */
2253 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).year = (yyvsp[-1].textintval).value; }
2254#line 2255 "parse-datetime.c" /* yacc.c:1646 */
2255 break;
2256
2257 case 56:
2258#line 847 "./parse-datetime.y" /* yacc.c:1646 */
2259 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).year = 1; }
2260#line 2261 "parse-datetime.c" /* yacc.c:1646 */
2261 break;
2262
2263 case 57:
2264#line 849 "./parse-datetime.y" /* yacc.c:1646 */
2265 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).month = (yyvsp[-1].intval); }
2266#line 2267 "parse-datetime.c" /* yacc.c:1646 */
2267 break;
2268
2269 case 58:
2270#line 851 "./parse-datetime.y" /* yacc.c:1646 */
2271 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).month = (yyvsp[-1].textintval).value; }
2272#line 2273 "parse-datetime.c" /* yacc.c:1646 */
2273 break;
2274
2275 case 59:
2276#line 853 "./parse-datetime.y" /* yacc.c:1646 */
2277 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).month = 1; }
2278#line 2279 "parse-datetime.c" /* yacc.c:1646 */
2279 break;
2280
2281 case 60:
2282#line 855 "./parse-datetime.y" /* yacc.c:1646 */
2283 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).day = (yyvsp[-1].intval) * (yyvsp[0].intval); }
2284#line 2285 "parse-datetime.c" /* yacc.c:1646 */
2285 break;
2286
2287 case 61:
2288#line 857 "./parse-datetime.y" /* yacc.c:1646 */
2289 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).day = (yyvsp[-1].textintval).value * (yyvsp[0].intval); }
2290#line 2291 "parse-datetime.c" /* yacc.c:1646 */
2291 break;
2292
2293 case 62:
2294#line 859 "./parse-datetime.y" /* yacc.c:1646 */
2295 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).day = (yyvsp[0].intval); }
2296#line 2297 "parse-datetime.c" /* yacc.c:1646 */
2297 break;
2298
2299 case 63:
2300#line 861 "./parse-datetime.y" /* yacc.c:1646 */
2301 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).hour = (yyvsp[-1].intval); }
2302#line 2303 "parse-datetime.c" /* yacc.c:1646 */
2303 break;
2304
2305 case 64:
2306#line 863 "./parse-datetime.y" /* yacc.c:1646 */
2307 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).hour = (yyvsp[-1].textintval).value; }
2308#line 2309 "parse-datetime.c" /* yacc.c:1646 */
2309 break;
2310
2311 case 65:
2312#line 865 "./parse-datetime.y" /* yacc.c:1646 */
2313 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).hour = 1; }
2314#line 2315 "parse-datetime.c" /* yacc.c:1646 */
2315 break;
2316
2317 case 66:
2318#line 867 "./parse-datetime.y" /* yacc.c:1646 */
2319 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).minutes = (yyvsp[-1].intval); }
2320#line 2321 "parse-datetime.c" /* yacc.c:1646 */
2321 break;
2322
2323 case 67:
2324#line 869 "./parse-datetime.y" /* yacc.c:1646 */
2325 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).minutes = (yyvsp[-1].textintval).value; }
2326#line 2327 "parse-datetime.c" /* yacc.c:1646 */
2327 break;
2328
2329 case 68:
2330#line 871 "./parse-datetime.y" /* yacc.c:1646 */
2331 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).minutes = 1; }
2332#line 2333 "parse-datetime.c" /* yacc.c:1646 */
2333 break;
2334
2335 case 69:
2336#line 873 "./parse-datetime.y" /* yacc.c:1646 */
2337 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = (yyvsp[-1].intval); }
2338#line 2339 "parse-datetime.c" /* yacc.c:1646 */
2339 break;
2340
2341 case 70:
2342#line 875 "./parse-datetime.y" /* yacc.c:1646 */
2343 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = (yyvsp[-1].textintval).value; }
2344#line 2345 "parse-datetime.c" /* yacc.c:1646 */
2345 break;
2346
2347 case 71:
2348#line 877 "./parse-datetime.y" /* yacc.c:1646 */
2349 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = (yyvsp[-1].timespec).tv_sec; (yyval.rel).ns = (yyvsp[-1].timespec).tv_nsec; }
2350#line 2351 "parse-datetime.c" /* yacc.c:1646 */
2351 break;
2352
2353 case 72:
2354#line 879 "./parse-datetime.y" /* yacc.c:1646 */
2355 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = (yyvsp[-1].timespec).tv_sec; (yyval.rel).ns = (yyvsp[-1].timespec).tv_nsec; }
2356#line 2357 "parse-datetime.c" /* yacc.c:1646 */
2357 break;
2358
2359 case 73:
2360#line 881 "./parse-datetime.y" /* yacc.c:1646 */
2361 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = 1; }
2362#line 2363 "parse-datetime.c" /* yacc.c:1646 */
2363 break;
2364
2365 case 75:
2366#line 887 "./parse-datetime.y" /* yacc.c:1646 */
2367 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).year = (yyvsp[-1].textintval).value; }
2368#line 2369 "parse-datetime.c" /* yacc.c:1646 */
2369 break;
2370
2371 case 76:
2372#line 889 "./parse-datetime.y" /* yacc.c:1646 */
2373 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).month = (yyvsp[-1].textintval).value; }
2374#line 2375 "parse-datetime.c" /* yacc.c:1646 */
2375 break;
2376
2377 case 77:
2378#line 891 "./parse-datetime.y" /* yacc.c:1646 */
2379 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).day = (yyvsp[-1].textintval).value * (yyvsp[0].intval); }
2380#line 2381 "parse-datetime.c" /* yacc.c:1646 */
2381 break;
2382
2383 case 78:
2384#line 893 "./parse-datetime.y" /* yacc.c:1646 */
2385 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).hour = (yyvsp[-1].textintval).value; }
2386#line 2387 "parse-datetime.c" /* yacc.c:1646 */
2387 break;
2388
2389 case 79:
2390#line 895 "./parse-datetime.y" /* yacc.c:1646 */
2391 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).minutes = (yyvsp[-1].textintval).value; }
2392#line 2393 "parse-datetime.c" /* yacc.c:1646 */
2393 break;
2394
2395 case 80:
2396#line 897 "./parse-datetime.y" /* yacc.c:1646 */
2397 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).seconds = (yyvsp[-1].textintval).value; }
2398#line 2399 "parse-datetime.c" /* yacc.c:1646 */
2399 break;
2400
2401 case 81:
2402#line 902 "./parse-datetime.y" /* yacc.c:1646 */
2403 { (yyval.rel) = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 }); (yyval.rel).day = (yyvsp[0].intval); }
2404#line 2405 "parse-datetime.c" /* yacc.c:1646 */
2405 break;
2406
2407 case 85:
2408#line 910 "./parse-datetime.y" /* yacc.c:1646 */
2409 { (yyval.timespec).tv_sec = (yyvsp[0].textintval).value; (yyval.timespec).tv_nsec = 0; }
2410#line 2411 "parse-datetime.c" /* yacc.c:1646 */
2411 break;
2412
2413 case 87:
2414#line 916 "./parse-datetime.y" /* yacc.c:1646 */
2415 { (yyval.timespec).tv_sec = (yyvsp[0].textintval).value; (yyval.timespec).tv_nsec = 0; }
2416#line 2417 "parse-datetime.c" /* yacc.c:1646 */
2417 break;
2418
2419 case 88:
2420#line 921 "./parse-datetime.y" /* yacc.c:1646 */
2421 { digits_to_date_time (pc, (yyvsp[0].textintval)); }
2422#line 2423 "parse-datetime.c" /* yacc.c:1646 */
2423 break;
2424
2425 case 89:
2426#line 926 "./parse-datetime.y" /* yacc.c:1646 */
2427 {
2428 /* Hybrid all-digit and relative offset, so that we accept e.g.,
2429 "YYYYMMDD +N days" as well as "YYYYMMDD N days". */
2430 digits_to_date_time (pc, (yyvsp[-1].textintval));
2431 apply_relative_time (pc, (yyvsp[0].rel), 1);
2432 }
2433#line 2434 "parse-datetime.c" /* yacc.c:1646 */
2434 break;
2435
2436 case 90:
2437#line 936 "./parse-datetime.y" /* yacc.c:1646 */
2438 { (yyval.intval) = -1; }
2439#line 2440 "parse-datetime.c" /* yacc.c:1646 */
2440 break;
2441
2442 case 91:
2443#line 938 "./parse-datetime.y" /* yacc.c:1646 */
2444 { (yyval.intval) = (yyvsp[0].textintval).value; }
2445#line 2446 "parse-datetime.c" /* yacc.c:1646 */
2446 break;
2447
2448
2449#line 2450 "parse-datetime.c" /* yacc.c:1646 */
2450 default: break;
2451 }
2452 /* User semantic actions sometimes alter yychar, and that requires
2453 that yytoken be updated with the new translation. We take the
2454 approach of translating immediately before every use of yytoken.
2455 One alternative is translating here after every semantic action,
2456 but that translation would be missed if the semantic action invokes
2457 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
2458 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
2459 incorrect destructor might then be invoked immediately. In the
2460 case of YYERROR or YYBACKUP, subsequent parser actions might lead
2461 to an incorrect destructor call or verbose syntax error message
2462 before the lookahead is translated. */
2463 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
2464
2465 YYPOPSTACK (yylen)(yyvsp -= (yylen), yyssp -= (yylen));
2466 yylen = 0;
2467 YY_STACK_PRINT (yyss, yyssp);
2468
2469 *++yyvsp = yyval;
2470
2471 /* Now 'shift' the result of the reduction. Determine what state
2472 that goes to, based on the state we popped back to and the rule
2473 number reduced by. */
2474
2475 yyn = yyr1[yyn];
2476
2477 yystate = yypgoto[yyn - YYNTOKENS28] + *yyssp;
2478 if (0 <= yystate && yystate <= YYLAST112 && yycheck[yystate] == *yyssp)
2479 yystate = yytable[yystate];
2480 else
2481 yystate = yydefgoto[yyn - YYNTOKENS28];
2482
2483 goto yynewstate;
2484
2485
2486/*--------------------------------------.
2487| yyerrlab -- here on detecting error. |
2488`--------------------------------------*/
2489yyerrlab:
2490 /* Make sure we have latest lookahead translation. See comments at
2491 user semantic actions for why this is necessary. */
2492 yytoken = yychar == YYEMPTY(-2) ? YYEMPTY(-2) : YYTRANSLATE (yychar)((unsigned int) (yychar) <= 277 ? yytranslate[yychar] : 2);
2493
2494 /* If not already recovering from an error, report this error. */
2495 if (!yyerrstatus)
2496 {
2497 ++yynerrs;
2498#if ! YYERROR_VERBOSE0
2499 yyerror (pc, YY_("syntax error")"syntax error");
2500#else
2501# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
2502 yyssp, yytoken)
2503 {
2504 char const *yymsgp = YY_("syntax error")"syntax error";
2505 int yysyntax_error_status;
2506 yysyntax_error_status = YYSYNTAX_ERROR;
2507 if (yysyntax_error_status == 0)
2508 yymsgp = yymsg;
2509 else if (yysyntax_error_status == 1)
2510 {
2511 if (yymsg != yymsgbuf)
2512 YYSTACK_FREEfree (yymsg);
2513 yymsg = (char *) YYSTACK_ALLOCmalloc (yymsg_alloc);
2514 if (!yymsg)
2515 {
2516 yymsg = yymsgbuf;
2517 yymsg_alloc = sizeof yymsgbuf;
2518 yysyntax_error_status = 2;
2519 }
2520 else
2521 {
2522 yysyntax_error_status = YYSYNTAX_ERROR;
2523 yymsgp = yymsg;
2524 }
2525 }
2526 yyerror (pc, yymsgp);
2527 if (yysyntax_error_status == 2)
2528 goto yyexhaustedlab;
2529 }
2530# undef YYSYNTAX_ERROR
2531#endif
2532 }
2533
2534
2535
2536 if (yyerrstatus == 3)
2537 {
2538 /* If just tried and failed to reuse lookahead token after an
2539 error, discard it. */
2540
2541 if (yychar <= YYEOF0)
2542 {
2543 /* Return failure if at end of input. */
2544 if (yychar == YYEOF0)
2545 YYABORTgoto yyabortlab;
2546 }
2547 else
2548 {
2549 yydestruct ("Error: discarding",
2550 yytoken, &yylval, pc);
2551 yychar = YYEMPTY(-2);
2552 }
2553 }
2554
2555 /* Else will try to reuse lookahead token after shifting the error
2556 token. */
2557 goto yyerrlab1;
2558
2559
2560/*---------------------------------------------------.
2561| yyerrorlab -- error raised explicitly by YYERROR. |
2562`---------------------------------------------------*/
2563yyerrorlab:
2564
2565 /* Pacify compilers like GCC when the user code never invokes
2566 YYERROR and the label yyerrorlab therefore never appears in user
2567 code. */
2568 if (/*CONSTCOND*/ 0)
2569 goto yyerrorlab;
2570
2571 /* Do not reclaim the symbols of the rule whose action triggered
2572 this YYERROR. */
2573 YYPOPSTACK (yylen)(yyvsp -= (yylen), yyssp -= (yylen));
2574 yylen = 0;
2575 YY_STACK_PRINT (yyss, yyssp);
2576 yystate = *yyssp;
2577 goto yyerrlab1;
2578
2579
2580/*-------------------------------------------------------------.
2581| yyerrlab1 -- common code for both syntax error and YYERROR. |
2582`-------------------------------------------------------------*/
2583yyerrlab1:
2584 yyerrstatus = 3; /* Each real token shifted decrements this. */
2585
2586 for (;;)
2587 {
2588 yyn = yypact[yystate];
2589 if (!yypact_value_is_default (yyn)(!!((yyn) == (-93))))
2590 {
2591 yyn += YYTERROR1;
2592 if (0 <= yyn && yyn <= YYLAST112 && yycheck[yyn] == YYTERROR1)
2593 {
2594 yyn = yytable[yyn];
2595 if (0 < yyn)
2596 break;
2597 }
2598 }
2599
2600 /* Pop the current state because it cannot handle the error token. */
2601 if (yyssp == yyss)
2602 YYABORTgoto yyabortlab;
2603
2604
2605 yydestruct ("Error: popping",
2606 yystos[yystate], yyvsp, pc);
2607 YYPOPSTACK (1)(yyvsp -= (1), yyssp -= (1));
2608 yystate = *yyssp;
2609 YY_STACK_PRINT (yyss, yyssp);
2610 }
2611
2612 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
2613 *++yyvsp = yylval;
2614 YY_IGNORE_MAYBE_UNINITIALIZED_END
2615
2616
2617 /* Shift the error token. */
2618 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
2619
2620 yystate = yyn;
2621 goto yynewstate;
2622
2623
2624/*-------------------------------------.
2625| yyacceptlab -- YYACCEPT comes here. |
2626`-------------------------------------*/
2627yyacceptlab:
2628 yyresult = 0;
2629 goto yyreturn;
2630
2631/*-----------------------------------.
2632| yyabortlab -- YYABORT comes here. |
2633`-----------------------------------*/
2634yyabortlab:
2635 yyresult = 1;
2636 goto yyreturn;
2637
2638#if !defined yyoverflow || YYERROR_VERBOSE0
2639/*-------------------------------------------------.
2640| yyexhaustedlab -- memory exhaustion comes here. |
2641`-------------------------------------------------*/
2642yyexhaustedlab:
2643 yyerror (pc, YY_("memory exhausted")"memory exhausted");
2644 yyresult = 2;
2645 /* Fall through. */
2646#endif
2647
2648yyreturn:
2649 if (yychar != YYEMPTY(-2))
2650 {
2651 /* Make sure we have latest lookahead translation. See comments at
2652 user semantic actions for why this is necessary. */
2653 yytoken = YYTRANSLATE (yychar)((unsigned int) (yychar) <= 277 ? yytranslate[yychar] : 2);
2654 yydestruct ("Cleanup: discarding lookahead",
2655 yytoken, &yylval, pc);
2656 }
2657 /* Do not reclaim the symbols of the rule whose action triggered
2658 this YYABORT or YYACCEPT. */
2659 YYPOPSTACK (yylen)(yyvsp -= (yylen), yyssp -= (yylen));
2660 YY_STACK_PRINT (yyss, yyssp);
2661 while (yyssp != yyss)
2662 {
2663 yydestruct ("Cleanup: popping",
2664 yystos[*yyssp], yyvsp, pc);
2665 YYPOPSTACK (1)(yyvsp -= (1), yyssp -= (1));
2666 }
2667#ifndef yyoverflow
2668 if (yyss != yyssa)
2669 YYSTACK_FREEfree (yyss);
2670#endif
2671#if YYERROR_VERBOSE0
2672 if (yymsg != yymsgbuf)
2673 YYSTACK_FREEfree (yymsg);
2674#endif
2675 return yyresult;
2676}
2677#line 941 "./parse-datetime.y" /* yacc.c:1906 */
2678
2679
2680static table const meridian_table[] =
2681{
2682 { "AM", tMERIDIAN270, MERam },
2683 { "A.M.", tMERIDIAN270, MERam },
2684 { "PM", tMERIDIAN270, MERpm },
2685 { "P.M.", tMERIDIAN270, MERpm },
2686 { NULL((void*)0), 0, 0 }
2687};
2688
2689static table const dst_table[] =
2690{
2691 { "DST", tDST259, 0 }
2692};
2693
2694static table const month_and_day_table[] =
2695{
2696 { "JANUARY", tMONTH271, 1 },
2697 { "FEBRUARY", tMONTH271, 2 },
2698 { "MARCH", tMONTH271, 3 },
2699 { "APRIL", tMONTH271, 4 },
2700 { "MAY", tMONTH271, 5 },
2701 { "JUNE", tMONTH271, 6 },
2702 { "JULY", tMONTH271, 7 },
2703 { "AUGUST", tMONTH271, 8 },
2704 { "SEPTEMBER",tMONTH271, 9 },
2705 { "SEPT", tMONTH271, 9 },
2706 { "OCTOBER", tMONTH271, 10 },
2707 { "NOVEMBER", tMONTH271, 11 },
2708 { "DECEMBER", tMONTH271, 12 },
2709 { "SUNDAY", tDAY267, 0 },
2710 { "MONDAY", tDAY267, 1 },
2711 { "TUESDAY", tDAY267, 2 },
2712 { "TUES", tDAY267, 2 },
2713 { "WEDNESDAY",tDAY267, 3 },
2714 { "WEDNES", tDAY267, 3 },
2715 { "THURSDAY", tDAY267, 4 },
2716 { "THUR", tDAY267, 4 },
2717 { "THURS", tDAY267, 4 },
2718 { "FRIDAY", tDAY267, 5 },
2719 { "SATURDAY", tDAY267, 6 },
2720 { NULL((void*)0), 0, 0 }
2721};
2722
2723static table const time_units_table[] =
2724{
2725 { "YEAR", tYEAR_UNIT260, 1 },
2726 { "MONTH", tMONTH_UNIT261, 1 },
2727 { "FORTNIGHT",tDAY_UNIT265, 14 },
2728 { "WEEK", tDAY_UNIT265, 7 },
2729 { "DAY", tDAY_UNIT265, 1 },
2730 { "HOUR", tHOUR_UNIT262, 1 },
2731 { "MINUTE", tMINUTE_UNIT263, 1 },
2732 { "MIN", tMINUTE_UNIT263, 1 },
2733 { "SECOND", tSEC_UNIT264, 1 },
2734 { "SEC", tSEC_UNIT264, 1 },
2735 { NULL((void*)0), 0, 0 }
2736};
2737
2738/* Assorted relative-time words. */
2739static table const relative_time_table[] =
2740{
2741 { "TOMORROW", tDAY_SHIFT266, 1 },
2742 { "YESTERDAY",tDAY_SHIFT266, -1 },
2743 { "TODAY", tDAY_SHIFT266, 0 },
2744 { "NOW", tDAY_SHIFT266, 0 },
2745 { "LAST", tORDINAL272, -1 },
2746 { "THIS", tORDINAL272, 0 },
2747 { "NEXT", tORDINAL272, 1 },
2748 { "FIRST", tORDINAL272, 1 },
2749/*{ "SECOND", tORDINAL, 2 }, */
2750 { "THIRD", tORDINAL272, 3 },
2751 { "FOURTH", tORDINAL272, 4 },
2752 { "FIFTH", tORDINAL272, 5 },
2753 { "SIXTH", tORDINAL272, 6 },
2754 { "SEVENTH", tORDINAL272, 7 },
2755 { "EIGHTH", tORDINAL272, 8 },
2756 { "NINTH", tORDINAL272, 9 },
2757 { "TENTH", tORDINAL272, 10 },
2758 { "ELEVENTH", tORDINAL272, 11 },
2759 { "TWELFTH", tORDINAL272, 12 },
2760 { "AGO", tAGO258, -1 },
2761 { "HENCE", tAGO258, 1 },
2762 { NULL((void*)0), 0, 0 }
2763};
2764
2765/* The universal time zone table. These labels can be used even for
2766 time stamps that would not otherwise be valid, e.g., GMT time
2767 stamps in London during summer. */
2768static table const universal_time_zone_table[] =
2769{
2770 { "GMT", tZONE273, HOUR ( 0)((0) * 60) }, /* Greenwich Mean */
2771 { "UT", tZONE273, HOUR ( 0)((0) * 60) }, /* Universal (Coordinated) */
2772 { "UTC", tZONE273, HOUR ( 0)((0) * 60) },
2773 { NULL((void*)0), 0, 0 }
2774};
2775
2776/* The time zone table. This table is necessarily incomplete, as time
2777 zone abbreviations are ambiguous; e.g. Australians interpret "EST"
2778 as Eastern time in Australia, not as US Eastern Standard Time.
2779 You cannot rely on parse_datetime to handle arbitrary time zone
2780 abbreviations; use numeric abbreviations like "-0500" instead. */
2781static table const time_zone_table[] =
2782{
2783 { "WET", tZONE273, HOUR ( 0)((0) * 60) }, /* Western European */
2784 { "WEST", tDAYZONE268, HOUR ( 0)((0) * 60) }, /* Western European Summer */
2785 { "BST", tDAYZONE268, HOUR ( 0)((0) * 60) }, /* British Summer */
2786 { "ART", tZONE273, -HOUR ( 3)((3) * 60) }, /* Argentina */
2787 { "BRT", tZONE273, -HOUR ( 3)((3) * 60) }, /* Brazil */
2788 { "BRST", tDAYZONE268, -HOUR ( 3)((3) * 60) }, /* Brazil Summer */
2789 { "NST", tZONE273, -(HOUR ( 3)((3) * 60) + 30) }, /* Newfoundland Standard */
2790 { "NDT", tDAYZONE268,-(HOUR ( 3)((3) * 60) + 30) }, /* Newfoundland Daylight */
2791 { "AST", tZONE273, -HOUR ( 4)((4) * 60) }, /* Atlantic Standard */
2792 { "ADT", tDAYZONE268, -HOUR ( 4)((4) * 60) }, /* Atlantic Daylight */
2793 { "CLT", tZONE273, -HOUR ( 4)((4) * 60) }, /* Chile */
2794 { "CLST", tDAYZONE268, -HOUR ( 4)((4) * 60) }, /* Chile Summer */
2795 { "EST", tZONE273, -HOUR ( 5)((5) * 60) }, /* Eastern Standard */
2796 { "EDT", tDAYZONE268, -HOUR ( 5)((5) * 60) }, /* Eastern Daylight */
2797 { "CST", tZONE273, -HOUR ( 6)((6) * 60) }, /* Central Standard */
2798 { "CDT", tDAYZONE268, -HOUR ( 6)((6) * 60) }, /* Central Daylight */
2799 { "MST", tZONE273, -HOUR ( 7)((7) * 60) }, /* Mountain Standard */
2800 { "MDT", tDAYZONE268, -HOUR ( 7)((7) * 60) }, /* Mountain Daylight */
2801 { "PST", tZONE273, -HOUR ( 8)((8) * 60) }, /* Pacific Standard */
2802 { "PDT", tDAYZONE268, -HOUR ( 8)((8) * 60) }, /* Pacific Daylight */
2803 { "AKST", tZONE273, -HOUR ( 9)((9) * 60) }, /* Alaska Standard */
2804 { "AKDT", tDAYZONE268, -HOUR ( 9)((9) * 60) }, /* Alaska Daylight */
2805 { "HST", tZONE273, -HOUR (10)((10) * 60) }, /* Hawaii Standard */
2806 { "HAST", tZONE273, -HOUR (10)((10) * 60) }, /* Hawaii-Aleutian Standard */
2807 { "HADT", tDAYZONE268, -HOUR (10)((10) * 60) }, /* Hawaii-Aleutian Daylight */
2808 { "SST", tZONE273, -HOUR (12)((12) * 60) }, /* Samoa Standard */
2809 { "WAT", tZONE273, HOUR ( 1)((1) * 60) }, /* West Africa */
2810 { "CET", tZONE273, HOUR ( 1)((1) * 60) }, /* Central European */
2811 { "CEST", tDAYZONE268, HOUR ( 1)((1) * 60) }, /* Central European Summer */
2812 { "MET", tZONE273, HOUR ( 1)((1) * 60) }, /* Middle European */
2813 { "MEZ", tZONE273, HOUR ( 1)((1) * 60) }, /* Middle European */
2814 { "MEST", tDAYZONE268, HOUR ( 1)((1) * 60) }, /* Middle European Summer */
2815 { "MESZ", tDAYZONE268, HOUR ( 1)((1) * 60) }, /* Middle European Summer */
2816 { "EET", tZONE273, HOUR ( 2)((2) * 60) }, /* Eastern European */
2817 { "EEST", tDAYZONE268, HOUR ( 2)((2) * 60) }, /* Eastern European Summer */
2818 { "CAT", tZONE273, HOUR ( 2)((2) * 60) }, /* Central Africa */
2819 { "SAST", tZONE273, HOUR ( 2)((2) * 60) }, /* South Africa Standard */
2820 { "EAT", tZONE273, HOUR ( 3)((3) * 60) }, /* East Africa */
2821 { "MSK", tZONE273, HOUR ( 3)((3) * 60) }, /* Moscow */
2822 { "MSD", tDAYZONE268, HOUR ( 3)((3) * 60) }, /* Moscow Daylight */
2823 { "IST", tZONE273, (HOUR ( 5)((5) * 60) + 30) }, /* India Standard */
2824 { "SGT", tZONE273, HOUR ( 8)((8) * 60) }, /* Singapore */
2825 { "KST", tZONE273, HOUR ( 9)((9) * 60) }, /* Korea Standard */
2826 { "JST", tZONE273, HOUR ( 9)((9) * 60) }, /* Japan Standard */
2827 { "GST", tZONE273, HOUR (10)((10) * 60) }, /* Guam Standard */
2828 { "NZST", tZONE273, HOUR (12)((12) * 60) }, /* New Zealand Standard */
2829 { "NZDT", tDAYZONE268, HOUR (12)((12) * 60) }, /* New Zealand Daylight */
2830 { NULL((void*)0), 0, 0 }
2831};
2832
2833/* Military time zone table.
2834
2835 Note 'T' is a special case, as it is used as the separator in ISO
2836 8601 date and time of day representation. */
2837static table const military_table[] =
2838{
2839 { "A", tZONE273, -HOUR ( 1)((1) * 60) },
2840 { "B", tZONE273, -HOUR ( 2)((2) * 60) },
2841 { "C", tZONE273, -HOUR ( 3)((3) * 60) },
2842 { "D", tZONE273, -HOUR ( 4)((4) * 60) },
2843 { "E", tZONE273, -HOUR ( 5)((5) * 60) },
2844 { "F", tZONE273, -HOUR ( 6)((6) * 60) },
2845 { "G", tZONE273, -HOUR ( 7)((7) * 60) },
2846 { "H", tZONE273, -HOUR ( 8)((8) * 60) },
2847 { "I", tZONE273, -HOUR ( 9)((9) * 60) },
2848 { "K", tZONE273, -HOUR (10)((10) * 60) },
2849 { "L", tZONE273, -HOUR (11)((11) * 60) },
2850 { "M", tZONE273, -HOUR (12)((12) * 60) },
2851 { "N", tZONE273, HOUR ( 1)((1) * 60) },
2852 { "O", tZONE273, HOUR ( 2)((2) * 60) },
2853 { "P", tZONE273, HOUR ( 3)((3) * 60) },
2854 { "Q", tZONE273, HOUR ( 4)((4) * 60) },
2855 { "R", tZONE273, HOUR ( 5)((5) * 60) },
2856 { "S", tZONE273, HOUR ( 6)((6) * 60) },
2857 { "T", 'T', 0 },
2858 { "U", tZONE273, HOUR ( 8)((8) * 60) },
2859 { "V", tZONE273, HOUR ( 9)((9) * 60) },
2860 { "W", tZONE273, HOUR (10)((10) * 60) },
2861 { "X", tZONE273, HOUR (11)((11) * 60) },
2862 { "Y", tZONE273, HOUR (12)((12) * 60) },
2863 { "Z", tZONE273, HOUR ( 0)((0) * 60) },
2864 { NULL((void*)0), 0, 0 }
2865};
2866
2867
2868
2869/* Convert a time zone expressed as HH:MM into an integer count of
2870 minutes. If MM is negative, then S is of the form HHMM and needs
2871 to be picked apart; otherwise, S is of the form HH. As specified in
2872 http://www.opengroup.org/susv3xbd/xbd_chap08.html#tag_08_03, allow
2873 only valid TZ range, and consider first two digits as hours, if no
2874 minutes specified. */
2875
2876static long int
2877time_zone_hhmm (parser_control *pc, textint s, long int mm)
2878{
2879 long int n_minutes;
2880
2881 /* If the length of S is 1 or 2 and no minutes are specified,
2882 interpret it as a number of hours. */
2883 if (s.digits <= 2 && mm < 0)
2884 s.value *= 100;
2885
2886 if (mm < 0)
2887 n_minutes = (s.value / 100) * 60 + s.value % 100;
2888 else
2889 n_minutes = s.value * 60 + (s.negative ? -mm : mm);
2890
2891 /* If the absolute number of minutes is larger than 24 hours,
2892 arrange to reject it by incrementing pc->zones_seen. Thus,
2893 we allow only values in the range UTC-24:00 to UTC+24:00. */
2894 if (24 * 60 < abs (n_minutes))
2895 pc->zones_seen++;
2896
2897 return n_minutes;
2898}
2899
2900static int
2901to_hour (long int hours, int meridian)
2902{
2903 switch (meridian)
2904 {
2905 default: /* Pacify GCC. */
2906 case MER24:
2907 return 0 <= hours && hours < 24 ? hours : -1;
2908 case MERam:
2909 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
2910 case MERpm:
2911 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
2912 }
2913}
2914
2915static long int
2916to_year (textint textyear, bool_Bool debug)
2917{
2918 long int year = textyear.value;
2919
2920 if (year < 0)
2921 year = -year;
2922
2923 /* XPG4 suggests that years 00-68 map to 2000-2068, and
2924 years 69-99 map to 1969-1999. */
2925 else if (textyear.digits == 2)
2926 {
2927 year += year < 69 ? 2000 : 1900;
2928 if (debug)
2929 dbg_printf (_("warning: adjusting year value %ld to %ld\n")((const char *) ("warning: adjusting year value %ld to %ld\n"
))
,
2930 textyear.value, year);
2931 }
2932
2933 return year;
2934}
2935
2936static table const * _GL_ATTRIBUTE_PURE__attribute__ ((__pure__))
2937lookup_zone (parser_control const *pc, char const *name)
2938{
2939 table const *tp;
2940
2941 for (tp = universal_time_zone_table; tp->name; tp++)
2942 if (strcmp (name, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(name) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (name), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(name, tp->name) : (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) && (__s1_len = __builtin_strlen (name), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (name, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (name))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (name))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (name) && (
(size_t)(const void *)((name) + 1) - (size_t)(const void *)(name
) == 1) ? __builtin_strcmp (name, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (name); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(name, tp->name)))); })
== 0)
2943 return tp;
2944
2945 /* Try local zone abbreviations before those in time_zone_table, as
2946 the local ones are more likely to be right. */
2947 for (tp = pc->local_time_zone_table; tp->name; tp++)
2948 if (strcmp (name, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(name) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (name), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(name, tp->name) : (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) && (__s1_len = __builtin_strlen (name), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (name, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (name))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (name))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (name) && (
(size_t)(const void *)((name) + 1) - (size_t)(const void *)(name
) == 1) ? __builtin_strcmp (name, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (name); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(name, tp->name)))); })
== 0)
2949 return tp;
2950
2951 for (tp = time_zone_table; tp->name; tp++)
2952 if (strcmp (name, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(name) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (name), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((name) + 1) - (size_t
)(const void *)(name) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(name, tp->name) : (__builtin_constant_p (name) &&
((size_t)(const void *)((name) + 1) - (size_t)(const void *)
(name) == 1) && (__s1_len = __builtin_strlen (name), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (name, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (name))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (name))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (name))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (name) && (
(size_t)(const void *)((name) + 1) - (size_t)(const void *)(name
) == 1) ? __builtin_strcmp (name, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (name); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(name, tp->name)))); })
== 0)
2953 return tp;
2954
2955 return NULL((void*)0);
2956}
2957
2958#if ! HAVE_TM_GMTOFF1
2959/* Yield the difference between *A and *B,
2960 measured in seconds, ignoring leap seconds.
2961 The body of this function is taken directly from the GNU C Library;
2962 see src/strftime.c. */
2963static long int
2964tm_diff (struct tm const *a, struct tm const *b)
2965{
2966 /* Compute intervening leap days correctly even if year is negative.
2967 Take care to avoid int overflow in leap day calculations. */
2968 int a4 = SHR (a->tm_year, 2)(-1 >> 1 == -1 ? (a->tm_year) >> (2) : (a->
tm_year) / (1 << (2)) - ((a->tm_year) % (1 << (
2)) < 0))
+ SHR (TM_YEAR_BASE, 2)(-1 >> 1 == -1 ? (1900) >> (2) : (1900) / (1 <<
(2)) - ((1900) % (1 << (2)) < 0))
- ! (a->tm_year & 3);
2969 int b4 = SHR (b->tm_year, 2)(-1 >> 1 == -1 ? (b->tm_year) >> (2) : (b->
tm_year) / (1 << (2)) - ((b->tm_year) % (1 << (
2)) < 0))
+ SHR (TM_YEAR_BASE, 2)(-1 >> 1 == -1 ? (1900) >> (2) : (1900) / (1 <<
(2)) - ((1900) % (1 << (2)) < 0))
- ! (b->tm_year & 3);
2970 int a100 = a4 / 25 - (a4 % 25 < 0);
2971 int b100 = b4 / 25 - (b4 % 25 < 0);
2972 int a400 = SHR (a100, 2)(-1 >> 1 == -1 ? (a100) >> (2) : (a100) / (1 <<
(2)) - ((a100) % (1 << (2)) < 0))
;
2973 int b400 = SHR (b100, 2)(-1 >> 1 == -1 ? (b100) >> (2) : (b100) / (1 <<
(2)) - ((b100) % (1 << (2)) < 0))
;
2974 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2975 long int ayear = a->tm_year;
2976 long int years = ayear - b->tm_year;
2977 long int days = (365 * years + intervening_leap_days
2978 + (a->tm_yday - b->tm_yday));
2979 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2980 + (a->tm_min - b->tm_min))
2981 + (a->tm_sec - b->tm_sec));
2982}
2983#endif /* ! HAVE_TM_GMTOFF */
2984
2985static table const *
2986lookup_word (parser_control const *pc, char *word)
2987{
2988 char *p;
2989 char *q;
2990 size_t wordlen;
2991 table const *tp;
2992 bool_Bool period_found;
2993 bool_Bool abbrev;
2994
2995 /* Make it uppercase. */
2996 for (p = word; *p; p++)
2997 {
2998 unsigned char ch = *p;
2999 *p = c_toupper (ch);
3000 }
3001
3002 for (tp = meridian_table; tp->name; tp++)
3003 if (strcmp (word, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); })
== 0)
3004 return tp;
3005
3006 /* See if we have an abbreviation for a month. */
3007 wordlen = strlen (word);
3008 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
3009
3010 for (tp = month_and_day_table; tp->name; tp++)
3011 if ((abbrev ? strncmp (word, tp->name, 3)(__extension__ (__builtin_constant_p (3) && ((__builtin_constant_p
(word) && strlen (word) < ((size_t) (3))) || (__builtin_constant_p
(tp->name) && strlen (tp->name) < ((size_t)
(3)))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); }) : strncmp (word, tp->name, 3))
)
: strcmp (word, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); })
) == 0)
3012 return tp;
3013
3014 if ((tp = lookup_zone (pc, word)))
3015 return tp;
3016
3017 if (strcmp (word, dst_table[0].name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (dst_table[0].name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(dst_table[0].name), (!((size_t)(const void *)((word) + 1) -
(size_t)(const void *)(word) == 1) || __s1_len >= 4) &&
(!((size_t)(const void *)((dst_table[0].name) + 1) - (size_t
)(const void *)(dst_table[0].name) == 1) || __s2_len >= 4)
) ? __builtin_strcmp (word, dst_table[0].name) : (__builtin_constant_p
(word) && ((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) && (__s1_len = __builtin_strlen
(word), __s1_len < 4) ? (__builtin_constant_p (dst_table[
0].name) && ((size_t)(const void *)((dst_table[0].name
) + 1) - (size_t)(const void *)(dst_table[0].name) == 1) ? __builtin_strcmp
(word, dst_table[0].name) : (__extension__ ({ const unsigned
char *__s2 = (const unsigned char *) (const char *) (dst_table
[0].name); int __result = (((const unsigned char *) (const char
*) (word))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
word))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
word))[2] - __s2[2]); if (__s1_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) (word
))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (
dst_table[0].name) && ((size_t)(const void *)((dst_table
[0].name) + 1) - (size_t)(const void *)(dst_table[0].name) ==
1) && (__s2_len = __builtin_strlen (dst_table[0].name
), __s2_len < 4) ? (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) ? __builtin_strcmp (word, dst_table[0].name) : (
- (__extension__ ({ const unsigned char *__s2 = (const unsigned
char *) (const char *) (word); int __result = (((const unsigned
char *) (const char *) (dst_table[0].name))[0] - __s2[0]); if
(__s2_len > 0 && __result == 0) { __result = (((const
unsigned char *) (const char *) (dst_table[0].name))[1] - __s2
[1]); if (__s2_len > 1 && __result == 0) { __result
= (((const unsigned char *) (const char *) (dst_table[0].name
))[2] - __s2[2]); if (__s2_len > 2 && __result == 0
) __result = (((const unsigned char *) (const char *) (dst_table
[0].name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, dst_table[0].name)))); })
== 0)
3018 return dst_table;
3019
3020 for (tp = time_units_table; tp->name; tp++)
3021 if (strcmp (word, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); })
== 0)
3022 return tp;
3023
3024 /* Strip off any plural and try the units table again. */
3025 if (word[wordlen - 1] == 'S')
3026 {
3027 word[wordlen - 1] = '\0';
3028 for (tp = time_units_table; tp->name; tp++)
3029 if (strcmp (word, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); })
== 0)
3030 return tp;
3031 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
3032 }
3033
3034 for (tp = relative_time_table; tp->name; tp++)
3035 if (strcmp (word, tp->name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(word) && __builtin_constant_p (tp->name) &&
(__s1_len = __builtin_strlen (word), __s2_len = __builtin_strlen
(tp->name), (!((size_t)(const void *)((word) + 1) - (size_t
)(const void *)(word) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)((tp->name) + 1) - (size_t)(const void
*)(tp->name) == 1) || __s2_len >= 4)) ? __builtin_strcmp
(word, tp->name) : (__builtin_constant_p (word) &&
((size_t)(const void *)((word) + 1) - (size_t)(const void *)
(word) == 1) && (__s1_len = __builtin_strlen (word), __s1_len
< 4) ? (__builtin_constant_p (tp->name) && ((size_t
)(const void *)((tp->name) + 1) - (size_t)(const void *)(tp
->name) == 1) ? __builtin_strcmp (word, tp->name) : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tp->name); int __result = (((const unsigned char
*) (const char *) (word))[0] - __s2[0]); if (__s1_len > 0
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[1] - __s2[1]); if (__s1_len > 1
&& __result == 0) { __result = (((const unsigned char
*) (const char *) (word))[2] - __s2[2]); if (__s1_len > 2
&& __result == 0) __result = (((const unsigned char *
) (const char *) (word))[3] - __s2[3]); } } __result; }))) : (
__builtin_constant_p (tp->name) && ((size_t)(const
void *)((tp->name) + 1) - (size_t)(const void *)(tp->name
) == 1) && (__s2_len = __builtin_strlen (tp->name)
, __s2_len < 4) ? (__builtin_constant_p (word) && (
(size_t)(const void *)((word) + 1) - (size_t)(const void *)(word
) == 1) ? __builtin_strcmp (word, tp->name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (word); int __result = (((const unsigned char *) (const
char *) (tp->name))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tp->name))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tp->name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(word, tp->name)))); })
== 0)
3036 return tp;
3037
3038 /* Military time zones. */
3039 if (wordlen == 1)
3040 for (tp = military_table; tp->name; tp++)
3041 if (word[0] == tp->name[0])
3042 return tp;
3043
3044 /* Drop out any periods and try the time zone table again. */
3045 for (period_found = false0, p = q = word; (*p = *q); q++)
3046 if (*q == '.')
3047 period_found = true1;
3048 else
3049 p++;
3050 if (period_found && (tp = lookup_zone (pc, word)))
3051 return tp;
3052
3053 return NULL((void*)0);
3054}
3055
3056static int
3057yylex (union YYSTYPE *lvalp, parser_control *pc)
3058{
3059 unsigned char c;
3060 size_t count;
3061
3062 for (;;)
3063 {
3064 while (c = *pc->input, c_isspace (c))
3065 pc->input++;
3066
3067 if (ISDIGIT (c)((unsigned int) (c) - '0' <= 9) || c == '-' || c == '+')
3068 {
3069 char const *p;
3070 int sign;
3071 unsigned long int value;
3072 if (c == '-' || c == '+')
3073 {
3074 sign = c == '-' ? -1 : 1;
3075 while (c = *++pc->input, c_isspace (c))
3076 continue;
3077 if (! ISDIGIT (c)((unsigned int) (c) - '0' <= 9))
3078 /* skip the '-' sign */
3079 continue;
3080 }
3081 else
3082 sign = 0;
3083 p = pc->input;
3084 for (value = 0; ; value *= 10)
3085 {
3086 unsigned long int value1 = value + (c - '0');
3087 if (value1 < value)
3088 return '?';
3089 value = value1;
3090 c = *++p;
3091 if (! ISDIGIT (c)((unsigned int) (c) - '0' <= 9))
3092 break;
3093 if (ULONG_MAX(9223372036854775807L *2UL+1UL) / 10 < value)
3094 return '?';
3095 }
3096 if ((c == '.' || c == ',') && ISDIGIT (p[1])((unsigned int) (p[1]) - '0' <= 9))
3097 {
3098 time_t s;
3099 int ns;
3100 int digits;
3101 unsigned long int value1;
3102
3103 /* Check for overflow when converting value to time_t. */
3104 if (sign < 0)
3105 {
3106 s = - value;
3107 if (0 < s)
3108 return '?';
3109 value1 = -s;
3110 }
3111 else
3112 {
3113 s = value;
3114 if (s < 0)
3115 return '?';
3116 value1 = s;
3117 }
3118 if (value != value1)
3119 return '?';
3120
3121 /* Accumulate fraction, to ns precision. */
3122 p++;
3123 ns = *p++ - '0';
3124 for (digits = 2; digits <= LOG10_BILLION; digits++)
3125 {
3126 ns *= 10;
3127 if (ISDIGIT (*p)((unsigned int) (*p) - '0' <= 9))
3128 ns += *p++ - '0';
3129 }
3130
3131 /* Skip excess digits, truncating toward -Infinity. */
3132 if (sign < 0)
3133 for (; ISDIGIT (*p)((unsigned int) (*p) - '0' <= 9); p++)
3134 if (*p != '0')
3135 {
3136 ns++;
3137 break;
3138 }
3139 while (ISDIGIT (*p)((unsigned int) (*p) - '0' <= 9))
3140 p++;
3141
3142 /* Adjust to the timespec convention, which is that
3143 tv_nsec is always a positive offset even if tv_sec is
3144 negative. */
3145 if (sign < 0 && ns)
3146 {
3147 s--;
3148 if (! (s < 0))
3149 return '?';
3150 ns = BILLION - ns;
3151 }
3152
3153 lvalp->timespec.tv_sec = s;
3154 lvalp->timespec.tv_nsec = ns;
3155 pc->input = p;
3156 return sign ? tSDECIMAL_NUMBER276 : tUDECIMAL_NUMBER277;
3157 }
3158 else
3159 {
3160 lvalp->textintval.negative = sign < 0;
3161 if (sign < 0)
3162 {
3163 lvalp->textintval.value = - value;
3164 if (0 < lvalp->textintval.value)
3165 return '?';
3166 }
3167 else
3168 {
3169 lvalp->textintval.value = value;
3170 if (lvalp->textintval.value < 0)
3171 return '?';
3172 }
3173 lvalp->textintval.digits = p - pc->input;
3174 pc->input = p;
3175 return sign ? tSNUMBER274 : tUNUMBER275;
3176 }
3177 }
3178
3179 if (c_isalpha (c))
3180 {
3181 char buff[20];
3182 char *p = buff;
3183 table const *tp;
3184
3185 do
3186 {
3187 if (p < buff + sizeof buff - 1)
3188 *p++ = c;
3189 c = *++pc->input;
3190 }
3191 while (c_isalpha (c) || c == '.');
3192
3193 *p = '\0';
3194 tp = lookup_word (pc, buff);
3195 if (! tp)
3196 {
3197 if (pc->parse_datetime_debug)
3198 dbg_printf (_("error: unknown word '%s'\n")((const char *) ("error: unknown word '%s'\n")), buff);
3199 return '?';
3200 }
3201 lvalp->intval = tp->value;
3202 return tp->type;
3203 }
3204
3205 if (c != '(')
3206 return to_uchar (*pc->input++);
3207
3208 count = 0;
3209 do
3210 {
3211 c = *pc->input++;
3212 if (c == '\0')
3213 return c;
3214 if (c == '(')
3215 count++;
3216 else if (c == ')')
3217 count--;
3218 }
3219 while (count != 0);
3220 }
3221}
3222
3223/* Do nothing if the parser reports an error. */
3224static int
3225yyerror (parser_control const *pc _GL_UNUSED__attribute__ ((__unused__)),
3226 char const *s _GL_UNUSED__attribute__ ((__unused__)))
3227{
3228 return 0;
3229}
3230
3231/* If *TM0 is the old and *TM1 is the new value of a struct tm after
3232 passing it to mktime, return true if it's OK that mktime returned T.
3233 It's not OK if *TM0 has out-of-range members. */
3234
3235static bool_Bool
3236mktime_ok (struct tm const *tm0, struct tm const *tm1, time_t t)
3237{
3238 if (t == (time_t) -1)
3239 {
3240 /* Guard against falsely reporting an error when parsing a time
3241 stamp that happens to equal (time_t) -1, on a host that
3242 supports such a time stamp. */
3243 tm1 = localtime (&t);
3244 if (!tm1)
3245 return false0;
3246 }
3247
3248 return ! ((tm0->tm_sec ^ tm1->tm_sec)
3249 | (tm0->tm_min ^ tm1->tm_min)
3250 | (tm0->tm_hour ^ tm1->tm_hour)
3251 | (tm0->tm_mday ^ tm1->tm_mday)
3252 | (tm0->tm_mon ^ tm1->tm_mon)
3253 | (tm0->tm_year ^ tm1->tm_year));
3254}
3255
3256/* A reasonable upper bound for the size of ordinary TZ strings.
3257 Use heap allocation if TZ's length exceeds this. */
3258enum { TZBUFSIZE = 100 };
3259
3260/* A reasonable upper bound for the buffer used in debug print outs.
3261 see days_to_name(), debug_strftime() and debug_mktime_not_ok() */
3262enum { DBGBUFSIZE = 100 };
3263
3264/* Return a copy of TZ, stored in TZBUF if it fits, and heap-allocated
3265 otherwise. */
3266static char *
3267get_tz (char tzbuf[TZBUFSIZE])
3268{
3269 char *tz = getenv ("TZ");
3270 if (tz)
3271 {
3272 size_t tzsize = strlen (tz) + 1;
3273 tz = (tzsize <= TZBUFSIZE
3274 ? memcpy (tzbuf, tz, tzsize)
3275 : xmemdup (tz, tzsize));
3276 }
3277 return tz;
3278}
3279
3280/* debugging: format a 'struct tm' into a buffer, taking the parser's
3281 timezone information into account (if pc!=NULL). */
3282static const char*
3283debug_strfdatetime (const struct tm *tm, const parser_control *pc,
3284 char* /*output*/ buf, size_t n)
3285{
3286 /* TODO:
3287 1. find an optimal way to print date string in a clear and unambiguous
3288 format. Currently, always add '(Y-M-D)' prefix.
3289 Consider '2016y01m10d' or 'year(2016) month(01) day(10)'.
3290
3291 If the user needs debug printing, it means he/she already having
3292 issues with the parsing - better to avoid formats that could
3293 be mis-interpreted (e.g. just YYYY-MM-DD).
3294
3295 2. Can strftime be used instead?
3296 depends if it is portable and can print invalid dates on all systems.
3297
3298 3. Print timezone information ?
3299
3300 4. Print DST information ?
3301
3302 5. Print nanosecond information ?
3303
3304 NOTE:
3305 Printed date/time values might not be valid, e.g. '2016-02-31'
3306 or '2016-19-2016' . These are the values as parsed from the user
3307 string, before validation.
3308 */
3309 int m = nstrftime (buf, n, "(Y-M-D) %Y-%m-%d %H:%M:%S", tm, 0, 0);
3310
3311 /* if parser_control information was provided (for timezone),
3312 and there's enough space in the buffer - add timezone info */
3313 if (pc != NULL((void*)0) && ((n-m)>0))
3314 {
3315 const long int tz = (pc->zones_seen || pc->local_zones_seen)
3316 ? pc->time_zone
3317 : pc->debug_default_input_timezone;
3318 snprintf (&buf[m],n-m," TZ=%+03d:%02d", (int)(tz/60), abs ((int)tz)%60);
3319 }
3320 return buf;
3321}
3322
3323static const char*
3324debug_strfdate (const struct tm *tm, char* /*output*/ buf, size_t n)
3325{
3326 snprintf (buf,n,"(Y-M-D) %04d-%02d-%02d",
3327 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
3328 return buf;
3329}
3330
3331static const char*
3332debug_strftime (const struct tm *tm, char* /*output*/ buf, size_t n)
3333{
3334 snprintf (buf,n,"%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
3335 return buf;
3336}
3337
3338/* If 'mktime_ok()' failed, display the failed time values,
3339 and provide possible hints. Example output:
3340
3341 date: error: invalid date/time value:
3342 date: user provided time: '(Y-M-D) 2006-04-02 02:45:00'
3343 date: normalized time: '(Y-M-D) 2006-04-02 03:45:00'
3344 date: __
3345 date: possible reasons:
3346 date: non-existing due to daylight-saving time;
3347 date: numeric values overflow;
3348 date: missing timezone;
3349 */
3350static void
3351debug_mktime_not_ok (struct tm const *tm0, struct tm const *tm1,
3352 const parser_control *pc, bool_Bool time_zone_seen)
3353{
3354 /* TODO: handle t==-1 (as in 'mktime_ok') */
3355 char tmp[DBGBUFSIZE];
3356 int i;
3357 const bool_Bool eq_sec = (tm0->tm_sec == tm1->tm_sec);
3358 const bool_Bool eq_min = (tm0->tm_min == tm1->tm_min);
3359 const bool_Bool eq_hour = (tm0->tm_hour == tm1->tm_hour);
3360 const bool_Bool eq_mday = (tm0->tm_mday == tm1->tm_mday);
3361 const bool_Bool eq_month = (tm0->tm_mon == tm1->tm_mon);
3362 const bool_Bool eq_year = (tm0->tm_year == tm1->tm_year);
3363
3364 const bool_Bool dst_shift = eq_sec && eq_min && !eq_hour
3365 && eq_mday && eq_month && eq_year;
3366
3367 if (!pc->parse_datetime_debug)
3368 return;
3369
3370 dbg_printf (_("error: invalid date/time value:\n")((const char *) ("error: invalid date/time value:\n")));
3371 dbg_printf (_(" user provided time: '%s'\n")((const char *) (" user provided time: '%s'\n")),
3372 debug_strfdatetime (tm0, pc, tmp, sizeof (tmp)));
3373 dbg_printf (_(" normalized time: '%s'\n")((const char *) (" normalized time: '%s'\n")),
3374 debug_strfdatetime (tm1, pc, tmp, sizeof (tmp)));
3375 /* NOTEs: the format must be aligned with debug_strfdatetime() and the two
3376 DEBUG statements above. this string is not translated. */
3377 i = snprintf (tmp, sizeof(tmp),
3378 " %4s %2s %2s %2s %2s %2s",
3379 eq_year?"":"----", eq_month?"":"--", eq_mday?"":"--",
3380 eq_hour?"":"--", eq_min?"":"--", eq_sec?"":"--");
3381 /* Trim trailing whitespace */
3382 if ((i>0) && (i<sizeof(tmp)))
3383 {
3384 while ((i>0) && (tmp[i-1]==' '))
3385 --i;
3386 tmp[i] = '\0';
3387 }
3388 dbg_printf ("%s\n", tmp);
3389
3390 dbg_printf (_(" possible reasons:\n")((const char *) (" possible reasons:\n")));
3391 if (dst_shift)
3392 dbg_printf (_(" non-existing due to daylight-saving time;\n")((const char *) (" non-existing due to daylight-saving time;\n"
))
);
3393 if (!eq_mday && !eq_month)
3394 dbg_printf (_(" invalid day/month combination;\n")((const char *) (" invalid day/month combination;\n")));
3395 dbg_printf (_(" numeric values overflow;\n")((const char *) (" numeric values overflow;\n")));
3396 dbg_printf (" %s\n",time_zone_seen?_("incorrect timezone")((const char *) ("incorrect timezone"))
3397 :_("missing timezone")((const char *) ("missing timezone")));
3398}
3399
3400
3401/* Returns the effective local timezone, in minutes. */
3402static long int
3403get_effective_timezone (void)
3404{
3405 /* TODO: check for failures */
3406 const time_t z = 0;
3407 time_t lz ;
3408 struct tm *ltm;
3409 ltm = localtime (&z);
3410 lz = timegm (ltm)/60;
3411 return (long int)lz;
3412}
3413
3414/* The original interface: run with debug=false */
3415bool_Bool
3416parse_datetime (struct timespec *result, char const *p,
3417 struct timespec const *now)
3418{
3419 return parse_datetime2 (result, p, now, 0);
3420}
3421
3422/* Parse a date/time string, storing the resulting time value into *RESULT.
3423 The string itself is pointed to by P. Return true if successful.
3424 P can be an incomplete or relative time specification; if so, use
3425 *NOW as the basis for the returned time. */
3426bool_Bool
3427parse_datetime2 (struct timespec *result, char const *p,
3428 struct timespec const *now, unsigned int flags)
3429{
3430 time_t Start;
3431 long int Start_ns;
3432 struct tm const *tmp;
3433 struct tm tm;
3434 struct tm tm0;
3435 parser_control pc;
3436 struct timespec gettime_buffer;
3437 unsigned char c;
3438 bool_Bool tz_was_altered = false0;
3439 char *tz0 = NULL((void*)0);
3440 char tz0buf[TZBUFSIZE];
3441 bool_Bool ok = true1;
3442 char dbg_ord[DBGBUFSIZE];
3443 char dbg_tm[DBGBUFSIZE];
3444
3445 if (! now)
3446 {
3447 gettime (&gettime_buffer);
3448 now = &gettime_buffer;
3449 }
3450
3451 Start = now->tv_sec;
3452 Start_ns = now->tv_nsec;
3453
3454 tmp = localtime (&now->tv_sec);
3455 if (! tmp)
3456 return false0;
3457
3458 while (c = *p, c_isspace (c))
3459 p++;
3460
3461 if (strncmp (p, "TZ=\"", 4)(__extension__ (__builtin_constant_p (4) && ((__builtin_constant_p
(p) && strlen (p) < ((size_t) (4))) || (__builtin_constant_p
("TZ=\"") && strlen ("TZ=\"") < ((size_t) (4)))) ?
__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(p) && __builtin_constant_p ("TZ=\"") && (__s1_len
= __builtin_strlen (p), __s2_len = __builtin_strlen ("TZ=\""
), (!((size_t)(const void *)((p) + 1) - (size_t)(const void *
)(p) == 1) || __s1_len >= 4) && (!((size_t)(const void
*)(("TZ=\"") + 1) - (size_t)(const void *)("TZ=\"") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (p, "TZ=\"") : (__builtin_constant_p
(p) && ((size_t)(const void *)((p) + 1) - (size_t)(const
void *)(p) == 1) && (__s1_len = __builtin_strlen (p)
, __s1_len < 4) ? (__builtin_constant_p ("TZ=\"") &&
((size_t)(const void *)(("TZ=\"") + 1) - (size_t)(const void
*)("TZ=\"") == 1) ? __builtin_strcmp (p, "TZ=\"") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("TZ=\""); int __result = (((const unsigned char *) (
const char *) (p))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (p))[1] - __s2[1]); if (__s1_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
p))[2] - __s2[2]); if (__s1_len > 2 && __result ==
0) __result = (((const unsigned char *) (const char *) (p))[
3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("TZ=\""
) && ((size_t)(const void *)(("TZ=\"") + 1) - (size_t
)(const void *)("TZ=\"") == 1) && (__s2_len = __builtin_strlen
("TZ=\""), __s2_len < 4) ? (__builtin_constant_p (p) &&
((size_t)(const void *)((p) + 1) - (size_t)(const void *)(p)
== 1) ? __builtin_strcmp (p, "TZ=\"") : (- (__extension__ ({
const unsigned char *__s2 = (const unsigned char *) (const char
*) (p); int __result = (((const unsigned char *) (const char
*) ("TZ=\""))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"TZ=\""))[1] - __s2[1]); if (__s2_len > 1 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
"TZ=\""))[2] - __s2[2]); if (__s2_len > 2 && __result
== 0) __result = (((const unsigned char *) (const char *) ("TZ=\""
))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (p, "TZ=\""
)))); }) : strncmp (p, "TZ=\"", 4)))
== 0)
3462 {
3463 char const *tzbase = p + 4;
3464 size_t tzsize = 1;
3465 char const *s;
3466
3467 for (s = tzbase; *s; s++, tzsize++)
3468 if (*s == '\\')
3469 {
3470 s++;
3471 if (! (*s == '\\' || *s == '"'))
3472 break;
3473 }
3474 else if (*s == '"')
3475 {
3476 char *z;
3477 char *tz1;
3478 char tz1buf[TZBUFSIZE];
3479 bool_Bool large_tz = TZBUFSIZE < tzsize;
3480 bool_Bool setenv_ok;
3481 tz0 = get_tz (tz0buf);
3482 z = tz1 = large_tz ? xmalloc (tzsize) : tz1buf;
3483 for (s = tzbase; *s != '"'; s++)
3484 *z++ = *(s += *s == '\\');
3485 *z = '\0';
3486 setenv_ok = setenv ("TZ", tz1, 1) == 0;
3487 if (large_tz)
3488 free (tz1);
3489 if (!setenv_ok)
3490 goto fail;
3491 tz_was_altered = true1;
3492
3493 p = s + 1;
3494 while (c = *p, c_isspace (c))
3495 p++;
3496
3497 break;
3498 }
3499 }
3500
3501 /* As documented, be careful to treat the empty string just like
3502 a date string of "0". Without this, an empty string would be
3503 declared invalid when parsed during a DST transition. */
3504 if (*p == '\0')
3505 p = "0";
3506
3507 pc.input = p;
3508 pc.year.value = tmp->tm_year;
3509 pc.year.value += TM_YEAR_BASE1900;
3510 pc.year.digits = 0;
3511 pc.month = tmp->tm_mon + 1;
3512 pc.day = tmp->tm_mday;
3513 pc.hour = tmp->tm_hour;
3514 pc.minutes = tmp->tm_min;
3515 pc.seconds.tv_sec = tmp->tm_sec;
3516 pc.seconds.tv_nsec = Start_ns;
3517 tm.tm_isdst = tmp->tm_isdst;
3518
3519 pc.meridian = MER24;
3520 pc.rel = RELATIVE_TIME_0((relative_time) { 0, 0, 0, 0, 0, 0, 0 });
3521 pc.timespec_seen = false0;
3522 pc.rels_seen = false0;
3523 pc.dates_seen = 0;
3524 pc.days_seen = 0;
3525 pc.times_seen = 0;
3526 pc.local_zones_seen = 0;
3527 pc.dsts_seen = 0;
3528 pc.zones_seen = 0;
3529 pc.parse_datetime_debug = (flags & PARSE_DATETIME_DEBUG1)!=0;
3530 pc.debug_dates_seen = 0;
3531 pc.debug_days_seen = 0;
3532 pc.debug_times_seen = 0;
3533 pc.debug_local_zones_seen = 0;
3534 pc.debug_dsts_seen = 0;
3535 pc.debug_zones_seen = 0;
3536 pc.debug_ordinal_day_seen = false0;
3537 pc.debug_default_input_timezone = 0;
3538
3539#if HAVE_STRUCT_TM_TM_ZONE1
3540 pc.local_time_zone_table[0].name = tmp->tm_zone;
3541 pc.local_time_zone_table[0].type = tLOCAL_ZONE269;
3542 pc.local_time_zone_table[0].value = tmp->tm_isdst;
3543 pc.local_time_zone_table[1].name = NULL((void*)0);
3544
3545 /* Probe the names used in the next three calendar quarters, looking
3546 for a tm_isdst different from the one we already have. */
3547 {
3548 int quarter;
3549 for (quarter = 1; quarter <= 3; quarter++)
3550 {
3551 time_t probe = Start + quarter * (90 * 24 * 60 * 60);
3552 struct tm const *probe_tm = localtime (&probe);
3553 if (probe_tm && probe_tm->tm_zone
3554 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
3555 {
3556 {
3557 pc.local_time_zone_table[1].name = probe_tm->tm_zone;
3558 pc.local_time_zone_table[1].type = tLOCAL_ZONE269;
3559 pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
3560 pc.local_time_zone_table[2].name = NULL((void*)0);
3561 }
3562 break;
3563 }
3564 }
3565 }
3566#else
3567#if HAVE_TZNAME
3568 {
3569# if !HAVE_DECL_TZNAME
3570 extern char *tzname[];
3571# endif
3572 int i;
3573 for (i = 0; i < 2; i++)
3574 {
3575 pc.local_time_zone_table[i].name = tzname[i];
3576 pc.local_time_zone_table[i].type = tLOCAL_ZONE269;
3577 pc.local_time_zone_table[i].value = i;
3578 }
3579 pc.local_time_zone_table[i].name = NULL((void*)0);
3580 }
3581#else
3582 pc.local_time_zone_table[0].name = NULL((void*)0);
3583#endif
3584#endif
3585
3586 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
3587 && ! strcmp (pc.local_time_zone_table[0].name,__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(pc.local_time_zone_table[0].name) && __builtin_constant_p
(pc.local_time_zone_table[1].name) && (__s1_len = __builtin_strlen
(pc.local_time_zone_table[0].name), __s2_len = __builtin_strlen
(pc.local_time_zone_table[1].name), (!((size_t)(const void *
)((pc.local_time_zone_table[0].name) + 1) - (size_t)(const void
*)(pc.local_time_zone_table[0].name) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((pc.local_time_zone_table
[1].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[1].name) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pc.
local_time_zone_table[0].name, pc.local_time_zone_table[1].name
) : (__builtin_constant_p (pc.local_time_zone_table[0].name) &&
((size_t)(const void *)((pc.local_time_zone_table[0].name) +
1) - (size_t)(const void *)(pc.local_time_zone_table[0].name
) == 1) && (__s1_len = __builtin_strlen (pc.local_time_zone_table
[0].name), __s1_len < 4) ? (__builtin_constant_p (pc.local_time_zone_table
[1].name) && ((size_t)(const void *)((pc.local_time_zone_table
[1].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[1].name) == 1) ? __builtin_strcmp (pc.local_time_zone_table[
0].name, pc.local_time_zone_table[1].name) : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (pc.local_time_zone_table[1].name); int __result = (((const
unsigned char *) (const char *) (pc.local_time_zone_table[0]
.name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
pc.local_time_zone_table[0].name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (pc.local_time_zone_table[0].name))[2
] - __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (pc.local_time_zone_table
[0].name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(pc.local_time_zone_table[1].name) && ((size_t)(const
void *)((pc.local_time_zone_table[1].name) + 1) - (size_t)(const
void *)(pc.local_time_zone_table[1].name) == 1) && (
__s2_len = __builtin_strlen (pc.local_time_zone_table[1].name
), __s2_len < 4) ? (__builtin_constant_p (pc.local_time_zone_table
[0].name) && ((size_t)(const void *)((pc.local_time_zone_table
[0].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[0].name) == 1) ? __builtin_strcmp (pc.local_time_zone_table[
0].name, pc.local_time_zone_table[1].name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (pc.local_time_zone_table[0].name); int __result = (
((const unsigned char *) (const char *) (pc.local_time_zone_table
[1].name))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
pc.local_time_zone_table[1].name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (pc.local_time_zone_table[1].name))[2
] - __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (pc.local_time_zone_table
[1].name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(pc.local_time_zone_table[0].name, pc.local_time_zone_table[
1].name)))); })
3588 pc.local_time_zone_table[1].name)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(pc.local_time_zone_table[0].name) && __builtin_constant_p
(pc.local_time_zone_table[1].name) && (__s1_len = __builtin_strlen
(pc.local_time_zone_table[0].name), __s2_len = __builtin_strlen
(pc.local_time_zone_table[1].name), (!((size_t)(const void *
)((pc.local_time_zone_table[0].name) + 1) - (size_t)(const void
*)(pc.local_time_zone_table[0].name) == 1) || __s1_len >=
4) && (!((size_t)(const void *)((pc.local_time_zone_table
[1].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[1].name) == 1) || __s2_len >= 4)) ? __builtin_strcmp (pc.
local_time_zone_table[0].name, pc.local_time_zone_table[1].name
) : (__builtin_constant_p (pc.local_time_zone_table[0].name) &&
((size_t)(const void *)((pc.local_time_zone_table[0].name) +
1) - (size_t)(const void *)(pc.local_time_zone_table[0].name
) == 1) && (__s1_len = __builtin_strlen (pc.local_time_zone_table
[0].name), __s1_len < 4) ? (__builtin_constant_p (pc.local_time_zone_table
[1].name) && ((size_t)(const void *)((pc.local_time_zone_table
[1].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[1].name) == 1) ? __builtin_strcmp (pc.local_time_zone_table[
0].name, pc.local_time_zone_table[1].name) : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) (pc.local_time_zone_table[1].name); int __result = (((const
unsigned char *) (const char *) (pc.local_time_zone_table[0]
.name))[0] - __s2[0]); if (__s1_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
pc.local_time_zone_table[0].name))[1] - __s2[1]); if (__s1_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (pc.local_time_zone_table[0].name))[2
] - __s2[2]); if (__s1_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (pc.local_time_zone_table
[0].name))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
(pc.local_time_zone_table[1].name) && ((size_t)(const
void *)((pc.local_time_zone_table[1].name) + 1) - (size_t)(const
void *)(pc.local_time_zone_table[1].name) == 1) && (
__s2_len = __builtin_strlen (pc.local_time_zone_table[1].name
), __s2_len < 4) ? (__builtin_constant_p (pc.local_time_zone_table
[0].name) && ((size_t)(const void *)((pc.local_time_zone_table
[0].name) + 1) - (size_t)(const void *)(pc.local_time_zone_table
[0].name) == 1) ? __builtin_strcmp (pc.local_time_zone_table[
0].name, pc.local_time_zone_table[1].name) : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (pc.local_time_zone_table[0].name); int __result = (
((const unsigned char *) (const char *) (pc.local_time_zone_table
[1].name))[0] - __s2[0]); if (__s2_len > 0 && __result
== 0) { __result = (((const unsigned char *) (const char *) (
pc.local_time_zone_table[1].name))[1] - __s2[1]); if (__s2_len
> 1 && __result == 0) { __result = (((const unsigned
char *) (const char *) (pc.local_time_zone_table[1].name))[2
] - __s2[2]); if (__s2_len > 2 && __result == 0) __result
= (((const unsigned char *) (const char *) (pc.local_time_zone_table
[1].name))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(pc.local_time_zone_table[0].name, pc.local_time_zone_table[
1].name)))); })
)
3589 {
3590 /* This locale uses the same abbreviation for standard and
3591 daylight times. So if we see that abbreviation, we don't
3592 know whether it's daylight time. */
3593 pc.local_time_zone_table[0].value = -1;
3594 pc.local_time_zone_table[1].name = NULL((void*)0);
3595 }
3596
3597 pc.debug_default_input_timezone = get_effective_timezone ();
3598
3599 if (yyparse (&pc) != 0)
3600 {
3601 if (pc.parse_datetime_debug)
3602 dbg_printf (_("error: parsing failed, stopped at '%s'\n")((const char *) ("error: parsing failed, stopped at '%s'\n")), pc.input);
3603 goto fail;
3604 }
3605
3606 /* determine effective timezone source */
3607 if (pc.parse_datetime_debug)
3608 {
3609 long int tz = pc.debug_default_input_timezone;
3610 const char* tz_env;
3611 const char* tz_src;
3612
3613 if (pc.timespec_seen)
3614 {
3615 tz = 0 ;
3616 tz_src = _("'@timespec' - always UTC0")((const char *) ("'@timespec' - always UTC0"));
3617 }
3618 else if (pc.local_zones_seen || pc.zones_seen)
3619 {
3620 tz = pc.time_zone;
3621 tz_src = _("parsed date/time string")((const char *) ("parsed date/time string"));
3622 }
3623 else if ((tz_env = getenv("TZ")))
3624 {
3625 if (tz_was_altered)
3626 {
3627 snprintf (dbg_tm, sizeof(dbg_tm), _("TZ=\"%s\" in date string")((const char *) ("TZ=\"%s\" in date string")),
3628 tz_env);
3629 tz_src = dbg_tm;
3630 }
3631 else if (STREQ(tz_env,"UTC0")(__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tz_env) && __builtin_constant_p ("UTC0") &&
(__s1_len = __builtin_strlen (tz_env), __s2_len = __builtin_strlen
("UTC0"), (!((size_t)(const void *)((tz_env) + 1) - (size_t)
(const void *)(tz_env) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("UTC0") + 1) - (size_t)(const void *
)("UTC0") == 1) || __s2_len >= 4)) ? __builtin_strcmp (tz_env
, "UTC0") : (__builtin_constant_p (tz_env) && ((size_t
)(const void *)((tz_env) + 1) - (size_t)(const void *)(tz_env
) == 1) && (__s1_len = __builtin_strlen (tz_env), __s1_len
< 4) ? (__builtin_constant_p ("UTC0") && ((size_t
)(const void *)(("UTC0") + 1) - (size_t)(const void *)("UTC0"
) == 1) ? __builtin_strcmp (tz_env, "UTC0") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("UTC0"); int __result = (((const unsigned char *) (const
char *) (tz_env))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tz_env))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tz_env))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tz_env))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("UTC0") && ((size_t)(const void *)(("UTC0") + 1) - (
size_t)(const void *)("UTC0") == 1) && (__s2_len = __builtin_strlen
("UTC0"), __s2_len < 4) ? (__builtin_constant_p (tz_env) &&
((size_t)(const void *)((tz_env) + 1) - (size_t)(const void *
)(tz_env) == 1) ? __builtin_strcmp (tz_env, "UTC0") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tz_env); int __result = (((const unsigned char *) (
const char *) ("UTC0"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("UTC0"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("UTC0"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("UTC0"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(tz_env, "UTC0")))); }) == 0)
)
3632 {
3633 /* Special case: using 'date -u' simply set TZ=UTC0 */
3634 tz_src = _("TZ=UTC0 environment value or -u")((const char *) ("TZ=UTC0 environment value or -u"));
3635 }
3636 else
3637 {
3638 snprintf (dbg_tm, sizeof(dbg_tm),
3639 _("TZ=\"%s\" environment value")((const char *) ("TZ=\"%s\" environment value")), tz_env);
3640 tz_src = dbg_tm;
3641 }
3642 }
3643 else
3644 {
3645 tz_src = _("system default")((const char *) ("system default"));
3646 }
3647
3648 if (pc.parse_datetime_debug)
3649 dbg_printf (_("input timezone: %+03d:%02d (set from %s)\n")((const char *) ("input timezone: %+03d:%02d (set from %s)\n"
))
,
3650 (int)(tz/60), abs ((int)tz)%60, tz_src);
3651
3652 }
3653
3654 if (pc.timespec_seen)
3655 *result = pc.seconds;
3656 else
3657 {
3658 if (1 < (pc.times_seen | pc.dates_seen | pc.days_seen | pc.dsts_seen
3659 | (pc.local_zones_seen + pc.zones_seen)))
3660 {
3661 if (pc.parse_datetime_debug)
3662 {
3663 if (pc.times_seen > 1)
3664 dbg_printf ("error: seen multiple time parts\n");
3665 if (pc.dates_seen > 1)
3666 dbg_printf ("error: seen multiple date parts\n");
3667 if (pc.days_seen > 1)
3668 dbg_printf ("error: seen multiple days parts\n");
3669 if (pc.dsts_seen > 1)
3670 dbg_printf ("error: seen multiple daylight-saving parts\n");
3671 if ( (pc.local_zones_seen + pc.zones_seen) > 1)
3672 dbg_printf ("error: seen multiple time-zone parts\n");
3673 }
3674 goto fail;
3675 }
3676
3677 tm.tm_year = to_year (pc.year, pc.parse_datetime_debug) - TM_YEAR_BASE1900;
3678 tm.tm_mon = pc.month - 1;
3679 tm.tm_mday = pc.day;
3680 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
3681 {
3682 tm.tm_hour = to_hour (pc.hour, pc.meridian);
3683 if (tm.tm_hour < 0)
3684 {
3685 const char* mrd = (pc.meridian==MERam)?"am":
3686 (pc.meridian==MERpm)?"pm":"";
3687 if (pc.parse_datetime_debug)
3688 dbg_printf (_("error: invalid hour %ld%s\n")((const char *) ("error: invalid hour %ld%s\n")), pc.hour, mrd);
3689
3690 goto fail;
3691 }
3692 tm.tm_min = pc.minutes;
3693 tm.tm_sec = pc.seconds.tv_sec;
3694 if (pc.parse_datetime_debug)
3695 dbg_printf (_("using %s time as starting value: '%s'\n")((const char *) ("using %s time as starting value: '%s'\n")),
3696 (pc.times_seen)?_("specified")((const char *) ("specified")):_("current")((const char *) ("current")),
3697 debug_strftime (&tm,dbg_tm,sizeof (dbg_tm)));
3698 }
3699 else
3700 {
3701 tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
3702 pc.seconds.tv_nsec = 0;
3703 if (pc.parse_datetime_debug)
3704 dbg_printf ("warning: using midnight as starting time: 00:00:00\n");
3705 }
3706
3707 /* Let mktime deduce tm_isdst if we have an absolute time stamp. */
3708 if (pc.dates_seen | pc.days_seen | pc.times_seen)
3709 tm.tm_isdst = -1;
3710
3711 /* But if the input explicitly specifies local time with or without
3712 DST, give mktime that information. */
3713 if (pc.local_zones_seen)
3714 tm.tm_isdst = pc.local_isdst;
3715
3716 tm0 = tm;
3717
3718 Start = mktimerpl_mktime (&tm);
3719
3720 if (! mktime_ok (&tm0, &tm, Start))
3721 {
3722 if (! pc.zones_seen)
3723 {
3724 debug_mktime_not_ok (&tm0, &tm, &pc, pc.zones_seen);
3725
3726 goto fail;
3727 }
3728 else
3729 {
3730 /* Guard against falsely reporting errors near the time_t
3731 boundaries when parsing times in other time zones. For
3732 example, suppose the input string "1969-12-31 23:00:00 -0100",
3733 the current time zone is 8 hours ahead of UTC, and the min
3734 time_t value is 1970-01-01 00:00:00 UTC. Then the min
3735 localtime value is 1970-01-01 08:00:00, and mktime will
3736 therefore fail on 1969-12-31 23:00:00. To work around the
3737 problem, set the time zone to 1 hour behind UTC temporarily
3738 by setting TZ="XXX1:00" and try mktime again. */
3739
3740 long int time_zone = pc.time_zone;
3741 long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
3742 long int abs_time_zone_hour = abs_time_zone / 60;
3743 int abs_time_zone_min = abs_time_zone % 60;
3744 char tz1buf[sizeof "XXX+0:00"
3745 + sizeof pc.time_zone * CHAR_BIT8 / 3];
3746 if (!tz_was_altered)
3747 tz0 = get_tz (tz0buf);
3748 sprintf (tz1buf, "XXX%s%ld:%02d", &"-"[time_zone < 0],
3749 abs_time_zone_hour, abs_time_zone_min);
3750 if (setenv ("TZ", tz1buf, 1) != 0)
3751 {
3752 /* TODO: was warn () + print errno? */
3753 if (pc.parse_datetime_debug)
3754 dbg_printf (_("error: setenv('TZ','%s') failed\n")((const char *) ("error: setenv('TZ','%s') failed\n")), tz1buf);
3755
3756 goto fail;
3757 }
3758 tz_was_altered = true1;
3759 tm = tm0;
3760 Start = mktimerpl_mktime (&tm);
3761 if (! mktime_ok (&tm0, &tm, Start))
3762 {
3763 debug_mktime_not_ok (&tm0, &tm, &pc, pc.zones_seen);
3764
3765 goto fail;
3766 }
3767 }
3768 }
3769
3770 if (pc.days_seen && ! pc.dates_seen)
3771 {
3772 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
3773 + 7 * (pc.day_ordinal
3774 - (0 < pc.day_ordinal
3775 && tm.tm_wday != pc.day_number)));
3776 tm.tm_isdst = -1;
3777 Start = mktimerpl_mktime (&tm);
3778 if (Start == (time_t) -1)
3779 {
3780 if (pc.parse_datetime_debug)
3781 dbg_printf (_("error: day '%s' (day ordinal=%ld number=%d) " \((const char *) ("error: day '%s' (day ordinal=%ld number=%d) "
"resulted in an invalid date: '%s'\n"))
3782 "resulted in an invalid date: '%s'\n")((const char *) ("error: day '%s' (day ordinal=%ld number=%d) "
"resulted in an invalid date: '%s'\n"))
,
3783 str_days (&pc,dbg_ord,sizeof (dbg_ord)),
3784 pc.day_ordinal,pc.day_number,
3785 debug_strfdatetime (&tm, &pc, dbg_tm,
3786 sizeof (dbg_tm)));
3787
3788 goto fail;
3789 }
3790
3791 if (pc.parse_datetime_debug)
3792 dbg_printf (_("new start date: '%s' is '%s'\n")((const char *) ("new start date: '%s' is '%s'\n")),
3793 str_days (&pc,dbg_ord,sizeof (dbg_ord)),
3794 debug_strfdatetime (&tm, &pc, dbg_tm,sizeof (dbg_tm)));
3795
3796 }
3797
3798 if (pc.parse_datetime_debug)
3799 {
3800 if (!pc.dates_seen && !pc.days_seen)
3801 dbg_printf (_("using current date as starting value: '%s'\n")((const char *) ("using current date as starting value: '%s'\n"
))
,
3802 debug_strfdate (&tm,dbg_tm,sizeof (dbg_tm)));
3803
3804 if (pc.days_seen && pc.dates_seen)
3805 dbg_printf (_("warning: day (%s) ignored when explicit dates " \((const char *) ("warning: day (%s) ignored when explicit dates "
"are given\n"))
3806 "are given\n")((const char *) ("warning: day (%s) ignored when explicit dates "
"are given\n"))
,
3807 str_days (&pc,dbg_ord,sizeof (dbg_ord)));
3808
3809 dbg_printf (_("starting date/time: '%s'\n")((const char *) ("starting date/time: '%s'\n")),
3810 debug_strfdatetime (&tm, &pc, dbg_tm,sizeof (dbg_tm)));
3811 }
3812
3813 /* Add relative date. */
3814 if (pc.rel.year | pc.rel.month | pc.rel.day)
3815 {
3816 if (pc.parse_datetime_debug)
3817 {
3818 if ((pc.rel.year != 0 || pc.rel.month !=0) && tm.tm_mday==1)
3819 dbg_printf (_("warning: when adding relative months/years, " \((const char *) ("warning: when adding relative months/years, "
"it is recommended to specify the 15th of the " "months\n"))
3820 "it is recommended to specify the 15th of the " \((const char *) ("warning: when adding relative months/years, "
"it is recommended to specify the 15th of the " "months\n"))
3821 "months\n")((const char *) ("warning: when adding relative months/years, "
"it is recommended to specify the 15th of the " "months\n"))
);
3822
3823 if (pc.rel.day != 0 && tm.tm_hour==0)
3824 dbg_printf (_("warning: when adding relative days, " \((const char *) ("warning: when adding relative days, " "it is recommended to specify 12:00pm\n"
))
3825 "it is recommended to specify 12:00pm\n")((const char *) ("warning: when adding relative days, " "it is recommended to specify 12:00pm\n"
))
);
3826 }
3827
3828 int year = tm.tm_year + pc.rel.year;
3829 int month = tm.tm_mon + pc.rel.month;
3830 int day = tm.tm_mday + pc.rel.day;
3831 if (((year < tm.tm_year) ^ (pc.rel.year < 0))
3832 | ((month < tm.tm_mon) ^ (pc.rel.month < 0))
3833 | ((day < tm.tm_mday) ^ (pc.rel.day < 0)))
3834 {
3835 /* TODO: what is the actual error? int-value wrap-around? */
3836 if (pc.parse_datetime_debug)
3837 dbg_printf (_("error: %s:%d\n")((const char *) ("error: %s:%d\n")), __FILE__"./parse-datetime.y",__LINE__2100);
3838
3839 goto fail;
3840 }
3841 tm.tm_year = year;
3842 tm.tm_mon = month;
3843 tm.tm_mday = day;
3844 tm.tm_hour = tm0.tm_hour;
3845 tm.tm_min = tm0.tm_min;
3846 tm.tm_sec = tm0.tm_sec;
3847 tm.tm_isdst = tm0.tm_isdst;
3848 Start = mktimerpl_mktime (&tm);
3849 if (Start == (time_t) -1)
3850 {
3851 if (pc.parse_datetime_debug)
3852 dbg_printf(_("error: adding relative date resulted " \((const char *) ("error: adding relative date resulted " "in an invalid date: '%s'\n"
))
3853 "in an invalid date: '%s'\n")((const char *) ("error: adding relative date resulted " "in an invalid date: '%s'\n"
))
,
3854 debug_strfdatetime (&tm, &pc, dbg_tm,
3855 sizeof (dbg_tm)));
3856
3857 goto fail;
3858 }
3859
3860 if (pc.parse_datetime_debug)
3861 {
3862 dbg_printf (_("after date adjustment " \((const char *) ("after date adjustment " "(%+ld years, %+ld months, %+ld days),\n"
))
3863 "(%+ld years, %+ld months, %+ld days),\n")((const char *) ("after date adjustment " "(%+ld years, %+ld months, %+ld days),\n"
))
,
3864 pc.rel.year, pc.rel.month, pc.rel.day);
3865 dbg_printf (_(" new date/time = '%s'\n")((const char *) (" new date/time = '%s'\n")),
3866 debug_strfdatetime (&tm, &pc, dbg_tm,
3867 sizeof (dbg_tm)));
3868 }
3869
3870 }
3871
3872 /* The only "output" of this if-block is an updated Start value,
3873 so this block must follow others that clobber Start. */
3874 if (pc.zones_seen)
3875 {
3876 long int delta = pc.time_zone * 60;
3877 time_t t1;
3878#ifdef HAVE_TM_GMTOFF1
3879 delta -= tm.tm_gmtoff;
3880#else
3881 time_t t = Start;
3882 struct tm const *gmt = gmtime (&t);
3883 if (! gmt)
3884 {
3885 /* TODO: use 'warn(3)' + print errno ? */
3886 if (pc.parse_datetime_debug)
3887 dbg_printf (_("error: gmtime failed for t=%ld\n")((const char *) ("error: gmtime failed for t=%ld\n")),t);
3888
3889 goto fail;
3890 }
3891 delta -= tm_diff (&tm, gmt);
3892#endif
3893 t1 = Start - delta;
3894 if ((Start < t1) != (delta < 0))
3895 {
3896 if (pc.parse_datetime_debug)
3897 dbg_printf (_("error: timezone %ld caused time_t overflow\n")((const char *) ("error: timezone %ld caused time_t overflow\n"
))
,
3898 pc.time_zone);
3899
3900 goto fail; /* time_t overflow */
3901 }
3902 Start = t1;
3903 }
3904
3905 if (pc.parse_datetime_debug)
3906 dbg_printf (_("'%s' = %ld epoch-seconds\n")((const char *) ("'%s' = %ld epoch-seconds\n")),
3907 debug_strfdatetime (&tm, &pc, dbg_tm, sizeof (dbg_tm)),
3908 Start);
3909
3910 /* Add relative hours, minutes, and seconds. On hosts that support
3911 leap seconds, ignore the possibility of leap seconds; e.g.,
3912 "+ 10 minutes" adds 600 seconds, even if one of them is a
3913 leap second. Typically this is not what the user wants, but it's
3914 too hard to do it the other way, because the time zone indicator
3915 must be applied before relative times, and if mktime is applied
3916 again the time zone will be lost. */
3917 {
3918 long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
3919 long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
3920 time_t t0 = Start;
3921 long int d1 = 60 * 60 * pc.rel.hour;
3922 time_t t1 = t0 + d1;
3923 long int d2 = 60 * pc.rel.minutes;
3924 time_t t2 = t1 + d2;
3925 long_time_t d3 = pc.rel.seconds;
3926 long_time_t t3 = t2 + d3;
3927 long int d4 = (sum_ns - normalized_ns) / BILLION;
3928 long_time_t t4 = t3 + d4;
3929 time_t t5 = t4;
3930
3931 if ((d1 / (60 * 60) ^ pc.rel.hour)
3932 | (d2 / 60 ^ pc.rel.minutes)
3933 | ((t1 < t0) ^ (d1 < 0))
3934 | ((t2 < t1) ^ (d2 < 0))
3935 | ((t3 < t2) ^ (d3 < 0))
3936 | ((t4 < t3) ^ (d4 < 0))
3937 | (t5 != t4))
3938 {
3939 if (pc.parse_datetime_debug)
3940 dbg_printf (_("error: adding relative time caused an " \((const char *) ("error: adding relative time caused an " "overflow\n"
))
3941 "overflow\n")((const char *) ("error: adding relative time caused an " "overflow\n"
))
);
3942
3943 goto fail;
3944 }
3945
3946 if (pc.parse_datetime_debug
3947 && (pc.rel.hour | pc.rel.minutes | pc.rel.seconds | pc.rel.ns))
3948 {
3949 dbg_printf (_("after time adjustment (%+ld hours, " \((const char *) ("after time adjustment (%+ld hours, " "%+ld minutes, %+ld seconds, %+ld ns),\n"
))
3950 "%+ld minutes, %+ld seconds, %+ld ns),\n")((const char *) ("after time adjustment (%+ld hours, " "%+ld minutes, %+ld seconds, %+ld ns),\n"
))
,
3951 pc.rel.hour,pc.rel.minutes,pc.rel.seconds,pc.rel.ns);
3952 dbg_printf (_(" new time = %ld epoch-seconds\n")((const char *) (" new time = %ld epoch-seconds\n")),t5);
3953 }
3954
3955 result->tv_sec = t5;
3956 result->tv_nsec = normalized_ns;
3957 }
3958 }
3959
3960 goto done;
3961
3962 fail:
3963 ok = false0;
3964 done:
3965 if (tz_was_altered)
3966 ok &= (tz0 ? setenv ("TZ", tz0, 1) : unsetenv ("TZ")) == 0;
3967 if (tz0 != tz0buf)
3968 free (tz0);
3969
3970 if (ok && pc.parse_datetime_debug)
3971 {
3972 /* print local timezone AFTER restoring TZ (if tz_was_altered)*/
3973 const long int otz = get_effective_timezone ();
3974 const char* tz_src;
3975 const char* tz_env;
3976
3977 if ((tz_env = getenv("TZ")))
3978 {
3979 /* Special case: using 'date -u' simply set TZ=UTC0 */
3980 if (STREQ(tz_env,"UTC0")(__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(tz_env) && __builtin_constant_p ("UTC0") &&
(__s1_len = __builtin_strlen (tz_env), __s2_len = __builtin_strlen
("UTC0"), (!((size_t)(const void *)((tz_env) + 1) - (size_t)
(const void *)(tz_env) == 1) || __s1_len >= 4) && (
!((size_t)(const void *)(("UTC0") + 1) - (size_t)(const void *
)("UTC0") == 1) || __s2_len >= 4)) ? __builtin_strcmp (tz_env
, "UTC0") : (__builtin_constant_p (tz_env) && ((size_t
)(const void *)((tz_env) + 1) - (size_t)(const void *)(tz_env
) == 1) && (__s1_len = __builtin_strlen (tz_env), __s1_len
< 4) ? (__builtin_constant_p ("UTC0") && ((size_t
)(const void *)(("UTC0") + 1) - (size_t)(const void *)("UTC0"
) == 1) ? __builtin_strcmp (tz_env, "UTC0") : (__extension__ (
{ const unsigned char *__s2 = (const unsigned char *) (const char
*) ("UTC0"); int __result = (((const unsigned char *) (const
char *) (tz_env))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tz_env))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (tz_env))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (tz_env))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("UTC0") && ((size_t)(const void *)(("UTC0") + 1) - (
size_t)(const void *)("UTC0") == 1) && (__s2_len = __builtin_strlen
("UTC0"), __s2_len < 4) ? (__builtin_constant_p (tz_env) &&
((size_t)(const void *)((tz_env) + 1) - (size_t)(const void *
)(tz_env) == 1) ? __builtin_strcmp (tz_env, "UTC0") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (tz_env); int __result = (((const unsigned char *) (
const char *) ("UTC0"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("UTC0"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("UTC0"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("UTC0"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(tz_env, "UTC0")))); }) == 0)
)
3981 {
3982 tz_src = _("TZ=UTC0 envionment value or -u")((const char *) ("TZ=UTC0 envionment value or -u"));
3983 }
3984 else
3985 {
3986 snprintf (dbg_tm, sizeof(dbg_tm),
3987 _("TZ=\"%s\" environment value")((const char *) ("TZ=\"%s\" environment value")), tz_env);
3988 tz_src = dbg_tm;
3989 }
3990 }
3991 else
3992 {
3993 tz_src = _("system default")((const char *) ("system default"));
3994 }
3995
3996 if (pc.parse_datetime_debug)
3997 {
3998 dbg_printf (_("output timezone: %+03d:%02d (set from %s)\n")((const char *) ("output timezone: %+03d:%02d (set from %s)\n"
))
,
3999 (int)(otz/60), abs ((int)otz)%60, tz_src);
4000
4001
4002 dbg_printf (_("final: %ld.%09ld (epoch-seconds)\n")((const char *) ("final: %ld.%09ld (epoch-seconds)\n")),
4003 result->tv_sec,result->tv_nsec);
4004
4005 struct tm const *gmt = gmtime (&result->tv_sec);
4006 dbg_printf (_("final: %s (UTC0)\n")((const char *) ("final: %s (UTC0)\n")),
4007 debug_strfdatetime (gmt, NULL((void*)0), dbg_tm, sizeof (dbg_tm)));
4008 struct tm const *lmt = localtime (&result->tv_sec);
4009 dbg_printf (_("final: %s (output timezone TZ=%+03d:%02d)\n")((const char *) ("final: %s (output timezone TZ=%+03d:%02d)\n"
))
,
4010 debug_strfdatetime (lmt, NULL((void*)0), dbg_tm, sizeof (dbg_tm)),
4011 (int)(otz/60), abs ((int)otz)%60);
4012 }
4013 }
4014
4015 return ok;
4016}
4017
4018#if TEST
4019
4020int
4021main (int ac, char **av)
4022{
4023 char buff[BUFSIZ8192];
4024
4025 printf ("Enter date, or blank line to exit.\n\t> ");
4026 fflush (stdoutstdout);
4027
4028 buff[BUFSIZ8192 - 1] = '\0';
4029 while (fgets (buff, BUFSIZ8192 - 1, stdinstdin) && buff[0])
4030 {
4031 struct timespec d;
4032 struct tm const *tm;
4033 if (! parse_datetime (&d, buff, NULL((void*)0)))
4034 printf ("Bad format - couldn't convert.\n");
4035 else if (! (tm = localtime (&d.tv_sec)))
4036 {
4037 long int sec = d.tv_sec;
4038 printf ("localtime (%ld) failed\n", sec);
4039 }
4040 else
4041 {
4042 int ns = d.tv_nsec;
4043 printf ("%04ld-%02d-%02d %02d:%02d:%02d.%09d\n",
4044 tm->tm_year + 1900L, tm->tm_mon + 1, tm->tm_mday,
4045 tm->tm_hour, tm->tm_min, tm->tm_sec, ns);
4046 }
4047 printf ("\t> ");
4048 fflush (stdoutstdout);
4049 }
4050 return 0;
4051}
4052#endif /* TEST */