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