* When saving a Task, if the status is COMPLETED then also set PERCENT-COMPLETE:100...
[citadel.git] / citadel / parsedate.c
blobc48cfbbc5d4e2fc447c7bdbf9fadd277dac5325c
1 /* A Bison parser, made by GNU Bison 2.3. */
3 /* Skeleton implementation for Bison's Yacc-like parsers in C
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
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.
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.
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. */
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.
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
36 /* C LALR(1) parser skeleton written by Richard Stallman, by
37 simplifying the original so-called "semantic" parser. */
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. */
46 /* Identify Bison output. */
47 #define YYBISON 1
49 /* Bison version. */
50 #define YYBISON_VERSION "2.3"
52 /* Skeleton name. */
53 #define YYSKELETON_NAME "yacc.c"
55 /* Pure parsers. */
56 #define YYPURE 0
58 /* Using locations. */
59 #define YYLSP_NEEDED 0
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 tDAY = 258,
70 tDAYZONE = 259,
71 tMERIDIAN = 260,
72 tMONTH = 261,
73 tMONTH_UNIT = 262,
74 tSEC_UNIT = 263,
75 tSNUMBER = 264,
76 tUNUMBER = 265,
77 tZONE = 266
79 #endif
80 /* Tokens. */
81 #define tDAY 258
82 #define tDAYZONE 259
83 #define tMERIDIAN 260
84 #define tMONTH 261
85 #define tMONTH_UNIT 262
86 #define tSEC_UNIT 263
87 #define tSNUMBER 264
88 #define tUNUMBER 265
89 #define tZONE 266
94 /* Copy the first part of user declarations. */
95 #line 1 "parsedate.y"
97 /* $Revision: 4003 $
99 ** Originally written by Steven M. Bellovin <smb@research.att.com> while
100 ** at the University of North Carolina at Chapel Hill. Later tweaked by
101 ** a couple of people on Usenet. Completely overhauled by Rich $alz
102 ** <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990.
103 ** Further revised (removed obsolete constructs and cleaned up timezone
104 ** names) in August, 1991, by Rich. Paul Eggert <eggert@twinsun.com>
105 ** helped in September, 1992. Art Cancro <ajc@uncensored.citadel.org> cleaned
106 ** it up for ANSI C in December, 1999.
108 ** This grammar has six shift/reduce conflicts.
110 ** This code is in the public domain and has no copyright.
112 /* SUPPRESS 530 *//* Empty body for statement */
113 /* SUPPRESS 593 on yyerrlab *//* Label was not used */
114 /* SUPPRESS 593 on yynewstate *//* Label was not used */
115 /* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */
117 #include "sysdep.h"
119 #include <stdio.h>
120 #include <stdlib.h>
121 #include <sys/types.h>
122 #include <ctype.h>
124 #if TIME_WITH_SYS_TIME
125 # include <sys/time.h>
126 # include <time.h>
127 #else
128 # if HAVE_SYS_TIME_H
129 # include <sys/time.h>
130 # else
131 # include <time.h>
132 # endif
133 #endif
135 #if HAVE_STRING_H
136 # if !STDC_HEADERS && HAVE_MEMORY_H
137 # include <memory.h>
138 # endif
139 # include <string.h>
140 #endif
141 #if HAVE_STRINGS_H
142 # include <strings.h>
143 #endif
145 #include "parsedate.h"
147 int date_lex(void);
149 #define yyparse date_parse
150 #define yylex date_lex
151 #define yyerror date_error
154 /* See the LeapYears table in Convert. */
155 #define EPOCH 1970
156 #define END_OF_TIME 2038
157 /* Constants for general time calculations. */
158 #define DST_OFFSET 1
159 #define SECSPERDAY (24L * 60L * 60L)
160 /* Readability for TABLE stuff. */
161 #define HOUR(x) (x * 60)
163 #define LPAREN '('
164 #define RPAREN ')'
165 #define IS7BIT(x) ((unsigned int)(x) < 0200)
167 #define SIZEOF(array) ((int)(sizeof array / sizeof array[0]))
168 #define ENDOF(array) (&array[SIZEOF(array)])
172 ** An entry in the lexical lookup table.
174 typedef struct _TABLE {
175 char *name;
176 int type;
177 time_t value;
178 } TABLE;
181 ** Daylight-savings mode: on, off, or not yet known.
183 typedef enum _DSTMODE {
184 DSTon, DSToff, DSTmaybe
185 } DSTMODE;
188 ** Meridian: am, pm, or 24-hour style.
190 typedef enum _MERIDIAN {
191 MERam, MERpm, MER24
192 } MERIDIAN;
196 ** Global variables. We could get rid of most of them by using a yacc
197 ** union, but this is more efficient. (This routine predates the
198 ** yacc %union construct.)
200 static char *yyInput;
201 static DSTMODE yyDSTmode;
202 static int yyHaveDate;
203 static int yyHaveRel;
204 static int yyHaveTime;
205 static time_t yyTimezone;
206 static time_t yyDay;
207 static time_t yyHour;
208 static time_t yyMinutes;
209 static time_t yyMonth;
210 static time_t yySeconds;
211 static time_t yyYear;
212 static MERIDIAN yyMeridian;
213 static time_t yyRelMonth;
214 static time_t yyRelSeconds;
217 static void date_error(char *);
220 /* Enabling traces. */
221 #ifndef YYDEBUG
222 # define YYDEBUG 0
223 #endif
225 /* Enabling verbose error messages. */
226 #ifdef YYERROR_VERBOSE
227 # undef YYERROR_VERBOSE
228 # define YYERROR_VERBOSE 1
229 #else
230 # define YYERROR_VERBOSE 0
231 #endif
233 /* Enabling the token table. */
234 #ifndef YYTOKEN_TABLE
235 # define YYTOKEN_TABLE 0
236 #endif
238 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
239 typedef union YYSTYPE
240 #line 125 "parsedate.y"
242 time_t Number;
243 enum _MERIDIAN Meridian;
245 /* Line 187 of yacc.c. */
246 #line 247 "y.tab.c"
247 YYSTYPE;
248 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
249 # define YYSTYPE_IS_DECLARED 1
250 # define YYSTYPE_IS_TRIVIAL 1
251 #endif
255 /* Copy the second part of user declarations. */
258 /* Line 216 of yacc.c. */
259 #line 260 "y.tab.c"
261 #ifdef short
262 # undef short
263 #endif
265 #ifdef YYTYPE_UINT8
266 typedef YYTYPE_UINT8 yytype_uint8;
267 #else
268 typedef unsigned char yytype_uint8;
269 #endif
271 #ifdef YYTYPE_INT8
272 typedef YYTYPE_INT8 yytype_int8;
273 #elif (defined __STDC__ || defined __C99__FUNC__ \
274 || defined __cplusplus || defined _MSC_VER)
275 typedef signed char yytype_int8;
276 #else
277 typedef short int yytype_int8;
278 #endif
280 #ifdef YYTYPE_UINT16
281 typedef YYTYPE_UINT16 yytype_uint16;
282 #else
283 typedef unsigned short int yytype_uint16;
284 #endif
286 #ifdef YYTYPE_INT16
287 typedef YYTYPE_INT16 yytype_int16;
288 #else
289 typedef short int yytype_int16;
290 #endif
292 #ifndef YYSIZE_T
293 # ifdef __SIZE_TYPE__
294 # define YYSIZE_T __SIZE_TYPE__
295 # elif defined size_t
296 # define YYSIZE_T size_t
297 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
298 || defined __cplusplus || defined _MSC_VER)
299 # include <stddef.h> /* INFRINGES ON USER NAME SPACE */
300 # define YYSIZE_T size_t
301 # else
302 # define YYSIZE_T unsigned int
303 # endif
304 #endif
306 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
308 #ifndef YY_
309 # if YYENABLE_NLS
310 # if ENABLE_NLS
311 # include <libintl.h> /* INFRINGES ON USER NAME SPACE */
312 # define YY_(msgid) dgettext ("bison-runtime", msgid)
313 # endif
314 # endif
315 # ifndef YY_
316 # define YY_(msgid) msgid
317 # endif
318 #endif
320 /* Suppress unused-variable warnings by "using" E. */
321 #if ! defined lint || defined __GNUC__
322 # define YYUSE(e) ((void) (e))
323 #else
324 # define YYUSE(e) /* empty */
325 #endif
327 /* Identity function, used to suppress warnings about constant conditions. */
328 #ifndef lint
329 # define YYID(n) (n)
330 #else
331 #if (defined __STDC__ || defined __C99__FUNC__ \
332 || defined __cplusplus || defined _MSC_VER)
333 static int
334 YYID (int i)
335 #else
336 static int
337 YYID (i)
338 int i;
339 #endif
341 return i;
343 #endif
345 #if ! defined yyoverflow || YYERROR_VERBOSE
347 /* The parser invokes alloca or malloc; define the necessary symbols. */
349 # ifdef YYSTACK_USE_ALLOCA
350 # if YYSTACK_USE_ALLOCA
351 # ifdef __GNUC__
352 # define YYSTACK_ALLOC __builtin_alloca
353 # elif defined __BUILTIN_VA_ARG_INCR
354 # include <alloca.h> /* INFRINGES ON USER NAME SPACE */
355 # elif defined _AIX
356 # define YYSTACK_ALLOC __alloca
357 # elif defined _MSC_VER
358 # include <malloc.h> /* INFRINGES ON USER NAME SPACE */
359 # define alloca _alloca
360 # else
361 # define YYSTACK_ALLOC alloca
362 # if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
363 || defined __cplusplus || defined _MSC_VER)
364 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
365 # ifndef _STDLIB_H
366 # define _STDLIB_H 1
367 # endif
368 # endif
369 # endif
370 # endif
371 # endif
373 # ifdef YYSTACK_ALLOC
374 /* Pacify GCC's `empty if-body' warning. */
375 # define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
376 # ifndef YYSTACK_ALLOC_MAXIMUM
377 /* The OS might guarantee only one guard page at the bottom of the stack,
378 and a page size can be as small as 4096 bytes. So we cannot safely
379 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
380 to allow for a few compiler-allocated temporary stack slots. */
381 # define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
382 # endif
383 # else
384 # define YYSTACK_ALLOC YYMALLOC
385 # define YYSTACK_FREE YYFREE
386 # ifndef YYSTACK_ALLOC_MAXIMUM
387 # define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
388 # endif
389 # if (defined __cplusplus && ! defined _STDLIB_H \
390 && ! ((defined YYMALLOC || defined malloc) \
391 && (defined YYFREE || defined free)))
392 # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
393 # ifndef _STDLIB_H
394 # define _STDLIB_H 1
395 # endif
396 # endif
397 # ifndef YYMALLOC
398 # define YYMALLOC malloc
399 # if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
400 || defined __cplusplus || defined _MSC_VER)
401 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
402 # endif
403 # endif
404 # ifndef YYFREE
405 # define YYFREE free
406 # if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
407 || defined __cplusplus || defined _MSC_VER)
408 void free (void *); /* INFRINGES ON USER NAME SPACE */
409 # endif
410 # endif
411 # endif
412 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
415 #if (! defined yyoverflow \
416 && (! defined __cplusplus \
417 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
419 /* A type that is properly aligned for any stack member. */
420 union yyalloc
422 yytype_int16 yyss;
423 YYSTYPE yyvs;
426 /* The size of the maximum gap between one aligned stack and the next. */
427 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
429 /* The size of an array large to enough to hold all stacks, each with
430 N elements. */
431 # define YYSTACK_BYTES(N) \
432 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
433 + YYSTACK_GAP_MAXIMUM)
435 /* Copy COUNT objects from FROM to TO. The source and destination do
436 not overlap. */
437 # ifndef YYCOPY
438 # if defined __GNUC__ && 1 < __GNUC__
439 # define YYCOPY(To, From, Count) \
440 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
441 # else
442 # define YYCOPY(To, From, Count) \
443 do \
445 YYSIZE_T yyi; \
446 for (yyi = 0; yyi < (Count); yyi++) \
447 (To)[yyi] = (From)[yyi]; \
449 while (YYID (0))
450 # endif
451 # endif
453 /* Relocate STACK from its old location to the new one. The
454 local variables YYSIZE and YYSTACKSIZE give the old and new number of
455 elements in the stack, and YYPTR gives the new location of the
456 stack. Advance YYPTR to a properly aligned location for the next
457 stack. */
458 # define YYSTACK_RELOCATE(Stack) \
459 do \
461 YYSIZE_T yynewbytes; \
462 YYCOPY (&yyptr->Stack, Stack, yysize); \
463 Stack = &yyptr->Stack; \
464 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
465 yyptr += yynewbytes / sizeof (*yyptr); \
467 while (YYID (0))
469 #endif
471 /* YYFINAL -- State number of the termination state. */
472 #define YYFINAL 2
473 /* YYLAST -- Last index in YYTABLE. */
474 #define YYLAST 40
476 /* YYNTOKENS -- Number of terminals. */
477 #define YYNTOKENS 15
478 /* YYNNTS -- Number of nonterminals. */
479 #define YYNNTS 9
480 /* YYNRULES -- Number of rules. */
481 #define YYNRULES 30
482 /* YYNRULES -- Number of states. */
483 #define YYNSTATES 44
485 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
486 #define YYUNDEFTOK 2
487 #define YYMAXUTOK 266
489 #define YYTRANSLATE(YYX) \
490 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
492 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
493 static const yytype_uint8 yytranslate[] =
495 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
496 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
497 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
498 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
499 2, 2, 2, 2, 14, 2, 2, 13, 2, 2,
500 2, 2, 2, 2, 2, 2, 2, 2, 12, 2,
501 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
502 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
503 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
504 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
505 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
506 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
507 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
508 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
509 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
510 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
511 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
512 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
513 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
514 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
515 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
516 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
517 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
518 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
519 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
520 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
521 5, 6, 7, 8, 9, 10, 11
524 #if YYDEBUG
525 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
526 YYRHS. */
527 static const yytype_uint8 yyprhs[] =
529 0, 0, 3, 4, 7, 9, 12, 14, 16, 19,
530 24, 29, 36, 43, 45, 47, 50, 52, 54, 58,
531 64, 67, 72, 75, 79, 85, 88, 91, 94, 97,
535 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
536 static const yytype_int8 yyrhs[] =
538 16, 0, -1, -1, 16, 17, -1, 18, -1, 18,
539 19, -1, 21, -1, 22, -1, 10, 23, -1, 10,
540 12, 10, 23, -1, 10, 12, 10, 20, -1, 10,
541 12, 10, 12, 10, 23, -1, 10, 12, 10, 12,
542 10, 20, -1, 11, -1, 4, -1, 11, 20, -1,
543 20, -1, 9, -1, 10, 13, 10, -1, 10, 13,
544 10, 13, 10, -1, 6, 10, -1, 6, 10, 14,
545 10, -1, 10, 6, -1, 10, 6, 10, -1, 3,
546 14, 10, 6, 10, -1, 9, 8, -1, 10, 8,
547 -1, 9, 7, -1, 10, 7, -1, -1, 5, -1
550 /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
551 static const yytype_uint16 yyrline[] =
553 0, 139, 139, 140, 143, 152, 156, 159, 164, 176,
554 182, 189, 195, 205, 209, 213, 221, 227, 248, 252,
555 264, 268, 273, 277, 282, 289, 292, 295, 298, 303,
558 #endif
560 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
561 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
562 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
563 static const char *const yytname[] =
565 "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN",
566 "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE",
567 "':'", "'/'", "','", "$accept", "spec", "item", "time", "zone",
568 "numzone", "date", "rel", "o_merid", 0
570 #endif
572 # ifdef YYPRINT
573 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
574 token YYLEX-NUM. */
575 static const yytype_uint16 yytoknum[] =
577 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
578 265, 266, 58, 47, 44
580 # endif
582 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
583 static const yytype_uint8 yyr1[] =
585 0, 15, 16, 16, 17, 17, 17, 17, 18, 18,
586 18, 18, 18, 19, 19, 19, 19, 20, 21, 21,
587 21, 21, 21, 21, 21, 22, 22, 22, 22, 23,
591 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
592 static const yytype_uint8 yyr2[] =
594 0, 2, 0, 2, 1, 2, 1, 1, 2, 4,
595 4, 6, 6, 1, 1, 2, 1, 1, 3, 5,
596 2, 4, 2, 3, 5, 2, 2, 2, 2, 0,
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 yytype_uint8 yydefact[] =
605 2, 0, 1, 0, 0, 0, 29, 3, 4, 6,
606 7, 0, 20, 27, 25, 30, 22, 28, 26, 0,
607 0, 8, 14, 17, 13, 5, 16, 0, 0, 23,
608 29, 18, 15, 0, 21, 0, 10, 9, 0, 24,
609 29, 19, 12, 11
612 /* YYDEFGOTO[NTERM-NUM]. */
613 static const yytype_int8 yydefgoto[] =
615 -1, 1, 7, 8, 25, 26, 9, 10, 21
618 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
619 STATE-NUM. */
620 #define YYPACT_NINF -29
621 static const yytype_int8 yypact[] =
623 -29, 1, -29, -11, 11, 20, 12, -29, 4, -29,
624 -29, 13, 16, -29, -29, -29, 21, -29, -29, 22,
625 23, -29, -29, -29, 5, -29, -29, 28, 25, -29,
626 17, 24, -29, 26, -29, 29, -29, -29, 30, -29,
627 0, -29, -29, -29
630 /* YYPGOTO[NTERM-NUM]. */
631 static const yytype_int8 yypgoto[] =
633 -29, -29, -29, -29, -29, -24, -29, -29, -28
636 /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
637 positive, shift that token. If negative, reduce the rule which
638 number is the opposite. If zero, do what YYDEFACT says.
639 If YYTABLE_NINF, syntax error. */
640 #define YYTABLE_NINF -1
641 static const yytype_uint8 yytable[] =
643 32, 2, 37, 11, 3, 15, 36, 4, 22, 23,
644 5, 6, 43, 23, 23, 24, 42, 15, 16, 17,
645 18, 12, 15, 27, 19, 20, 23, 13, 14, 35,
646 28, 29, 30, 31, 33, 34, 39, 38, 0, 40,
650 static const yytype_int8 yycheck[] =
652 24, 0, 30, 14, 3, 5, 30, 6, 4, 9,
653 9, 10, 40, 9, 9, 11, 40, 5, 6, 7,
654 8, 10, 5, 10, 12, 13, 9, 7, 8, 12,
655 14, 10, 10, 10, 6, 10, 10, 13, -1, 10,
659 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
660 symbol of state STATE-NUM. */
661 static const yytype_uint8 yystos[] =
663 0, 16, 0, 3, 6, 9, 10, 17, 18, 21,
664 22, 14, 10, 7, 8, 5, 6, 7, 8, 12,
665 13, 23, 4, 9, 11, 19, 20, 10, 14, 10,
666 10, 10, 20, 6, 10, 12, 20, 23, 13, 10,
667 10, 10, 20, 23
670 #define yyerrok (yyerrstatus = 0)
671 #define yyclearin (yychar = YYEMPTY)
672 #define YYEMPTY (-2)
673 #define YYEOF 0
675 #define YYACCEPT goto yyacceptlab
676 #define YYABORT goto yyabortlab
677 #define YYERROR goto yyerrorlab
680 /* Like YYERROR except do call yyerror. This remains here temporarily
681 to ease the transition to the new meaning of YYERROR, for GCC.
682 Once GCC version 2 has supplanted version 1, this can go. */
684 #define YYFAIL goto yyerrlab
686 #define YYRECOVERING() (!!yyerrstatus)
688 #define YYBACKUP(Token, Value) \
689 do \
690 if (yychar == YYEMPTY && yylen == 1) \
692 yychar = (Token); \
693 yylval = (Value); \
694 yytoken = YYTRANSLATE (yychar); \
695 YYPOPSTACK (1); \
696 goto yybackup; \
698 else \
700 yyerror (YY_("syntax error: cannot back up")); \
701 YYERROR; \
703 while (YYID (0))
706 #define YYTERROR 1
707 #define YYERRCODE 256
710 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
711 If N is 0, then set CURRENT to the empty location which ends
712 the previous symbol: RHS[0] (always defined). */
714 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
715 #ifndef YYLLOC_DEFAULT
716 # define YYLLOC_DEFAULT(Current, Rhs, N) \
717 do \
718 if (YYID (N)) \
720 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
721 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
722 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
723 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
725 else \
727 (Current).first_line = (Current).last_line = \
728 YYRHSLOC (Rhs, 0).last_line; \
729 (Current).first_column = (Current).last_column = \
730 YYRHSLOC (Rhs, 0).last_column; \
732 while (YYID (0))
733 #endif
736 /* YY_LOCATION_PRINT -- Print the location on the stream.
737 This macro was not mandated originally: define only if we know
738 we won't break user code: when these are the locations we know. */
740 #ifndef YY_LOCATION_PRINT
741 # if YYLTYPE_IS_TRIVIAL
742 # define YY_LOCATION_PRINT(File, Loc) \
743 fprintf (File, "%d.%d-%d.%d", \
744 (Loc).first_line, (Loc).first_column, \
745 (Loc).last_line, (Loc).last_column)
746 # else
747 # define YY_LOCATION_PRINT(File, Loc) ((void) 0)
748 # endif
749 #endif
752 /* YYLEX -- calling `yylex' with the right arguments. */
754 #ifdef YYLEX_PARAM
755 # define YYLEX yylex (YYLEX_PARAM)
756 #else
757 # define YYLEX yylex ()
758 #endif
760 /* Enable debugging if requested. */
761 #if YYDEBUG
763 # ifndef YYFPRINTF
764 # include <stdio.h> /* INFRINGES ON USER NAME SPACE */
765 # define YYFPRINTF fprintf
766 # endif
768 # define YYDPRINTF(Args) \
769 do { \
770 if (yydebug) \
771 YYFPRINTF Args; \
772 } while (YYID (0))
774 # define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
775 do { \
776 if (yydebug) \
778 YYFPRINTF (stderr, "%s ", Title); \
779 yy_symbol_print (stderr, \
780 Type, Value); \
781 YYFPRINTF (stderr, "\n"); \
783 } while (YYID (0))
786 /*--------------------------------.
787 | Print this symbol on YYOUTPUT. |
788 `--------------------------------*/
790 /*ARGSUSED*/
791 #if (defined __STDC__ || defined __C99__FUNC__ \
792 || defined __cplusplus || defined _MSC_VER)
793 static void
794 yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
795 #else
796 static void
797 yy_symbol_value_print (yyoutput, yytype, yyvaluep)
798 FILE *yyoutput;
799 int yytype;
800 YYSTYPE const * const yyvaluep;
801 #endif
803 if (!yyvaluep)
804 return;
805 # ifdef YYPRINT
806 if (yytype < YYNTOKENS)
807 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
808 # else
809 YYUSE (yyoutput);
810 # endif
811 switch (yytype)
813 default:
814 break;
819 /*--------------------------------.
820 | Print this symbol on YYOUTPUT. |
821 `--------------------------------*/
823 #if (defined __STDC__ || defined __C99__FUNC__ \
824 || defined __cplusplus || defined _MSC_VER)
825 static void
826 yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
827 #else
828 static void
829 yy_symbol_print (yyoutput, yytype, yyvaluep)
830 FILE *yyoutput;
831 int yytype;
832 YYSTYPE const * const yyvaluep;
833 #endif
835 if (yytype < YYNTOKENS)
836 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
837 else
838 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
840 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
841 YYFPRINTF (yyoutput, ")");
844 /*------------------------------------------------------------------.
845 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
846 | TOP (included). |
847 `------------------------------------------------------------------*/
849 #if (defined __STDC__ || defined __C99__FUNC__ \
850 || defined __cplusplus || defined _MSC_VER)
851 static void
852 yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
853 #else
854 static void
855 yy_stack_print (bottom, top)
856 yytype_int16 *bottom;
857 yytype_int16 *top;
858 #endif
860 YYFPRINTF (stderr, "Stack now");
861 for (; bottom <= top; ++bottom)
862 YYFPRINTF (stderr, " %d", *bottom);
863 YYFPRINTF (stderr, "\n");
866 # define YY_STACK_PRINT(Bottom, Top) \
867 do { \
868 if (yydebug) \
869 yy_stack_print ((Bottom), (Top)); \
870 } while (YYID (0))
873 /*------------------------------------------------.
874 | Report that the YYRULE is going to be reduced. |
875 `------------------------------------------------*/
877 #if (defined __STDC__ || defined __C99__FUNC__ \
878 || defined __cplusplus || defined _MSC_VER)
879 static void
880 yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
881 #else
882 static void
883 yy_reduce_print (yyvsp, yyrule)
884 YYSTYPE *yyvsp;
885 int yyrule;
886 #endif
888 int yynrhs = yyr2[yyrule];
889 int yyi;
890 unsigned long int yylno = yyrline[yyrule];
891 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
892 yyrule - 1, yylno);
893 /* The symbols being reduced. */
894 for (yyi = 0; yyi < yynrhs; yyi++)
896 fprintf (stderr, " $%d = ", yyi + 1);
897 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
898 &(yyvsp[(yyi + 1) - (yynrhs)])
900 fprintf (stderr, "\n");
904 # define YY_REDUCE_PRINT(Rule) \
905 do { \
906 if (yydebug) \
907 yy_reduce_print (yyvsp, Rule); \
908 } while (YYID (0))
910 /* Nonzero means print parse trace. It is left uninitialized so that
911 multiple parsers can coexist. */
912 int yydebug;
913 #else /* !YYDEBUG */
914 # define YYDPRINTF(Args)
915 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
916 # define YY_STACK_PRINT(Bottom, Top)
917 # define YY_REDUCE_PRINT(Rule)
918 #endif /* !YYDEBUG */
921 /* YYINITDEPTH -- initial size of the parser's stacks. */
922 #ifndef YYINITDEPTH
923 # define YYINITDEPTH 200
924 #endif
926 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
927 if the built-in stack extension method is used).
929 Do not make this value too large; the results are undefined if
930 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
931 evaluated with infinite-precision integer arithmetic. */
933 #ifndef YYMAXDEPTH
934 # define YYMAXDEPTH 10000
935 #endif
939 #if YYERROR_VERBOSE
941 # ifndef yystrlen
942 # if defined __GLIBC__ && defined _STRING_H
943 # define yystrlen strlen
944 # else
945 /* Return the length of YYSTR. */
946 #if (defined __STDC__ || defined __C99__FUNC__ \
947 || defined __cplusplus || defined _MSC_VER)
948 static YYSIZE_T
949 yystrlen (const char *yystr)
950 #else
951 static YYSIZE_T
952 yystrlen (yystr)
953 const char *yystr;
954 #endif
956 YYSIZE_T yylen;
957 for (yylen = 0; yystr[yylen]; yylen++)
958 continue;
959 return yylen;
961 # endif
962 # endif
964 # ifndef yystpcpy
965 # if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
966 # define yystpcpy stpcpy
967 # else
968 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
969 YYDEST. */
970 #if (defined __STDC__ || defined __C99__FUNC__ \
971 || defined __cplusplus || defined _MSC_VER)
972 static char *
973 yystpcpy (char *yydest, const char *yysrc)
974 #else
975 static char *
976 yystpcpy (yydest, yysrc)
977 char *yydest;
978 const char *yysrc;
979 #endif
981 char *yyd = yydest;
982 const char *yys = yysrc;
984 while ((*yyd++ = *yys++) != '\0')
985 continue;
987 return yyd - 1;
989 # endif
990 # endif
992 # ifndef yytnamerr
993 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
994 quotes and backslashes, so that it's suitable for yyerror. The
995 heuristic is that double-quoting is unnecessary unless the string
996 contains an apostrophe, a comma, or backslash (other than
997 backslash-backslash). YYSTR is taken from yytname. If YYRES is
998 null, do not copy; instead, return the length of what the result
999 would have been. */
1000 static YYSIZE_T
1001 yytnamerr (char *yyres, const char *yystr)
1003 if (*yystr == '"')
1005 YYSIZE_T yyn = 0;
1006 char const *yyp = yystr;
1008 for (;;)
1009 switch (*++yyp)
1011 case '\'':
1012 case ',':
1013 goto do_not_strip_quotes;
1015 case '\\':
1016 if (*++yyp != '\\')
1017 goto do_not_strip_quotes;
1018 /* Fall through. */
1019 default:
1020 if (yyres)
1021 yyres[yyn] = *yyp;
1022 yyn++;
1023 break;
1025 case '"':
1026 if (yyres)
1027 yyres[yyn] = '\0';
1028 return yyn;
1030 do_not_strip_quotes: ;
1033 if (! yyres)
1034 return yystrlen (yystr);
1036 return yystpcpy (yyres, yystr) - yyres;
1038 # endif
1040 /* Copy into YYRESULT an error message about the unexpected token
1041 YYCHAR while in state YYSTATE. Return the number of bytes copied,
1042 including the terminating null byte. If YYRESULT is null, do not
1043 copy anything; just return the number of bytes that would be
1044 copied. As a special case, return 0 if an ordinary "syntax error"
1045 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
1046 size calculation. */
1047 static YYSIZE_T
1048 yysyntax_error (char *yyresult, int yystate, int yychar)
1050 int yyn = yypact[yystate];
1052 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
1053 return 0;
1054 else
1056 int yytype = YYTRANSLATE (yychar);
1057 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1058 YYSIZE_T yysize = yysize0;
1059 YYSIZE_T yysize1;
1060 int yysize_overflow = 0;
1061 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1062 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1063 int yyx;
1065 # if 0
1066 /* This is so xgettext sees the translatable formats that are
1067 constructed on the fly. */
1068 YY_("syntax error, unexpected %s");
1069 YY_("syntax error, unexpected %s, expecting %s");
1070 YY_("syntax error, unexpected %s, expecting %s or %s");
1071 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1072 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1073 # endif
1074 char *yyfmt;
1075 char const *yyf;
1076 static char const yyunexpected[] = "syntax error, unexpected %s";
1077 static char const yyexpecting[] = ", expecting %s";
1078 static char const yyor[] = " or %s";
1079 char yyformat[sizeof yyunexpected
1080 + sizeof yyexpecting - 1
1081 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1082 * (sizeof yyor - 1))];
1083 char const *yyprefix = yyexpecting;
1085 /* Start YYX at -YYN if negative to avoid negative indexes in
1086 YYCHECK. */
1087 int yyxbegin = yyn < 0 ? -yyn : 0;
1089 /* Stay within bounds of both yycheck and yytname. */
1090 int yychecklim = YYLAST - yyn + 1;
1091 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1092 int yycount = 1;
1094 yyarg[0] = yytname[yytype];
1095 yyfmt = yystpcpy (yyformat, yyunexpected);
1097 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1098 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1100 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1102 yycount = 1;
1103 yysize = yysize0;
1104 yyformat[sizeof yyunexpected - 1] = '\0';
1105 break;
1107 yyarg[yycount++] = yytname[yyx];
1108 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1109 yysize_overflow |= (yysize1 < yysize);
1110 yysize = yysize1;
1111 yyfmt = yystpcpy (yyfmt, yyprefix);
1112 yyprefix = yyor;
1115 yyf = YY_(yyformat);
1116 yysize1 = yysize + yystrlen (yyf);
1117 yysize_overflow |= (yysize1 < yysize);
1118 yysize = yysize1;
1120 if (yysize_overflow)
1121 return YYSIZE_MAXIMUM;
1123 if (yyresult)
1125 /* Avoid sprintf, as that infringes on the user's name space.
1126 Don't have undefined behavior even if the translation
1127 produced a string with the wrong number of "%s"s. */
1128 char *yyp = yyresult;
1129 int yyi = 0;
1130 while ((*yyp = *yyf) != '\0')
1132 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1134 yyp += yytnamerr (yyp, yyarg[yyi++]);
1135 yyf += 2;
1137 else
1139 yyp++;
1140 yyf++;
1144 return yysize;
1147 #endif /* YYERROR_VERBOSE */
1150 /*-----------------------------------------------.
1151 | Release the memory associated to this symbol. |
1152 `-----------------------------------------------*/
1154 /*ARGSUSED*/
1155 #if (defined __STDC__ || defined __C99__FUNC__ \
1156 || defined __cplusplus || defined _MSC_VER)
1157 static void
1158 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1159 #else
1160 static void
1161 yydestruct (yymsg, yytype, yyvaluep)
1162 const char *yymsg;
1163 int yytype;
1164 YYSTYPE *yyvaluep;
1165 #endif
1167 YYUSE (yyvaluep);
1169 if (!yymsg)
1170 yymsg = "Deleting";
1171 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1173 switch (yytype)
1176 default:
1177 break;
1182 /* Prevent warnings from -Wmissing-prototypes. */
1184 #ifdef YYPARSE_PARAM
1185 #if defined __STDC__ || defined __cplusplus
1186 int yyparse (void *YYPARSE_PARAM);
1187 #else
1188 int yyparse ();
1189 #endif
1190 #else /* ! YYPARSE_PARAM */
1191 #if defined __STDC__ || defined __cplusplus
1192 int yyparse (void);
1193 #else
1194 int yyparse ();
1195 #endif
1196 #endif /* ! YYPARSE_PARAM */
1200 /* The look-ahead symbol. */
1201 int yychar;
1203 /* The semantic value of the look-ahead symbol. */
1204 YYSTYPE yylval;
1206 /* Number of syntax errors so far. */
1207 int yynerrs;
1211 /*----------.
1212 | yyparse. |
1213 `----------*/
1215 #ifdef YYPARSE_PARAM
1216 #if (defined __STDC__ || defined __C99__FUNC__ \
1217 || defined __cplusplus || defined _MSC_VER)
1219 yyparse (void *YYPARSE_PARAM)
1220 #else
1222 yyparse (YYPARSE_PARAM)
1223 void *YYPARSE_PARAM;
1224 #endif
1225 #else /* ! YYPARSE_PARAM */
1226 #if (defined __STDC__ || defined __C99__FUNC__ \
1227 || defined __cplusplus || defined _MSC_VER)
1229 yyparse (void)
1230 #else
1232 yyparse ()
1234 #endif
1235 #endif
1238 int yystate;
1239 int yyn;
1240 int yyresult;
1241 /* Number of tokens to shift before error messages enabled. */
1242 int yyerrstatus;
1243 /* Look-ahead token as an internal (translated) token number. */
1244 int yytoken = 0;
1245 #if YYERROR_VERBOSE
1246 /* Buffer for error messages, and its allocated size. */
1247 char yymsgbuf[128];
1248 char *yymsg = yymsgbuf;
1249 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1250 #endif
1252 /* Three stacks and their tools:
1253 `yyss': related to states,
1254 `yyvs': related to semantic values,
1255 `yyls': related to locations.
1257 Refer to the stacks thru separate pointers, to allow yyoverflow
1258 to reallocate them elsewhere. */
1260 /* The state stack. */
1261 yytype_int16 yyssa[YYINITDEPTH];
1262 yytype_int16 *yyss = yyssa;
1263 yytype_int16 *yyssp;
1265 /* The semantic value stack. */
1266 YYSTYPE yyvsa[YYINITDEPTH];
1267 YYSTYPE *yyvs = yyvsa;
1268 YYSTYPE *yyvsp;
1272 #define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1274 YYSIZE_T yystacksize = YYINITDEPTH;
1276 /* The variables used to return semantic value and location from the
1277 action routines. */
1278 YYSTYPE yyval;
1281 /* The number of symbols on the RHS of the reduced rule.
1282 Keep to zero when no symbol should be popped. */
1283 int yylen = 0;
1285 YYDPRINTF ((stderr, "Starting parse\n"));
1287 yystate = 0;
1288 yyerrstatus = 0;
1289 yynerrs = 0;
1290 yychar = YYEMPTY; /* Cause a token to be read. */
1292 /* Initialize stack pointers.
1293 Waste one element of value and location stack
1294 so that they stay on the same level as the state stack.
1295 The wasted elements are never initialized. */
1297 yyssp = yyss;
1298 yyvsp = yyvs;
1300 goto yysetstate;
1302 /*------------------------------------------------------------.
1303 | yynewstate -- Push a new state, which is found in yystate. |
1304 `------------------------------------------------------------*/
1305 yynewstate:
1306 /* In all cases, when you get here, the value and location stacks
1307 have just been pushed. So pushing a state here evens the stacks. */
1308 yyssp++;
1310 yysetstate:
1311 *yyssp = yystate;
1313 if (yyss + yystacksize - 1 <= yyssp)
1315 /* Get the current used size of the three stacks, in elements. */
1316 YYSIZE_T yysize = yyssp - yyss + 1;
1318 #ifdef yyoverflow
1320 /* Give user a chance to reallocate the stack. Use copies of
1321 these so that the &'s don't force the real ones into
1322 memory. */
1323 YYSTYPE *yyvs1 = yyvs;
1324 yytype_int16 *yyss1 = yyss;
1327 /* Each stack pointer address is followed by the size of the
1328 data in use in that stack, in bytes. This used to be a
1329 conditional around just the two extra args, but that might
1330 be undefined if yyoverflow is a macro. */
1331 yyoverflow (YY_("memory exhausted"),
1332 &yyss1, yysize * sizeof (*yyssp),
1333 &yyvs1, yysize * sizeof (*yyvsp),
1335 &yystacksize);
1337 yyss = yyss1;
1338 yyvs = yyvs1;
1340 #else /* no yyoverflow */
1341 # ifndef YYSTACK_RELOCATE
1342 goto yyexhaustedlab;
1343 # else
1344 /* Extend the stack our own way. */
1345 if (YYMAXDEPTH <= yystacksize)
1346 goto yyexhaustedlab;
1347 yystacksize *= 2;
1348 if (YYMAXDEPTH < yystacksize)
1349 yystacksize = YYMAXDEPTH;
1352 yytype_int16 *yyss1 = yyss;
1353 union yyalloc *yyptr =
1354 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1355 if (! yyptr)
1356 goto yyexhaustedlab;
1357 YYSTACK_RELOCATE (yyss);
1358 YYSTACK_RELOCATE (yyvs);
1360 # undef YYSTACK_RELOCATE
1361 if (yyss1 != yyssa)
1362 YYSTACK_FREE (yyss1);
1364 # endif
1365 #endif /* no yyoverflow */
1367 yyssp = yyss + yysize - 1;
1368 yyvsp = yyvs + yysize - 1;
1371 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1372 (unsigned long int) yystacksize));
1374 if (yyss + yystacksize - 1 <= yyssp)
1375 YYABORT;
1378 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1380 goto yybackup;
1382 /*-----------.
1383 | yybackup. |
1384 `-----------*/
1385 yybackup:
1387 /* Do appropriate processing given the current state. Read a
1388 look-ahead token if we need one and don't already have one. */
1390 /* First try to decide what to do without reference to look-ahead token. */
1391 yyn = yypact[yystate];
1392 if (yyn == YYPACT_NINF)
1393 goto yydefault;
1395 /* Not known => get a look-ahead token if don't already have one. */
1397 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1398 if (yychar == YYEMPTY)
1400 YYDPRINTF ((stderr, "Reading a token: "));
1401 yychar = YYLEX;
1404 if (yychar <= YYEOF)
1406 yychar = yytoken = YYEOF;
1407 YYDPRINTF ((stderr, "Now at end of input.\n"));
1409 else
1411 yytoken = YYTRANSLATE (yychar);
1412 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1415 /* If the proper action on seeing token YYTOKEN is to reduce or to
1416 detect an error, take that action. */
1417 yyn += yytoken;
1418 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1419 goto yydefault;
1420 yyn = yytable[yyn];
1421 if (yyn <= 0)
1423 if (yyn == 0 || yyn == YYTABLE_NINF)
1424 goto yyerrlab;
1425 yyn = -yyn;
1426 goto yyreduce;
1429 if (yyn == YYFINAL)
1430 YYACCEPT;
1432 /* Count tokens shifted since error; after three, turn off error
1433 status. */
1434 if (yyerrstatus)
1435 yyerrstatus--;
1437 /* Shift the look-ahead token. */
1438 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1440 /* Discard the shifted token unless it is eof. */
1441 if (yychar != YYEOF)
1442 yychar = YYEMPTY;
1444 yystate = yyn;
1445 *++yyvsp = yylval;
1447 goto yynewstate;
1450 /*-----------------------------------------------------------.
1451 | yydefault -- do the default action for the current state. |
1452 `-----------------------------------------------------------*/
1453 yydefault:
1454 yyn = yydefact[yystate];
1455 if (yyn == 0)
1456 goto yyerrlab;
1457 goto yyreduce;
1460 /*-----------------------------.
1461 | yyreduce -- Do a reduction. |
1462 `-----------------------------*/
1463 yyreduce:
1464 /* yyn is the number of a rule to reduce with. */
1465 yylen = yyr2[yyn];
1467 /* If YYLEN is nonzero, implement the default value of the action:
1468 `$$ = $1'.
1470 Otherwise, the following line sets YYVAL to garbage.
1471 This behavior is undocumented and Bison
1472 users should not rely upon it. Assigning to YYVAL
1473 unconditionally makes the parser a bit smaller, and it avoids a
1474 GCC warning that YYVAL may be used uninitialized. */
1475 yyval = yyvsp[1-yylen];
1478 YY_REDUCE_PRINT (yyn);
1479 switch (yyn)
1481 case 4:
1482 #line 143 "parsedate.y"
1484 yyHaveTime++;
1485 #ifdef lint
1486 /* I am compulsive about lint natterings... */
1487 if (yyHaveTime == -1) {
1488 YYERROR;
1490 #endif /* lint */
1492 break;
1494 case 5:
1495 #line 152 "parsedate.y"
1497 yyHaveTime++;
1498 yyTimezone = (yyvsp[(2) - (2)].Number);
1500 break;
1502 case 6:
1503 #line 156 "parsedate.y"
1505 yyHaveDate++;
1507 break;
1509 case 7:
1510 #line 159 "parsedate.y"
1512 yyHaveRel = 1;
1514 break;
1516 case 8:
1517 #line 164 "parsedate.y"
1519 if ((yyvsp[(1) - (2)].Number) < 100) {
1520 yyHour = (yyvsp[(1) - (2)].Number);
1521 yyMinutes = 0;
1523 else {
1524 yyHour = (yyvsp[(1) - (2)].Number) / 100;
1525 yyMinutes = (yyvsp[(1) - (2)].Number) % 100;
1527 yySeconds = 0;
1528 yyMeridian = (yyvsp[(2) - (2)].Meridian);
1530 break;
1532 case 9:
1533 #line 176 "parsedate.y"
1535 yyHour = (yyvsp[(1) - (4)].Number);
1536 yyMinutes = (yyvsp[(3) - (4)].Number);
1537 yySeconds = 0;
1538 yyMeridian = (yyvsp[(4) - (4)].Meridian);
1540 break;
1542 case 10:
1543 #line 182 "parsedate.y"
1545 yyHour = (yyvsp[(1) - (4)].Number);
1546 yyMinutes = (yyvsp[(3) - (4)].Number);
1547 yyTimezone = (yyvsp[(4) - (4)].Number);
1548 yyMeridian = MER24;
1549 yyDSTmode = DSToff;
1551 break;
1553 case 11:
1554 #line 189 "parsedate.y"
1556 yyHour = (yyvsp[(1) - (6)].Number);
1557 yyMinutes = (yyvsp[(3) - (6)].Number);
1558 yySeconds = (yyvsp[(5) - (6)].Number);
1559 yyMeridian = (yyvsp[(6) - (6)].Meridian);
1561 break;
1563 case 12:
1564 #line 195 "parsedate.y"
1566 yyHour = (yyvsp[(1) - (6)].Number);
1567 yyMinutes = (yyvsp[(3) - (6)].Number);
1568 yySeconds = (yyvsp[(5) - (6)].Number);
1569 yyTimezone = (yyvsp[(6) - (6)].Number);
1570 yyMeridian = MER24;
1571 yyDSTmode = DSToff;
1573 break;
1575 case 13:
1576 #line 205 "parsedate.y"
1578 (yyval.Number) = (yyvsp[(1) - (1)].Number);
1579 yyDSTmode = DSToff;
1581 break;
1583 case 14:
1584 #line 209 "parsedate.y"
1586 (yyval.Number) = (yyvsp[(1) - (1)].Number);
1587 yyDSTmode = DSTon;
1589 break;
1591 case 15:
1592 #line 213 "parsedate.y"
1594 /* Only allow "GMT+300" and "GMT-0800" */
1595 if ((yyvsp[(1) - (2)].Number) != 0) {
1596 YYABORT;
1598 (yyval.Number) = (yyvsp[(2) - (2)].Number);
1599 yyDSTmode = DSToff;
1601 break;
1603 case 16:
1604 #line 221 "parsedate.y"
1606 (yyval.Number) = (yyvsp[(1) - (1)].Number);
1607 yyDSTmode = DSToff;
1609 break;
1611 case 17:
1612 #line 227 "parsedate.y"
1614 int i;
1616 /* Unix and GMT and numeric timezones -- a little confusing. */
1617 if ((yyvsp[(1) - (1)].Number) < 0) {
1618 /* Don't work with negative modulus. */
1619 (yyvsp[(1) - (1)].Number) = -(yyvsp[(1) - (1)].Number);
1620 if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) {
1621 YYABORT;
1623 (yyval.Number) = ((yyvsp[(1) - (1)].Number) / 100) * 60 + i;
1625 else {
1626 if ((yyvsp[(1) - (1)].Number) > 9999 || (i = (yyvsp[(1) - (1)].Number) % 100) >= 60) {
1627 YYABORT;
1629 (yyval.Number) = -(((yyvsp[(1) - (1)].Number) / 100) * 60 + i);
1632 break;
1634 case 18:
1635 #line 248 "parsedate.y"
1637 yyMonth = (yyvsp[(1) - (3)].Number);
1638 yyDay = (yyvsp[(3) - (3)].Number);
1640 break;
1642 case 19:
1643 #line 252 "parsedate.y"
1645 if ((yyvsp[(1) - (5)].Number) > 100) {
1646 yyYear = (yyvsp[(1) - (5)].Number);
1647 yyMonth = (yyvsp[(3) - (5)].Number);
1648 yyDay = (yyvsp[(5) - (5)].Number);
1650 else {
1651 yyMonth = (yyvsp[(1) - (5)].Number);
1652 yyDay = (yyvsp[(3) - (5)].Number);
1653 yyYear = (yyvsp[(5) - (5)].Number);
1656 break;
1658 case 20:
1659 #line 264 "parsedate.y"
1661 yyMonth = (yyvsp[(1) - (2)].Number);
1662 yyDay = (yyvsp[(2) - (2)].Number);
1664 break;
1666 case 21:
1667 #line 268 "parsedate.y"
1669 yyMonth = (yyvsp[(1) - (4)].Number);
1670 yyDay = (yyvsp[(2) - (4)].Number);
1671 yyYear = (yyvsp[(4) - (4)].Number);
1673 break;
1675 case 22:
1676 #line 273 "parsedate.y"
1678 yyDay = (yyvsp[(1) - (2)].Number);
1679 yyMonth = (yyvsp[(2) - (2)].Number);
1681 break;
1683 case 23:
1684 #line 277 "parsedate.y"
1686 yyDay = (yyvsp[(1) - (3)].Number);
1687 yyMonth = (yyvsp[(2) - (3)].Number);
1688 yyYear = (yyvsp[(3) - (3)].Number);
1690 break;
1692 case 24:
1693 #line 282 "parsedate.y"
1695 yyDay = (yyvsp[(3) - (5)].Number);
1696 yyMonth = (yyvsp[(4) - (5)].Number);
1697 yyYear = (yyvsp[(5) - (5)].Number);
1699 break;
1701 case 25:
1702 #line 289 "parsedate.y"
1704 yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
1706 break;
1708 case 26:
1709 #line 292 "parsedate.y"
1711 yyRelSeconds += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
1713 break;
1715 case 27:
1716 #line 295 "parsedate.y"
1718 yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
1720 break;
1722 case 28:
1723 #line 298 "parsedate.y"
1725 yyRelMonth += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
1727 break;
1729 case 29:
1730 #line 303 "parsedate.y"
1732 (yyval.Meridian) = MER24;
1734 break;
1736 case 30:
1737 #line 306 "parsedate.y"
1739 (yyval.Meridian) = (yyvsp[(1) - (1)].Meridian);
1741 break;
1744 /* Line 1267 of yacc.c. */
1745 #line 1746 "y.tab.c"
1746 default: break;
1748 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1750 YYPOPSTACK (yylen);
1751 yylen = 0;
1752 YY_STACK_PRINT (yyss, yyssp);
1754 *++yyvsp = yyval;
1757 /* Now `shift' the result of the reduction. Determine what state
1758 that goes to, based on the state we popped back to and the rule
1759 number reduced by. */
1761 yyn = yyr1[yyn];
1763 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1764 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1765 yystate = yytable[yystate];
1766 else
1767 yystate = yydefgoto[yyn - YYNTOKENS];
1769 goto yynewstate;
1772 /*------------------------------------.
1773 | yyerrlab -- here on detecting error |
1774 `------------------------------------*/
1775 yyerrlab:
1776 /* If not already recovering from an error, report this error. */
1777 if (!yyerrstatus)
1779 ++yynerrs;
1780 #if ! YYERROR_VERBOSE
1781 yyerror (YY_("syntax error"));
1782 #else
1784 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1785 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1787 YYSIZE_T yyalloc = 2 * yysize;
1788 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1789 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1790 if (yymsg != yymsgbuf)
1791 YYSTACK_FREE (yymsg);
1792 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1793 if (yymsg)
1794 yymsg_alloc = yyalloc;
1795 else
1797 yymsg = yymsgbuf;
1798 yymsg_alloc = sizeof yymsgbuf;
1802 if (0 < yysize && yysize <= yymsg_alloc)
1804 (void) yysyntax_error (yymsg, yystate, yychar);
1805 yyerror (yymsg);
1807 else
1809 yyerror (YY_("syntax error"));
1810 if (yysize != 0)
1811 goto yyexhaustedlab;
1814 #endif
1819 if (yyerrstatus == 3)
1821 /* If just tried and failed to reuse look-ahead token after an
1822 error, discard it. */
1824 if (yychar <= YYEOF)
1826 /* Return failure if at end of input. */
1827 if (yychar == YYEOF)
1828 YYABORT;
1830 else
1832 yydestruct ("Error: discarding",
1833 yytoken, &yylval);
1834 yychar = YYEMPTY;
1838 /* Else will try to reuse look-ahead token after shifting the error
1839 token. */
1840 goto yyerrlab1;
1843 /*---------------------------------------------------.
1844 | yyerrorlab -- error raised explicitly by YYERROR. |
1845 `---------------------------------------------------*/
1846 yyerrorlab:
1848 /* Pacify compilers like GCC when the user code never invokes
1849 YYERROR and the label yyerrorlab therefore never appears in user
1850 code. */
1851 if (/*CONSTCOND*/ 0)
1852 goto yyerrorlab;
1854 /* Do not reclaim the symbols of the rule which action triggered
1855 this YYERROR. */
1856 YYPOPSTACK (yylen);
1857 yylen = 0;
1858 YY_STACK_PRINT (yyss, yyssp);
1859 yystate = *yyssp;
1860 goto yyerrlab1;
1863 /*-------------------------------------------------------------.
1864 | yyerrlab1 -- common code for both syntax error and YYERROR. |
1865 `-------------------------------------------------------------*/
1866 yyerrlab1:
1867 yyerrstatus = 3; /* Each real token shifted decrements this. */
1869 for (;;)
1871 yyn = yypact[yystate];
1872 if (yyn != YYPACT_NINF)
1874 yyn += YYTERROR;
1875 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1877 yyn = yytable[yyn];
1878 if (0 < yyn)
1879 break;
1883 /* Pop the current state because it cannot handle the error token. */
1884 if (yyssp == yyss)
1885 YYABORT;
1888 yydestruct ("Error: popping",
1889 yystos[yystate], yyvsp);
1890 YYPOPSTACK (1);
1891 yystate = *yyssp;
1892 YY_STACK_PRINT (yyss, yyssp);
1895 if (yyn == YYFINAL)
1896 YYACCEPT;
1898 *++yyvsp = yylval;
1901 /* Shift the error token. */
1902 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1904 yystate = yyn;
1905 goto yynewstate;
1908 /*-------------------------------------.
1909 | yyacceptlab -- YYACCEPT comes here. |
1910 `-------------------------------------*/
1911 yyacceptlab:
1912 yyresult = 0;
1913 goto yyreturn;
1915 /*-----------------------------------.
1916 | yyabortlab -- YYABORT comes here. |
1917 `-----------------------------------*/
1918 yyabortlab:
1919 yyresult = 1;
1920 goto yyreturn;
1922 #ifndef yyoverflow
1923 /*-------------------------------------------------.
1924 | yyexhaustedlab -- memory exhaustion comes here. |
1925 `-------------------------------------------------*/
1926 yyexhaustedlab:
1927 yyerror (YY_("memory exhausted"));
1928 yyresult = 2;
1929 /* Fall through. */
1930 #endif
1932 yyreturn:
1933 if (yychar != YYEOF && yychar != YYEMPTY)
1934 yydestruct ("Cleanup: discarding lookahead",
1935 yytoken, &yylval);
1936 /* Do not reclaim the symbols of the rule which action triggered
1937 this YYABORT or YYACCEPT. */
1938 YYPOPSTACK (yylen);
1939 YY_STACK_PRINT (yyss, yyssp);
1940 while (yyssp != yyss)
1942 yydestruct ("Cleanup: popping",
1943 yystos[*yyssp], yyvsp);
1944 YYPOPSTACK (1);
1946 #ifndef yyoverflow
1947 if (yyss != yyssa)
1948 YYSTACK_FREE (yyss);
1949 #endif
1950 #if YYERROR_VERBOSE
1951 if (yymsg != yymsgbuf)
1952 YYSTACK_FREE (yymsg);
1953 #endif
1954 /* Make sure YYID is used. */
1955 return YYID (yyresult);
1959 #line 311 "parsedate.y"
1962 /* Month and day table. */
1963 static TABLE MonthDayTable[] = {
1964 { "january", tMONTH, 1 },
1965 { "february", tMONTH, 2 },
1966 { "march", tMONTH, 3 },
1967 { "april", tMONTH, 4 },
1968 { "may", tMONTH, 5 },
1969 { "june", tMONTH, 6 },
1970 { "july", tMONTH, 7 },
1971 { "august", tMONTH, 8 },
1972 { "september", tMONTH, 9 },
1973 { "october", tMONTH, 10 },
1974 { "november", tMONTH, 11 },
1975 { "december", tMONTH, 12 },
1976 /* The value of the day isn't used... */
1977 { "sunday", tDAY, 0 },
1978 { "monday", tDAY, 0 },
1979 { "tuesday", tDAY, 0 },
1980 { "wednesday", tDAY, 0 },
1981 { "thursday", tDAY, 0 },
1982 { "friday", tDAY, 0 },
1983 { "saturday", tDAY, 0 },
1986 /* Time units table. */
1987 static TABLE UnitsTable[] = {
1988 { "year", tMONTH_UNIT, 12 },
1989 { "month", tMONTH_UNIT, 1 },
1990 { "week", tSEC_UNIT, 7L * 24 * 60 * 60 },
1991 { "day", tSEC_UNIT, 1L * 24 * 60 * 60 },
1992 { "hour", tSEC_UNIT, 60 * 60 },
1993 { "minute", tSEC_UNIT, 60 },
1994 { "min", tSEC_UNIT, 60 },
1995 { "second", tSEC_UNIT, 1 },
1996 { "sec", tSEC_UNIT, 1 },
1999 /* Timezone table. */
2000 static TABLE TimezoneTable[] = {
2001 { "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
2002 { "ut", tZONE, HOUR( 0) }, /* Universal */
2003 { "utc", tZONE, HOUR( 0) }, /* Universal Coordinated */
2004 { "cut", tZONE, HOUR( 0) }, /* Coordinated Universal */
2005 { "z", tZONE, HOUR( 0) }, /* Greenwich Mean */
2006 { "wet", tZONE, HOUR( 0) }, /* Western European */
2007 { "bst", tDAYZONE, HOUR( 0) }, /* British Summer */
2008 { "nst", tZONE, HOUR(3)+30 }, /* Newfoundland Standard */
2009 { "ndt", tDAYZONE, HOUR(3)+30 }, /* Newfoundland Daylight */
2010 { "ast", tZONE, HOUR( 4) }, /* Atlantic Standard */
2011 { "adt", tDAYZONE, HOUR( 4) }, /* Atlantic Daylight */
2012 { "est", tZONE, HOUR( 5) }, /* Eastern Standard */
2013 { "edt", tDAYZONE, HOUR( 5) }, /* Eastern Daylight */
2014 { "cst", tZONE, HOUR( 6) }, /* Central Standard */
2015 { "cdt", tDAYZONE, HOUR( 6) }, /* Central Daylight */
2016 { "mst", tZONE, HOUR( 7) }, /* Mountain Standard */
2017 { "mdt", tDAYZONE, HOUR( 7) }, /* Mountain Daylight */
2018 { "pst", tZONE, HOUR( 8) }, /* Pacific Standard */
2019 { "pdt", tDAYZONE, HOUR( 8) }, /* Pacific Daylight */
2020 { "yst", tZONE, HOUR( 9) }, /* Yukon Standard */
2021 { "ydt", tDAYZONE, HOUR( 9) }, /* Yukon Daylight */
2022 { "akst", tZONE, HOUR( 9) }, /* Alaska Standard */
2023 { "akdt", tDAYZONE, HOUR( 9) }, /* Alaska Daylight */
2024 { "hst", tZONE, HOUR(10) }, /* Hawaii Standard */
2025 { "hast", tZONE, HOUR(10) }, /* Hawaii-Aleutian Standard */
2026 { "hadt", tDAYZONE, HOUR(10) }, /* Hawaii-Aleutian Daylight */
2027 { "ces", tDAYZONE, -HOUR(1) }, /* Central European Summer */
2028 { "cest", tDAYZONE, -HOUR(1) }, /* Central European Summer */
2029 { "mez", tZONE, -HOUR(1) }, /* Middle European */
2030 { "mezt", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
2031 { "cet", tZONE, -HOUR(1) }, /* Central European */
2032 { "met", tZONE, -HOUR(1) }, /* Middle European */
2033 { "eet", tZONE, -HOUR(2) }, /* Eastern Europe */
2034 { "msk", tZONE, -HOUR(3) }, /* Moscow Winter */
2035 { "msd", tDAYZONE, -HOUR(3) }, /* Moscow Summer */
2036 { "wast", tZONE, -HOUR(8) }, /* West Australian Standard */
2037 { "wadt", tDAYZONE, -HOUR(8) }, /* West Australian Daylight */
2038 { "hkt", tZONE, -HOUR(8) }, /* Hong Kong */
2039 { "cct", tZONE, -HOUR(8) }, /* China Coast */
2040 { "jst", tZONE, -HOUR(9) }, /* Japan Standard */
2041 { "kst", tZONE, -HOUR(9) }, /* Korean Standard */
2042 { "kdt", tZONE, -HOUR(9) }, /* Korean Daylight */
2043 { "cast", tZONE, -(HOUR(9)+30) }, /* Central Australian Standard */
2044 { "cadt", tDAYZONE, -(HOUR(9)+30) }, /* Central Australian Daylight */
2045 { "east", tZONE, -HOUR(10) }, /* Eastern Australian Standard */
2046 { "eadt", tDAYZONE, -HOUR(10) }, /* Eastern Australian Daylight */
2047 { "nzst", tZONE, -HOUR(12) }, /* New Zealand Standard */
2048 { "nzdt", tDAYZONE, -HOUR(12) }, /* New Zealand Daylight */
2050 /* For completeness we include the following entries. */
2051 #if 0
2053 /* Duplicate names. Either they conflict with a zone listed above
2054 * (which is either more likely to be seen or just been in circulation
2055 * longer), or they conflict with another zone in this section and
2056 * we could not reasonably choose one over the other. */
2057 { "fst", tZONE, HOUR( 2) }, /* Fernando De Noronha Standard */
2058 { "fdt", tDAYZONE, HOUR( 2) }, /* Fernando De Noronha Daylight */
2059 { "bst", tZONE, HOUR( 3) }, /* Brazil Standard */
2060 { "est", tZONE, HOUR( 3) }, /* Eastern Standard (Brazil) */
2061 { "edt", tDAYZONE, HOUR( 3) }, /* Eastern Daylight (Brazil) */
2062 { "wst", tZONE, HOUR( 4) }, /* Western Standard (Brazil) */
2063 { "wdt", tDAYZONE, HOUR( 4) }, /* Western Daylight (Brazil) */
2064 { "cst", tZONE, HOUR( 5) }, /* Chile Standard */
2065 { "cdt", tDAYZONE, HOUR( 5) }, /* Chile Daylight */
2066 { "ast", tZONE, HOUR( 5) }, /* Acre Standard */
2067 { "adt", tDAYZONE, HOUR( 5) }, /* Acre Daylight */
2068 { "cst", tZONE, HOUR( 5) }, /* Cuba Standard */
2069 { "cdt", tDAYZONE, HOUR( 5) }, /* Cuba Daylight */
2070 { "est", tZONE, HOUR( 6) }, /* Easter Island Standard */
2071 { "edt", tDAYZONE, HOUR( 6) }, /* Easter Island Daylight */
2072 { "sst", tZONE, HOUR(11) }, /* Samoa Standard */
2073 { "ist", tZONE, -HOUR(2) }, /* Israel Standard */
2074 { "idt", tDAYZONE, -HOUR(2) }, /* Israel Daylight */
2075 { "idt", tDAYZONE, -(HOUR(3)+30) }, /* Iran Daylight */
2076 { "ist", tZONE, -(HOUR(3)+30) }, /* Iran Standard */
2077 { "cst", tZONE, -HOUR(8) }, /* China Standard */
2078 { "cdt", tDAYZONE, -HOUR(8) }, /* China Daylight */
2079 { "sst", tZONE, -HOUR(8) }, /* Singapore Standard */
2081 /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
2082 { "gst", tZONE, HOUR( 3) }, /* Greenland Standard */
2083 { "wat", tZONE, -HOUR(1) }, /* West Africa */
2084 { "at", tZONE, HOUR( 2) }, /* Azores */
2085 { "gst", tZONE, -HOUR(10) }, /* Guam Standard */
2086 { "nft", tZONE, HOUR(3)+30 }, /* Newfoundland */
2087 { "idlw", tZONE, HOUR(12) }, /* International Date Line West */
2088 { "mewt", tZONE, -HOUR(1) }, /* Middle European Winter */
2089 { "mest", tDAYZONE, -HOUR(1) }, /* Middle European Summer */
2090 { "swt", tZONE, -HOUR(1) }, /* Swedish Winter */
2091 { "sst", tDAYZONE, -HOUR(1) }, /* Swedish Summer */
2092 { "fwt", tZONE, -HOUR(1) }, /* French Winter */
2093 { "fst", tDAYZONE, -HOUR(1) }, /* French Summer */
2094 { "bt", tZONE, -HOUR(3) }, /* Baghdad */
2095 { "it", tZONE, -(HOUR(3)+30) }, /* Iran */
2096 { "zp4", tZONE, -HOUR(4) }, /* USSR Zone 3 */
2097 { "zp5", tZONE, -HOUR(5) }, /* USSR Zone 4 */
2098 { "ist", tZONE, -(HOUR(5)+30) }, /* Indian Standard */
2099 { "zp6", tZONE, -HOUR(6) }, /* USSR Zone 5 */
2100 { "nst", tZONE, -HOUR(7) }, /* North Sumatra */
2101 { "sst", tZONE, -HOUR(7) }, /* South Sumatra */
2102 { "jt", tZONE, -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
2103 { "nzt", tZONE, -HOUR(12) }, /* New Zealand */
2104 { "idle", tZONE, -HOUR(12) }, /* International Date Line East */
2105 { "cat", tZONE, HOUR(10) }, /* -- expired 1967 */
2106 { "nt", tZONE, HOUR(11) }, /* -- expired 1967 */
2107 { "ahst", tZONE, HOUR(10) }, /* -- expired 1983 */
2108 { "hdt", tDAYZONE, HOUR(10) }, /* -- expired 1986 */
2109 #endif /* 0 */
2113 /* ARGSUSED */
2114 static void
2115 date_error(char *s)
2117 /* NOTREACHED */
2121 static time_t
2122 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
2124 if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
2125 return -1;
2126 if (Meridian == MER24) {
2127 if (Hours < 0 || Hours > 23)
2128 return -1;
2130 else {
2131 if (Hours < 1 || Hours > 12)
2132 return -1;
2133 if (Hours == 12)
2134 Hours = 0;
2135 if (Meridian == MERpm)
2136 Hours += 12;
2138 return (Hours * 60L + Minutes) * 60L + Seconds;
2142 static time_t
2143 Convert(time_t Month, time_t Day, time_t Year,
2144 time_t Hours, time_t Minutes, time_t Seconds,
2145 MERIDIAN Meridian, DSTMODE dst)
2147 static int DaysNormal[13] = {
2148 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
2150 static int DaysLeap[13] = {
2151 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
2153 static int LeapYears[] = {
2154 1972, 1976, 1980, 1984, 1988, 1992, 1996,
2155 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
2157 register int *yp;
2158 register int *mp;
2159 register time_t Julian;
2160 register int i;
2161 time_t tod;
2163 if (Year < 0)
2164 Year = -Year;
2165 if (Year < 100)
2166 Year += 1900;
2167 if (Year < EPOCH)
2168 Year += 100;
2169 for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
2170 if (Year == *yp) {
2171 mp = DaysLeap;
2172 break;
2174 if (Year < EPOCH || Year > END_OF_TIME
2175 || Month < 1 || Month > 12
2176 /* NOSTRICT *//* conversion from long may lose accuracy */
2177 || Day < 1 || Day > mp[(int)Month])
2178 return -1;
2180 Julian = Day - 1 + (Year - EPOCH) * 365;
2181 for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
2182 if (Year <= *yp)
2183 break;
2184 for (i = 1; i < Month; i++)
2185 Julian += *++mp;
2186 Julian *= SECSPERDAY;
2187 Julian += yyTimezone * 60L;
2188 if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
2189 return -1;
2190 Julian += tod;
2191 tod = Julian;
2192 if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
2193 Julian -= DST_OFFSET * 60L * 60L;
2194 return Julian;
2198 static time_t
2199 DSTcorrect(time_t Start, time_t Future)
2201 time_t StartDay;
2202 time_t FutureDay;
2204 StartDay = (localtime(&Start)->tm_hour + 1) % 24;
2205 FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
2206 return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L;
2210 static time_t
2211 RelativeMonth(time_t Start, time_t RelMonth)
2213 struct tm *tm;
2214 time_t Month;
2215 time_t Year;
2217 tm = localtime(&Start);
2218 Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
2219 Year = Month / 12;
2220 Month = Month % 12 + 1;
2221 return DSTcorrect(Start,
2222 Convert(Month, (time_t)tm->tm_mday, Year,
2223 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
2224 MER24, DSTmaybe));
2228 static int
2229 LookupWord(char *buff, register int length)
2231 register char *p;
2232 register char *q;
2233 register TABLE *tp;
2234 register int c;
2236 p = buff;
2237 c = p[0];
2239 /* See if we have an abbreviation for a month. */
2240 if (length == 3 || (length == 4 && p[3] == '.'))
2241 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
2242 q = tp->name;
2243 if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
2244 yylval.Number = tp->value;
2245 return tp->type;
2248 else
2249 for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
2250 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
2251 yylval.Number = tp->value;
2252 return tp->type;
2255 /* Try for a timezone. */
2256 for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
2257 if (c == tp->name[0] && p[1] == tp->name[1]
2258 && strcmp(p, tp->name) == 0) {
2259 yylval.Number = tp->value;
2260 return tp->type;
2263 /* Try the units table. */
2264 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
2265 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
2266 yylval.Number = tp->value;
2267 return tp->type;
2270 /* Strip off any plural and try the units table again. */
2271 if (--length > 0 && p[length] == 's') {
2272 p[length] = '\0';
2273 for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
2274 if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
2275 p[length] = 's';
2276 yylval.Number = tp->value;
2277 return tp->type;
2279 p[length] = 's';
2281 length++;
2283 /* Drop out any periods. */
2284 for (p = buff, q = (char*)buff; *q; q++)
2285 if (*q != '.')
2286 *p++ = *q;
2287 *p = '\0';
2289 /* Try the meridians. */
2290 if (buff[1] == 'm' && buff[2] == '\0') {
2291 if (buff[0] == 'a') {
2292 yylval.Meridian = MERam;
2293 return tMERIDIAN;
2295 if (buff[0] == 'p') {
2296 yylval.Meridian = MERpm;
2297 return tMERIDIAN;
2301 /* If we saw any periods, try the timezones again. */
2302 if (p - buff != length) {
2303 c = buff[0];
2304 for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
2305 if (c == tp->name[0] && p[1] == tp->name[1]
2306 && strcmp(p, tp->name) == 0) {
2307 yylval.Number = tp->value;
2308 return tp->type;
2312 /* Unknown word -- assume GMT timezone. */
2313 yylval.Number = 0;
2314 return tZONE;
2319 date_lex(void)
2321 register char c;
2322 register char *p;
2323 char buff[20];
2324 register int sign;
2325 register int i;
2326 register int nesting;
2328 for ( ; ; ) {
2329 /* Get first character after the whitespace. */
2330 for ( ; ; ) {
2331 while (isspace(*yyInput))
2332 yyInput++;
2333 c = *yyInput;
2335 /* Ignore RFC 822 comments, typically time zone names. */
2336 if (c != LPAREN)
2337 break;
2338 for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
2339 if (c == LPAREN)
2340 nesting++;
2341 else if (!IS7BIT(c) || c == '\0' || c == '\r'
2342 || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
2343 /* Lexical error: bad comment. */
2344 return '?';
2345 yyInput++;
2348 /* A number? */
2349 if (isdigit(c) || c == '-' || c == '+') {
2350 if (c == '-' || c == '+') {
2351 sign = c == '-' ? -1 : 1;
2352 yyInput++;
2353 if (!isdigit(*yyInput))
2354 /* Skip the plus or minus sign. */
2355 continue;
2357 else
2358 sign = 0;
2359 for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
2360 i = 10 * i + c - '0';
2361 yyInput--;
2362 yylval.Number = sign < 0 ? -i : i;
2363 return sign ? tSNUMBER : tUNUMBER;
2366 /* A word? */
2367 if (isalpha(c)) {
2368 for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
2369 if (p < &buff[sizeof buff - 1])
2370 *p++ = isupper(c) ? tolower(c) : c;
2371 *p = '\0';
2372 yyInput--;
2373 return LookupWord(buff, p - buff);
2376 return *yyInput++;
2381 time_t
2382 parsedate(char *p)
2384 extern int date_parse(void);
2385 time_t Start;
2387 yyInput = p;
2389 yyYear = 0;
2390 yyMonth = 0;
2391 yyDay = 0;
2392 yyTimezone = 0;
2393 yyDSTmode = DSTmaybe;
2394 yyHour = 0;
2395 yyMinutes = 0;
2396 yySeconds = 0;
2397 yyMeridian = MER24;
2398 yyRelSeconds = 0;
2399 yyRelMonth = 0;
2400 yyHaveDate = 0;
2401 yyHaveRel = 0;
2402 yyHaveTime = 0;
2404 if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
2405 return -1;
2407 if (yyHaveDate || yyHaveTime) {
2408 Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2409 yyMeridian, yyDSTmode);
2410 if (Start < 0)
2411 return -1;
2413 else
2414 return -1;
2416 Start += yyRelSeconds;
2417 if (yyRelMonth)
2418 Start += RelativeMonth(Start, yyRelMonth);
2420 /* Have to do *something* with a legitimate -1 so it's distinguishable
2421 * from the error return value. (Alternately could set errno on error.) */
2422 return Start == -1 ? 0 : Start;
2426 #ifdef TEST
2428 #if YYDEBUG
2429 extern int yydebug;
2430 #endif /* YYDEBUG */
2432 /* ARGSUSED */
2434 main(int ac, char *av[])
2436 char buff[128];
2437 time_t d;
2439 #if YYDEBUG
2440 yydebug = 1;
2441 #endif /* YYDEBUG */
2443 (void)printf("Enter date, or blank line to exit.\n\t> ");
2444 for ( ; ; ) {
2445 (void)printf("\t> ");
2446 (void)fflush(stdout);
2447 if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2448 break;
2449 #if YYDEBUG
2450 if (strcmp(buff, "yydebug") == 0) {
2451 yydebug = !yydebug;
2452 printf("yydebug = %s\n", yydebug ? "on" : "off");
2453 continue;
2455 #endif /* YYDEBUG */
2456 d = parsedate(buff, (TIMEINFO *)NULL);
2457 if (d == -1)
2458 (void)printf("Bad format - couldn't convert.\n");
2459 else
2460 (void)printf("%s", ctime(&d));
2463 exit(0);
2464 /* NOTREACHED */
2466 #endif /* TEST */