]> code.citadel.org Git - citadel.git/blob - rss2ctdl/parsedate.c
cb1e3633fff82fd33837001f55af925dc522cd29
[citadel.git] / rss2ctdl / parsedate.c
1 /* A Bison parser, made by GNU Bison 1.875.  */
2
3 /* Skeleton parser for Yacc-like parsing with Bison,
4    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 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 0
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      tDAY = 258,
57      tDAYZONE = 259,
58      tMERIDIAN = 260,
59      tMONTH = 261,
60      tMONTH_UNIT = 262,
61      tSEC_UNIT = 263,
62      tSNUMBER = 264,
63      tUNUMBER = 265,
64      tZONE = 266
65    };
66 #endif
67 #define tDAY 258
68 #define tDAYZONE 259
69 #define tMERIDIAN 260
70 #define tMONTH 261
71 #define tMONTH_UNIT 262
72 #define tSEC_UNIT 263
73 #define tSNUMBER 264
74 #define tUNUMBER 265
75 #define tZONE 266
76
77
78
79
80 /* Copy the first part of user declarations.  */
81
82 /* $Revision$
83 **
84 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
85 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
86 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
87 **  <rsalz@osf.org> and Jim Berets <jberets@bbn.com> in August, 1990.
88 **  Further revised (removed obsolete constructs and cleaned up timezone
89 **  names) in August, 1991, by Rich.  Paul Eggert <eggert@twinsun.com>
90 **  helped in September, 1992.  Art Cancro <ajc@uncensored.citadel.org> cleaned
91 **  it up for ANSI C in December, 1999.
92 **
93 **  This grammar has six shift/reduce conflicts.
94 **
95 **  This code is in the public domain and has no copyright.
96 */
97 /* SUPPRESS 530 *//* Empty body for statement */
98 /* SUPPRESS 593 on yyerrlab *//* Label was not used */
99 /* SUPPRESS 593 on yynewstate *//* Label was not used */
100 /* SUPPRESS 595 on yypvt *//* Automatic variable may be used before set */
101
102
103
104 #include <stdio.h>
105 #include <stdlib.h>
106 #include <sys/types.h>
107 #include <ctype.h>
108 #include <time.h>
109 #include <string.h>
110
111 #include "parsedate.h"
112
113 int date_lex(void);
114
115 #define yyparse         date_parse
116 #define yylex           date_lex
117 #define yyerror         date_error
118
119
120     /* See the LeapYears table in Convert. */
121 #define EPOCH           1970
122 #define END_OF_TIME     2038
123     /* Constants for general time calculations. */
124 #define DST_OFFSET      1
125 #define SECSPERDAY      (24L * 60L * 60L)
126     /* Readability for TABLE stuff. */
127 #define HOUR(x)         (x * 60)
128
129 #define LPAREN          '('
130 #define RPAREN          ')'
131 #define IS7BIT(x)       ((unsigned int)(x) < 0200)
132
133 #define SIZEOF(array)   ((int)(sizeof array / sizeof array[0]))
134 #define ENDOF(array)    (&array[SIZEOF(array)])
135
136
137 /*
138 **  An entry in the lexical lookup table.
139 */
140 typedef struct _TABLE {
141     char        *name;
142     int         type;
143     time_t      value;
144 } TABLE;
145
146 /*
147 **  Daylight-savings mode:  on, off, or not yet known.
148 */
149 typedef enum _DSTMODE {
150     DSTon, DSToff, DSTmaybe
151 } DSTMODE;
152
153 /*
154 **  Meridian:  am, pm, or 24-hour style.
155 */
156 typedef enum _MERIDIAN {
157     MERam, MERpm, MER24
158 } MERIDIAN;
159
160
161 /*
162 **  Global variables.  We could get rid of most of them by using a yacc
163 **  union, but this is more efficient.  (This routine predates the
164 **  yacc %union construct.)
165 */
166 static char     *yyInput;
167 static DSTMODE  yyDSTmode;
168 static int      yyHaveDate;
169 static int      yyHaveRel;
170 static int      yyHaveTime;
171 static time_t   yyTimezone;
172 static time_t   yyDay;
173 static time_t   yyHour;
174 static time_t   yyMinutes;
175 static time_t   yyMonth;
176 static time_t   yySeconds;
177 static time_t   yyYear;
178 static MERIDIAN yyMeridian;
179 static time_t   yyRelMonth;
180 static time_t   yyRelSeconds;
181
182
183 static void             date_error(char *);
184
185
186 /* Enabling traces.  */
187 #ifndef YYDEBUG
188 # define YYDEBUG 0
189 #endif
190
191 /* Enabling verbose error messages.  */
192 #ifdef YYERROR_VERBOSE
193 # undef YYERROR_VERBOSE
194 # define YYERROR_VERBOSE 1
195 #else
196 # define YYERROR_VERBOSE 0
197 #endif
198
199 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
200 typedef union YYSTYPE {
201     time_t              Number;
202     enum _MERIDIAN      Meridian;
203 } YYSTYPE;
204 /* Line 191 of yacc.c.  */
205 #line 230 "y.tab.c"
206 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
207 # define YYSTYPE_IS_DECLARED 1
208 # define YYSTYPE_IS_TRIVIAL 1
209 #endif
210
211
212
213 /* Copy the second part of user declarations.  */
214
215
216 /* Line 214 of yacc.c.  */
217 #line 242 "y.tab.c"
218
219 #if ! defined (yyoverflow) || YYERROR_VERBOSE
220
221 /* The parser invokes alloca or malloc; define the necessary symbols.  */
222
223 # if YYSTACK_USE_ALLOCA
224 #  define YYSTACK_ALLOC alloca
225 # else
226 #  ifndef YYSTACK_USE_ALLOCA
227 #   if defined (alloca) || defined (_ALLOCA_H)
228 #    define YYSTACK_ALLOC alloca
229 #   else
230 #    ifdef __GNUC__
231 #     define YYSTACK_ALLOC __builtin_alloca
232 #    endif
233 #   endif
234 #  endif
235 # endif
236
237 # ifdef YYSTACK_ALLOC
238    /* Pacify GCC's `empty if-body' warning. */
239 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
240 # else
241 #  if defined (__STDC__) || defined (__cplusplus)
242 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
243 #   define YYSIZE_T size_t
244 #  endif
245 #  define YYSTACK_ALLOC malloc
246 #  define YYSTACK_FREE free
247 # endif
248 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
249
250
251 #if (! defined (yyoverflow) \
252      && (! defined (__cplusplus) \
253          || (YYSTYPE_IS_TRIVIAL)))
254
255 /* A type that is properly aligned for any stack member.  */
256 union yyalloc
257 {
258   short yyss;
259   YYSTYPE yyvs;
260   };
261
262 /* The size of the maximum gap between one aligned stack and the next.  */
263 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
264
265 /* The size of an array large to enough to hold all stacks, each with
266    N elements.  */
267 # define YYSTACK_BYTES(N) \
268      ((N) * (sizeof (short) + sizeof (YYSTYPE))                         \
269       + YYSTACK_GAP_MAXIMUM)
270
271 /* Copy COUNT objects from FROM to TO.  The source and destination do
272    not overlap.  */
273 # ifndef YYCOPY
274 #  if 1 < __GNUC__
275 #   define YYCOPY(To, From, Count) \
276       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
277 #  else
278 #   define YYCOPY(To, From, Count)              \
279       do                                        \
280         {                                       \
281           register YYSIZE_T yyi;                \
282           for (yyi = 0; yyi < (Count); yyi++)   \
283             (To)[yyi] = (From)[yyi];            \
284         }                                       \
285       while (0)
286 #  endif
287 # endif
288
289 /* Relocate STACK from its old location to the new one.  The
290    local variables YYSIZE and YYSTACKSIZE give the old and new number of
291    elements in the stack, and YYPTR gives the new location of the
292    stack.  Advance YYPTR to a properly aligned location for the next
293    stack.  */
294 # define YYSTACK_RELOCATE(Stack)                                        \
295     do                                                                  \
296       {                                                                 \
297         YYSIZE_T yynewbytes;                                            \
298         YYCOPY (&yyptr->Stack, Stack, yysize);                          \
299         Stack = &yyptr->Stack;                                          \
300         yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
301         yyptr += yynewbytes / sizeof (*yyptr);                          \
302       }                                                                 \
303     while (0)
304
305 #endif
306
307 #if defined (__STDC__) || defined (__cplusplus)
308    typedef signed char yysigned_char;
309 #else
310    typedef short yysigned_char;
311 #endif
312
313 /* YYFINAL -- State number of the termination state. */
314 #define YYFINAL  2
315 /* YYLAST -- Last index in YYTABLE.  */
316 #define YYLAST   40
317
318 /* YYNTOKENS -- Number of terminals. */
319 #define YYNTOKENS  15
320 /* YYNNTS -- Number of nonterminals. */
321 #define YYNNTS  9
322 /* YYNRULES -- Number of rules. */
323 #define YYNRULES  30
324 /* YYNRULES -- Number of states. */
325 #define YYNSTATES  44
326
327 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
328 #define YYUNDEFTOK  2
329 #define YYMAXUTOK   266
330
331 #define YYTRANSLATE(YYX)                                                \
332   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
333
334 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
335 static const unsigned char yytranslate[] =
336 {
337        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
338        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
339        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
340        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
341        2,     2,     2,     2,    14,     2,     2,    13,     2,     2,
342        2,     2,     2,     2,     2,     2,     2,     2,    12,     2,
343        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
344        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
345        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
346        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
347        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
348        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
349        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
350        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
351        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
352        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
353        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
354        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
355        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
356        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
357        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
358        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
359        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
360        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
361        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
362        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
363        5,     6,     7,     8,     9,    10,    11
364 };
365
366 #if YYDEBUG
367 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
368    YYRHS.  */
369 static const unsigned char yyprhs[] =
370 {
371        0,     0,     3,     4,     7,     9,    12,    14,    16,    19,
372       24,    29,    36,    43,    45,    47,    50,    52,    54,    58,
373       64,    67,    72,    75,    79,    85,    88,    91,    94,    97,
374       98
375 };
376
377 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
378 static const yysigned_char yyrhs[] =
379 {
380       16,     0,    -1,    -1,    16,    17,    -1,    18,    -1,    18,
381       19,    -1,    21,    -1,    22,    -1,    10,    23,    -1,    10,
382       12,    10,    23,    -1,    10,    12,    10,    20,    -1,    10,
383       12,    10,    12,    10,    23,    -1,    10,    12,    10,    12,
384       10,    20,    -1,    11,    -1,     4,    -1,    11,    20,    -1,
385       20,    -1,     9,    -1,    10,    13,    10,    -1,    10,    13,
386       10,    13,    10,    -1,     6,    10,    -1,     6,    10,    14,
387       10,    -1,    10,     6,    -1,    10,     6,    10,    -1,     3,
388       14,    10,     6,    10,    -1,     9,     8,    -1,    10,     8,
389       -1,     9,     7,    -1,    10,     7,    -1,    -1,     5,    -1
390 };
391
392 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
393 static const unsigned short yyrline[] =
394 {
395        0,   143,   143,   144,   147,   156,   160,   163,   168,   180,
396      186,   193,   199,   209,   213,   217,   225,   231,   252,   256,
397      268,   272,   277,   281,   286,   293,   296,   299,   302,   307,
398      310
399 };
400 #endif
401
402 #if YYDEBUG || YYERROR_VERBOSE
403 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
404    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
405 static const char *const yytname[] =
406 {
407   "$end", "error", "$undefined", "tDAY", "tDAYZONE", "tMERIDIAN", "tMONTH", 
408   "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", "tUNUMBER", "tZONE", "':'", 
409   "'/'", "','", "$accept", "spec", "item", "time", "zone", "numzone", 
410   "date", "rel", "o_merid", 0
411 };
412 #endif
413
414 # ifdef YYPRINT
415 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
416    token YYLEX-NUM.  */
417 static const unsigned short yytoknum[] =
418 {
419        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
420      265,   266,    58,    47,    44
421 };
422 # endif
423
424 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
425 static const unsigned char yyr1[] =
426 {
427        0,    15,    16,    16,    17,    17,    17,    17,    18,    18,
428       18,    18,    18,    19,    19,    19,    19,    20,    21,    21,
429       21,    21,    21,    21,    21,    22,    22,    22,    22,    23,
430       23
431 };
432
433 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
434 static const unsigned char yyr2[] =
435 {
436        0,     2,     0,     2,     1,     2,     1,     1,     2,     4,
437        4,     6,     6,     1,     1,     2,     1,     1,     3,     5,
438        2,     4,     2,     3,     5,     2,     2,     2,     2,     0,
439        1
440 };
441
442 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
443    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
444    means the default is an error.  */
445 static const unsigned char yydefact[] =
446 {
447        2,     0,     1,     0,     0,     0,    29,     3,     4,     6,
448        7,     0,    20,    27,    25,    30,    22,    28,    26,     0,
449        0,     8,    14,    17,    13,     5,    16,     0,     0,    23,
450       29,    18,    15,     0,    21,     0,    10,     9,     0,    24,
451       29,    19,    12,    11
452 };
453
454 /* YYDEFGOTO[NTERM-NUM]. */
455 static const yysigned_char yydefgoto[] =
456 {
457       -1,     1,     7,     8,    25,    26,     9,    10,    21
458 };
459
460 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
461    STATE-NUM.  */
462 #define YYPACT_NINF -29
463 static const yysigned_char yypact[] =
464 {
465      -29,     1,   -29,   -11,    11,    20,    12,   -29,     4,   -29,
466      -29,    13,    16,   -29,   -29,   -29,    21,   -29,   -29,    22,
467       23,   -29,   -29,   -29,     5,   -29,   -29,    28,    25,   -29,
468       17,    24,   -29,    26,   -29,    29,   -29,   -29,    30,   -29,
469        0,   -29,   -29,   -29
470 };
471
472 /* YYPGOTO[NTERM-NUM].  */
473 static const yysigned_char yypgoto[] =
474 {
475      -29,   -29,   -29,   -29,   -29,   -24,   -29,   -29,   -28
476 };
477
478 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
479    positive, shift that token.  If negative, reduce the rule which
480    number is the opposite.  If zero, do what YYDEFACT says.
481    If YYTABLE_NINF, syntax error.  */
482 #define YYTABLE_NINF -1
483 static const unsigned char yytable[] =
484 {
485       32,     2,    37,    11,     3,    15,    36,     4,    22,    23,
486        5,     6,    43,    23,    23,    24,    42,    15,    16,    17,
487       18,    12,    15,    27,    19,    20,    23,    13,    14,    35,
488       28,    29,    30,    31,    33,    34,    39,    38,     0,    40,
489       41
490 };
491
492 static const yysigned_char yycheck[] =
493 {
494       24,     0,    30,    14,     3,     5,    30,     6,     4,     9,
495        9,    10,    40,     9,     9,    11,    40,     5,     6,     7,
496        8,    10,     5,    10,    12,    13,     9,     7,     8,    12,
497       14,    10,    10,    10,     6,    10,    10,    13,    -1,    10,
498       10
499 };
500
501 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
502    symbol of state STATE-NUM.  */
503 static const unsigned char yystos[] =
504 {
505        0,    16,     0,     3,     6,     9,    10,    17,    18,    21,
506       22,    14,    10,     7,     8,     5,     6,     7,     8,    12,
507       13,    23,     4,     9,    11,    19,    20,    10,    14,    10,
508       10,    10,    20,     6,    10,    12,    20,    23,    13,    10,
509       10,    10,    20,    23
510 };
511
512 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
513 # define YYSIZE_T __SIZE_TYPE__
514 #endif
515 #if ! defined (YYSIZE_T) && defined (size_t)
516 # define YYSIZE_T size_t
517 #endif
518 #if ! defined (YYSIZE_T)
519 # if defined (__STDC__) || defined (__cplusplus)
520 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
521 #  define YYSIZE_T size_t
522 # endif
523 #endif
524 #if ! defined (YYSIZE_T)
525 # define YYSIZE_T unsigned int
526 #endif
527
528 #define yyerrok         (yyerrstatus = 0)
529 #define yyclearin       (yychar = YYEMPTY)
530 #define YYEMPTY         (-2)
531 #define YYEOF           0
532
533 #define YYACCEPT        goto yyacceptlab
534 #define YYABORT         goto yyabortlab
535 #define YYERROR         goto yyerrlab1
536
537
538 /* Like YYERROR except do call yyerror.  This remains here temporarily
539    to ease the transition to the new meaning of YYERROR, for GCC.
540    Once GCC version 2 has supplanted version 1, this can go.  */
541
542 #define YYFAIL          goto yyerrlab
543
544 #define YYRECOVERING()  (!!yyerrstatus)
545
546 #define YYBACKUP(Token, Value)                                  \
547 do                                                              \
548   if (yychar == YYEMPTY && yylen == 1)                          \
549     {                                                           \
550       yychar = (Token);                                         \
551       yylval = (Value);                                         \
552       yytoken = YYTRANSLATE (yychar);                           \
553       YYPOPSTACK;                                               \
554       goto yybackup;                                            \
555     }                                                           \
556   else                                                          \
557     {                                                           \
558       yyerror ("syntax error: cannot back up");\
559       YYERROR;                                                  \
560     }                                                           \
561 while (0)
562
563 #define YYTERROR        1
564 #define YYERRCODE       256
565
566 /* YYLLOC_DEFAULT -- Compute the default location (before the actions
567    are run).  */
568
569 #ifndef YYLLOC_DEFAULT
570 # define YYLLOC_DEFAULT(Current, Rhs, N)         \
571   Current.first_line   = Rhs[1].first_line;      \
572   Current.first_column = Rhs[1].first_column;    \
573   Current.last_line    = Rhs[N].last_line;       \
574   Current.last_column  = Rhs[N].last_column;
575 #endif
576
577 /* YYLEX -- calling `yylex' with the right arguments.  */
578
579 #ifdef YYLEX_PARAM
580 # define YYLEX yylex (YYLEX_PARAM)
581 #else
582 # define YYLEX yylex ()
583 #endif
584
585 /* Enable debugging if requested.  */
586 #if YYDEBUG
587
588 # ifndef YYFPRINTF
589 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
590 #  define YYFPRINTF fprintf
591 # endif
592
593 # define YYDPRINTF(Args)                        \
594 do {                                            \
595   if (yydebug)                                  \
596     YYFPRINTF Args;                             \
597 } while (0)
598
599 # define YYDSYMPRINT(Args)                      \
600 do {                                            \
601   if (yydebug)                                  \
602     yysymprint Args;                            \
603 } while (0)
604
605 # define YYDSYMPRINTF(Title, Token, Value, Location)            \
606 do {                                                            \
607   if (yydebug)                                                  \
608     {                                                           \
609       YYFPRINTF (stderr, "%s ", Title);                         \
610       yysymprint (stderr,                                       \
611                   Token, Value);        \
612       YYFPRINTF (stderr, "\n");                                 \
613     }                                                           \
614 } while (0)
615
616 /*------------------------------------------------------------------.
617 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
618 | TOP (cinluded).                                                   |
619 `------------------------------------------------------------------*/
620
621 #if defined (__STDC__) || defined (__cplusplus)
622 static void
623 yy_stack_print (short *bottom, short *top)
624 #else
625 static void
626 yy_stack_print (bottom, top)
627     short *bottom;
628     short *top;
629 #endif
630 {
631   YYFPRINTF (stderr, "Stack now");
632   for (/* Nothing. */; bottom <= top; ++bottom)
633     YYFPRINTF (stderr, " %d", *bottom);
634   YYFPRINTF (stderr, "\n");
635 }
636
637 # define YY_STACK_PRINT(Bottom, Top)                            \
638 do {                                                            \
639   if (yydebug)                                                  \
640     yy_stack_print ((Bottom), (Top));                           \
641 } while (0)
642
643
644 /*------------------------------------------------.
645 | Report that the YYRULE is going to be reduced.  |
646 `------------------------------------------------*/
647
648 #if defined (__STDC__) || defined (__cplusplus)
649 static void
650 yy_reduce_print (int yyrule)
651 #else
652 static void
653 yy_reduce_print (yyrule)
654     int yyrule;
655 #endif
656 {
657   int yyi;
658   unsigned int yylineno = yyrline[yyrule];
659   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
660              yyrule - 1, yylineno);
661   /* Print the symbols being reduced, and their result.  */
662   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
663     YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
664   YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
665 }
666
667 # define YY_REDUCE_PRINT(Rule)          \
668 do {                                    \
669   if (yydebug)                          \
670     yy_reduce_print (Rule);             \
671 } while (0)
672
673 /* Nonzero means print parse trace.  It is left uninitialized so that
674    multiple parsers can coexist.  */
675 int yydebug;
676 #else /* !YYDEBUG */
677 # define YYDPRINTF(Args)
678 # define YYDSYMPRINT(Args)
679 # define YYDSYMPRINTF(Title, Token, Value, Location)
680 # define YY_STACK_PRINT(Bottom, Top)
681 # define YY_REDUCE_PRINT(Rule)
682 #endif /* !YYDEBUG */
683
684
685 /* YYINITDEPTH -- initial size of the parser's stacks.  */
686 #ifndef YYINITDEPTH
687 # define YYINITDEPTH 200
688 #endif
689
690 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
691    if the built-in stack extension method is used).
692
693    Do not make this value too large; the results are undefined if
694    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
695    evaluated with infinite-precision integer arithmetic.  */
696
697 #if YYMAXDEPTH == 0
698 # undef YYMAXDEPTH
699 #endif
700
701 #ifndef YYMAXDEPTH
702 # define YYMAXDEPTH 10000
703 #endif
704
705 \f
706
707 #if YYERROR_VERBOSE
708
709 # ifndef yystrlen
710 #  if defined (__GLIBC__) && defined (_STRING_H)
711 #   define yystrlen strlen
712 #  else
713 /* Return the length of YYSTR.  */
714 static YYSIZE_T
715 #   if defined (__STDC__) || defined (__cplusplus)
716 yystrlen (const char *yystr)
717 #   else
718 yystrlen (yystr)
719      const char *yystr;
720 #   endif
721 {
722   register const char *yys = yystr;
723
724   while (*yys++ != '\0')
725     continue;
726
727   return yys - yystr - 1;
728 }
729 #  endif
730 # endif
731
732 # ifndef yystpcpy
733 #  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
734 #   define yystpcpy stpcpy
735 #  else
736 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
737    YYDEST.  */
738 static char *
739 #   if defined (__STDC__) || defined (__cplusplus)
740 yystpcpy (char *yydest, const char *yysrc)
741 #   else
742 yystpcpy (yydest, yysrc)
743      char *yydest;
744      const char *yysrc;
745 #   endif
746 {
747   register char *yyd = yydest;
748   register const char *yys = yysrc;
749
750   while ((*yyd++ = *yys++) != '\0')
751     continue;
752
753   return yyd - 1;
754 }
755 #  endif
756 # endif
757
758 #endif /* !YYERROR_VERBOSE */
759
760 \f
761
762 #if YYDEBUG
763 /*--------------------------------.
764 | Print this symbol on YYOUTPUT.  |
765 `--------------------------------*/
766
767 #if defined (__STDC__) || defined (__cplusplus)
768 static void
769 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
770 #else
771 static void
772 yysymprint (yyoutput, yytype, yyvaluep)
773     FILE *yyoutput;
774     int yytype;
775     YYSTYPE *yyvaluep;
776 #endif
777 {
778   /* Pacify ``unused variable'' warnings.  */
779   (void) yyvaluep;
780
781   if (yytype < YYNTOKENS)
782     {
783       YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
784 # ifdef YYPRINT
785       YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
786 # endif
787     }
788   else
789     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
790
791   switch (yytype)
792     {
793       default:
794         break;
795     }
796   YYFPRINTF (yyoutput, ")");
797 }
798
799 #endif /* ! YYDEBUG */
800 /*-----------------------------------------------.
801 | Release the memory associated to this symbol.  |
802 `-----------------------------------------------*/
803
804 #if defined (__STDC__) || defined (__cplusplus)
805 static void
806 yydestruct (int yytype, YYSTYPE *yyvaluep)
807 #else
808 static void
809 yydestruct (yytype, yyvaluep)
810     int yytype;
811     YYSTYPE *yyvaluep;
812 #endif
813 {
814   /* Pacify ``unused variable'' warnings.  */
815   (void) yyvaluep;
816
817   switch (yytype)
818     {
819
820       default:
821         break;
822     }
823 }
824 \f
825
826 /* Prevent warnings from -Wmissing-prototypes.  */
827
828 #ifdef YYPARSE_PARAM
829 # if defined (__STDC__) || defined (__cplusplus)
830 int yyparse (void *YYPARSE_PARAM);
831 # else
832 int yyparse ();
833 # endif
834 #else /* ! YYPARSE_PARAM */
835 #if defined (__STDC__) || defined (__cplusplus)
836 int yyparse (void);
837 #else
838 int yyparse ();
839 #endif
840 #endif /* ! YYPARSE_PARAM */
841
842
843
844 /* The lookahead symbol.  */
845 int yychar;
846
847 /* The semantic value of the lookahead symbol.  */
848 YYSTYPE yylval;
849
850 /* Number of syntax errors so far.  */
851 int yynerrs;
852
853
854
855 /*----------.
856 | yyparse.  |
857 `----------*/
858
859 #ifdef YYPARSE_PARAM
860 # if defined (__STDC__) || defined (__cplusplus)
861 int yyparse (void *YYPARSE_PARAM)
862 # else
863 int yyparse (YYPARSE_PARAM)
864   void *YYPARSE_PARAM;
865 # endif
866 #else /* ! YYPARSE_PARAM */
867 #if defined (__STDC__) || defined (__cplusplus)
868 int
869 yyparse (void)
870 #else
871 int
872 yyparse ()
873
874 #endif
875 #endif
876 {
877   
878   register int yystate;
879   register int yyn;
880   int yyresult;
881   /* Number of tokens to shift before error messages enabled.  */
882   int yyerrstatus;
883   /* Lookahead token as an internal (translated) token number.  */
884   int yytoken = 0;
885
886   /* Three stacks and their tools:
887      `yyss': related to states,
888      `yyvs': related to semantic values,
889      `yyls': related to locations.
890
891      Refer to the stacks thru separate pointers, to allow yyoverflow
892      to reallocate them elsewhere.  */
893
894   /* The state stack.  */
895   short yyssa[YYINITDEPTH];
896   short *yyss = yyssa;
897   register short *yyssp;
898
899   /* The semantic value stack.  */
900   YYSTYPE yyvsa[YYINITDEPTH];
901   YYSTYPE *yyvs = yyvsa;
902   register YYSTYPE *yyvsp;
903
904
905
906 #define YYPOPSTACK   (yyvsp--, yyssp--)
907
908   YYSIZE_T yystacksize = YYINITDEPTH;
909
910   /* The variables used to return semantic value and location from the
911      action routines.  */
912   YYSTYPE yyval;
913
914
915   /* When reducing, the number of symbols on the RHS of the reduced
916      rule.  */
917   int yylen;
918
919   YYDPRINTF ((stderr, "Starting parse\n"));
920
921   yystate = 0;
922   yyerrstatus = 0;
923   yynerrs = 0;
924   yychar = YYEMPTY;             /* Cause a token to be read.  */
925
926   /* Initialize stack pointers.
927      Waste one element of value and location stack
928      so that they stay on the same level as the state stack.
929      The wasted elements are never initialized.  */
930
931   yyssp = yyss;
932   yyvsp = yyvs;
933
934   goto yysetstate;
935
936 /*------------------------------------------------------------.
937 | yynewstate -- Push a new state, which is found in yystate.  |
938 `------------------------------------------------------------*/
939  yynewstate:
940   /* In all cases, when you get here, the value and location stacks
941      have just been pushed. so pushing a state here evens the stacks.
942      */
943   yyssp++;
944
945  yysetstate:
946   *yyssp = yystate;
947
948   if (yyss + yystacksize - 1 <= yyssp)
949     {
950       /* Get the current used size of the three stacks, in elements.  */
951       YYSIZE_T yysize = yyssp - yyss + 1;
952
953 #ifdef yyoverflow
954       {
955         /* Give user a chance to reallocate the stack. Use copies of
956            these so that the &'s don't force the real ones into
957            memory.  */
958         YYSTYPE *yyvs1 = yyvs;
959         short *yyss1 = yyss;
960
961
962         /* Each stack pointer address is followed by the size of the
963            data in use in that stack, in bytes.  This used to be a
964            conditional around just the two extra args, but that might
965            be undefined if yyoverflow is a macro.  */
966         yyoverflow ("parser stack overflow",
967                     &yyss1, yysize * sizeof (*yyssp),
968                     &yyvs1, yysize * sizeof (*yyvsp),
969
970                     &yystacksize);
971
972         yyss = yyss1;
973         yyvs = yyvs1;
974       }
975 #else /* no yyoverflow */
976 # ifndef YYSTACK_RELOCATE
977       goto yyoverflowlab;
978 # else
979       /* Extend the stack our own way.  */
980       if (YYMAXDEPTH <= yystacksize)
981         goto yyoverflowlab;
982       yystacksize *= 2;
983       if (YYMAXDEPTH < yystacksize)
984         yystacksize = YYMAXDEPTH;
985
986       {
987         short *yyss1 = yyss;
988         union yyalloc *yyptr =
989           (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
990         if (! yyptr)
991           goto yyoverflowlab;
992         YYSTACK_RELOCATE (yyss);
993         YYSTACK_RELOCATE (yyvs);
994
995 #  undef YYSTACK_RELOCATE
996         if (yyss1 != yyssa)
997           YYSTACK_FREE (yyss1);
998       }
999 # endif
1000 #endif /* no yyoverflow */
1001
1002       yyssp = yyss + yysize - 1;
1003       yyvsp = yyvs + yysize - 1;
1004
1005
1006       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1007                   (unsigned long int) yystacksize));
1008
1009       if (yyss + yystacksize - 1 <= yyssp)
1010         YYABORT;
1011     }
1012
1013   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1014
1015   goto yybackup;
1016
1017 /*-----------.
1018 | yybackup.  |
1019 `-----------*/
1020 yybackup:
1021
1022 /* Do appropriate processing given the current state.  */
1023 /* Read a lookahead token if we need one and don't already have one.  */
1024 /* yyresume: */
1025
1026   /* First try to decide what to do without reference to lookahead token.  */
1027
1028   yyn = yypact[yystate];
1029   if (yyn == YYPACT_NINF)
1030     goto yydefault;
1031
1032   /* Not known => get a lookahead token if don't already have one.  */
1033
1034   /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
1035   if (yychar == YYEMPTY)
1036     {
1037       YYDPRINTF ((stderr, "Reading a token: "));
1038       yychar = YYLEX;
1039     }
1040
1041   if (yychar <= YYEOF)
1042     {
1043       yychar = yytoken = YYEOF;
1044       YYDPRINTF ((stderr, "Now at end of input.\n"));
1045     }
1046   else
1047     {
1048       yytoken = YYTRANSLATE (yychar);
1049       YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
1050     }
1051
1052   /* If the proper action on seeing token YYTOKEN is to reduce or to
1053      detect an error, take that action.  */
1054   yyn += yytoken;
1055   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1056     goto yydefault;
1057   yyn = yytable[yyn];
1058   if (yyn <= 0)
1059     {
1060       if (yyn == 0 || yyn == YYTABLE_NINF)
1061         goto yyerrlab;
1062       yyn = -yyn;
1063       goto yyreduce;
1064     }
1065
1066   if (yyn == YYFINAL)
1067     YYACCEPT;
1068
1069   /* Shift the lookahead token.  */
1070   YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
1071
1072   /* Discard the token being shifted unless it is eof.  */
1073   if (yychar != YYEOF)
1074     yychar = YYEMPTY;
1075
1076   *++yyvsp = yylval;
1077
1078
1079   /* Count tokens shifted since error; after three, turn off error
1080      status.  */
1081   if (yyerrstatus)
1082     yyerrstatus--;
1083
1084   yystate = yyn;
1085   goto yynewstate;
1086
1087
1088 /*-----------------------------------------------------------.
1089 | yydefault -- do the default action for the current state.  |
1090 `-----------------------------------------------------------*/
1091 yydefault:
1092   yyn = yydefact[yystate];
1093   if (yyn == 0)
1094     goto yyerrlab;
1095   goto yyreduce;
1096
1097
1098 /*-----------------------------.
1099 | yyreduce -- Do a reduction.  |
1100 `-----------------------------*/
1101 yyreduce:
1102   /* yyn is the number of a rule to reduce with.  */
1103   yylen = yyr2[yyn];
1104
1105   /* If YYLEN is nonzero, implement the default value of the action:
1106      `$$ = $1'.
1107
1108      Otherwise, the following line sets YYVAL to garbage.
1109      This behavior is undocumented and Bison
1110      users should not rely upon it.  Assigning to YYVAL
1111      unconditionally makes the parser a bit smaller, and it avoids a
1112      GCC warning that YYVAL may be used uninitialized.  */
1113   yyval = yyvsp[1-yylen];
1114
1115
1116   YY_REDUCE_PRINT (yyn);
1117   switch (yyn)
1118     {
1119         case 4:
1120     {
1121             yyHaveTime++;
1122 #ifdef lint
1123             /* I am compulsive about lint natterings... */
1124             if (yyHaveTime == -1) {
1125                 YYERROR;
1126             }
1127 #endif /* lint */
1128         }
1129     break;
1130
1131   case 5:
1132     {
1133             yyHaveTime++;
1134             yyTimezone = yyvsp[0].Number;
1135         }
1136     break;
1137
1138   case 6:
1139     {
1140             yyHaveDate++;
1141         }
1142     break;
1143
1144   case 7:
1145     {
1146             yyHaveRel = 1;
1147         }
1148     break;
1149
1150   case 8:
1151     {
1152             if (yyvsp[-1].Number < 100) {
1153                 yyHour = yyvsp[-1].Number;
1154                 yyMinutes = 0;
1155             }
1156             else {
1157                 yyHour = yyvsp[-1].Number / 100;
1158                 yyMinutes = yyvsp[-1].Number % 100;
1159             }
1160             yySeconds = 0;
1161             yyMeridian = yyvsp[0].Meridian;
1162         }
1163     break;
1164
1165   case 9:
1166     {
1167             yyHour = yyvsp[-3].Number;
1168             yyMinutes = yyvsp[-1].Number;
1169             yySeconds = 0;
1170             yyMeridian = yyvsp[0].Meridian;
1171         }
1172     break;
1173
1174   case 10:
1175     {
1176             yyHour = yyvsp[-3].Number;
1177             yyMinutes = yyvsp[-1].Number;
1178             yyTimezone = yyvsp[0].Number;
1179             yyMeridian = MER24;
1180             yyDSTmode = DSToff;
1181         }
1182     break;
1183
1184   case 11:
1185     {
1186             yyHour = yyvsp[-5].Number;
1187             yyMinutes = yyvsp[-3].Number;
1188             yySeconds = yyvsp[-1].Number;
1189             yyMeridian = yyvsp[0].Meridian;
1190         }
1191     break;
1192
1193   case 12:
1194     {
1195             yyHour = yyvsp[-5].Number;
1196             yyMinutes = yyvsp[-3].Number;
1197             yySeconds = yyvsp[-1].Number;
1198             yyTimezone = yyvsp[0].Number;
1199             yyMeridian = MER24;
1200             yyDSTmode = DSToff;
1201         }
1202     break;
1203
1204   case 13:
1205     {
1206             yyval.Number = yyvsp[0].Number;
1207             yyDSTmode = DSToff;
1208         }
1209     break;
1210
1211   case 14:
1212     {
1213             yyval.Number = yyvsp[0].Number;
1214             yyDSTmode = DSTon;
1215         }
1216     break;
1217
1218   case 15:
1219     {
1220             /* Only allow "GMT+300" and "GMT-0800" */
1221             if (yyvsp[-1].Number != 0) {
1222                 YYABORT;
1223             }
1224             yyval.Number = yyvsp[0].Number;
1225             yyDSTmode = DSToff;
1226         }
1227     break;
1228
1229   case 16:
1230     {
1231             yyval.Number = yyvsp[0].Number;
1232             yyDSTmode = DSToff;
1233         }
1234     break;
1235
1236   case 17:
1237     {
1238             int         i;
1239
1240             /* Unix and GMT and numeric timezones -- a little confusing. */
1241             if (yyvsp[0].Number < 0) {
1242                 /* Don't work with negative modulus. */
1243                 yyvsp[0].Number = -yyvsp[0].Number;
1244                 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1245                     YYABORT;
1246                 }
1247                 yyval.Number = (yyvsp[0].Number / 100) * 60 + i;
1248             }
1249             else {
1250                 if (yyvsp[0].Number > 9999 || (i = yyvsp[0].Number % 100) >= 60) {
1251                     YYABORT;
1252                 }
1253                 yyval.Number = -((yyvsp[0].Number / 100) * 60 + i);
1254             }
1255         }
1256     break;
1257
1258   case 18:
1259     {
1260             yyMonth = yyvsp[-2].Number;
1261             yyDay = yyvsp[0].Number;
1262         }
1263     break;
1264
1265   case 19:
1266     {
1267             if (yyvsp[-4].Number > 100) {
1268                 yyYear = yyvsp[-4].Number;
1269                 yyMonth = yyvsp[-2].Number;
1270                 yyDay = yyvsp[0].Number;
1271             }
1272             else {
1273                 yyMonth = yyvsp[-4].Number;
1274                 yyDay = yyvsp[-2].Number;
1275                 yyYear = yyvsp[0].Number;
1276             }
1277         }
1278     break;
1279
1280   case 20:
1281     {
1282             yyMonth = yyvsp[-1].Number;
1283             yyDay = yyvsp[0].Number;
1284         }
1285     break;
1286
1287   case 21:
1288     {
1289             yyMonth = yyvsp[-3].Number;
1290             yyDay = yyvsp[-2].Number;
1291             yyYear = yyvsp[0].Number;
1292         }
1293     break;
1294
1295   case 22:
1296     {
1297             yyDay = yyvsp[-1].Number;
1298             yyMonth = yyvsp[0].Number;
1299         }
1300     break;
1301
1302   case 23:
1303     {
1304             yyDay = yyvsp[-2].Number;
1305             yyMonth = yyvsp[-1].Number;
1306             yyYear = yyvsp[0].Number;
1307         }
1308     break;
1309
1310   case 24:
1311     {
1312             yyDay = yyvsp[-2].Number;
1313             yyMonth = yyvsp[-1].Number;
1314             yyYear = yyvsp[0].Number;
1315         }
1316     break;
1317
1318   case 25:
1319     {
1320             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1321         }
1322     break;
1323
1324   case 26:
1325     {
1326             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number;
1327         }
1328     break;
1329
1330   case 27:
1331     {
1332             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1333         }
1334     break;
1335
1336   case 28:
1337     {
1338             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1339         }
1340     break;
1341
1342   case 29:
1343     {
1344             yyval.Meridian = MER24;
1345         }
1346     break;
1347
1348   case 30:
1349     {
1350             yyval.Meridian = yyvsp[0].Meridian;
1351         }
1352     break;
1353
1354
1355     }
1356
1357 /* Line 999 of yacc.c.  */
1358 #line 1410 "y.tab.c"
1359 \f
1360   yyvsp -= yylen;
1361   yyssp -= yylen;
1362
1363
1364   YY_STACK_PRINT (yyss, yyssp);
1365
1366   *++yyvsp = yyval;
1367
1368
1369   /* Now `shift' the result of the reduction.  Determine what state
1370      that goes to, based on the state we popped back to and the rule
1371      number reduced by.  */
1372
1373   yyn = yyr1[yyn];
1374
1375   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1376   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1377     yystate = yytable[yystate];
1378   else
1379     yystate = yydefgoto[yyn - YYNTOKENS];
1380
1381   goto yynewstate;
1382
1383
1384 /*------------------------------------.
1385 | yyerrlab -- here on detecting error |
1386 `------------------------------------*/
1387 yyerrlab:
1388   /* If not already recovering from an error, report this error.  */
1389   if (!yyerrstatus)
1390     {
1391       ++yynerrs;
1392 #if YYERROR_VERBOSE
1393       yyn = yypact[yystate];
1394
1395       if (YYPACT_NINF < yyn && yyn < YYLAST)
1396         {
1397           YYSIZE_T yysize = 0;
1398           int yytype = YYTRANSLATE (yychar);
1399           char *yymsg;
1400           int yyx, yycount;
1401
1402           yycount = 0;
1403           /* Start YYX at -YYN if negative to avoid negative indexes in
1404              YYCHECK.  */
1405           for (yyx = yyn < 0 ? -yyn : 0;
1406                yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
1407             if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1408               yysize += yystrlen (yytname[yyx]) + 15, yycount++;
1409           yysize += yystrlen ("syntax error, unexpected ") + 1;
1410           yysize += yystrlen (yytname[yytype]);
1411           yymsg = (char *) YYSTACK_ALLOC (yysize);
1412           if (yymsg != 0)
1413             {
1414               char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
1415               yyp = yystpcpy (yyp, yytname[yytype]);
1416
1417               if (yycount < 5)
1418                 {
1419                   yycount = 0;
1420                   for (yyx = yyn < 0 ? -yyn : 0;
1421                        yyx < (int) (sizeof (yytname) / sizeof (char *));
1422                        yyx++)
1423                     if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1424                       {
1425                         const char *yyq = ! yycount ? ", expecting " : " or ";
1426                         yyp = yystpcpy (yyp, yyq);
1427                         yyp = yystpcpy (yyp, yytname[yyx]);
1428                         yycount++;
1429                       }
1430                 }
1431               yyerror (yymsg);
1432               YYSTACK_FREE (yymsg);
1433             }
1434           else
1435             yyerror ("syntax error; also virtual memory exhausted");
1436         }
1437       else
1438 #endif /* YYERROR_VERBOSE */
1439         yyerror ("syntax error");
1440     }
1441
1442
1443
1444   if (yyerrstatus == 3)
1445     {
1446       /* If just tried and failed to reuse lookahead token after an
1447          error, discard it.  */
1448
1449       /* Return failure if at end of input.  */
1450       if (yychar == YYEOF)
1451         {
1452           /* Pop the error token.  */
1453           YYPOPSTACK;
1454           /* Pop the rest of the stack.  */
1455           while (yyss < yyssp)
1456             {
1457               YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1458               yydestruct (yystos[*yyssp], yyvsp);
1459               YYPOPSTACK;
1460             }
1461           YYABORT;
1462         }
1463
1464       YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
1465       yydestruct (yytoken, &yylval);
1466       yychar = YYEMPTY;
1467
1468     }
1469
1470   /* Else will try to reuse lookahead token after shifting the error
1471      token.  */
1472   goto yyerrlab1;
1473
1474
1475 /*----------------------------------------------------.
1476 | yyerrlab1 -- error raised explicitly by an action.  |
1477 `----------------------------------------------------*/
1478 yyerrlab1:
1479   yyerrstatus = 3;      /* Each real token shifted decrements this.  */
1480
1481   for (;;)
1482     {
1483       yyn = yypact[yystate];
1484       if (yyn != YYPACT_NINF)
1485         {
1486           yyn += YYTERROR;
1487           if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1488             {
1489               yyn = yytable[yyn];
1490               if (0 < yyn)
1491                 break;
1492             }
1493         }
1494
1495       /* Pop the current state because it cannot handle the error token.  */
1496       if (yyssp == yyss)
1497         YYABORT;
1498
1499       YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
1500       yydestruct (yystos[yystate], yyvsp);
1501       yyvsp--;
1502       yystate = *--yyssp;
1503
1504       YY_STACK_PRINT (yyss, yyssp);
1505     }
1506
1507   if (yyn == YYFINAL)
1508     YYACCEPT;
1509
1510   YYDPRINTF ((stderr, "Shifting error token, "));
1511
1512   *++yyvsp = yylval;
1513
1514
1515   yystate = yyn;
1516   goto yynewstate;
1517
1518
1519 /*-------------------------------------.
1520 | yyacceptlab -- YYACCEPT comes here.  |
1521 `-------------------------------------*/
1522 yyacceptlab:
1523   yyresult = 0;
1524   goto yyreturn;
1525
1526 /*-----------------------------------.
1527 | yyabortlab -- YYABORT comes here.  |
1528 `-----------------------------------*/
1529 yyabortlab:
1530   yyresult = 1;
1531   goto yyreturn;
1532
1533 #ifndef yyoverflow
1534 /*----------------------------------------------.
1535 | yyoverflowlab -- parser overflow comes here.  |
1536 `----------------------------------------------*/
1537 yyoverflowlab:
1538   yyerror ("parser stack overflow");
1539   yyresult = 2;
1540   /* Fall through.  */
1541 #endif
1542
1543 yyreturn:
1544 #ifndef yyoverflow
1545   if (yyss != yyssa)
1546     YYSTACK_FREE (yyss);
1547 #endif
1548   return yyresult;
1549 }
1550
1551
1552
1553
1554 /* Month and day table. */
1555 static TABLE    MonthDayTable[] = {
1556     { "january",        tMONTH,  1 },
1557     { "february",       tMONTH,  2 },
1558     { "march",          tMONTH,  3 },
1559     { "april",          tMONTH,  4 },
1560     { "may",            tMONTH,  5 },
1561     { "june",           tMONTH,  6 },
1562     { "july",           tMONTH,  7 },
1563     { "august",         tMONTH,  8 },
1564     { "september",      tMONTH,  9 },
1565     { "october",        tMONTH, 10 },
1566     { "november",       tMONTH, 11 },
1567     { "december",       tMONTH, 12 },
1568         /* The value of the day isn't used... */
1569     { "sunday",         tDAY, 0 },
1570     { "monday",         tDAY, 0 },
1571     { "tuesday",        tDAY, 0 },
1572     { "wednesday",      tDAY, 0 },
1573     { "thursday",       tDAY, 0 },
1574     { "friday",         tDAY, 0 },
1575     { "saturday",       tDAY, 0 },
1576 };
1577
1578 /* Time units table. */
1579 static TABLE    UnitsTable[] = {
1580     { "year",           tMONTH_UNIT,    12 },
1581     { "month",          tMONTH_UNIT,    1 },
1582     { "week",           tSEC_UNIT,      7L * 24 * 60 * 60 },
1583     { "day",            tSEC_UNIT,      1L * 24 * 60 * 60 },
1584     { "hour",           tSEC_UNIT,      60 * 60 },
1585     { "minute",         tSEC_UNIT,      60 },
1586     { "min",            tSEC_UNIT,      60 },
1587     { "second",         tSEC_UNIT,      1 },
1588     { "sec",            tSEC_UNIT,      1 },
1589 };
1590
1591 /* Timezone table. */
1592 static TABLE    TimezoneTable[] = {
1593     { "gmt",    tZONE,     HOUR( 0) },  /* Greenwich Mean */
1594     { "ut",     tZONE,     HOUR( 0) },  /* Universal */
1595     { "utc",    tZONE,     HOUR( 0) },  /* Universal Coordinated */
1596     { "cut",    tZONE,     HOUR( 0) },  /* Coordinated Universal */
1597     { "z",      tZONE,     HOUR( 0) },  /* Greenwich Mean */
1598     { "wet",    tZONE,     HOUR( 0) },  /* Western European */
1599     { "bst",    tDAYZONE,  HOUR( 0) },  /* British Summer */
1600     { "nst",    tZONE,     HOUR(3)+30 }, /* Newfoundland Standard */
1601     { "ndt",    tDAYZONE,  HOUR(3)+30 }, /* Newfoundland Daylight */
1602     { "ast",    tZONE,     HOUR( 4) },  /* Atlantic Standard */
1603     { "adt",    tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
1604     { "est",    tZONE,     HOUR( 5) },  /* Eastern Standard */
1605     { "edt",    tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
1606     { "cst",    tZONE,     HOUR( 6) },  /* Central Standard */
1607     { "cdt",    tDAYZONE,  HOUR( 6) },  /* Central Daylight */
1608     { "mst",    tZONE,     HOUR( 7) },  /* Mountain Standard */
1609     { "mdt",    tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
1610     { "pst",    tZONE,     HOUR( 8) },  /* Pacific Standard */
1611     { "pdt",    tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
1612     { "yst",    tZONE,     HOUR( 9) },  /* Yukon Standard */
1613     { "ydt",    tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
1614     { "akst",   tZONE,     HOUR( 9) },  /* Alaska Standard */
1615     { "akdt",   tDAYZONE,  HOUR( 9) },  /* Alaska Daylight */
1616     { "hst",    tZONE,     HOUR(10) },  /* Hawaii Standard */
1617     { "hast",   tZONE,     HOUR(10) },  /* Hawaii-Aleutian Standard */
1618     { "hadt",   tDAYZONE,  HOUR(10) },  /* Hawaii-Aleutian Daylight */
1619     { "ces",    tDAYZONE,  -HOUR(1) },  /* Central European Summer */
1620     { "cest",   tDAYZONE,  -HOUR(1) },  /* Central European Summer */
1621     { "mez",    tZONE,     -HOUR(1) },  /* Middle European */
1622     { "mezt",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
1623     { "cet",    tZONE,     -HOUR(1) },  /* Central European */
1624     { "met",    tZONE,     -HOUR(1) },  /* Middle European */
1625     { "eet",    tZONE,     -HOUR(2) },  /* Eastern Europe */
1626     { "msk",    tZONE,     -HOUR(3) },  /* Moscow Winter */
1627     { "msd",    tDAYZONE,  -HOUR(3) },  /* Moscow Summer */
1628     { "wast",   tZONE,     -HOUR(8) },  /* West Australian Standard */
1629     { "wadt",   tDAYZONE,  -HOUR(8) },  /* West Australian Daylight */
1630     { "hkt",    tZONE,     -HOUR(8) },  /* Hong Kong */
1631     { "cct",    tZONE,     -HOUR(8) },  /* China Coast */
1632     { "jst",    tZONE,     -HOUR(9) },  /* Japan Standard */
1633     { "kst",    tZONE,     -HOUR(9) },  /* Korean Standard */
1634     { "kdt",    tZONE,     -HOUR(9) },  /* Korean Daylight */
1635     { "cast",   tZONE,     -(HOUR(9)+30) }, /* Central Australian Standard */
1636     { "cadt",   tDAYZONE,  -(HOUR(9)+30) }, /* Central Australian Daylight */
1637     { "east",   tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
1638     { "eadt",   tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
1639     { "nzst",   tZONE,     -HOUR(12) }, /* New Zealand Standard */
1640     { "nzdt",   tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
1641
1642     /* For completeness we include the following entries. */
1643 #if 0
1644
1645     /* Duplicate names.  Either they conflict with a zone listed above
1646      * (which is either more likely to be seen or just been in circulation
1647      * longer), or they conflict with another zone in this section and
1648      * we could not reasonably choose one over the other. */
1649     { "fst",    tZONE,     HOUR( 2) },  /* Fernando De Noronha Standard */
1650     { "fdt",    tDAYZONE,  HOUR( 2) },  /* Fernando De Noronha Daylight */
1651     { "bst",    tZONE,     HOUR( 3) },  /* Brazil Standard */
1652     { "est",    tZONE,     HOUR( 3) },  /* Eastern Standard (Brazil) */
1653     { "edt",    tDAYZONE,  HOUR( 3) },  /* Eastern Daylight (Brazil) */
1654     { "wst",    tZONE,     HOUR( 4) },  /* Western Standard (Brazil) */
1655     { "wdt",    tDAYZONE,  HOUR( 4) },  /* Western Daylight (Brazil) */
1656     { "cst",    tZONE,     HOUR( 5) },  /* Chile Standard */
1657     { "cdt",    tDAYZONE,  HOUR( 5) },  /* Chile Daylight */
1658     { "ast",    tZONE,     HOUR( 5) },  /* Acre Standard */
1659     { "adt",    tDAYZONE,  HOUR( 5) },  /* Acre Daylight */
1660     { "cst",    tZONE,     HOUR( 5) },  /* Cuba Standard */
1661     { "cdt",    tDAYZONE,  HOUR( 5) },  /* Cuba Daylight */
1662     { "est",    tZONE,     HOUR( 6) },  /* Easter Island Standard */
1663     { "edt",    tDAYZONE,  HOUR( 6) },  /* Easter Island Daylight */
1664     { "sst",    tZONE,     HOUR(11) },  /* Samoa Standard */
1665     { "ist",    tZONE,     -HOUR(2) },  /* Israel Standard */
1666     { "idt",    tDAYZONE,  -HOUR(2) },  /* Israel Daylight */
1667     { "idt",    tDAYZONE,  -(HOUR(3)+30) }, /* Iran Daylight */
1668     { "ist",    tZONE,     -(HOUR(3)+30) }, /* Iran Standard */
1669     { "cst",     tZONE,     -HOUR(8) }, /* China Standard */
1670     { "cdt",     tDAYZONE,  -HOUR(8) }, /* China Daylight */
1671     { "sst",     tZONE,     -HOUR(8) }, /* Singapore Standard */
1672
1673     /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
1674     { "gst",    tZONE,     HOUR( 3) },  /* Greenland Standard */
1675     { "wat",    tZONE,     -HOUR(1) },  /* West Africa */
1676     { "at",     tZONE,     HOUR( 2) },  /* Azores */
1677     { "gst",    tZONE,     -HOUR(10) }, /* Guam Standard */
1678     { "nft",    tZONE,     HOUR(3)+30 }, /* Newfoundland */
1679     { "idlw",   tZONE,     HOUR(12) },  /* International Date Line West */
1680     { "mewt",   tZONE,     -HOUR(1) },  /* Middle European Winter */
1681     { "mest",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
1682     { "swt",    tZONE,     -HOUR(1) },  /* Swedish Winter */
1683     { "sst",    tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
1684     { "fwt",    tZONE,     -HOUR(1) },  /* French Winter */
1685     { "fst",    tDAYZONE,  -HOUR(1) },  /* French Summer */
1686     { "bt",     tZONE,     -HOUR(3) },  /* Baghdad */
1687     { "it",     tZONE,     -(HOUR(3)+30) }, /* Iran */
1688     { "zp4",    tZONE,     -HOUR(4) },  /* USSR Zone 3 */
1689     { "zp5",    tZONE,     -HOUR(5) },  /* USSR Zone 4 */
1690     { "ist",    tZONE,     -(HOUR(5)+30) }, /* Indian Standard */
1691     { "zp6",    tZONE,     -HOUR(6) },  /* USSR Zone 5 */
1692     { "nst",    tZONE,     -HOUR(7) },  /* North Sumatra */
1693     { "sst",    tZONE,     -HOUR(7) },  /* South Sumatra */
1694     { "jt",     tZONE,     -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
1695     { "nzt",    tZONE,     -HOUR(12) }, /* New Zealand */
1696     { "idle",   tZONE,     -HOUR(12) }, /* International Date Line East */
1697     { "cat",    tZONE,     HOUR(10) },  /* -- expired 1967 */
1698     { "nt",     tZONE,     HOUR(11) },  /* -- expired 1967 */
1699     { "ahst",   tZONE,     HOUR(10) },  /* -- expired 1983 */
1700     { "hdt",    tDAYZONE,  HOUR(10) },  /* -- expired 1986 */
1701 #endif /* 0 */
1702 };
1703
1704
1705 /* ARGSUSED */
1706 static void
1707 date_error(char *s)
1708 {
1709     /* NOTREACHED */
1710 }
1711
1712
1713 static time_t
1714 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1715 {
1716     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 61)
1717         return -1;
1718     if (Meridian == MER24) {
1719         if (Hours < 0 || Hours > 23)
1720             return -1;
1721     }
1722     else {
1723         if (Hours < 1 || Hours > 12)
1724             return -1;
1725         if (Hours == 12)
1726             Hours = 0;
1727         if (Meridian == MERpm)
1728             Hours += 12;
1729     }
1730     return (Hours * 60L + Minutes) * 60L + Seconds;
1731 }
1732
1733
1734 static time_t
1735 Convert(time_t Month, time_t Day, time_t Year,
1736         time_t Hours, time_t Minutes, time_t Seconds,
1737         MERIDIAN Meridian, DSTMODE dst)
1738 {
1739     static int  DaysNormal[13] = {
1740         0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1741     };
1742     static int  DaysLeap[13] = {
1743         0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1744     };
1745     static int  LeapYears[] = {
1746         1972, 1976, 1980, 1984, 1988, 1992, 1996,
1747         2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
1748     };
1749     register int        *yp;
1750     register int        *mp;
1751     register time_t     Julian;
1752     register int        i;
1753     time_t              tod;
1754
1755     if (Year < 0)
1756         Year = -Year;
1757     if (Year < 100)
1758         Year += 1900;
1759     if (Year < EPOCH)
1760         Year += 100;
1761     for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
1762         if (Year == *yp) {
1763             mp = DaysLeap;
1764             break;
1765         }
1766     if (Year < EPOCH || Year > END_OF_TIME
1767      || Month < 1 || Month > 12
1768      /* NOSTRICT *//* conversion from long may lose accuracy */
1769      || Day < 1 || Day > mp[(int)Month])
1770         return -1;
1771
1772     Julian = Day - 1 + (Year - EPOCH) * 365;
1773     for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++)
1774         if (Year <= *yp)
1775             break;
1776     for (i = 1; i < Month; i++)
1777         Julian += *++mp;
1778     Julian *= SECSPERDAY;
1779     Julian += yyTimezone * 60L;
1780     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1781         return -1;
1782     Julian += tod;
1783     tod = Julian;
1784     if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
1785         Julian -= DST_OFFSET * 60L * 60L;
1786     return Julian;
1787 }
1788
1789
1790 static time_t
1791 DSTcorrect(time_t Start, time_t Future)
1792 {
1793     time_t      StartDay;
1794     time_t      FutureDay;
1795
1796     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
1797     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
1798     return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60L * 60L;
1799 }
1800
1801
1802 static time_t
1803 RelativeMonth(time_t Start, time_t RelMonth)
1804 {
1805     struct tm   *tm;
1806     time_t      Month;
1807     time_t      Year;
1808
1809     tm = localtime(&Start);
1810     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
1811     Year = Month / 12;
1812     Month = Month % 12 + 1;
1813     return DSTcorrect(Start,
1814             Convert(Month, (time_t)tm->tm_mday, Year,
1815                 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
1816                 MER24, DSTmaybe));
1817 }
1818
1819
1820 static int
1821 LookupWord(char *buff, register int length)
1822 {
1823     register char       *p;
1824     register char       *q;
1825     register TABLE      *tp;
1826     register int        c;
1827
1828     p = buff;
1829     c = p[0];
1830
1831     /* See if we have an abbreviation for a month. */
1832     if (length == 3 || (length == 4 && p[3] == '.'))
1833         for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
1834             q = tp->name;
1835             if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
1836                 yylval.Number = tp->value;
1837                 return tp->type;
1838             }
1839         }
1840     else
1841         for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++)
1842             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1843                 yylval.Number = tp->value;
1844                 return tp->type;
1845             }
1846
1847     /* Try for a timezone. */
1848     for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1849         if (c == tp->name[0] && p[1] == tp->name[1]
1850          && strcmp(p, tp->name) == 0) {
1851             yylval.Number = tp->value;
1852             return tp->type;
1853         }
1854
1855     /* Try the units table. */
1856     for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1857         if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1858             yylval.Number = tp->value;
1859             return tp->type;
1860         }
1861
1862     /* Strip off any plural and try the units table again. */
1863     if (--length > 0 && p[length] == 's') {
1864         p[length] = '\0';
1865         for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++)
1866             if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
1867                 p[length] = 's';
1868                 yylval.Number = tp->value;
1869                 return tp->type;
1870             }
1871         p[length] = 's';
1872     }
1873     length++;
1874
1875     /* Drop out any periods. */
1876     for (p = buff, q = (char*)buff; *q; q++)
1877         if (*q != '.')
1878             *p++ = *q;
1879     *p = '\0';
1880
1881     /* Try the meridians. */
1882     if (buff[1] == 'm' && buff[2] == '\0') {
1883         if (buff[0] == 'a') {
1884             yylval.Meridian = MERam;
1885             return tMERIDIAN;
1886         }
1887         if (buff[0] == 'p') {
1888             yylval.Meridian = MERpm;
1889             return tMERIDIAN;
1890         }
1891     }
1892
1893     /* If we saw any periods, try the timezones again. */
1894     if (p - buff != length) {
1895         c = buff[0];
1896         for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++)
1897             if (c == tp->name[0] && p[1] == tp->name[1]
1898             && strcmp(p, tp->name) == 0) {
1899                 yylval.Number = tp->value;
1900                 return tp->type;
1901             }
1902     }
1903
1904     /* Unknown word -- assume GMT timezone. */
1905     yylval.Number = 0;
1906     return tZONE;
1907 }
1908
1909
1910 int
1911 date_lex(void)
1912 {
1913     register char       c;
1914     register char       *p;
1915     char                buff[20];
1916     register int        sign;
1917     register int        i;
1918     register int        nesting;
1919
1920     for ( ; ; ) {
1921         /* Get first character after the whitespace. */
1922         for ( ; ; ) {
1923             while (isspace(*yyInput))
1924                 yyInput++;
1925             c = *yyInput;
1926
1927             /* Ignore RFC 822 comments, typically time zone names. */
1928             if (c != LPAREN)
1929                 break;
1930             for (nesting = 1; (c = *++yyInput) != RPAREN || --nesting; )
1931                 if (c == LPAREN)
1932                     nesting++;
1933                 else if (!IS7BIT(c) || c == '\0' || c == '\r'
1934                      || (c == '\\' && ((c = *++yyInput) == '\0' || !IS7BIT(c))))
1935                     /* Lexical error: bad comment. */
1936                     return '?';
1937             yyInput++;
1938         }
1939
1940         /* A number? */
1941         if (isdigit(c) || c == '-' || c == '+') {
1942             if (c == '-' || c == '+') {
1943                 sign = c == '-' ? -1 : 1;
1944                 yyInput++;
1945                 if (!isdigit(*yyInput))
1946                     /* Skip the plus or minus sign. */
1947                     continue;
1948             }
1949             else
1950                 sign = 0;
1951             for (i = 0; (c = *yyInput++) != '\0' && isdigit(c); )
1952                 i = 10 * i + c - '0';
1953             yyInput--;
1954             yylval.Number = sign < 0 ? -i : i;
1955             return sign ? tSNUMBER : tUNUMBER;
1956         }
1957
1958         /* A word? */
1959         if (isalpha(c)) {
1960             for (p = buff; (c = *yyInput++) == '.' || isalpha(c); )
1961                 if (p < &buff[sizeof buff - 1])
1962                     *p++ = isupper(c) ? tolower(c) : c;
1963             *p = '\0';
1964             yyInput--;
1965             return LookupWord(buff, p - buff);
1966         }
1967
1968         return *yyInput++;
1969     }
1970 }
1971
1972
1973 time_t
1974 parsedate(char *p)
1975 {
1976     extern int          date_parse(void);
1977     time_t              Start;
1978
1979     yyInput = p;
1980
1981     yyYear = 0;
1982     yyMonth = 0;
1983     yyDay = 0;
1984     yyTimezone = 0;
1985     yyDSTmode = DSTmaybe;
1986     yyHour = 0;
1987     yyMinutes = 0;
1988     yySeconds = 0;
1989     yyMeridian = MER24;
1990     yyRelSeconds = 0;
1991     yyRelMonth = 0;
1992     yyHaveDate = 0;
1993     yyHaveRel = 0;
1994     yyHaveTime = 0;
1995
1996     if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
1997         return -1;
1998
1999     if (yyHaveDate || yyHaveTime) {
2000         Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
2001                     yyMeridian, yyDSTmode);
2002         if (Start < 0)
2003             return -1;
2004     }
2005     else
2006         return -1;
2007
2008     Start += yyRelSeconds;
2009     if (yyRelMonth)
2010         Start += RelativeMonth(Start, yyRelMonth);
2011
2012     /* Have to do *something* with a legitimate -1 so it's distinguishable
2013      * from the error return value.  (Alternately could set errno on error.) */
2014     return Start == -1 ? 0 : Start;
2015 }
2016
2017
2018 #ifdef TEST
2019
2020 #if YYDEBUG
2021 extern int      yydebug;
2022 #endif /* YYDEBUG */
2023
2024 /* ARGSUSED */
2025 int
2026 main(int ac, char *av[])
2027 {
2028     char        buff[128];
2029     time_t      d;
2030
2031 #if YYDEBUG
2032     yydebug = 1;
2033 #endif /* YYDEBUG */
2034
2035     (void)printf("Enter date, or blank line to exit.\n\t> ");
2036     for ( ; ; ) {
2037         (void)printf("\t> ");
2038         (void)fflush(stdout);
2039         if (fgets(buff, sizeof buff, stdin) == NULL || buff[0] == '\n')
2040             break;
2041 #if YYDEBUG
2042         if (strcmp(buff, "yydebug") == 0) {
2043             yydebug = !yydebug;
2044             printf("yydebug = %s\n", yydebug ? "on" : "off");
2045             continue;
2046         }
2047 #endif /* YYDEBUG */
2048         d = parsedate(buff, (TIMEINFO *)NULL);
2049         if (d == -1)
2050             (void)printf("Bad format - couldn't convert.\n");
2051         else
2052             (void)printf("%s", ctime(&d));
2053     }
2054
2055     exit(0);
2056     /* NOTREACHED */
2057 }
2058 #endif /* TEST */
2059
2060