1/* A Bison parser, made by GNU Bison 1.875a. */ 2 3/* Skeleton parser for Yacc-like parsing with Bison, 4 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, 19 Boston, MA 02111-1307, USA. */ 20 21/* As a special exception, when this file is copied by Bison into a 22 Bison output file, you may use that output file without restriction. 23 This special exception was added by the Free Software Foundation 24 in version 1.24 of Bison. */ 25 26/* Written by Richard Stallman by simplifying the original so called 27 ``semantic'' parser. */ 28 29/* All symbols defined below should begin with yy or YY, to avoid 30 infringing on user name space. This should be done even for local 31 variables, as they might otherwise be expanded by user macros. 32 There are some unavoidable exceptions within include files to 33 define necessary library symbols; they are noted "INFRINGES ON 34 USER NAME SPACE" below. */ 35 36/* Identify Bison output. */ 37#define YYBISON 1 38 39/* Skeleton name. */ 40#define YYSKELETON_NAME "yacc.c" 41 42/* Pure parsers. */ 43#define YYPURE 1 44 45/* Using locations. */ 46#define YYLSP_NEEDED 0 47 48 49 50/* Tokens. */ 51#ifndef YYTOKENTYPE 52# define YYTOKENTYPE 53 /* Put the tokens into the symbol table, so that GDB and other debuggers 54 know about them. */ 55 enum yytokentype { 56 tAGO = 258, 57 tDST = 259, 58 tDAY = 260, 59 tDAY_UNIT = 261, 60 tDAYZONE = 262, 61 tHOUR_UNIT = 263, 62 tLOCAL_ZONE = 264, 63 tMERIDIAN = 265, 64 tMINUTE_UNIT = 266, 65 tMONTH = 267, 66 tMONTH_UNIT = 268, 67 tSEC_UNIT = 269, 68 tYEAR_UNIT = 270, 69 tZONE = 271, 70 tSNUMBER = 272, 71 tUNUMBER = 273 72 }; 73#endif 74#define tAGO 258 75#define tDST 259 76#define tDAY 260 77#define tDAY_UNIT 261 78#define tDAYZONE 262 79#define tHOUR_UNIT 263 80#define tLOCAL_ZONE 264 81#define tMERIDIAN 265 82#define tMINUTE_UNIT 266 83#define tMONTH 267 84#define tMONTH_UNIT 268 85#define tSEC_UNIT 269 86#define tYEAR_UNIT 270 87#define tZONE 271 88#define tSNUMBER 272 89#define tUNUMBER 273 90 91 92 93 94/* Copy the first part of user declarations. */ 95#line 1 "getdate.y" 96 97/* Parse a string into an internal time stamp. 98 Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. 99 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) 103 any later version. 104 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. 109 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. */ 113 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. 118 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. */ 122 123#ifdef HAVE_CONFIG_H 124# include <config.h> 125# ifdef HAVE_ALLOCA_H 126# include <alloca.h> 127# endif 128#endif 129 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. */ 136#ifdef emacs 137# undef static 138#endif 139 140#include <ctype.h> 141 142#if HAVE_STDLIB_H 143# include <stdlib.h> /* for `free'; used by Bison 1.27 */ 144#endif 145 146#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII) 147# define IN_CTYPE_DOMAIN(c) 1 148#else 149# define IN_CTYPE_DOMAIN(c) isascii (c) 150#endif 151 152#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c)) 153#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c)) 154#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c)) 155#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c)) 156 157/* ISDIGIT differs from ISDIGIT_LOCALE, as follows: 158 - Its arg may be any int or unsigned int; it need not be an unsigned char. 159 - It's guaranteed to evaluate its argument exactly once. 160 - It's typically faster. 161 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to 162 ISDIGIT_LOCALE unless it's important to use the locale's definition 163 of `digit' even when the host does not conform to POSIX. */ 164#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) 165 166#if STDC_HEADERS || HAVE_STRING_H 167# include <string.h> 168#endif 169 170#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__ 171# define __attribute__(x) 172#endif 173 174#ifndef ATTRIBUTE_UNUSED 175# define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 176#endif 177 178#define EPOCH_YEAR 1970 179#define TM_YEAR_BASE 1900 180 181#define HOUR(x) ((x) * 60) 182 183/* An integer value, and the number of digits in its textual 184 representation. */ 185typedef struct 186{ 187 int value; 188 int digits; 189} textint; 190 191/* An entry in the lexical lookup table. */ 192typedef struct 193{ 194 char const *name; 195 int type; 196 int value; 197} table; 198 199/* Meridian: am, pm, or 24-hour style. */ 200enum { MERam, MERpm, MER24 }; 201 202/* Information passed to and from the parser. */ 203typedef struct 204{ 205 /* The input string remaining to be parsed. */ 206 const char *input; 207 208 /* N, if this is the Nth Tuesday. */ 209 int day_ordinal; 210 211 /* Day of week; Sunday is 0. */ 212 int day_number; 213 214 /* tm_isdst flag for the local zone. */ 215 int local_isdst; 216 217 /* Time zone, in minutes east of UTC. */ 218 int time_zone; 219 220 /* Style used for time. */ 221 int meridian; 222 223 /* Gregorian year, month, day, hour, minutes, and seconds. */ 224 textint year; 225 int month; 226 int day; 227 int hour; 228 int minutes; 229 int seconds; 230 231 /* Relative year, month, day, hour, minutes, and seconds. */ 232 int rel_year; 233 int rel_month; 234 int rel_day; 235 int rel_hour; 236 int rel_minutes; 237 int rel_seconds; 238 239 /* Counts of nonterminals of various flavors parsed so far. */ 240 int dates_seen; 241 int days_seen; 242 int local_zones_seen; 243 int rels_seen; 244 int times_seen; 245 int zones_seen; 246 247 /* Table of local time zone abbrevations, terminated by a null entry. */ 248 table local_time_zone_table[3]; 249} parser_control; 250 251#define PC (* (parser_control *) parm) 252#define YYLEX_PARAM parm 253#define YYPARSE_PARAM parm 254 255static int yyerror (); 256static int yylex (); 257 258 259 260/* Enabling traces. */ 261#ifndef YYDEBUG 262# define YYDEBUG 0 263#endif 264 265/* Enabling verbose error messages. */ 266#ifdef YYERROR_VERBOSE 267# undef YYERROR_VERBOSE 268# define YYERROR_VERBOSE 1 269#else 270# define YYERROR_VERBOSE 0 271#endif 272 273#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) 274#line 172 "getdate.y" 275typedef union YYSTYPE { 276 int intval; 277 textint textintval; 278} YYSTYPE; 279/* Line 191 of yacc.c. */ 280#line 281 "getdate.c" 281# define yystype YYSTYPE /* obsolescent; will be withdrawn */ 282# define YYSTYPE_IS_DECLARED 1 283# define YYSTYPE_IS_TRIVIAL 1 284#endif 285 286 287 288/* Copy the second part of user declarations. */ 289 290 291/* Line 214 of yacc.c. */ 292#line 293 "getdate.c" 293 294#if ! defined (yyoverflow) || YYERROR_VERBOSE 295 296/* The parser invokes alloca or malloc; define the necessary symbols. */ 297 298# if YYSTACK_USE_ALLOCA 299# define YYSTACK_ALLOC alloca 300# else 301# ifndef YYSTACK_USE_ALLOCA 302# if defined (alloca) || defined (_ALLOCA_H) 303# define YYSTACK_ALLOC alloca 304# else 305# ifdef __GNUC__ 306# define YYSTACK_ALLOC __builtin_alloca 307# endif 308# endif 309# endif 310# endif 311 312# ifdef YYSTACK_ALLOC 313 /* Pacify GCC's `empty if-body' warning. */ 314# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) 315# else 316# if defined (__STDC__) || defined (__cplusplus) 317# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ 318# define YYSIZE_T size_t 319# endif 320# define YYSTACK_ALLOC malloc 321# define YYSTACK_FREE free 322# endif 323#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ 324 325 326#if (! defined (yyoverflow) \ 327 && (! defined (__cplusplus) \ 328 || (YYSTYPE_IS_TRIVIAL))) 329 330/* A type that is properly aligned for any stack member. */ 331union yyalloc 332{ 333 short yyss; 334 YYSTYPE yyvs; 335 }; 336 337/* The size of the maximum gap between one aligned stack and the next. */ 338# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) 339 340/* The size of an array large to enough to hold all stacks, each with 341 N elements. */ 342# define YYSTACK_BYTES(N) \ 343 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ 344 + YYSTACK_GAP_MAXIMUM) 345 346/* Copy COUNT objects from FROM to TO. The source and destination do 347 not overlap. */ 348# ifndef YYCOPY 349# if 1 < __GNUC__ 350# define YYCOPY(To, From, Count) \ 351 __builtin_memcpy (To, From, (Count) * sizeof (*(From))) 352# else 353# define YYCOPY(To, From, Count) \ 354 do \ 355 { \ 356 register YYSIZE_T yyi; \ 357 for (yyi = 0; yyi < (Count); yyi++) \ 358 (To)[yyi] = (From)[yyi]; \ 359 } \ 360 while (0) 361# endif 362# endif 363 364/* Relocate STACK from its old location to the new one. The 365 local variables YYSIZE and YYSTACKSIZE give the old and new number of 366 elements in the stack, and YYPTR gives the new location of the 367 stack. Advance YYPTR to a properly aligned location for the next 368 stack. */ 369# define YYSTACK_RELOCATE(Stack) \ 370 do \ 371 { \ 372 YYSIZE_T yynewbytes; \ 373 YYCOPY (&yyptr->Stack, Stack, yysize); \ 374 Stack = &yyptr->Stack; \ 375 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ 376 yyptr += yynewbytes / sizeof (*yyptr); \ 377 } \ 378 while (0) 379 380#endif 381 382#if defined (__STDC__) || defined (__cplusplus) 383 typedef signed char yysigned_char; 384#else 385 typedef short yysigned_char; 386#endif 387 388/* YYFINAL -- State number of the termination state. */ 389#define YYFINAL 2 390/* YYLAST -- Last index in YYTABLE. */ 391#define YYLAST 52 392 393/* YYNTOKENS -- Number of terminals. */ 394#define YYNTOKENS 22 395/* YYNNTS -- Number of nonterminals. */ 396#define YYNNTS 12 397/* YYNRULES -- Number of rules. */ 398#define YYNRULES 54 399/* YYNRULES -- Number of states. */ 400#define YYNSTATES 64 401 402/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ 403#define YYUNDEFTOK 2 404#define YYMAXUTOK 273 405 406#define YYTRANSLATE(YYX) \ 407 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) 408 409/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ 410static const unsigned char yytranslate[] = 411{ 412 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 413 2, 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, 20, 2, 2, 21, 2, 2, 417 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, 418 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 1, 2, 3, 4, 438 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 439 15, 16, 17, 18 440}; 441 442#if YYDEBUG 443/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in 444 YYRHS. */ 445static const unsigned char yyprhs[] = 446{ 447 0, 0, 3, 4, 7, 9, 11, 13, 15, 17, 448 19, 21, 24, 29, 34, 41, 48, 50, 53, 55, 449 57, 60, 62, 65, 68, 72, 78, 82, 86, 89, 450 94, 97, 101, 104, 106, 109, 112, 114, 117, 120, 451 122, 125, 128, 130, 133, 136, 138, 141, 144, 146, 452 149, 152, 154, 156, 157 453}; 454 455/* YYRHS -- A `-1'-separated list of the rules' RHS. */ 456static const yysigned_char yyrhs[] = 457{ 458 23, 0, -1, -1, 23, 24, -1, 25, -1, 26, 459 -1, 27, -1, 29, -1, 28, -1, 30, -1, 32, 460 -1, 18, 10, -1, 18, 19, 18, 33, -1, 18, 461 19, 18, 17, -1, 18, 19, 18, 19, 18, 33, 462 -1, 18, 19, 18, 19, 18, 17, -1, 9, -1, 463 9, 4, -1, 16, -1, 7, -1, 16, 4, -1, 464 5, -1, 5, 20, -1, 18, 5, -1, 18, 21, 465 18, -1, 18, 21, 18, 21, 18, -1, 18, 17, 466 17, -1, 18, 12, 17, -1, 12, 18, -1, 12, 467 18, 20, 18, -1, 18, 12, -1, 18, 12, 18, 468 -1, 31, 3, -1, 31, -1, 18, 15, -1, 17, 469 15, -1, 15, -1, 18, 13, -1, 17, 13, -1, 470 13, -1, 18, 6, -1, 17, 6, -1, 6, -1, 471 18, 8, -1, 17, 8, -1, 8, -1, 18, 11, 472 -1, 17, 11, -1, 11, -1, 18, 14, -1, 17, 473 14, -1, 14, -1, 18, -1, -1, 10, -1 474}; 475 476/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ 477static const unsigned short yyrline[] = 478{ 479 0, 188, 188, 190, 194, 196, 198, 200, 202, 204, 480 206, 210, 217, 224, 232, 239, 251, 253, 258, 260, 481 262, 267, 272, 277, 285, 290, 310, 317, 325, 330, 482 336, 341, 350, 359, 363, 365, 367, 369, 371, 373, 483 375, 377, 379, 381, 383, 385, 387, 389, 391, 393, 484 395, 397, 402, 439, 440 485}; 486#endif 487 488#if YYDEBUG || YYERROR_VERBOSE 489/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. 490 First, the terminals, then, starting at YYNTOKENS, nonterminals. */ 491static const char *const yytname[] = 492{ 493 "$end", "error", "$undefined", "tAGO", "tDST", "tDAY", "tDAY_UNIT", 494 "tDAYZONE", "tHOUR_UNIT", "tLOCAL_ZONE", "tMERIDIAN", "tMINUTE_UNIT", 495 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tYEAR_UNIT", "tZONE", "tSNUMBER", 496 "tUNUMBER", "':'", "','", "'/'", "$accept", "spec", "item", "time", 497 "local_zone", "zone", "day", "date", "rel", "relunit", "number", 498 "o_merid", 0 499}; 500#endif 501 502# ifdef YYPRINT 503/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to 504 token YYLEX-NUM. */ 505static const unsigned short yytoknum[] = 506{ 507 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 508 265, 266, 267, 268, 269, 270, 271, 272, 273, 58, 509 44, 47 510}; 511# endif 512 513/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ 514static const unsigned char yyr1[] = 515{ 516 0, 22, 23, 23, 24, 24, 24, 24, 24, 24, 517 24, 25, 25, 25, 25, 25, 26, 26, 27, 27, 518 27, 28, 28, 28, 29, 29, 29, 29, 29, 29, 519 29, 29, 30, 30, 31, 31, 31, 31, 31, 31, 520 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 521 31, 31, 32, 33, 33 522}; 523 524/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ 525static const unsigned char yyr2[] = 526{ 527 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, 528 1, 2, 4, 4, 6, 6, 1, 2, 1, 1, 529 2, 1, 2, 2, 3, 5, 3, 3, 2, 4, 530 2, 3, 2, 1, 2, 2, 1, 2, 2, 1, 531 2, 2, 1, 2, 2, 1, 2, 2, 1, 2, 532 2, 1, 1, 0, 1 533}; 534 535/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state 536 STATE-NUM when YYTABLE doesn't specify something else to do. Zero 537 means the default is an error. */ 538static const unsigned char yydefact[] = 539{ 540 2, 0, 1, 21, 42, 19, 45, 16, 48, 0, 541 39, 51, 36, 18, 0, 52, 3, 4, 5, 6, 542 8, 7, 9, 33, 10, 22, 17, 28, 20, 41, 543 44, 47, 38, 50, 35, 23, 40, 43, 11, 46, 544 30, 37, 49, 34, 0, 0, 0, 32, 0, 27, 545 31, 26, 53, 24, 29, 54, 13, 0, 12, 0, 546 53, 25, 15, 14 547}; 548 549/* YYDEFGOTO[NTERM-NUM]. */ 550static const yysigned_char yydefgoto[] = 551{ 552 -1, 1, 16, 17, 18, 19, 20, 21, 22, 23, 553 24, 58 554}; 555 556/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing 557 STATE-NUM. */ 558#define YYPACT_NINF -17 559static const yysigned_char yypact[] = 560{ 561 -17, 0, -17, 1, -17, -17, -17, 19, -17, -14, 562 -17, -17, -17, 32, 26, 14, -17, -17, -17, -17, 563 -17, -17, -17, 27, -17, -17, -17, 22, -17, -17, 564 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 565 -16, -17, -17, -17, 29, 25, 30, -17, 31, -17, 566 -17, -17, 28, 23, -17, -17, -17, 33, -17, 34, 567 -7, -17, -17, -17 568}; 569 570/* YYPGOTO[NTERM-NUM]. */ 571static const yysigned_char yypgoto[] = 572{ 573 -17, -17, -17, -17, -17, -17, -17, -17, -17, -17, 574 -17, -10 575}; 576 577/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If 578 positive, shift that token. If negative, reduce the rule which 579 number is the opposite. If zero, do what YYDEFACT says. 580 If YYTABLE_NINF, syntax error. */ 581#define YYTABLE_NINF -1 582static const unsigned char yytable[] = 583{ 584 2, 49, 50, 55, 27, 3, 4, 5, 6, 7, 585 62, 8, 9, 10, 11, 12, 13, 14, 15, 35, 586 36, 25, 37, 26, 38, 39, 40, 41, 42, 43, 587 47, 44, 29, 45, 30, 46, 28, 31, 55, 32, 588 33, 34, 48, 52, 59, 56, 51, 57, 53, 54, 589 63, 60, 61 590}; 591 592static const unsigned char yycheck[] = 593{ 594 0, 17, 18, 10, 18, 5, 6, 7, 8, 9, 595 17, 11, 12, 13, 14, 15, 16, 17, 18, 5, 596 6, 20, 8, 4, 10, 11, 12, 13, 14, 15, 597 3, 17, 6, 19, 8, 21, 4, 11, 10, 13, 598 14, 15, 20, 18, 21, 17, 17, 19, 18, 18, 599 60, 18, 18 600}; 601 602/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing 603 symbol of state STATE-NUM. */ 604static const unsigned char yystos[] = 605{ 606 0, 23, 0, 5, 6, 7, 8, 9, 11, 12, 607 13, 14, 15, 16, 17, 18, 24, 25, 26, 27, 608 28, 29, 30, 31, 32, 20, 4, 18, 4, 6, 609 8, 11, 13, 14, 15, 5, 6, 8, 10, 11, 610 12, 13, 14, 15, 17, 19, 21, 3, 20, 17, 611 18, 17, 18, 18, 18, 10, 17, 19, 33, 21, 612 18, 18, 17, 33 613}; 614 615#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) 616# define YYSIZE_T __SIZE_TYPE__ 617#endif 618#if ! defined (YYSIZE_T) && defined (size_t) 619# define YYSIZE_T size_t 620#endif 621#if ! defined (YYSIZE_T) 622# if defined (__STDC__) || defined (__cplusplus) 623# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ 624# define YYSIZE_T size_t 625# endif 626#endif 627#if ! defined (YYSIZE_T) 628# define YYSIZE_T unsigned int 629#endif 630 631#define yyerrok (yyerrstatus = 0) 632#define yyclearin (yychar = YYEMPTY) 633#define YYEMPTY (-2) 634#define YYEOF 0 635 636#define YYACCEPT goto yyacceptlab 637#define YYABORT goto yyabortlab 638#define YYERROR goto yyerrlab1 639 640 641/* Like YYERROR except do call yyerror. This remains here temporarily 642 to ease the transition to the new meaning of YYERROR, for GCC. 643 Once GCC version 2 has supplanted version 1, this can go. */ 644 645#define YYFAIL goto yyerrlab 646 647#define YYRECOVERING() (!!yyerrstatus) 648 649#define YYBACKUP(Token, Value) \ 650do \ 651 if (yychar == YYEMPTY && yylen == 1) \ 652 { \ 653 yychar = (Token); \ 654 yylval = (Value); \ 655 yytoken = YYTRANSLATE (yychar); \ 656 YYPOPSTACK; \ 657 goto yybackup; \ 658 } \ 659 else \ 660 { \ 661 yyerror ("syntax error: cannot back up");\ 662 YYERROR; \ 663 } \ 664while (0) 665 666#define YYTERROR 1 667#define YYERRCODE 256 668 669/* YYLLOC_DEFAULT -- Compute the default location (before the actions 670 are run). */ 671 672#ifndef YYLLOC_DEFAULT 673# define YYLLOC_DEFAULT(Current, Rhs, N) \ 674 Current.first_line = Rhs[1].first_line; \ 675 Current.first_column = Rhs[1].first_column; \ 676 Current.last_line = Rhs[N].last_line; \ 677 Current.last_column = Rhs[N].last_column; 678#endif 679 680/* YYLEX -- calling `yylex' with the right arguments. */ 681 682#ifdef YYLEX_PARAM 683# define YYLEX yylex (&yylval, YYLEX_PARAM) 684#else 685# define YYLEX yylex (&yylval) 686#endif 687 688/* Enable debugging if requested. */ 689#if YYDEBUG 690 691# ifndef YYFPRINTF 692# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ 693# define YYFPRINTF fprintf 694# endif 695 696# define YYDPRINTF(Args) \ 697do { \ 698 if (yydebug) \ 699 YYFPRINTF Args; \ 700} while (0) 701 702# define YYDSYMPRINT(Args) \ 703do { \ 704 if (yydebug) \ 705 yysymprint Args; \ 706} while (0) 707 708# define YYDSYMPRINTF(Title, Token, Value, Location) \ 709do { \ 710 if (yydebug) \ 711 { \ 712 YYFPRINTF (stderr, "%s ", Title); \ 713 yysymprint (stderr, \ 714 Token, Value); \ 715 YYFPRINTF (stderr, "\n"); \ 716 } \ 717} while (0) 718 719/*------------------------------------------------------------------. 720| yy_stack_print -- Print the state stack from its BOTTOM up to its | 721| TOP (cinluded). | 722`------------------------------------------------------------------*/ 723 724#if defined (__STDC__) || defined (__cplusplus) 725static void 726yy_stack_print (short *bottom, short *top) 727#else 728static void 729yy_stack_print (bottom, top) 730 short *bottom; 731 short *top; 732#endif 733{ 734 YYFPRINTF (stderr, "Stack now"); 735 for (/* Nothing. */; bottom <= top; ++bottom) 736 YYFPRINTF (stderr, " %d", *bottom); 737 YYFPRINTF (stderr, "\n"); 738} 739 740# define YY_STACK_PRINT(Bottom, Top) \ 741do { \ 742 if (yydebug) \ 743 yy_stack_print ((Bottom), (Top)); \ 744} while (0) 745 746 747/*------------------------------------------------. 748| Report that the YYRULE is going to be reduced. | 749`------------------------------------------------*/ 750 751#if defined (__STDC__) || defined (__cplusplus) 752static void 753yy_reduce_print (int yyrule) 754#else 755static void 756yy_reduce_print (yyrule) 757 int yyrule; 758#endif 759{ 760 int yyi; 761 unsigned int yylineno = yyrline[yyrule]; 762 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", 763 yyrule - 1, yylineno); 764 /* Print the symbols being reduced, and their result. */ 765 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) 766 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); 767 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); 768} 769 770# define YY_REDUCE_PRINT(Rule) \ 771do { \ 772 if (yydebug) \ 773 yy_reduce_print (Rule); \ 774} while (0) 775 776/* Nonzero means print parse trace. It is left uninitialized so that 777 multiple parsers can coexist. */ 778int yydebug; 779#else /* !YYDEBUG */ 780# define YYDPRINTF(Args) 781# define YYDSYMPRINT(Args) 782# define YYDSYMPRINTF(Title, Token, Value, Location) 783# define YY_STACK_PRINT(Bottom, Top) 784# define YY_REDUCE_PRINT(Rule) 785#endif /* !YYDEBUG */ 786 787 788/* YYINITDEPTH -- initial size of the parser's stacks. */ 789#ifndef YYINITDEPTH 790# define YYINITDEPTH 200 791#endif 792 793/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only 794 if the built-in stack extension method is used). 795 796 Do not make this value too large; the results are undefined if 797 SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) 798 evaluated with infinite-precision integer arithmetic. */ 799 800#if YYMAXDEPTH == 0 801# undef YYMAXDEPTH 802#endif 803 804#ifndef YYMAXDEPTH 805# define YYMAXDEPTH 10000 806#endif 807 808 809 810#if YYERROR_VERBOSE 811 812# ifndef yystrlen 813# if defined (__GLIBC__) && defined (_STRING_H) 814# define yystrlen strlen 815# else 816/* Return the length of YYSTR. */ 817static YYSIZE_T 818# if defined (__STDC__) || defined (__cplusplus) 819yystrlen (const char *yystr) 820# else 821yystrlen (yystr) 822 const char *yystr; 823# endif 824{ 825 register const char *yys = yystr; 826 827 while (*yys++ != '\0') 828 continue; 829 830 return yys - yystr - 1; 831} 832# endif 833# endif 834 835# ifndef yystpcpy 836# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) 837# define yystpcpy stpcpy 838# else 839/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in 840 YYDEST. */ 841static char * 842# if defined (__STDC__) || defined (__cplusplus) 843yystpcpy (char *yydest, const char *yysrc) 844# else 845yystpcpy (yydest, yysrc) 846 char *yydest; 847 const char *yysrc; 848# endif 849{ 850 register char *yyd = yydest; 851 register const char *yys = yysrc; 852 853 while ((*yyd++ = *yys++) != '\0') 854 continue; 855 856 return yyd - 1; 857} 858# endif 859# endif 860 861#endif /* !YYERROR_VERBOSE */ 862 863 864 865#if YYDEBUG 866/*--------------------------------. 867| Print this symbol on YYOUTPUT. | 868`--------------------------------*/ 869 870#if defined (__STDC__) || defined (__cplusplus) 871static void 872yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) 873#else 874static void 875yysymprint (yyoutput, yytype, yyvaluep) 876 FILE *yyoutput; 877 int yytype; 878 YYSTYPE *yyvaluep; 879#endif 880{ 881 /* Pacify ``unused variable'' warnings. */ 882 (void) yyvaluep; 883 884 if (yytype < YYNTOKENS) 885 { 886 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); 887# ifdef YYPRINT 888 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); 889# endif 890 } 891 else 892 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); 893 894 switch (yytype) 895 { 896 default: 897 break; 898 } 899 YYFPRINTF (yyoutput, ")"); 900} 901 902#endif /* ! YYDEBUG */ 903/*-----------------------------------------------. 904| Release the memory associated to this symbol. | 905`-----------------------------------------------*/ 906 907#if defined (__STDC__) || defined (__cplusplus) 908static void 909yydestruct (int yytype, YYSTYPE *yyvaluep) 910#else 911static void 912yydestruct (yytype, yyvaluep) 913 int yytype; 914 YYSTYPE *yyvaluep; 915#endif 916{ 917 /* Pacify ``unused variable'' warnings. */ 918 (void) yyvaluep; 919 920 switch (yytype) 921 { 922 923 default: 924 break; 925 } 926} 927 928 929/* Prevent warnings from -Wmissing-prototypes. */ 930 931#ifdef YYPARSE_PARAM 932# if defined (__STDC__) || defined (__cplusplus) 933int yyparse (void *YYPARSE_PARAM); 934# else 935int yyparse (); 936# endif 937#else /* ! YYPARSE_PARAM */ 938#if defined (__STDC__) || defined (__cplusplus) 939int yyparse (void); 940#else 941int yyparse (); 942#endif 943#endif /* ! YYPARSE_PARAM */ 944 945 946 947 948 949 950/*----------. 951| yyparse. | 952`----------*/ 953 954#ifdef YYPARSE_PARAM 955# if defined (__STDC__) || defined (__cplusplus) 956int yyparse (void *YYPARSE_PARAM) 957# else 958int yyparse (YYPARSE_PARAM) 959 void *YYPARSE_PARAM; 960# endif 961#else /* ! YYPARSE_PARAM */ 962#if defined (__STDC__) || defined (__cplusplus) 963int 964yyparse (void) 965#else 966int 967yyparse () 968 969#endif 970#endif 971{ 972 /* The lookahead symbol. */ 973int yychar; 974 975/* The semantic value of the lookahead symbol. */ 976YYSTYPE yylval; 977 978/* Number of syntax errors so far. */ 979int yynerrs; 980 981 register int yystate; 982 register int yyn; 983 int yyresult; 984 /* Number of tokens to shift before error messages enabled. */ 985 int yyerrstatus; 986 /* Lookahead token as an internal (translated) token number. */ 987 int yytoken = 0; 988 989 /* Three stacks and their tools: 990 `yyss': related to states, 991 `yyvs': related to semantic values, 992 `yyls': related to locations. 993 994 Refer to the stacks thru separate pointers, to allow yyoverflow 995 to reallocate them elsewhere. */ 996 997 /* The state stack. */ 998 short yyssa[YYINITDEPTH]; 999 short *yyss = yyssa; 1000 register short *yyssp; 1001 1002 /* The semantic value stack. */ 1003 YYSTYPE yyvsa[YYINITDEPTH]; 1004 YYSTYPE *yyvs = yyvsa; 1005 register YYSTYPE *yyvsp; 1006 1007 1008 1009#define YYPOPSTACK (yyvsp--, yyssp--) 1010 1011 YYSIZE_T yystacksize = YYINITDEPTH; 1012 1013 /* The variables used to return semantic value and location from the 1014 action routines. */ 1015 YYSTYPE yyval; 1016 1017 1018 /* When reducing, the number of symbols on the RHS of the reduced 1019 rule. */ 1020 int yylen; 1021 1022 YYDPRINTF ((stderr, "Starting parse\n")); 1023 1024 yystate = 0; 1025 yyerrstatus = 0; 1026 yynerrs = 0; 1027 yychar = YYEMPTY; /* Cause a token to be read. */ 1028 1029 /* Initialize stack pointers. 1030 Waste one element of value and location stack 1031 so that they stay on the same level as the state stack. 1032 The wasted elements are never initialized. */ 1033 1034 yyssp = yyss; 1035 yyvsp = yyvs; 1036 1037 goto yysetstate; 1038 1039/*------------------------------------------------------------. 1040| yynewstate -- Push a new state, which is found in yystate. | 1041`------------------------------------------------------------*/ 1042 yynewstate: 1043 /* In all cases, when you get here, the value and location stacks 1044 have just been pushed. so pushing a state here evens the stacks. 1045 */ 1046 yyssp++; 1047 1048 yysetstate: 1049 *yyssp = yystate; 1050 1051 if (yyss + yystacksize - 1 <= yyssp) 1052 { 1053 /* Get the current used size of the three stacks, in elements. */ 1054 YYSIZE_T yysize = yyssp - yyss + 1; 1055 1056#ifdef yyoverflow 1057 { 1058 /* Give user a chance to reallocate the stack. Use copies of 1059 these so that the &'s don't force the real ones into 1060 memory. */ 1061 YYSTYPE *yyvs1 = yyvs; 1062 short *yyss1 = yyss; 1063 1064 1065 /* Each stack pointer address is followed by the size of the 1066 data in use in that stack, in bytes. This used to be a 1067 conditional around just the two extra args, but that might 1068 be undefined if yyoverflow is a macro. */ 1069 yyoverflow ("parser stack overflow", 1070 &yyss1, yysize * sizeof (*yyssp), 1071 &yyvs1, yysize * sizeof (*yyvsp), 1072 1073 &yystacksize); 1074 1075 yyss = yyss1; 1076 yyvs = yyvs1; 1077 } 1078#else /* no yyoverflow */ 1079# ifndef YYSTACK_RELOCATE 1080 goto yyoverflowlab; 1081# else 1082 /* Extend the stack our own way. */ 1083 if (YYMAXDEPTH <= yystacksize) 1084 goto yyoverflowlab; 1085 yystacksize *= 2; 1086 if (YYMAXDEPTH < yystacksize) 1087 yystacksize = YYMAXDEPTH; 1088 1089 { 1090 short *yyss1 = yyss; 1091 union yyalloc *yyptr = 1092 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); 1093 if (! yyptr) 1094 goto yyoverflowlab; 1095 YYSTACK_RELOCATE (yyss); 1096 YYSTACK_RELOCATE (yyvs); 1097 1098# undef YYSTACK_RELOCATE 1099 if (yyss1 != yyssa) 1100 YYSTACK_FREE (yyss1); 1101 } 1102# endif 1103#endif /* no yyoverflow */ 1104 1105 yyssp = yyss + yysize - 1; 1106 yyvsp = yyvs + yysize - 1; 1107 1108 1109 YYDPRINTF ((stderr, "Stack size increased to %lu\n", 1110 (unsigned long int) yystacksize)); 1111 1112 if (yyss + yystacksize - 1 <= yyssp) 1113 YYABORT; 1114 } 1115 1116 YYDPRINTF ((stderr, "Entering state %d\n", yystate)); 1117 1118 goto yybackup; 1119 1120/*-----------. 1121| yybackup. | 1122`-----------*/ 1123yybackup: 1124 1125/* Do appropriate processing given the current state. */ 1126/* Read a lookahead token if we need one and don't already have one. */ 1127/* yyresume: */ 1128 1129 /* First try to decide what to do without reference to lookahead token. */ 1130 1131 yyn = yypact[yystate]; 1132 if (yyn == YYPACT_NINF) 1133 goto yydefault; 1134 1135 /* Not known => get a lookahead token if don't already have one. */ 1136 1137 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ 1138 if (yychar == YYEMPTY) 1139 { 1140 YYDPRINTF ((stderr, "Reading a token: ")); 1141 yychar = YYLEX; 1142 } 1143 1144 if (yychar <= YYEOF) 1145 { 1146 yychar = yytoken = YYEOF; 1147 YYDPRINTF ((stderr, "Now at end of input.\n")); 1148 } 1149 else 1150 { 1151 yytoken = YYTRANSLATE (yychar); 1152 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); 1153 } 1154 1155 /* If the proper action on seeing token YYTOKEN is to reduce or to 1156 detect an error, take that action. */ 1157 yyn += yytoken; 1158 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) 1159 goto yydefault; 1160 yyn = yytable[yyn]; 1161 if (yyn <= 0) 1162 { 1163 if (yyn == 0 || yyn == YYTABLE_NINF) 1164 goto yyerrlab; 1165 yyn = -yyn; 1166 goto yyreduce; 1167 } 1168 1169 if (yyn == YYFINAL) 1170 YYACCEPT; 1171 1172 /* Shift the lookahead token. */ 1173 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); 1174 1175 /* Discard the token being shifted unless it is eof. */ 1176 if (yychar != YYEOF) 1177 yychar = YYEMPTY; 1178 1179 *++yyvsp = yylval; 1180 1181 1182 /* Count tokens shifted since error; after three, turn off error 1183 status. */ 1184 if (yyerrstatus) 1185 yyerrstatus--; 1186 1187 yystate = yyn; 1188 goto yynewstate; 1189 1190 1191/*-----------------------------------------------------------. 1192| yydefault -- do the default action for the current state. | 1193`-----------------------------------------------------------*/ 1194yydefault: 1195 yyn = yydefact[yystate]; 1196 if (yyn == 0) 1197 goto yyerrlab; 1198 goto yyreduce; 1199 1200 1201/*-----------------------------. 1202| yyreduce -- Do a reduction. | 1203`-----------------------------*/ 1204yyreduce: 1205 /* yyn is the number of a rule to reduce with. */ 1206 yylen = yyr2[yyn]; 1207 1208 /* If YYLEN is nonzero, implement the default value of the action: 1209 `$$ = $1'. 1210 1211 Otherwise, the following line sets YYVAL to garbage. 1212 This behavior is undocumented and Bison 1213 users should not rely upon it. Assigning to YYVAL 1214 unconditionally makes the parser a bit smaller, and it avoids a 1215 GCC warning that YYVAL may be used uninitialized. */ 1216 yyval = yyvsp[1-yylen]; 1217 1218 1219 YY_REDUCE_PRINT (yyn); 1220 switch (yyn) 1221 { 1222 case 4: 1223#line 195 "getdate.y" 1224 { PC.times_seen++; } 1225 break; 1226 1227 case 5: 1228#line 197 "getdate.y" 1229 { PC.local_zones_seen++; } 1230 break; 1231 1232 case 6: 1233#line 199 "getdate.y" 1234 { PC.zones_seen++; } 1235 break; 1236 1237 case 7: 1238#line 201 "getdate.y" 1239 { PC.dates_seen++; } 1240 break; 1241 1242 case 8: 1243#line 203 "getdate.y" 1244 { PC.days_seen++; } 1245 break; 1246 1247 case 9: 1248#line 205 "getdate.y" 1249 { PC.rels_seen++; } 1250 break; 1251 1252 case 11: 1253#line 211 "getdate.y" 1254 { 1255 PC.hour = yyvsp[-1].textintval.value; 1256 PC.minutes = 0; 1257 PC.seconds = 0; 1258 PC.meridian = yyvsp[0].intval; 1259 } 1260 break; 1261 1262 case 12: 1263#line 218 "getdate.y" 1264 { 1265 PC.hour = yyvsp[-3].textintval.value; 1266 PC.minutes = yyvsp[-1].textintval.value; 1267 PC.seconds = 0; 1268 PC.meridian = yyvsp[0].intval; 1269 } 1270 break; 1271 1272 case 13: 1273#line 225 "getdate.y" 1274 { 1275 PC.hour = yyvsp[-3].textintval.value; 1276 PC.minutes = yyvsp[-1].textintval.value; 1277 PC.meridian = MER24; 1278 PC.zones_seen++; 1279 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60; 1280 } 1281 break; 1282 1283 case 14: 1284#line 233 "getdate.y" 1285 { 1286 PC.hour = yyvsp[-5].textintval.value; 1287 PC.minutes = yyvsp[-3].textintval.value; 1288 PC.seconds = yyvsp[-1].textintval.value; 1289 PC.meridian = yyvsp[0].intval; 1290 } 1291 break; 1292 1293 case 15: 1294#line 240 "getdate.y" 1295 { 1296 PC.hour = yyvsp[-5].textintval.value; 1297 PC.minutes = yyvsp[-3].textintval.value; 1298 PC.seconds = yyvsp[-1].textintval.value; 1299 PC.meridian = MER24; 1300 PC.zones_seen++; 1301 PC.time_zone = yyvsp[0].textintval.value % 100 + (yyvsp[0].textintval.value / 100) * 60; 1302 } 1303 break; 1304 1305 case 16: 1306#line 252 "getdate.y" 1307 { PC.local_isdst = yyvsp[0].intval; } 1308 break; 1309 1310 case 17: 1311#line 254 "getdate.y" 1312 { PC.local_isdst = yyvsp[-1].intval < 0 ? 1 : yyvsp[-1].intval + 1; } 1313 break; 1314 1315 case 18: 1316#line 259 "getdate.y" 1317 { PC.time_zone = yyvsp[0].intval; } 1318 break; 1319 1320 case 19: 1321#line 261 "getdate.y" 1322 { PC.time_zone = yyvsp[0].intval + 60; } 1323 break; 1324 1325 case 20: 1326#line 263 "getdate.y" 1327 { PC.time_zone = yyvsp[-1].intval + 60; } 1328 break; 1329 1330 case 21: 1331#line 268 "getdate.y" 1332 { 1333 PC.day_ordinal = 1; 1334 PC.day_number = yyvsp[0].intval; 1335 } 1336 break; 1337 1338 case 22: 1339#line 273 "getdate.y" 1340 { 1341 PC.day_ordinal = 1; 1342 PC.day_number = yyvsp[-1].intval; 1343 } 1344 break; 1345 1346 case 23: 1347#line 278 "getdate.y" 1348 { 1349 PC.day_ordinal = yyvsp[-1].textintval.value; 1350 PC.day_number = yyvsp[0].intval; 1351 } 1352 break; 1353 1354 case 24: 1355#line 286 "getdate.y" 1356 { 1357 PC.month = yyvsp[-2].textintval.value; 1358 PC.day = yyvsp[0].textintval.value; 1359 } 1360 break; 1361 1362 case 25: 1363#line 291 "getdate.y" 1364 { 1365 /* Interpret as YYYY/MM/DD if the first value has 4 or more digits, 1366 otherwise as MM/DD/YY. 1367 The goal in recognizing YYYY/MM/DD is solely to support legacy 1368 machine-generated dates like those in an RCS log listing. If 1369 you want portability, use the ISO 8601 format. */ 1370 if (4 <= yyvsp[-4].textintval.digits) 1371 { 1372 PC.year = yyvsp[-4].textintval; 1373 PC.month = yyvsp[-2].textintval.value; 1374 PC.day = yyvsp[0].textintval.value; 1375 } 1376 else 1377 { 1378 PC.month = yyvsp[-4].textintval.value; 1379 PC.day = yyvsp[-2].textintval.value; 1380 PC.year = yyvsp[0].textintval; 1381 } 1382 } 1383 break; 1384 1385 case 26: 1386#line 311 "getdate.y" 1387 { 1388 /* ISO 8601 format. YYYY-MM-DD. */ 1389 PC.year = yyvsp[-2].textintval; 1390 PC.month = -yyvsp[-1].textintval.value; 1391 PC.day = -yyvsp[0].textintval.value; 1392 } 1393 break; 1394 1395 case 27: 1396#line 318 "getdate.y" 1397 { 1398 /* e.g. 17-JUN-1992. */ 1399 PC.day = yyvsp[-2].textintval.value; 1400 PC.month = yyvsp[-1].intval; 1401 PC.year.value = -yyvsp[0].textintval.value; 1402 PC.year.digits = yyvsp[0].textintval.digits; 1403 } 1404 break; 1405 1406 case 28: 1407#line 326 "getdate.y" 1408 { 1409 PC.month = yyvsp[-1].intval; 1410 PC.day = yyvsp[0].textintval.value; 1411 } 1412 break; 1413 1414 case 29: 1415#line 331 "getdate.y" 1416 { 1417 PC.month = yyvsp[-3].intval; 1418 PC.day = yyvsp[-2].textintval.value; 1419 PC.year = yyvsp[0].textintval; 1420 } 1421 break; 1422 1423 case 30: 1424#line 337 "getdate.y" 1425 { 1426 PC.day = yyvsp[-1].textintval.value; 1427 PC.month = yyvsp[0].intval; 1428 } 1429 break; 1430 1431 case 31: 1432#line 342 "getdate.y" 1433 { 1434 PC.day = yyvsp[-2].textintval.value; 1435 PC.month = yyvsp[-1].intval; 1436 PC.year = yyvsp[0].textintval; 1437 } 1438 break; 1439 1440 case 32: 1441#line 351 "getdate.y" 1442 { 1443 PC.rel_seconds = -PC.rel_seconds; 1444 PC.rel_minutes = -PC.rel_minutes; 1445 PC.rel_hour = -PC.rel_hour; 1446 PC.rel_day = -PC.rel_day; 1447 PC.rel_month = -PC.rel_month; 1448 PC.rel_year = -PC.rel_year; 1449 } 1450 break; 1451 1452 case 34: 1453#line 364 "getdate.y" 1454 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1455 break; 1456 1457 case 35: 1458#line 366 "getdate.y" 1459 { PC.rel_year += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1460 break; 1461 1462 case 36: 1463#line 368 "getdate.y" 1464 { PC.rel_year += yyvsp[0].intval; } 1465 break; 1466 1467 case 37: 1468#line 370 "getdate.y" 1469 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1470 break; 1471 1472 case 38: 1473#line 372 "getdate.y" 1474 { PC.rel_month += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1475 break; 1476 1477 case 39: 1478#line 374 "getdate.y" 1479 { PC.rel_month += yyvsp[0].intval; } 1480 break; 1481 1482 case 40: 1483#line 376 "getdate.y" 1484 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1485 break; 1486 1487 case 41: 1488#line 378 "getdate.y" 1489 { PC.rel_day += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1490 break; 1491 1492 case 42: 1493#line 380 "getdate.y" 1494 { PC.rel_day += yyvsp[0].intval; } 1495 break; 1496 1497 case 43: 1498#line 382 "getdate.y" 1499 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1500 break; 1501 1502 case 44: 1503#line 384 "getdate.y" 1504 { PC.rel_hour += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1505 break; 1506 1507 case 45: 1508#line 386 "getdate.y" 1509 { PC.rel_hour += yyvsp[0].intval; } 1510 break; 1511 1512 case 46: 1513#line 388 "getdate.y" 1514 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1515 break; 1516 1517 case 47: 1518#line 390 "getdate.y" 1519 { PC.rel_minutes += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1520 break; 1521 1522 case 48: 1523#line 392 "getdate.y" 1524 { PC.rel_minutes += yyvsp[0].intval; } 1525 break; 1526 1527 case 49: 1528#line 394 "getdate.y" 1529 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1530 break; 1531 1532 case 50: 1533#line 396 "getdate.y" 1534 { PC.rel_seconds += yyvsp[-1].textintval.value * yyvsp[0].intval; } 1535 break; 1536 1537 case 51: 1538#line 398 "getdate.y" 1539 { PC.rel_seconds += yyvsp[0].intval; } 1540 break; 1541 1542 case 52: 1543#line 403 "getdate.y" 1544 { 1545 if (PC.dates_seen 1546 && ! PC.rels_seen && (PC.times_seen || 2 < yyvsp[0].textintval.digits)) 1547 PC.year = yyvsp[0].textintval; 1548 else 1549 { 1550 if (4 < yyvsp[0].textintval.digits) 1551 { 1552 PC.dates_seen++; 1553 PC.day = yyvsp[0].textintval.value % 100; 1554 PC.month = (yyvsp[0].textintval.value / 100) % 100; 1555 PC.year.value = yyvsp[0].textintval.value / 10000; 1556 PC.year.digits = yyvsp[0].textintval.digits - 4; 1557 } 1558 else 1559 { 1560 PC.times_seen++; 1561 if (yyvsp[0].textintval.digits <= 2) 1562 { 1563 PC.hour = yyvsp[0].textintval.value; 1564 PC.minutes = 0; 1565 } 1566 else 1567 { 1568 PC.hour = yyvsp[0].textintval.value / 100; 1569 PC.minutes = yyvsp[0].textintval.value % 100; 1570 } 1571 PC.seconds = 0; 1572 PC.meridian = MER24; 1573 } 1574 } 1575 } 1576 break; 1577 1578 case 53: 1579#line 439 "getdate.y" 1580 { yyval.intval = MER24; } 1581 break; 1582 1583 case 54: 1584#line 441 "getdate.y" 1585 { yyval.intval = yyvsp[0].intval; } 1586 break; 1587 1588 1589 } 1590 1591/* Line 999 of yacc.c. */ 1592#line 1593 "getdate.c" 1593 1594 yyvsp -= yylen; 1595 yyssp -= yylen; 1596 1597 1598 YY_STACK_PRINT (yyss, yyssp); 1599 1600 *++yyvsp = yyval; 1601 1602 1603 /* Now `shift' the result of the reduction. Determine what state 1604 that goes to, based on the state we popped back to and the rule 1605 number reduced by. */ 1606 1607 yyn = yyr1[yyn]; 1608 1609 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; 1610 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) 1611 yystate = yytable[yystate]; 1612 else 1613 yystate = yydefgoto[yyn - YYNTOKENS]; 1614 1615 goto yynewstate; 1616 1617 1618/*------------------------------------. 1619| yyerrlab -- here on detecting error | 1620`------------------------------------*/ 1621yyerrlab: 1622 /* If not already recovering from an error, report this error. */ 1623 if (!yyerrstatus) 1624 { 1625 ++yynerrs; 1626#if YYERROR_VERBOSE 1627 yyn = yypact[yystate]; 1628 1629 if (YYPACT_NINF < yyn && yyn < YYLAST) 1630 { 1631 YYSIZE_T yysize = 0; 1632 int yytype = YYTRANSLATE (yychar); 1633 char *yymsg; 1634 int yyx, yycount; 1635 1636 yycount = 0; 1637 /* Start YYX at -YYN if negative to avoid negative indexes in 1638 YYCHECK. */ 1639 for (yyx = yyn < 0 ? -yyn : 0; 1640 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) 1641 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1642 yysize += yystrlen (yytname[yyx]) + 15, yycount++; 1643 yysize += yystrlen ("syntax error, unexpected ") + 1; 1644 yysize += yystrlen (yytname[yytype]); 1645 yymsg = (char *) YYSTACK_ALLOC (yysize); 1646 if (yymsg != 0) 1647 { 1648 char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); 1649 yyp = yystpcpy (yyp, yytname[yytype]); 1650 1651 if (yycount < 5) 1652 { 1653 yycount = 0; 1654 for (yyx = yyn < 0 ? -yyn : 0; 1655 yyx < (int) (sizeof (yytname) / sizeof (char *)); 1656 yyx++) 1657 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) 1658 { 1659 const char *yyq = ! yycount ? ", expecting " : " or "; 1660 yyp = yystpcpy (yyp, yyq); 1661 yyp = yystpcpy (yyp, yytname[yyx]); 1662 yycount++; 1663 } 1664 } 1665 yyerror (yymsg); 1666 YYSTACK_FREE (yymsg); 1667 } 1668 else 1669 yyerror ("syntax error; also virtual memory exhausted"); 1670 } 1671 else 1672#endif /* YYERROR_VERBOSE */ 1673 yyerror ("syntax error"); 1674 } 1675 1676 1677 1678 if (yyerrstatus == 3) 1679 { 1680 /* If just tried and failed to reuse lookahead token after an 1681 error, discard it. */ 1682 1683 /* Return failure if at end of input. */ 1684 if (yychar == YYEOF) 1685 { 1686 /* Pop the error token. */ 1687 YYPOPSTACK; 1688 /* Pop the rest of the stack. */ 1689 while (yyss < yyssp) 1690 { 1691 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 1692 yydestruct (yystos[*yyssp], yyvsp); 1693 YYPOPSTACK; 1694 } 1695 YYABORT; 1696 } 1697 1698 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); 1699 yydestruct (yytoken, &yylval); 1700 yychar = YYEMPTY; 1701 1702 } 1703 1704 /* Else will try to reuse lookahead token after shifting the error 1705 token. */ 1706 goto yyerrlab1; 1707 1708 1709/*----------------------------------------------------. 1710| yyerrlab1 -- error raised explicitly by an action. | 1711`----------------------------------------------------*/ 1712yyerrlab1: 1713 yyerrstatus = 3; /* Each real token shifted decrements this. */ 1714 1715 for (;;) 1716 { 1717 yyn = yypact[yystate]; 1718 if (yyn != YYPACT_NINF) 1719 { 1720 yyn += YYTERROR; 1721 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) 1722 { 1723 yyn = yytable[yyn]; 1724 if (0 < yyn) 1725 break; 1726 } 1727 } 1728 1729 /* Pop the current state because it cannot handle the error token. */ 1730 if (yyssp == yyss) 1731 YYABORT; 1732 1733 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); 1734 yydestruct (yystos[yystate], yyvsp); 1735 yyvsp--; 1736 yystate = *--yyssp; 1737 1738 YY_STACK_PRINT (yyss, yyssp); 1739 } 1740 1741 if (yyn == YYFINAL) 1742 YYACCEPT; 1743 1744 YYDPRINTF ((stderr, "Shifting error token, ")); 1745 1746 *++yyvsp = yylval; 1747 1748 1749 yystate = yyn; 1750 goto yynewstate; 1751 1752 1753/*-------------------------------------. 1754| yyacceptlab -- YYACCEPT comes here. | 1755`-------------------------------------*/ 1756yyacceptlab: 1757 yyresult = 0; 1758 goto yyreturn; 1759 1760/*-----------------------------------. 1761| yyabortlab -- YYABORT comes here. | 1762`-----------------------------------*/ 1763yyabortlab: 1764 yyresult = 1; 1765 goto yyreturn; 1766 1767#ifndef yyoverflow 1768/*----------------------------------------------. 1769| yyoverflowlab -- parser overflow comes here. | 1770`----------------------------------------------*/ 1771yyoverflowlab: 1772 yyerror ("parser stack overflow"); 1773 yyresult = 2; 1774 /* Fall through. */ 1775#endif 1776 1777yyreturn: 1778#ifndef yyoverflow 1779 if (yyss != yyssa) 1780 YYSTACK_FREE (yyss); 1781#endif 1782 return yyresult; 1783} 1784 1785 1786#line 444 "getdate.y" 1787 1788 1789/* Include this file down here because bison inserts code above which 1790 may define-away `const'. We want the prototype for get_date to have 1791 the same signature as the function definition. */ 1792#include "modules/getdate.h" 1793 1794#ifndef gmtime 1795struct tm *gmtime (); 1796#endif 1797#ifndef localtime 1798struct tm *localtime (); 1799#endif 1800#ifndef mktime 1801time_t mktime (); 1802#endif 1803 1804static table const meridian_table[] = 1805{ 1806 { "AM", tMERIDIAN, MERam }, 1807 { "A.M.", tMERIDIAN, MERam }, 1808 { "PM", tMERIDIAN, MERpm }, 1809 { "P.M.", tMERIDIAN, MERpm }, 1810 { 0, 0, 0 } 1811}; 1812 1813static table const dst_table[] = 1814{ 1815 { "DST", tDST, 0 } 1816}; 1817 1818static table const month_and_day_table[] = 1819{ 1820 { "JANUARY", tMONTH, 1 }, 1821 { "FEBRUARY", tMONTH, 2 }, 1822 { "MARCH", tMONTH, 3 }, 1823 { "APRIL", tMONTH, 4 }, 1824 { "MAY", tMONTH, 5 }, 1825 { "JUNE", tMONTH, 6 }, 1826 { "JULY", tMONTH, 7 }, 1827 { "AUGUST", tMONTH, 8 }, 1828 { "SEPTEMBER",tMONTH, 9 }, 1829 { "SEPT", tMONTH, 9 }, 1830 { "OCTOBER", tMONTH, 10 }, 1831 { "NOVEMBER", tMONTH, 11 }, 1832 { "DECEMBER", tMONTH, 12 }, 1833 { "SUNDAY", tDAY, 0 }, 1834 { "MONDAY", tDAY, 1 }, 1835 { "TUESDAY", tDAY, 2 }, 1836 { "TUES", tDAY, 2 }, 1837 { "WEDNESDAY",tDAY, 3 }, 1838 { "WEDNES", tDAY, 3 }, 1839 { "THURSDAY", tDAY, 4 }, 1840 { "THUR", tDAY, 4 }, 1841 { "THURS", tDAY, 4 }, 1842 { "FRIDAY", tDAY, 5 }, 1843 { "SATURDAY", tDAY, 6 }, 1844 { 0, 0, 0 } 1845}; 1846 1847static table const time_units_table[] = 1848{ 1849 { "YEAR", tYEAR_UNIT, 1 }, 1850 { "MONTH", tMONTH_UNIT, 1 }, 1851 { "FORTNIGHT",tDAY_UNIT, 14 }, 1852 { "WEEK", tDAY_UNIT, 7 }, 1853 { "DAY", tDAY_UNIT, 1 }, 1854 { "HOUR", tHOUR_UNIT, 1 }, 1855 { "MINUTE", tMINUTE_UNIT, 1 }, 1856 { "MIN", tMINUTE_UNIT, 1 }, 1857 { "SECOND", tSEC_UNIT, 1 }, 1858 { "SEC", tSEC_UNIT, 1 }, 1859 { 0, 0, 0 } 1860}; 1861 1862/* Assorted relative-time words. */ 1863static table const relative_time_table[] = 1864{ 1865 { "TOMORROW", tMINUTE_UNIT, 24 * 60 }, 1866 { "YESTERDAY",tMINUTE_UNIT, - (24 * 60) }, 1867 { "TODAY", tMINUTE_UNIT, 0 }, 1868 { "NOW", tMINUTE_UNIT, 0 }, 1869 { "LAST", tUNUMBER, -1 }, 1870 { "THIS", tUNUMBER, 0 }, 1871 { "NEXT", tUNUMBER, 1 }, 1872 { "FIRST", tUNUMBER, 1 }, 1873/*{ "SECOND", tUNUMBER, 2 }, */ 1874 { "THIRD", tUNUMBER, 3 }, 1875 { "FOURTH", tUNUMBER, 4 }, 1876 { "FIFTH", tUNUMBER, 5 }, 1877 { "SIXTH", tUNUMBER, 6 }, 1878 { "SEVENTH", tUNUMBER, 7 }, 1879 { "EIGHTH", tUNUMBER, 8 }, 1880 { "NINTH", tUNUMBER, 9 }, 1881 { "TENTH", tUNUMBER, 10 }, 1882 { "ELEVENTH", tUNUMBER, 11 }, 1883 { "TWELFTH", tUNUMBER, 12 }, 1884 { "AGO", tAGO, 1 }, 1885 { 0, 0, 0 } 1886}; 1887 1888/* The time zone table. This table is necessarily incomplete, as time 1889 zone abbreviations are ambiguous; e.g. Australians interpret "EST" 1890 as Eastern time in Australia, not as US Eastern Standard Time. 1891 You cannot rely on getdate to handle arbitrary time zone 1892 abbreviations; use numeric abbreviations like `-0500' instead. */ 1893static table const time_zone_table[] = 1894{ 1895 { "GMT", tZONE, HOUR ( 0) }, /* Greenwich Mean */ 1896 { "UT", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */ 1897 { "UTC", tZONE, HOUR ( 0) }, 1898 { "WET", tZONE, HOUR ( 0) }, /* Western European */ 1899 { "WEST", tDAYZONE, HOUR ( 0) }, /* Western European Summer */ 1900 { "BST", tDAYZONE, HOUR ( 0) }, /* British Summer */ 1901 { "ART", tZONE, -HOUR ( 3) }, /* Argentina */ 1902 { "BRT", tZONE, -HOUR ( 3) }, /* Brazil */ 1903 { "BRST", tDAYZONE, -HOUR ( 3) }, /* Brazil Summer */ 1904 { "NST", tZONE, -(HOUR ( 3) + 30) }, /* Newfoundland Standard */ 1905 { "NDT", tDAYZONE,-(HOUR ( 3) + 30) }, /* Newfoundland Daylight */ 1906 { "AST", tZONE, -HOUR ( 4) }, /* Atlantic Standard */ 1907 { "ADT", tDAYZONE, -HOUR ( 4) }, /* Atlantic Daylight */ 1908 { "CLT", tZONE, -HOUR ( 4) }, /* Chile */ 1909 { "CLST", tDAYZONE, -HOUR ( 4) }, /* Chile Summer */ 1910 { "EST", tZONE, -HOUR ( 5) }, /* Eastern Standard */ 1911 { "EDT", tDAYZONE, -HOUR ( 5) }, /* Eastern Daylight */ 1912 { "CST", tZONE, -HOUR ( 6) }, /* Central Standard */ 1913 { "CDT", tDAYZONE, -HOUR ( 6) }, /* Central Daylight */ 1914 { "MST", tZONE, -HOUR ( 7) }, /* Mountain Standard */ 1915 { "MDT", tDAYZONE, -HOUR ( 7) }, /* Mountain Daylight */ 1916 { "PST", tZONE, -HOUR ( 8) }, /* Pacific Standard */ 1917 { "PDT", tDAYZONE, -HOUR ( 8) }, /* Pacific Daylight */ 1918 { "AKST", tZONE, -HOUR ( 9) }, /* Alaska Standard */ 1919 { "AKDT", tDAYZONE, -HOUR ( 9) }, /* Alaska Daylight */ 1920 { "HST", tZONE, -HOUR (10) }, /* Hawaii Standard */ 1921 { "HAST", tZONE, -HOUR (10) }, /* Hawaii-Aleutian Standard */ 1922 { "HADT", tDAYZONE, -HOUR (10) }, /* Hawaii-Aleutian Daylight */ 1923 { "SST", tZONE, -HOUR (12) }, /* Samoa Standard */ 1924 { "WAT", tZONE, HOUR ( 1) }, /* West Africa */ 1925 { "CET", tZONE, HOUR ( 1) }, /* Central European */ 1926 { "CEST", tDAYZONE, HOUR ( 1) }, /* Central European Summer */ 1927 { "MET", tZONE, HOUR ( 1) }, /* Middle European */ 1928 { "MEZ", tZONE, HOUR ( 1) }, /* Middle European */ 1929 { "MEST", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ 1930 { "MESZ", tDAYZONE, HOUR ( 1) }, /* Middle European Summer */ 1931 { "EET", tZONE, HOUR ( 2) }, /* Eastern European */ 1932 { "EEST", tDAYZONE, HOUR ( 2) }, /* Eastern European Summer */ 1933 { "CAT", tZONE, HOUR ( 2) }, /* Central Africa */ 1934 { "SAST", tZONE, HOUR ( 2) }, /* South Africa Standard */ 1935 { "EAT", tZONE, HOUR ( 3) }, /* East Africa */ 1936 { "MSK", tZONE, HOUR ( 3) }, /* Moscow */ 1937 { "MSD", tDAYZONE, HOUR ( 3) }, /* Moscow Daylight */ 1938 { "IST", tZONE, (HOUR ( 5) + 30) }, /* India Standard */ 1939 { "SGT", tZONE, HOUR ( 8) }, /* Singapore */ 1940 { "KST", tZONE, HOUR ( 9) }, /* Korea Standard */ 1941 { "JST", tZONE, HOUR ( 9) }, /* Japan Standard */ 1942 { "GST", tZONE, HOUR (10) }, /* Guam Standard */ 1943 { "NZST", tZONE, HOUR (12) }, /* New Zealand Standard */ 1944 { "NZDT", tDAYZONE, HOUR (12) }, /* New Zealand Daylight */ 1945 { 0, 0, 0 } 1946}; 1947 1948/* Military time zone table. */ 1949static table const military_table[] = 1950{ 1951 { "A", tZONE, -HOUR ( 1) }, 1952 { "B", tZONE, -HOUR ( 2) }, 1953 { "C", tZONE, -HOUR ( 3) }, 1954 { "D", tZONE, -HOUR ( 4) }, 1955 { "E", tZONE, -HOUR ( 5) }, 1956 { "F", tZONE, -HOUR ( 6) }, 1957 { "G", tZONE, -HOUR ( 7) }, 1958 { "H", tZONE, -HOUR ( 8) }, 1959 { "I", tZONE, -HOUR ( 9) }, 1960 { "K", tZONE, -HOUR (10) }, 1961 { "L", tZONE, -HOUR (11) }, 1962 { "M", tZONE, -HOUR (12) }, 1963 { "N", tZONE, HOUR ( 1) }, 1964 { "O", tZONE, HOUR ( 2) }, 1965 { "P", tZONE, HOUR ( 3) }, 1966 { "Q", tZONE, HOUR ( 4) }, 1967 { "R", tZONE, HOUR ( 5) }, 1968 { "S", tZONE, HOUR ( 6) }, 1969 { "T", tZONE, HOUR ( 7) }, 1970 { "U", tZONE, HOUR ( 8) }, 1971 { "V", tZONE, HOUR ( 9) }, 1972 { "W", tZONE, HOUR (10) }, 1973 { "X", tZONE, HOUR (11) }, 1974 { "Y", tZONE, HOUR (12) }, 1975 { "Z", tZONE, HOUR ( 0) }, 1976 { 0, 0, 0 } 1977}; 1978 1979 1980 1981static int 1982to_hour (int hours, int meridian) 1983{ 1984 switch (meridian) 1985 { 1986 case MER24: 1987 return 0 <= hours && hours < 24 ? hours : -1; 1988 case MERam: 1989 return 0 < hours && hours < 12 ? hours : hours == 12 ? 0 : -1; 1990 case MERpm: 1991 return 0 < hours && hours < 12 ? hours + 12 : hours == 12 ? 12 : -1; 1992 default: 1993 abort (); 1994 } 1995 /* NOTREACHED */ 1996 return 0; 1997} 1998 1999static int 2000to_year (textint textyear) 2001{ 2002 int year = textyear.value; 2003 2004 if (year < 0) 2005 year = -year; 2006 2007 /* XPG4 suggests that years 00-68 map to 2000-2068, and 2008 years 69-99 map to 1969-1999. */ 2009 if (textyear.digits == 2) 2010 year += year < 69 ? 2000 : 1900; 2011 2012 return year; 2013} 2014 2015static table const * 2016lookup_zone (parser_control const *pc, char const *name) 2017{ 2018 table const *tp; 2019 2020 /* Try local zone abbreviations first; they're more likely to be right. */ 2021 for (tp = pc->local_time_zone_table; tp->name; tp++) 2022 if (strcmp (name, tp->name) == 0) 2023 return tp; 2024 2025 for (tp = time_zone_table; tp->name; tp++) 2026 if (strcmp (name, tp->name) == 0) 2027 return tp; 2028 2029 return 0; 2030} 2031 2032#if ! HAVE_TM_GMTOFF 2033/* Yield the difference between *A and *B, 2034 measured in seconds, ignoring leap seconds. 2035 The body of this function is taken directly from the GNU C Library; 2036 see src/strftime.c. */ 2037static int 2038tm_diff (struct tm const *a, struct tm const *b) 2039{ 2040 /* Compute intervening leap days correctly even if year is negative. 2041 Take care to avoid int overflow in leap day calculations, 2042 but it's OK to assume that A and B are close to each other. */ 2043 int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3); 2044 int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3); 2045 int a100 = a4 / 25 - (a4 % 25 < 0); 2046 int b100 = b4 / 25 - (b4 % 25 < 0); 2047 int a400 = a100 >> 2; 2048 int b400 = b100 >> 2; 2049 int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); 2050 int years = a->tm_year - b->tm_year; 2051 int days = (365 * years + intervening_leap_days 2052 + (a->tm_yday - b->tm_yday)); 2053 return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) 2054 + (a->tm_min - b->tm_min)) 2055 + (a->tm_sec - b->tm_sec)); 2056} 2057#endif /* ! HAVE_TM_GMTOFF */ 2058 2059static table const * 2060lookup_word (parser_control const *pc, char *word) 2061{ 2062 char *p; 2063 char *q; 2064 size_t wordlen; 2065 table const *tp; 2066 int i; 2067 int abbrev; 2068 2069 /* Make it uppercase. */ 2070 for (p = word; *p; p++) 2071 if (ISLOWER ((unsigned char) *p)) 2072 *p = toupper ((unsigned char) *p); 2073 2074 for (tp = meridian_table; tp->name; tp++) 2075 if (strcmp (word, tp->name) == 0) 2076 return tp; 2077 2078 /* See if we have an abbreviation for a month. */ 2079 wordlen = strlen (word); 2080 abbrev = wordlen == 3 || (wordlen == 4 && word[3] == '.'); 2081 2082 for (tp = month_and_day_table; tp->name; tp++) 2083 if ((abbrev ? strncmp (word, tp->name, 3) : strcmp (word, tp->name)) == 0) 2084 return tp; 2085 2086 if ((tp = lookup_zone (pc, word))) 2087 return tp; 2088 2089 if (strcmp (word, dst_table[0].name) == 0) 2090 return dst_table; 2091 2092 for (tp = time_units_table; tp->name; tp++) 2093 if (strcmp (word, tp->name) == 0) 2094 return tp; 2095 2096 /* Strip off any plural and try the units table again. */ 2097 if (word[wordlen - 1] == 'S') 2098 { 2099 word[wordlen - 1] = '\0'; 2100 for (tp = time_units_table; tp->name; tp++) 2101 if (strcmp (word, tp->name) == 0) 2102 return tp; 2103 word[wordlen - 1] = 'S'; /* For "this" in relative_time_table. */ 2104 } 2105 2106 for (tp = relative_time_table; tp->name; tp++) 2107 if (strcmp (word, tp->name) == 0) 2108 return tp; 2109 2110 /* Military time zones. */ 2111 if (wordlen == 1) 2112 for (tp = military_table; tp->name; tp++) 2113 if (word[0] == tp->name[0]) 2114 return tp; 2115 2116 /* Drop out any periods and try the time zone table again. */ 2117 for (i = 0, p = q = word; (*p = *q); q++) 2118 if (*q == '.') 2119 i = 1; 2120 else 2121 p++; 2122 if (i && (tp = lookup_zone (pc, word))) 2123 return tp; 2124 2125 return 0; 2126} 2127 2128static int 2129yylex (YYSTYPE *lvalp, parser_control *pc) 2130{ 2131 unsigned char c; 2132 int count; 2133 2134 for (;;) 2135 { 2136 while (c = *pc->input, ISSPACE (c)) 2137 pc->input++; 2138 2139 if (ISDIGIT (c) || c == '-' || c == '+') 2140 { 2141 char const *p; 2142 int sign; 2143 int value; 2144 if (c == '-' || c == '+') 2145 { 2146 sign = c == '-' ? -1 : 1; 2147 c = *++pc->input; 2148 if (! ISDIGIT (c)) 2149 /* skip the '-' sign */ 2150 continue; 2151 } 2152 else 2153 sign = 0; 2154 p = pc->input; 2155 value = 0; 2156 do 2157 { 2158 value = 10 * value + c - '0'; 2159 c = *++p; 2160 } 2161 while (ISDIGIT (c)); 2162 lvalp->textintval.value = sign < 0 ? -value : value; 2163 lvalp->textintval.digits = p - pc->input; 2164 pc->input = p; 2165 return sign ? tSNUMBER : tUNUMBER; 2166 } 2167 2168 if (ISALPHA (c)) 2169 { 2170 char buff[20]; 2171 char *p = buff; 2172 table const *tp; 2173 2174 do 2175 { 2176 if (p < buff + sizeof buff - 1) 2177 *p++ = c; 2178 c = *++pc->input; 2179 } 2180 while (ISALPHA (c) || c == '.'); 2181 2182 *p = '\0'; 2183 tp = lookup_word (pc, buff); 2184 if (! tp) 2185 return '?'; 2186 lvalp->intval = tp->value; 2187 return tp->type; 2188 } 2189 2190 if (c != '(') 2191 return *pc->input++; 2192 count = 0; 2193 do 2194 { 2195 c = *pc->input++; 2196 if (c == '\0') 2197 return c; 2198 if (c == '(') 2199 count++; 2200 else if (c == ')') 2201 count--; 2202 } 2203 while (count > 0); 2204 } 2205} 2206 2207/* Do nothing if the parser reports an error. */ 2208static int 2209yyerror (char *s ATTRIBUTE_UNUSED) 2210{ 2211 return 0; 2212} 2213 2214/* Parse a date/time string P. Return the corresponding time_t value, 2215 or (time_t) -1 if there is an error. P can be an incomplete or 2216 relative time specification; if so, use *NOW as the basis for the 2217 returned time. */ 2218time_t 2219get_date (const char *p, const time_t *now) 2220{ 2221 time_t Start = now ? *now : time (0); 2222 struct tm *tmp = localtime (&Start); 2223 struct tm tm; 2224 struct tm tm0; 2225 parser_control pc; 2226 2227 if (! tmp) 2228 return -1; 2229 2230 pc.input = p; 2231 pc.year.value = tmp->tm_year + TM_YEAR_BASE; 2232 pc.year.digits = 4; 2233 pc.month = tmp->tm_mon + 1; 2234 pc.day = tmp->tm_mday; 2235 pc.hour = tmp->tm_hour; 2236 pc.minutes = tmp->tm_min; 2237 pc.seconds = tmp->tm_sec; 2238 tm.tm_isdst = tmp->tm_isdst; 2239 2240 pc.meridian = MER24; 2241 pc.rel_seconds = 0; 2242 pc.rel_minutes = 0; 2243 pc.rel_hour = 0; 2244 pc.rel_day = 0; 2245 pc.rel_month = 0; 2246 pc.rel_year = 0; 2247 pc.dates_seen = 0; 2248 pc.days_seen = 0; 2249 pc.rels_seen = 0; 2250 pc.times_seen = 0; 2251 pc.local_zones_seen = 0; 2252 pc.zones_seen = 0; 2253 2254#if HAVE_STRUCT_TM_TM_ZONE 2255 pc.local_time_zone_table[0].name = tmp->tm_zone; 2256 pc.local_time_zone_table[0].type = tLOCAL_ZONE; 2257 pc.local_time_zone_table[0].value = tmp->tm_isdst; 2258 pc.local_time_zone_table[1].name = 0; 2259 2260 /* Probe the names used in the next three calendar quarters, looking 2261 for a tm_isdst different from the one we already have. */ 2262 { 2263 int quarter; 2264 for (quarter = 1; quarter <= 3; quarter++) 2265 { 2266 time_t probe = Start + quarter * (90 * 24 * 60 * 60); 2267 struct tm *probe_tm = localtime (&probe); 2268 if (probe_tm && probe_tm->tm_zone 2269 && probe_tm->tm_isdst != pc.local_time_zone_table[0].value) 2270 { 2271 { 2272 pc.local_time_zone_table[1].name = probe_tm->tm_zone; 2273 pc.local_time_zone_table[1].type = tLOCAL_ZONE; 2274 pc.local_time_zone_table[1].value = probe_tm->tm_isdst; 2275 pc.local_time_zone_table[2].name = 0; 2276 } 2277 break; 2278 } 2279 } 2280 } 2281#else 2282#if HAVE_TZNAME 2283 { 2284# ifndef tzname 2285 extern char *tzname[]; 2286# endif 2287 int i; 2288 for (i = 0; i < 2; i++) 2289 { 2290 pc.local_time_zone_table[i].name = tzname[i]; 2291 pc.local_time_zone_table[i].type = tLOCAL_ZONE; 2292 pc.local_time_zone_table[i].value = i; 2293 } 2294 pc.local_time_zone_table[i].name = 0; 2295 } 2296#else 2297 pc.local_time_zone_table[0].name = 0; 2298#endif 2299#endif 2300 2301 if (pc.local_time_zone_table[0].name && pc.local_time_zone_table[1].name 2302 && ! strcmp (pc.local_time_zone_table[0].name, 2303 pc.local_time_zone_table[1].name)) 2304 { 2305 /* This locale uses the same abbrevation for standard and 2306 daylight times. So if we see that abbreviation, we don't 2307 know whether it's daylight time. */ 2308 pc.local_time_zone_table[0].value = -1; 2309 pc.local_time_zone_table[1].name = 0; 2310 } 2311 2312 if (yyparse (&pc) != 0 2313 || 1 < pc.times_seen || 1 < pc.dates_seen || 1 < pc.days_seen 2314 || 1 < (pc.local_zones_seen + pc.zones_seen) 2315 || (pc.local_zones_seen && 1 < pc.local_isdst)) 2316 return -1; 2317 2318 tm.tm_year = to_year (pc.year) - TM_YEAR_BASE + pc.rel_year; 2319 tm.tm_mon = pc.month - 1 + pc.rel_month; 2320 tm.tm_mday = pc.day + pc.rel_day; 2321 if (pc.times_seen || (pc.rels_seen && ! pc.dates_seen && ! pc.days_seen)) 2322 { 2323 tm.tm_hour = to_hour (pc.hour, pc.meridian); 2324 if (tm.tm_hour < 0) 2325 return -1; 2326 tm.tm_min = pc.minutes; 2327 tm.tm_sec = pc.seconds; 2328 } 2329 else 2330 { 2331 tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 2332 } 2333 2334 /* Let mktime deduce tm_isdst if we have an absolute time stamp, 2335 or if the relative time stamp mentions days, months, or years. */ 2336 if (pc.dates_seen | pc.days_seen | pc.times_seen | pc.rel_day 2337 | pc.rel_month | pc.rel_year) 2338 tm.tm_isdst = -1; 2339 2340 /* But if the input explicitly specifies local time with or without 2341 DST, give mktime that information. */ 2342 if (pc.local_zones_seen) 2343 tm.tm_isdst = pc.local_isdst; 2344 2345 tm0 = tm; 2346 2347 Start = mktime (&tm); 2348 2349 if (Start == (time_t) -1) 2350 { 2351 2352 /* Guard against falsely reporting errors near the time_t boundaries 2353 when parsing times in other time zones. For example, if the min 2354 time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead 2355 of UTC, then the min localtime value is 1970-01-01 08:00:00; if 2356 we apply mktime to 1970-01-01 00:00:00 we will get an error, so 2357 we apply mktime to 1970-01-02 08:00:00 instead and adjust the time 2358 zone by 24 hours to compensate. This algorithm assumes that 2359 there is no DST transition within a day of the time_t boundaries. */ 2360 if (pc.zones_seen) 2361 { 2362 tm = tm0; 2363 if (tm.tm_year <= EPOCH_YEAR - TM_YEAR_BASE) 2364 { 2365 tm.tm_mday++; 2366 pc.time_zone += 24 * 60; 2367 } 2368 else 2369 { 2370 tm.tm_mday--; 2371 pc.time_zone -= 24 * 60; 2372 } 2373 Start = mktime (&tm); 2374 } 2375 2376 if (Start == (time_t) -1) 2377 return Start; 2378 } 2379 2380 if (pc.days_seen && ! pc.dates_seen) 2381 { 2382 tm.tm_mday += ((pc.day_number - tm.tm_wday + 7) % 7 2383 + 7 * (pc.day_ordinal - (0 < pc.day_ordinal))); 2384 tm.tm_isdst = -1; 2385 Start = mktime (&tm); 2386 if (Start == (time_t) -1) 2387 return Start; 2388 } 2389 2390 if (pc.zones_seen) 2391 { 2392 int delta = pc.time_zone * 60; 2393#ifdef HAVE_TM_GMTOFF 2394 delta -= tm.tm_gmtoff; 2395#else 2396 struct tm *gmt = gmtime (&Start); 2397 if (! gmt) 2398 return -1; 2399 delta -= tm_diff (&tm, gmt); 2400#endif 2401 if ((Start < Start - delta) != (delta < 0)) 2402 return -1; /* time_t overflow */ 2403 Start -= delta; 2404 } 2405 2406 /* Add relative hours, minutes, and seconds. Ignore leap seconds; 2407 i.e. "+ 10 minutes" means 600 seconds, even if one of them is a 2408 leap second. Typically this is not what the user wants, but it's 2409 too hard to do it the other way, because the time zone indicator 2410 must be applied before relative times, and if mktime is applied 2411 again the time zone will be lost. */ 2412 { 2413 time_t t0 = Start; 2414 long d1 = 60 * 60 * (long) pc.rel_hour; 2415 time_t t1 = t0 + d1; 2416 long d2 = 60 * (long) pc.rel_minutes; 2417 time_t t2 = t1 + d2; 2418 int d3 = pc.rel_seconds; 2419 time_t t3 = t2 + d3; 2420 if ((d1 / (60 * 60) ^ pc.rel_hour) 2421 | (d2 / 60 ^ pc.rel_minutes) 2422 | ((t0 + d1 < t0) ^ (d1 < 0)) 2423 | ((t1 + d2 < t1) ^ (d2 < 0)) 2424 | ((t2 + d3 < t2) ^ (d3 < 0))) 2425 return -1; 2426 Start = t3; 2427 } 2428 2429 return Start; 2430} 2431 2432#if TEST 2433 2434#include <stdio.h> 2435 2436int 2437main (int ac, char **av) 2438{ 2439 char buff[BUFSIZ]; 2440 time_t d; 2441 2442 printf ("Enter date, or blank line to exit.\n\t> "); 2443 fflush (stdout); 2444 2445 buff[BUFSIZ - 1] = 0; 2446 while (fgets (buff, BUFSIZ - 1, stdin) && buff[0]) 2447 { 2448 d = get_date (buff, 0); 2449 if (d == (time_t) -1) 2450 printf ("Bad format - couldn't convert.\n"); 2451 else 2452 printf ("%s", ctime (&d)); 2453 printf ("\t> "); 2454 fflush (stdout); 2455 } 2456 return 0; 2457} 2458#endif /* defined TEST */ 2459 2460 2461