1
/* A Bison parser, made by GNU Bison 1.875a. */
3
/* Skeleton parser for Yacc-like parsing with Bison,
4
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 59 Temple Place - Suite 330,
19
Boston, MA 02111-1307, USA. */
21
/* As a special exception, when this file is copied by Bison into a
22
Bison output file, you may use that output file without restriction.
23
This special exception was added by the Free Software Foundation
24
in version 1.24 of Bison. */
26
/* Written by Richard Stallman by simplifying the original so called
27
``semantic'' parser. */
29
/* All symbols defined below should begin with yy or YY, to avoid
30
infringing on user name space. This should be done even for local
31
variables, as they might otherwise be expanded by user macros.
32
There are some unavoidable exceptions within include files to
33
define necessary library symbols; they are noted "INFRINGES ON
34
USER NAME SPACE" below. */
36
/* Identify Bison output. */
40
#define YYSKELETON_NAME "yacc.c"
45
/* Using locations. */
46
#define YYLSP_NEEDED 0
53
/* Put the tokens into the symbol table, so that GDB and other debuggers
79
#define tHOUR_UNIT 263
80
#define tLOCAL_ZONE 264
82
#define tMINUTE_UNIT 266
84
#define tMONTH_UNIT 268
86
#define tYEAR_UNIT 270
94
/* Copy the first part of user declarations. */
97
/* Parse a string into an internal time stamp.
98
Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc.
100
This program is free software; you can redistribute it and/or modify
101
it under the terms of the GNU General Public License as published by
102
the Free Software Foundation; either version 2, or (at your option)
105
This program is distributed in the hope that it will be useful,
106
but WITHOUT ANY WARRANTY; without even the implied warranty of
107
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
108
GNU General Public License for more details.
110
You should have received a copy of the GNU General Public License
111
along with this program; if not, write to the Free Software Foundation,
112
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
114
/* Originally written by Steven M. Bellovin <smb@research.att.com> while
115
at the University of North Carolina at Chapel Hill. Later tweaked by
116
a couple of people on Usenet. Completely overhauled by Rich $alz
117
<rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
119
Modified by Paul Eggert <eggert@twinsun.com> in August 1999 to do
120
the right thing about local DST. Unlike previous versions, this
121
version is reentrant. */
125
# ifdef HAVE_ALLOCA_H
130
/* Since the code of getdate.y is not included in the Emacs executable
131
itself, there is no need to #define static in this file. Even if
132
the code were included in the Emacs executable, it probably
133
wouldn't do any harm to #undef it here; this will only cause
134
problems if we try to write to a static variable, which I don't
135
think this code needs to do. */
144
# include <stdlib.h> /* for `free'; used by Bison 1.27 */
147
#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
148
# define IN_CTYPE_DOMAIN(c) 1
150
# define IN_CTYPE_DOMAIN(c) isascii (c)
153
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
154
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
155
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
156
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
158
/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
159
- Its arg may be any int or unsigned int; it need not be an unsigned char.
160
- It's guaranteed to evaluate its argument exactly once.
161
- It's typically faster.
162
POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
163
ISDIGIT_LOCALE unless it's important to use the locale's definition
164
of `digit' even when the host does not conform to POSIX. */
165
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
167
#if STDC_HEADERS || HAVE_STRING_H
171
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
172
# define __attribute__(x)
175
#ifndef ATTRIBUTE_UNUSED
176
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
179
#define EPOCH_YEAR 1970
180
#define TM_YEAR_BASE 1900
182
#define HOUR(x) ((x) * 60)
184
/* An integer value, and the number of digits in its textual
192
/* An entry in the lexical lookup table. */
200
/* Meridian: am, pm, or 24-hour style. */
201
enum { MERam, MERpm, MER24 };
203
/* Information passed to and from the parser. */
206
/* The input string remaining to be parsed. */
209
/* N, if this is the Nth Tuesday. */
212
/* Day of week; Sunday is 0. */
215
/* tm_isdst flag for the local zone. */
218
/* Time zone, in minutes east of UTC. */
221
/* Style used for time. */
224
/* Gregorian year, month, day, hour, minutes, and seconds. */
232
/* Relative year, month, day, hour, minutes, and seconds. */
240
/* Counts of nonterminals of various flavors parsed so far. */
243
int local_zones_seen;
248
/* Table of local time zone abbrevations, terminated by a null entry. */
249
table local_time_zone_table[3];
252
#define PC (* (parser_control *) parm)
253
#define YYLEX_PARAM parm
254
#define YYPARSE_PARAM parm
256
static int yyerror ();
261
/* Enabling traces. */
266
/* Enabling verbose error messages. */
267
#ifdef YYERROR_VERBOSE
268
# undef YYERROR_VERBOSE
269
# define YYERROR_VERBOSE 1
271
# define YYERROR_VERBOSE 0
274
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
275
#line 172 "getdate.y"
276
typedef union YYSTYPE {
280
/* Line 191 of yacc.c. */
281
#line 281 "getdate.c"
282
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
283
# define YYSTYPE_IS_DECLARED 1
284
# define YYSTYPE_IS_TRIVIAL 1
289
/* Copy the second part of user declarations. */
292
/* Line 214 of yacc.c. */
293
#line 293 "getdate.c"
295
#if ! defined (yyoverflow) || YYERROR_VERBOSE
297
/* The parser invokes alloca or malloc; define the necessary symbols. */
299
# if YYSTACK_USE_ALLOCA
300
# define YYSTACK_ALLOC alloca
302
# ifndef YYSTACK_USE_ALLOCA
303
# if defined (alloca) || defined (_ALLOCA_H)
304
# define YYSTACK_ALLOC alloca
307
# define YYSTACK_ALLOC __builtin_alloca
313
# ifdef YYSTACK_ALLOC
314
/* Pacify GCC's `empty if-body' warning. */
315
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
317
# if defined (__STDC__) || defined (__cplusplus)
318
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
319
# define YYSIZE_T size_t
321
# define YYSTACK_ALLOC malloc
322
# define YYSTACK_FREE free
324
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
327
#if (! defined (yyoverflow) \
328
&& (! defined (__cplusplus) \
329
|| (YYSTYPE_IS_TRIVIAL)))
331
/* A type that is properly aligned for any stack member. */
338
/* The size of the maximum gap between one aligned stack and the next. */
339
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
341
/* The size of an array large to enough to hold all stacks, each with
343
# define YYSTACK_BYTES(N) \
344
((N) * (sizeof (short) + sizeof (YYSTYPE)) \
345
+ YYSTACK_GAP_MAXIMUM)
347
/* Copy COUNT objects from FROM to TO. The source and destination do
351
# define YYCOPY(To, From, Count) \
352
__builtin_memcpy (To, From, (Count) * sizeof (*(From)))
354
# define YYCOPY(To, From, Count) \
357
register YYSIZE_T yyi; \
358
for (yyi = 0; yyi < (Count); yyi++) \
359
(To)[yyi] = (From)[yyi]; \
365
/* Relocate STACK from its old location to the new one. The
366
local variables YYSIZE and YYSTACKSIZE give the old and new number of
367
elements in the stack, and YYPTR gives the new location of the
368
stack. Advance YYPTR to a properly aligned location for the next
370
# define YYSTACK_RELOCATE(Stack) \
373
YYSIZE_T yynewbytes; \
374
YYCOPY (&yyptr->Stack, Stack, yysize); \
375
Stack = &yyptr->Stack; \
376
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
377
yyptr += yynewbytes / sizeof (*yyptr); \
383
#if defined (__STDC__) || defined (__cplusplus)
384
typedef signed char yysigned_char;
386
typedef short yysigned_char;
389
/* YYFINAL -- State number of the termination state. */
391
/* YYLAST -- Last index in YYTABLE. */
394
/* YYNTOKENS -- Number of terminals. */
396
/* YYNNTS -- Number of nonterminals. */
398
/* YYNRULES -- Number of rules. */
400
/* YYNRULES -- Number of states. */
403
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
405
#define YYMAXUTOK 273
407
#define YYTRANSLATE(YYX) \
408
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
410
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
411
static const unsigned char yytranslate[] =
413
0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
415
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
416
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
417
2, 2, 2, 2, 20, 2, 2, 21, 2, 2,
418
2, 2, 2, 2, 2, 2, 2, 2, 19, 2,
419
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
420
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
423
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
428
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
432
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
433
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
436
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
437
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
438
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
439
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
444
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
446
static const unsigned char yyprhs[] =
448
0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
449
19, 21, 24, 29, 34, 41, 48, 50, 53, 55,
450
57, 60, 62, 65, 68, 72, 78, 82, 86, 89,
451
94, 97, 101, 104, 106, 109, 112, 114, 117, 120,
452
122, 125, 128, 130, 133, 136, 138, 141, 144, 146,
453
149, 152, 154, 156, 157
456
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
457
static const yysigned_char yyrhs[] =
459
23, 0, -1, -1, 23, 24, -1, 25, -1, 26,
460
-1, 27, -1, 29, -1, 28, -1, 30, -1, 32,
461
-1, 18, 10, -1, 18, 19, 18, 33, -1, 18,
462
19, 18, 17, -1, 18, 19, 18, 19, 18, 33,
463
-1, 18, 19, 18, 19, 18, 17, -1, 9, -1,
464
9, 4, -1, 16, -1, 7, -1, 16, 4, -1,
465
5, -1, 5, 20, -1, 18, 5, -1, 18, 21,
466
18, -1, 18, 21, 18, 21, 18, -1, 18, 17,
467
17, -1, 18, 12, 17, -1, 12, 18, -1, 12,
468
18, 20, 18, -1, 18, 12, -1, 18, 12, 18,
469
-1, 31, 3, -1, 31, -1, 18, 15, -1, 17,
470
15, -1, 15, -1, 18, 13, -1, 17, 13, -1,
471
13, -1, 18, 6, -1, 17, 6, -1, 6, -1,
472
18, 8, -1, 17, 8, -1, 8, -1, 18, 11,
473
-1, 17, 11, -1, 11, -1, 18, 14, -1, 17,
474
14, -1, 14, -1, 18, -1, -1, 10, -1
477
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
478
static const unsigned short yyrline[] =
480
0, 188, 188, 190, 194, 196, 198, 200, 202, 204,
481
206, 210, 217, 224, 232, 239, 251, 253, 258, 260,
482
262, 267, 272, 277, 285, 290, 310, 317, 325, 330,
483
336, 341, 350, 359, 363, 365, 367, 369, 371, 373,
484
375, 377, 379, 381, 383, 385, 387, 389, 391, 393,
485
395, 397, 402, 439, 440
489
#if YYDEBUG || YYERROR_VERBOSE
490
/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
491
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
492
static const char *const yytname[] =
494
"$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT",
495
"tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT",
496
"tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER",
497
"tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time",
498
"local_zone", "zone", "day", "date", "rel", "relunit", "number",
504
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
506
static const unsigned short yytoknum[] =
508
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
509
265, 266, 267, 268, 269, 270, 271, 272, 273, 58,
514
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
515
static const unsigned char yyr1[] =
517
0, 22, 23, 23, 24, 24, 24, 24, 24, 24,
518
24, 25, 25, 25, 25, 25, 26, 26, 27, 27,
519
27, 28, 28, 28, 29, 29, 29, 29, 29, 29,
520
29, 29, 30, 30, 31, 31, 31, 31, 31, 31,
521
31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
525
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
526
static const unsigned char yyr2[] =
528
0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
529
1, 2, 4, 4, 6, 6, 1, 2, 1, 1,
530
2, 1, 2, 2, 3, 5, 3, 3, 2, 4,
531
2, 3, 2, 1, 2, 2, 1, 2, 2, 1,
532
2, 2, 1, 2, 2, 1, 2, 2, 1, 2,
536
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
537
STATE-NUM when YYTABLE doesn't specify something else to do. Zero
538
means the default is an error. */
539
static const unsigned char yydefact[] =
541
2, 0, 1, 21, 42, 19, 45, 16, 48, 0,
542
39, 51, 36, 18, 0, 52, 3, 4, 5, 6,
543
8, 7, 9, 33, 10, 22, 17, 28, 20, 41,
544
44, 47, 38, 50, 35, 23, 40, 43, 11, 46,
545
30, 37, 49, 34, 0, 0, 0, 32, 0, 27,
546
31, 26, 53, 24, 29, 54, 13, 0, 12, 0,
550
/* YYDEFGOTO[NTERM-NUM]. */
551
static const yysigned_char yydefgoto[] =
553
-1, 1, 16, 17, 18, 19, 20, 21, 22, 23,
557
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
559
#define YYPACT_NINF -17
560
static const yysigned_char yypact[] =
562
-17, 0, -17, 1, -17, -17, -17, 19, -17, -14,
563
-17, -17, -17, 32, 26, 14, -17, -17, -17, -17,
564
-17, -17, -17, 27, -17, -17, -17, 22, -17, -17,
565
-17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
566
-16, -17, -17, -17, 29, 25, 30, -17, 31, -17,
567
-17, -17, 28, 23, -17, -17, -17, 33, -17, 34,
571
/* YYPGOTO[NTERM-NUM]. */
572
static const yysigned_char yypgoto[] =
574
-17, -17, -17, -17, -17, -17, -17, -17, -17, -17,
578
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
579
positive, shift that token. If negative, reduce the rule which
580
number is the opposite. If zero, do what YYDEFACT says.
581
If YYTABLE_NINF, syntax error. */
582
#define YYTABLE_NINF -1
583
static const unsigned char yytable[] =
585
2, 49, 50, 55, 27, 3, 4, 5, 6, 7,
586
62, 8, 9, 10, 11, 12, 13, 14, 15, 35,
587
36, 25, 37, 26, 38, 39, 40, 41, 42, 43,
588
47, 44, 29, 45, 30, 46, 28, 31, 55, 32,
589
33, 34, 48, 52, 59, 56, 51, 57, 53, 54,
593
static const unsigned char yycheck[] =
595
0, 17, 18, 10, 18, 5, 6, 7, 8, 9,
596
17, 11, 12, 13, 14, 15, 16, 17, 18, 5,
597
6, 20, 8, 4, 10, 11, 12, 13, 14, 15,
598
3, 17, 6, 19, 8, 21, 4, 11, 10, 13,
599
14, 15, 20, 18, 21, 17, 17, 19, 18, 18,
603
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
604
symbol of state STATE-NUM. */
605
static const unsigned char yystos[] =
607
0, 23, 0, 5, 6, 7, 8, 9, 11, 12,
608
13, 14, 15, 16, 17, 18, 24, 25, 26, 27,
609
28, 29, 30, 31, 32, 20, 4, 18, 4, 6,
610
8, 11, 13, 14, 15, 5, 6, 8, 10, 11,
611
12, 13, 14, 15, 17, 19, 21, 3, 20, 17,
612
18, 17, 18, 18, 18, 10, 17, 19, 33, 21,
616
#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
617
# define YYSIZE_T __SIZE_TYPE__
619
#if ! defined (YYSIZE_T) && defined (size_t)
620
# define YYSIZE_T size_t
622
#if ! defined (YYSIZE_T)
623
# if defined (__STDC__) || defined (__cplusplus)
624
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
625
# define YYSIZE_T size_t
628
#if ! defined (YYSIZE_T)
629
# define YYSIZE_T unsigned int
632
#define yyerrok (yyerrstatus = 0)
633
#define yyclearin (yychar = YYEMPTY)
637
#define YYACCEPT goto yyacceptlab
638
#define YYABORT goto yyabortlab
639
#define YYERROR goto yyerrlab1
642
/* Like YYERROR except do call yyerror. This remains here temporarily
643
to ease the transition to the new meaning of YYERROR, for GCC.
644
Once GCC version 2 has supplanted version 1, this can go. */
646
#define YYFAIL goto yyerrlab
648
#define YYRECOVERING() (!!yyerrstatus)
650
#define YYBACKUP(Token, Value) \
652
if (yychar == YYEMPTY && yylen == 1) \
656
yytoken = YYTRANSLATE (yychar); \
662
yyerror ("syntax error: cannot back up");\
668
#define YYERRCODE 256
670
/* YYLLOC_DEFAULT -- Compute the default location (before the actions
673
#ifndef YYLLOC_DEFAULT
674
# define YYLLOC_DEFAULT(Current, Rhs, N) \
675
Current.first_line = Rhs[1].first_line; \
676
Current.first_column = Rhs[1].first_column; \
677
Current.last_line = Rhs[N].last_line; \
678
Current.last_column = Rhs[N].last_column;
681
/* YYLEX -- calling `yylex' with the right arguments. */
684
# define YYLEX yylex (&yylval, YYLEX_PARAM)
686
# define YYLEX yylex (&yylval)
689
/* Enable debugging if requested. */
693
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
694
# define YYFPRINTF fprintf
697
# define YYDPRINTF(Args) \
703
# define YYDSYMPRINT(Args) \
709
# define YYDSYMPRINTF(Title, Token, Value, Location) \
713
YYFPRINTF (stderr, "%s ", Title); \
714
yysymprint (stderr, \
716
YYFPRINTF (stderr, "\n"); \
720
/*------------------------------------------------------------------.
721
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
723
`------------------------------------------------------------------*/
725
#if defined (__STDC__) || defined (__cplusplus)
727
yy_stack_print (short *bottom, short *top)
730
yy_stack_print (bottom, top)
735
YYFPRINTF (stderr, "Stack now");
736
for (/* Nothing. */; bottom <= top; ++bottom)
737
YYFPRINTF (stderr, " %d", *bottom);
738
YYFPRINTF (stderr, "\n");
741
# define YY_STACK_PRINT(Bottom, Top) \
744
yy_stack_print ((Bottom), (Top)); \
748
/*------------------------------------------------.
749
| Report that the YYRULE is going to be reduced. |
750
`------------------------------------------------*/
752
#if defined (__STDC__) || defined (__cplusplus)
754
yy_reduce_print (int yyrule)
757
yy_reduce_print (yyrule)
762
unsigned int yylineno = yyrline[yyrule];
763
YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
764
yyrule - 1, yylineno);
765
/* Print the symbols being reduced, and their result. */
766
for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
767
YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
768
YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
771
# define YY_REDUCE_PRINT(Rule) \
774
yy_reduce_print (Rule); \
777
/* Nonzero means print parse trace. It is left uninitialized so that
778
multiple parsers can coexist. */
781
# define YYDPRINTF(Args)
782
# define YYDSYMPRINT(Args)
783
# define YYDSYMPRINTF(Title, Token, Value, Location)
784
# define YY_STACK_PRINT(Bottom, Top)
785
# define YY_REDUCE_PRINT(Rule)
786
#endif /* !YYDEBUG */
789
/* YYINITDEPTH -- initial size of the parser's stacks. */
791
# define YYINITDEPTH 200
794
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
795
if the built-in stack extension method is used).
797
Do not make this value too large; the results are undefined if
798
SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
799
evaluated with infinite-precision integer arithmetic. */
806
# define YYMAXDEPTH 10000
814
# if defined (__GLIBC__) && defined (_STRING_H)
815
# define yystrlen strlen
817
/* Return the length of YYSTR. */
819
# if defined (__STDC__) || defined (__cplusplus)
820
yystrlen (const char *yystr)
826
register const char *yys = yystr;
828
while (*yys++ != '\0')
831
return yys - yystr - 1;
837
# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
838
# define yystpcpy stpcpy
840
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
843
# if defined (__STDC__) || defined (__cplusplus)
844
yystpcpy (char *yydest, const char *yysrc)
846
yystpcpy (yydest, yysrc)
851
register char *yyd = yydest;
852
register const char *yys = yysrc;
854
while ((*yyd++ = *yys++) != '\0')
862
#endif /* !YYERROR_VERBOSE */
867
/*--------------------------------.
868
| Print this symbol on YYOUTPUT. |
869
`--------------------------------*/
871
#if defined (__STDC__) || defined (__cplusplus)
873
yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
876
yysymprint (yyoutput, yytype, yyvaluep)
882
/* Pacify ``unused variable'' warnings. */
885
if (yytype < YYNTOKENS)
887
YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
889
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
893
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
900
YYFPRINTF (yyoutput, ")");
903
#endif /* ! YYDEBUG */
904
/*-----------------------------------------------.
905
| Release the memory associated to this symbol. |
906
`-----------------------------------------------*/
908
#if defined (__STDC__) || defined (__cplusplus)
910
yydestruct (int yytype, YYSTYPE *yyvaluep)
913
yydestruct (yytype, yyvaluep)
918
/* Pacify ``unused variable'' warnings. */
930
/* Prevent warnings from -Wmissing-prototypes. */
933
# if defined (__STDC__) || defined (__cplusplus)
934
int yyparse (void *YYPARSE_PARAM);
938
#else /* ! YYPARSE_PARAM */
939
#if defined (__STDC__) || defined (__cplusplus)
944
#endif /* ! YYPARSE_PARAM */
956
# if defined (__STDC__) || defined (__cplusplus)
957
int yyparse (void *YYPARSE_PARAM)
959
int yyparse (YYPARSE_PARAM)
962
#else /* ! YYPARSE_PARAM */
963
#if defined (__STDC__) || defined (__cplusplus)
973
/* The lookahead symbol. */
976
/* The semantic value of the lookahead symbol. */
979
/* Number of syntax errors so far. */
982
register int yystate;
985
/* Number of tokens to shift before error messages enabled. */
987
/* Lookahead token as an internal (translated) token number. */
990
/* Three stacks and their tools:
991
`yyss': related to states,
992
`yyvs': related to semantic values,
993
`yyls': related to locations.
995
Refer to the stacks thru separate pointers, to allow yyoverflow
996
to reallocate them elsewhere. */
998
/* The state stack. */
999
short yyssa[YYINITDEPTH];
1000
short *yyss = yyssa;
1001
register short *yyssp;
1003
/* The semantic value stack. */
1004
YYSTYPE yyvsa[YYINITDEPTH];
1005
YYSTYPE *yyvs = yyvsa;
1006
register YYSTYPE *yyvsp;
1010
#define YYPOPSTACK (yyvsp--, yyssp--)
1012
YYSIZE_T yystacksize = YYINITDEPTH;
1014
/* The variables used to return semantic value and location from the
1019
/* When reducing, the number of symbols on the RHS of the reduced
1023
YYDPRINTF ((stderr, "Starting parse\n"));
1028
yychar = YYEMPTY; /* Cause a token to be read. */
1030
/* Initialize stack pointers.
1031
Waste one element of value and location stack
1032
so that they stay on the same level as the state stack.
1033
The wasted elements are never initialized. */
1040
/*------------------------------------------------------------.
1041
| yynewstate -- Push a new state, which is found in yystate. |
1042
`------------------------------------------------------------*/
1044
/* In all cases, when you get here, the value and location stacks
1045
have just been pushed. so pushing a state here evens the stacks.
1052
if (yyss + yystacksize - 1 <= yyssp)
1054
/* Get the current used size of the three stacks, in elements. */
1055
YYSIZE_T yysize = yyssp - yyss + 1;
1059
/* Give user a chance to reallocate the stack. Use copies of
1060
these so that the &'s don't force the real ones into
1062
YYSTYPE *yyvs1 = yyvs;
1063
short *yyss1 = yyss;
1066
/* Each stack pointer address is followed by the size of the
1067
data in use in that stack, in bytes. This used to be a
1068
conditional around just the two extra args, but that might
1069
be undefined if yyoverflow is a macro. */
1070
yyoverflow ("parser stack overflow",
1071
&yyss1, yysize * sizeof (*yyssp),
1072
&yyvs1, yysize * sizeof (*yyvsp),
1079
#else /* no yyoverflow */
1080
# ifndef YYSTACK_RELOCATE
1083
/* Extend the stack our own way. */
1084
if (YYMAXDEPTH <= yystacksize)
1087
if (YYMAXDEPTH < yystacksize)
1088
yystacksize = YYMAXDEPTH;
1091
short *yyss1 = yyss;
1092
union yyalloc *yyptr =
1093
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1096
YYSTACK_RELOCATE (yyss);
1097
YYSTACK_RELOCATE (yyvs);
1099
# undef YYSTACK_RELOCATE
1101
YYSTACK_FREE (yyss1);
1104
#endif /* no yyoverflow */
1106
yyssp = yyss + yysize - 1;
1107
yyvsp = yyvs + yysize - 1;
1110
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1111
(unsigned long int) yystacksize));
1113
if (yyss + yystacksize - 1 <= yyssp)
1117
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1126
/* Do appropriate processing given the current state. */
1127
/* Read a lookahead token if we need one and don't already have one. */
1130
/* First try to decide what to do without reference to lookahead token. */
1132
yyn = yypact[yystate];
1133
if (yyn == YYPACT_NINF)
1136
/* Not known => get a lookahead token if don't already have one. */
1138
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1139
if (yychar == YYEMPTY)
1141
YYDPRINTF ((stderr, "Reading a token: "));
1145
if (yychar <= YYEOF)
1147
yychar = yytoken = YYEOF;
1148
YYDPRINTF ((stderr, "Now at end of input.\n"));
1152
yytoken = YYTRANSLATE (yychar);
1153
YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1156
/* If the proper action on seeing token YYTOKEN is to reduce or to
1157
detect an error, take that action. */
1159
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1164
if (yyn == 0 || yyn == YYTABLE_NINF)
1173
/* Shift the lookahead token. */
1174
YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1176
/* Discard the token being shifted unless it is eof. */
1177
if (yychar != YYEOF)
1183
/* Count tokens shifted since error; after three, turn off error
1192
/*-----------------------------------------------------------.
1193
| yydefault -- do the default action for the current state. |
1194
`-----------------------------------------------------------*/
1196
yyn = yydefact[yystate];
1202
/*-----------------------------.
1203
| yyreduce -- Do a reduction. |
1204
`-----------------------------*/
1206
/* yyn is the number of a rule to reduce with. */
1209
/* If YYLEN is nonzero, implement the default value of the action:
1212
Otherwise, the following line sets YYVAL to garbage.
1213
This behavior is undocumented and Bison
1214
users should not rely upon it. Assigning to YYVAL
1215
unconditionally makes the parser a bit smaller, and it avoids a
1216
GCC warning that YYVAL may be used uninitialized. */
1217
yyval = yyvsp[1-yylen];
1220
YY_REDUCE_PRINT (yyn);
1224
#line 195 "getdate.y"
1225
{ PC.times_seen++; }
1229
#line 197 "getdate.y"
1230
{ PC.local_zones_seen++; }
1234
#line 199 "getdate.y"
1235
{ PC.zones_seen++; }
1239
#line 201 "getdate.y"
1240
{ PC.dates_seen++; }
1244
#line 203 "getdate.y"
1249
#line 205 "getdate.y"
1254
#line 211 "getdate.y"
1256
PC.hour = yyvsp[-1].textintval.value;
1259
PC.meridian = yyvsp[0].intval;
1264
#line 218 "getdate.y"
1266
PC.hour = yyvsp[-3].textintval.value;
1267
PC.minutes = yyvsp[-1].textintval.value;
1269
PC.meridian = yyvsp[0].intval;
1274
#line 225 "getdate.y"
1276
PC.hour = yyvsp[-3].textintval.value;
1277
PC.minutes = yyvsp[-1].textintval.value;
1278
PC.meridian = MER24;
1280
PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1285
#line 233 "getdate.y"
1287
PC.hour = yyvsp[-5].textintval.value;
1288
PC.minutes = yyvsp[-3].textintval.value;
1289
PC.seconds = yyvsp[-1].textintval.value;
1290
PC.meridian = yyvsp[0].intval;
1295
#line 240 "getdate.y"
1297
PC.hour = yyvsp[-5].textintval.value;
1298
PC.minutes = yyvsp[-3].textintval.value;
1299
PC.seconds = yyvsp[-1].textintval.value;
1300
PC.meridian = MER24;
1302
PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60;
1307
#line 252 "getdate.y"
1308
{ PC.local_isdst = yyvsp[0].intval; }
1312
#line 254 "getdate.y"
1313
{ PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; }
1317
#line 259 "getdate.y"
1318
{ PC.time_zone = yyvsp[0].intval; }
1322
#line 261 "getdate.y"
1323
{ PC.time_zone = yyvsp[0].intval + 60; }
1327
#line 263 "getdate.y"
1328
{ PC.time_zone = yyvsp[-1].intval + 60; }
1332
#line 268 "getdate.y"
1335
PC.day_number = yyvsp[0].intval;
1340
#line 273 "getdate.y"
1343
PC.day_number = yyvsp[-1].intval;
1348
#line 278 "getdate.y"
1350
PC.day_ordinal = yyvsp[-1].textintval.value;
1351
PC.day_number = yyvsp[0].intval;
1356
#line 286 "getdate.y"
1358
PC.month = yyvsp[-2].textintval.value;
1359
PC.day = yyvsp[0].textintval.value;
1364
#line 291 "getdate.y"
1366
/* Interpret as YYYY/MM/DD if the first value has 4 or more digits,
1367
otherwise as MM/DD/YY.
1368
The goal in recognizing YYYY/MM/DD is solely to support legacy
1369
machine-generated dates like those in an RCS log listing. If
1370
you want portability, use the ISO 8601 format. */
1371
if (4 <= yyvsp[-4].textintval.digits)
1373
PC.year = yyvsp[-4].textintval;
1374
PC.month = yyvsp[-2].textintval.value;
1375
PC.day = yyvsp[0].textintval.value;
1379
PC.month = yyvsp[-4].textintval.value;
1380
PC.day = yyvsp[-2].textintval.value;
1381
PC.year = yyvsp[0].textintval;
1387
#line 311 "getdate.y"
1389
/* ISO 8601 format. YYYY-MM-DD. */
1390
PC.year = yyvsp[-2].textintval;
1391
PC.month = -yyvsp[-1].textintval.value;
1392
PC.day = -yyvsp[0].textintval.value;
1397
#line 318 "getdate.y"
1399
/* e.g. 17-JUN-1992. */
1400
PC.day = yyvsp[-2].textintval.value;
1401
PC.month = yyvsp[-1].intval;
1402
PC.year.value = -yyvsp[0].textintval.value;
1403
PC.year.digits = yyvsp[0].textintval.digits;
1408
#line 326 "getdate.y"
1410
PC.month = yyvsp[-1].intval;
1411
PC.day = yyvsp[0].textintval.value;
1416
#line 331 "getdate.y"
1418
PC.month = yyvsp[-3].intval;
1419
PC.day = yyvsp[-2].textintval.value;
1420
PC.year = yyvsp[0].textintval;
1425
#line 337 "getdate.y"
1427
PC.day = yyvsp[-1].textintval.value;
1428
PC.month = yyvsp[0].intval;
1433
#line 342 "getdate.y"
1435
PC.day = yyvsp[-2].textintval.value;
1436
PC.month = yyvsp[-1].intval;
1437
PC.year = yyvsp[0].textintval;
1442
#line 351 "getdate.y"
1444
PC.rel_seconds = -PC.rel_seconds;
1445
PC.rel_minutes = -PC.rel_minutes;
1446
PC.rel_hour = -PC.rel_hour;
1447
PC.rel_day = -PC.rel_day;
1448
PC.rel_month = -PC.rel_month;
1449
PC.rel_year = -PC.rel_year;
1454
#line 364 "getdate.y"
1455
{ PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1459
#line 366 "getdate.y"
1460
{ PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1464
#line 368 "getdate.y"
1465
{ PC.rel_year += yyvsp[0].intval; }
1469
#line 370 "getdate.y"
1470
{ PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1474
#line 372 "getdate.y"
1475
{ PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1479
#line 374 "getdate.y"
1480
{ PC.rel_month += yyvsp[0].intval; }
1484
#line 376 "getdate.y"
1485
{ PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1489
#line 378 "getdate.y"
1490
{ PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1494
#line 380 "getdate.y"
1495
{ PC.rel_day += yyvsp[0].intval; }
1499
#line 382 "getdate.y"
1500
{ PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1504
#line 384 "getdate.y"
1505
{ PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1509
#line 386 "getdate.y"
1510
{ PC.rel_hour += yyvsp[0].intval; }
1514
#line 388 "getdate.y"
1515
{ PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1519
#line 390 "getdate.y"
1520
{ PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1524
#line 392 "getdate.y"
1525
{ PC.rel_minutes += yyvsp[0].intval; }
1529
#line 394 "getdate.y"
1530
{ PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1534
#line 396 "getdate.y"
1535
{ PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; }
1539
#line 398 "getdate.y"
1540
{ PC.rel_seconds += yyvsp[0].intval; }
1544
#line 403 "getdate.y"
1547
&& ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits))
1548
PC.year = yyvsp[0].textintval;
1551
if (4 < yyvsp[0].textintval.digits)
1554
PC.day = yyvsp[0].textintval.value % 100;
1555
PC.month = (yyvsp[0].textintval.value / 100) % 100;
1556
PC.year.value = yyvsp[0].textintval.value / 10000;
1557
PC.year.digits = yyvsp[0].textintval.digits - 4;
1562
if (yyvsp[0].textintval.digits <= 2)
1564
PC.hour = yyvsp[0].textintval.value;
1569
PC.hour = yyvsp[0].textintval.value / 100;
1570
PC.minutes = yyvsp[0].textintval.value % 100;
1573
PC.meridian = MER24;
1580
#line 439 "getdate.y"
1581
{ yyval.intval = MER24; }
1585
#line 441 "getdate.y"
1586
{ yyval.intval = yyvsp[0].intval; }
1592
/* Line 999 of yacc.c. */
1593
#line 1593 "getdate.c"
1599
YY_STACK_PRINT (yyss, yyssp);
1604
/* Now `shift' the result of the reduction. Determine what state
1605
that goes to, based on the state we popped back to and the rule
1606
number reduced by. */
1610
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1611
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1612
yystate = yytable[yystate];
1614
yystate = yydefgoto[yyn - YYNTOKENS];
1619
/*------------------------------------.
1620
| yyerrlab -- here on detecting error |
1621
`------------------------------------*/
1623
/* If not already recovering from an error, report this error. */
1628
yyn = yypact[yystate];
1630
if (YYPACT_NINF < yyn && yyn < YYLAST)
1632
YYSIZE_T yysize = 0;
1633
int yytype = YYTRANSLATE (yychar);
1638
/* Start YYX at -YYN if negative to avoid negative indexes in
1640
for (yyx = yyn < 0 ? -yyn : 0;
1641
yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1642
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1643
yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1644
yysize += yystrlen ("syntax error, unexpected ") + 1;
1645
yysize += yystrlen (yytname[yytype]);
1646
yymsg = (char *) YYSTACK_ALLOC (yysize);
1649
char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1650
yyp = yystpcpy (yyp, yytname[yytype]);
1655
for (yyx = yyn < 0 ? -yyn : 0;
1656
yyx < (int) (sizeof (yytname) / sizeof (char *));
1658
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1660
const char *yyq = ! yycount ? ", expecting " : " or ";
1661
yyp = yystpcpy (yyp, yyq);
1662
yyp = yystpcpy (yyp, yytname[yyx]);
1667
YYSTACK_FREE (yymsg);
1670
yyerror ("syntax error; also virtual memory exhausted");
1673
#endif /* YYERROR_VERBOSE */
1674
yyerror ("syntax error");
1679
if (yyerrstatus == 3)
1681
/* If just tried and failed to reuse lookahead token after an
1682
error, discard it. */
1684
/* Return failure if at end of input. */
1685
if (yychar == YYEOF)
1687
/* Pop the error token. */
1689
/* Pop the rest of the stack. */
1690
while (yyss < yyssp)
1692
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1693
yydestruct (yystos[*yyssp], yyvsp);
1699
YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1700
yydestruct (yytoken, &yylval);
1705
/* Else will try to reuse lookahead token after shifting the error
1710
/*----------------------------------------------------.
1711
| yyerrlab1 -- error raised explicitly by an action. |
1712
`----------------------------------------------------*/
1714
yyerrstatus = 3; /* Each real token shifted decrements this. */
1718
yyn = yypact[yystate];
1719
if (yyn != YYPACT_NINF)
1722
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1730
/* Pop the current state because it cannot handle the error token. */
1734
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1735
yydestruct (yystos[yystate], yyvsp);
1739
YY_STACK_PRINT (yyss, yyssp);
1745
YYDPRINTF ((stderr, "Shifting error token, "));
1754
/*-------------------------------------.
1755
| yyacceptlab -- YYACCEPT comes here. |
1756
`-------------------------------------*/
1761
/*-----------------------------------.
1762
| yyabortlab -- YYABORT comes here. |
1763
`-----------------------------------*/
1769
/*----------------------------------------------.
1770
| yyoverflowlab -- parser overflow comes here. |
1771
`----------------------------------------------*/
1773
yyerror ("parser stack overflow");
1781
YYSTACK_FREE (yyss);
1787
#line 444 "getdate.y"
1790
/* Include this file down here because bison inserts code above which
1791
may define-away `const'. We want the prototype for get_date to have
1792
the same signature as the function definition. */
1793
#include "modules/getdate.h"
1796
struct tm *gmtime ();
1799
struct tm *localtime ();
1805
static table const meridian_table[] =
1807
{ "AM", tMERIDIAN, MERam },
1808
{ "A.M.", tMERIDIAN, MERam },
1809
{ "PM", tMERIDIAN, MERpm },
1810
{ "P.M.", tMERIDIAN, MERpm },
1814
static table const dst_table[] =
1819
static table const month_and_day_table[] =
1821
{ "JANUARY", tMONTH, 1 },
1822
{ "FEBRUARY", tMONTH, 2 },
1823
{ "MARCH", tMONTH, 3 },
1824
{ "APRIL", tMONTH, 4 },
1825
{ "MAY", tMONTH, 5 },
1826
{ "JUNE", tMONTH, 6 },
1827
{ "JULY", tMONTH, 7 },
1828
{ "AUGUST", tMONTH, 8 },
1829
{ "SEPTEMBER",tMONTH, 9 },
1830
{ "SEPT", tMONTH, 9 },
1831
{ "OCTOBER", tMONTH, 10 },
1832
{ "NOVEMBER", tMONTH, 11 },
1833
{ "DECEMBER", tMONTH, 12 },
1834
{ "SUNDAY", tDAY, 0 },
1835
{ "MONDAY", tDAY, 1 },
1836
{ "TUESDAY", tDAY, 2 },
1837
{ "TUES", tDAY, 2 },
1838
{ "WEDNESDAY",tDAY, 3 },
1839
{ "WEDNES", tDAY, 3 },
1840
{ "THURSDAY", tDAY, 4 },
1841
{ "THUR", tDAY, 4 },
1842
{ "THURS", tDAY, 4 },
1843
{ "FRIDAY", tDAY, 5 },
1844
{ "SATURDAY", tDAY, 6 },
1848
static table const time_units_table[] =
1850
{ "YEAR", tYEAR_UNIT, 1 },
1851
{ "MONTH", tMONTH_UNIT, 1 },
1852
{ "FORTNIGHT",tDAY_UNIT, 14 },
1853
{ "WEEK", tDAY_UNIT, 7 },
1854
{ "DAY", tDAY_UNIT, 1 },
1855
{ "HOUR", tHOUR_UNIT, 1 },
1856
{ "MINUTE", tMINUTE_UNIT, 1 },
1857
{ "MIN", tMINUTE_UNIT, 1 },
1858
{ "SECOND", tSEC_UNIT, 1 },
1859
{ "SEC", tSEC_UNIT, 1 },
1863
/* Assorted relative-time words. */
1864
static table const relative_time_table[] =
1866
{ "TOMORROW", tMINUTE_UNIT, 24 * 60 },
1867
{ "YESTERDAY",tMINUTE_UNIT, - (24 * 60) },
1868
{ "TODAY", tMINUTE_UNIT, 0 },
1869
{ "NOW", tMINUTE_UNIT, 0 },
1870
{ "LAST", tUNUMBER, -1 },
1871
{ "THIS", tUNUMBER, 0 },
1872
{ "NEXT", tUNUMBER, 1 },
1873
{ "FIRST", tUNUMBER, 1 },
1874
/*{ "SECOND", tUNUMBER, 2 }, */
1875
{ "THIRD", tUNUMBER, 3 },
1876
{ "FOURTH", tUNUMBER, 4 },
1877
{ "FIFTH", tUNUMBER, 5 },
1878
{ "SIXTH", tUNUMBER, 6 },
1879
{ "SEVENTH", tUNUMBER, 7 },
1880
{ "EIGHTH", tUNUMBER, 8 },
1881
{ "NINTH", tUNUMBER, 9 },
1882
{ "TENTH", tUNUMBER, 10 },
1883
{ "ELEVENTH", tUNUMBER, 11 },
1884
{ "TWELFTH", tUNUMBER, 12 },
1889
/* The time zone table. This table is necessarily incomplete, as time
1890
zone abbreviations are ambiguous; e.g. Australians interpret "EST"
1891
as Eastern time in Australia, not as US Eastern Standard Time.
1892
You cannot rely on getdate to handle arbitrary time zone
1893
abbreviations; use numeric abbreviations like `-0500' instead. */
1894
static table const time_zone_table[] =
1896
{ "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */
1897
{ "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
1898
{ "UTC", tZONE, HOUR ( 0) },
1899
{ "WET", tZONE, HOUR ( 0) }, /* Western European */
1900
{ "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */
1901
{ "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */
1902
{ "ART", tZONE, -HOUR ( 3) }, /* Argentina */
1903
{ "BRT", tZONE, -HOUR ( 3) }, /* Brazil */
1904
{ "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */
1905
{ "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */
1906
{ "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */
1907
{ "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */
1908
{ "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */
1909
{ "CLT", tZONE, -HOUR ( 4) }, /* Chile */
1910
{ "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */
1911
{ "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */
1912
{ "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */
1913
{ "CST", tZONE, -HOUR ( 6) }, /* Central Standard */
1914
{ "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */
1915
{ "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */
1916
{ "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */
1917
{ "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */
1918
{ "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */
1919
{ "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */
1920
{ "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */
1921
{ "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */
1922
{ "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */
1923
{ "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */
1924
{ "SST", tZONE, -HOUR (12) }, /* Samoa Standard */
1925
{ "WAT", tZONE, HOUR ( 1) }, /* West Africa */
1926
{ "CET", tZONE, HOUR ( 1) }, /* Central European */
1927
{ "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */
1928
{ "MET", tZONE, HOUR ( 1) }, /* Middle European */
1929
{ "MEZ", tZONE, HOUR ( 1) }, /* Middle European */
1930
{ "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1931
{ "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */
1932
{ "EET", tZONE, HOUR ( 2) }, /* Eastern European */
1933
{ "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */
1934
{ "CAT", tZONE, HOUR ( 2) }, /* Central Africa */
1935
{ "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */
1936
{ "EAT", tZONE, HOUR ( 3) }, /* East Africa */
1937
{ "MSK", tZONE, HOUR ( 3) }, /* Moscow */
1938
{ "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */
1939
{ "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */
1940
{ "SGT", tZONE, HOUR ( 8) }, /* Singapore */
1941
{ "KST", tZONE, HOUR ( 9) }, /* Korea Standard */
1942
{ "JST", tZONE, HOUR ( 9) }, /* Japan Standard */
1943
{ "GST", tZONE, HOUR (10) }, /* Guam Standard */
1944
{ "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */
1945
{ "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */
1949
/* Military time zone table. */
1950
static table const military_table[] =
1952
{ "A", tZONE, -HOUR ( 1) },
1953
{ "B", tZONE, -HOUR ( 2) },
1954
{ "C", tZONE, -HOUR ( 3) },
1955
{ "D", tZONE, -HOUR ( 4) },
1956
{ "E", tZONE, -HOUR ( 5) },
1957
{ "F", tZONE, -HOUR ( 6) },
1958
{ "G", tZONE, -HOUR ( 7) },
1959
{ "H", tZONE, -HOUR ( 8) },
1960
{ "I", tZONE, -HOUR ( 9) },
1961
{ "K", tZONE, -HOUR (10) },
1962
{ "L", tZONE, -HOUR (11) },
1963
{ "M", tZONE, -HOUR (12) },
1964
{ "N", tZONE, HOUR ( 1) },
1965
{ "O", tZONE, HOUR ( 2) },
1966
{ "P", tZONE, HOUR ( 3) },
1967
{ "Q", tZONE, HOUR ( 4) },
1968
{ "R", tZONE, HOUR ( 5) },
1969
{ "S", tZONE, HOUR ( 6) },
1970
{ "T", tZONE, HOUR ( 7) },
1971
{ "U", tZONE, HOUR ( 8) },
1972
{ "V", tZONE, HOUR ( 9) },
1973
{ "W", tZONE, HOUR (10) },
1974
{ "X", tZONE, HOUR (11) },
1975
{ "Y", tZONE, HOUR (12) },
1976
{ "Z", tZONE, HOUR ( 0) },
1983
to_hour (int hours, int meridian)
1988
return 0 <= hours && hours < 24 ? hours : -1;
1990
return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1;
1992
return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1;
2001
to_year (textint textyear)
2003
int year = textyear.value;
2008
/* XPG4 suggests that years 00-68 map to 2000-2068, and
2009
years 69-99 map to 1969-1999. */
2010
if (textyear.digits == 2)
2011
year += year < 69 ? 2000 : 1900;
2016
static table const *
2017
lookup_zone (parser_control const *pc, char const *name)
2021
/* Try local zone abbreviations first; they're more likely to be right. */
2022
for (tp = pc->local_time_zone_table; tp->name; tp++)
2023
if (strcmp (name, tp->name) == 0)
2026
for (tp = time_zone_table; tp->name; tp++)
2027
if (strcmp (name, tp->name) == 0)
2033
#if ! HAVE_TM_GMTOFF
2034
/* Yield the difference between *A and *B,
2035
measured in seconds, ignoring leap seconds.
2036
The body of this function is taken directly from the GNU C Library;
2037
see src/strftime.c. */
2039
tm_diff (struct tm const *a, struct tm const *b)
2041
/* Compute intervening leap days correctly even if year is negative.
2042
Take care to avoid int overflow in leap day calculations,
2043
but it's OK to assume that A and B are close to each other. */
2044
int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3);
2045
int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3);
2046
int a100 = a4 / 25 - (a4 % 25 < 0);
2047
int b100 = b4 / 25 - (b4 % 25 < 0);
2048
int a400 = a100 >> 2;
2049
int b400 = b100 >> 2;
2050
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
2051
int years = a->tm_year - b->tm_year;
2052
int days = (365 * years + intervening_leap_days
2053
+ (a->tm_yday - b->tm_yday));
2054
return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
2055
+ (a->tm_min - b->tm_min))
2056
+ (a->tm_sec - b->tm_sec));
2058
#endif /* ! HAVE_TM_GMTOFF */
2060
static table const *
2061
lookup_word (parser_control const *pc, char *word)
2070
/* Make it uppercase. */
2071
for (p = word; *p; p++)
2072
if (ISLOWER ((unsigned char) *p))
2073
*p = toupper ((unsigned char) *p);
2075
for (tp = meridian_table; tp->name; tp++)
2076
if (strcmp (word, tp->name) == 0)
2079
/* See if we have an abbreviation for a month. */
2080
wordlen = strlen (word);
2081
abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.');
2083
for (tp = month_and_day_table; tp->name; tp++)
2084
if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0)
2087
if ((tp = lookup_zone (pc, word)))
2090
if (strcmp (word, dst_table[0].name) == 0)
2093
for (tp = time_units_table; tp->name; tp++)
2094
if (strcmp (word, tp->name) == 0)
2097
/* Strip off any plural and try the units table again. */
2098
if (word[wordlen - 1] == 'S')
2100
word[wordlen - 1] = '\0';
2101
for (tp = time_units_table; tp->name; tp++)
2102
if (strcmp (word, tp->name) == 0)
2104
word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */
2107
for (tp = relative_time_table; tp->name; tp++)
2108
if (strcmp (word, tp->name) == 0)
2111
/* Military time zones. */
2113
for (tp = military_table; tp->name; tp++)
2114
if (word[0] == tp->name[0])
2117
/* Drop out any periods and try the time zone table again. */
2118
for (i = 0, p = q = word; (*p = *q); q++)
2123
if (i && (tp = lookup_zone (pc, word)))
2130
yylex (YYSTYPE *lvalp, parser_control *pc)
2137
while (c = *pc->input, ISSPACE (c))
2140
if (ISDIGIT (c) || c == '-' || c == '+')
2145
if (c == '-' || c == '+')
2147
sign = c == '-' ? -1 : 1;
2150
/* skip the '-' sign */
2159
value = 10 * value + c - '0';
2162
while (ISDIGIT (c));
2163
lvalp->textintval.value = sign < 0 ? -value : value;
2164
lvalp->textintval.digits = p - pc->input;
2166
return sign ? tSNUMBER : tUNUMBER;
2177
if (p < buff + sizeof buff - 1)
2181
while (ISALPHA (c) || c == '.');
2184
tp = lookup_word (pc, buff);
2187
lvalp->intval = tp->value;
2192
return *pc->input++;
2208
/* Do nothing if the parser reports an error. */
2210
yyerror (char *s ATTRIBUTE_UNUSED)
2215
/* Parse a date/time string P. Return the corresponding time_t value,
2216
or (time_t) -1 if there is an error. P can be an incomplete or
2217
relative time specification; if so, use *NOW as the basis for the
2220
get_date (const char *p, const time_t *now)
2222
time_t Start = now ? *now : time (0);
2223
struct tm *tmp = localtime (&Start);
2232
pc.year.value = tmp->tm_year + TM_YEAR_BASE;
2234
pc.month = tmp->tm_mon + 1;
2235
pc.day = tmp->tm_mday;
2236
pc.hour = tmp->tm_hour;
2237
pc.minutes = tmp->tm_min;
2238
pc.seconds = tmp->tm_sec;
2239
tm.tm_isdst = tmp->tm_isdst;
2241
pc.meridian = MER24;
2252
pc.local_zones_seen = 0;
2255
#if HAVE_STRUCT_TM_TM_ZONE
2256
pc.local_time_zone_table[0].name = tmp->tm_zone;
2257
pc.local_time_zone_table[0].type = tLOCAL_ZONE;
2258
pc.local_time_zone_table[0].value = tmp->tm_isdst;
2259
pc.local_time_zone_table[1].name = 0;
2261
/* Probe the names used in the next three calendar quarters, looking
2262
for a tm_isdst different from the one we already have. */
2265
for (quarter = 1; quarter <= 3; quarter++)
2267
time_t probe = Start + quarter * (90 * 24 * 60 * 60);
2268
struct tm *probe_tm = localtime (&probe);
2269
if (probe_tm && probe_tm->tm_zone
2270
&& probe_tm->tm_isdst != pc.local_time_zone_table[0].value)
2273
pc.local_time_zone_table[1].name = probe_tm->tm_zone;
2274
pc.local_time_zone_table[1].type = tLOCAL_ZONE;
2275
pc.local_time_zone_table[1].value = probe_tm->tm_isdst;
2276
pc.local_time_zone_table[2].name = 0;
2286
extern char *tzname[];
2289
for (i = 0; i < 2; i++)
2291
pc.local_time_zone_table[i].name = tzname[i];
2292
pc.local_time_zone_table[i].type = tLOCAL_ZONE;
2293
pc.local_time_zone_table[i].value = i;
2295
pc.local_time_zone_table[i].name = 0;
2298
pc.local_time_zone_table[0].name = 0;
2302
if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name
2303
&& ! strcmp (pc.local_time_zone_table[0].name,
2304
pc.local_time_zone_table[1].name))
2306
/* This locale uses the same abbrevation for standard and
2307
daylight times. So if we see that abbreviation, we don't
2308
know whether it's daylight time. */
2309
pc.local_time_zone_table[0].value = -1;
2310
pc.local_time_zone_table[1].name = 0;
2313
if (yyparse (&pc) != 0
2314
|| 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen
2315
|| 1 < (pc.local_zones_seen + pc.zones_seen)
2316
|| (pc.local_zones_seen && 1 < pc.local_isdst))
2319
tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year;
2320
tm.tm_mon = pc.month - 1 + pc.rel_month;
2321
tm.tm_mday = pc.day + pc.rel_day;
2322
if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen))
2324
tm.tm_hour = to_hour (pc.hour, pc.meridian);
2327
tm.tm_min = pc.minutes;
2328
tm.tm_sec = pc.seconds;
2332
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
2335
/* Let mktime deduce tm_isdst if we have an absolute time stamp,
2336
or if the relative time stamp mentions days, months, or years. */
2337
if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day
2338
| pc.rel_month | pc.rel_year)
2341
/* But if the input explicitly specifies local time with or without
2342
DST, give mktime that information. */
2343
if (pc.local_zones_seen)
2344
tm.tm_isdst = pc.local_isdst;
2348
Start = mktime (&tm);
2350
if (Start == (time_t) -1)
2353
/* Guard against falsely reporting errors near the time_t boundaries
2354
when parsing times in other time zones. For example, if the min
2355
time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
2356
of UTC, then the min localtime value is 1970-01-01 08:00:00; if
2357
we apply mktime to 1970-01-01 00:00:00 we will get an error, so
2358
we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
2359
zone by 24 hours to compensate. This algorithm assumes that
2360
there is no DST transition within a day of the time_t boundaries. */
2364
if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE)
2367
pc.time_zone += 24 * 60;
2372
pc.time_zone -= 24 * 60;
2374
Start = mktime (&tm);
2377
if (Start == (time_t) -1)
2381
if (pc.days_seen && ! pc.dates_seen)
2383
tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7
2384
+ 7 * (pc.day_ordinal - (0 < pc.day_ordinal)));
2386
Start = mktime (&tm);
2387
if (Start == (time_t) -1)
2393
int delta = pc.time_zone * 60;
2394
#ifdef HAVE_TM_GMTOFF
2395
delta -= tm.tm_gmtoff;
2397
struct tm *gmt = gmtime (&Start);
2400
delta -= tm_diff (&tm, gmt);
2402
if ((Start < Start - delta) != (delta < 0))
2403
return -1; /* time_t overflow */
2407
/* Add relative hours, minutes, and seconds. Ignore leap seconds;
2408
i.e. "+ 10 minutes" means 600 seconds, even if one of them is a
2409
leap second. Typically this is not what the user wants, but it's
2410
too hard to do it the other way, because the time zone indicator
2411
must be applied before relative times, and if mktime is applied
2412
again the time zone will be lost. */
2415
long d1 = 60 * 60 * (long) pc.rel_hour;
2416
time_t t1 = t0 + d1;
2417
long d2 = 60 * (long) pc.rel_minutes;
2418
time_t t2 = t1 + d2;
2419
int d3 = pc.rel_seconds;
2420
time_t t3 = t2 + d3;
2421
if ((d1 / (60 * 60) ^ pc.rel_hour)
2422
| (d2 / 60 ^ pc.rel_minutes)
2423
| ((t0 + d1 < t0) ^ (d1 < 0))
2424
| ((t1 + d2 < t1) ^ (d2 < 0))
2425
| ((t2 + d3 < t2) ^ (d3 < 0)))
2438
main (int ac, char **av)
2443
printf ("Enter date, or blank line to exit.\n\t> ");
2446
buff[BUFSIZ - 1] = 0;
2447
while (fgets (buff, BUFSIZ - 1, stdin) && buff[0])
2449
d = get_date (buff, 0);
2450
if (d == (time_t) -1)
2451
printf ("Bad format - couldn't convert.\n");
2453
printf ("%s", ctime (&d));
2459
#endif /* defined TEST */