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