Merge commit 'upstream/1.7.4'
[debian/sudo] / getdate.c
1 #include <stdlib.h>
2 #include <string.h>
3 #define YYBYACC 1
4 #define YYMAJOR 1
5 #define YYMINOR 9
6 #define YYLEX yylex()
7 #define YYEMPTY -1
8 #define yyclearin (yychar=(YYEMPTY))
9 #define yyerrok (yyerrflag=0)
10 #define YYRECOVERING() (yyerrflag!=0)
11 #define YYPREFIX "yy"
12 #line 2 "getdate.y"
13 /*
14 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
15 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
16 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
17 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
18 **
19 **  This grammar has 10 shift/reduce conflicts.
20 **
21 **  This code is in the public domain and has no copyright.
22 */
23 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
24 /* SUPPRESS 288 on yyerrlab *//* Label unused */
25
26 #include <config.h>
27
28 #include <sys/types.h>
29 #include <sys/time.h>
30 #include <stdio.h>
31 #ifdef STDC_HEADERS
32 # include <stdlib.h>
33 # include <stddef.h>
34 #else
35 # ifdef HAVE_STDLIB_H
36 #  include <stdlib.h>
37 # endif
38 #endif /* STDC_HEADERS */
39 #ifdef HAVE_STRING_H
40 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
41 #  include <memory.h>
42 # endif
43 # include <string.h>
44 #endif /* HAVE_STRING_H */
45 #ifdef HAVE_STRINGS_H
46 # include <strings.h>
47 #endif /* HAVE_STRINGS_H */
48 #if TIME_WITH_SYS_TIME
49 # include <time.h>
50 #endif
51 #include <ctype.h>
52
53 #include "compat.h"
54
55
56 #define EPOCH           1970
57 #define HOUR(x)         ((time_t)(x) * 60)
58 #define SECSPERDAY      (24L * 60L * 60L)
59
60
61 /*
62 **  An entry in the lexical lookup table.
63 */
64 typedef struct _TABLE {
65     char        *name;
66     int         type;
67     time_t      value;
68 } TABLE;
69
70
71 /*
72 **  Daylight-savings mode:  on, off, or not yet known.
73 */
74 typedef enum _DSTMODE {
75     DSTon, DSToff, DSTmaybe
76 } DSTMODE;
77
78 /*
79 **  Meridian:  am, pm, or 24-hour style.
80 */
81 typedef enum _MERIDIAN {
82     MERam, MERpm, MER24
83 } MERIDIAN;
84
85
86 /*
87 **  Global variables.  We could get rid of most of these by using a good
88 **  union as the yacc stack.  (This routine was originally written before
89 **  yacc had the %union construct.)  Maybe someday; right now we only use
90 **  the %union very rarely.
91 */
92 static char     *yyInput;
93 static DSTMODE  yyDSTmode;
94 static time_t   yyDayOrdinal;
95 static time_t   yyDayNumber;
96 static int      yyHaveDate;
97 static int      yyHaveDay;
98 static int      yyHaveRel;
99 static int      yyHaveTime;
100 static int      yyHaveZone;
101 static time_t   yyTimezone;
102 static time_t   yyDay;
103 static time_t   yyHour;
104 static time_t   yyMinutes;
105 static time_t   yyMonth;
106 static time_t   yySeconds;
107 static time_t   yyYear;
108 static MERIDIAN yyMeridian;
109 static time_t   yyRelMonth;
110 static time_t   yyRelSeconds;
111
112 static int      yyerror __P((char *s));
113 static int      yylex __P((void));
114 static int      yyparse __P((void));
115
116 #line 107 "getdate.y"
117 #ifndef YYSTYPE_DEFINED
118 #define YYSTYPE_DEFINED
119 typedef union {
120     time_t              Number;
121     enum _MERIDIAN      Meridian;
122 } YYSTYPE;
123 #endif /* YYSTYPE_DEFINED */
124 #line 125 "y.tab.c"
125 #define tAGO 257
126 #define tDAY 258
127 #define tDAYZONE 259
128 #define tID 260
129 #define tMERIDIAN 261
130 #define tMINUTE_UNIT 262
131 #define tMONTH 263
132 #define tMONTH_UNIT 264
133 #define tSEC_UNIT 265
134 #define tSNUMBER 266
135 #define tUNUMBER 267
136 #define tZONE 268
137 #define tDST 269
138 #define YYERRCODE 256
139 #if defined(__cplusplus) || defined(__STDC__)
140 const short yylhs[] =
141 #else
142 short yylhs[] =
143 #endif
144         {                                        -1,
145     0,    0,    2,    2,    2,    2,    2,    2,    3,    3,
146     3,    3,    3,    4,    4,    4,    6,    6,    6,    5,
147     5,    5,    5,    5,    5,    5,    5,    7,    7,    9,
148     9,    9,    9,    9,    9,    9,    9,    9,    8,    1,
149     1,
150 };
151 #if defined(__cplusplus) || defined(__STDC__)
152 const short yylen[] =
153 #else
154 short yylen[] =
155 #endif
156         {                                         2,
157     0,    2,    1,    1,    1,    1,    1,    1,    2,    4,
158     4,    6,    6,    1,    1,    2,    1,    2,    2,    3,
159     5,    3,    3,    2,    4,    2,    3,    2,    1,    2,
160     2,    1,    2,    2,    1,    2,    2,    1,    1,    0,
161     1,
162 };
163 #if defined(__cplusplus) || defined(__STDC__)
164 const short yydefred[] =
165 #else
166 short yydefred[] =
167 #endif
168         {                                      1,
169     0,    0,   15,   32,    0,   38,   35,    0,    0,    0,
170     2,    3,    4,    5,    6,    7,    8,    0,   18,    0,
171    31,   36,   33,   19,    9,   30,    0,   37,   34,    0,
172     0,    0,   16,   28,    0,   23,   27,   22,    0,    0,
173    25,   41,   11,    0,   10,    0,    0,   21,   13,   12,
174 };
175 #if defined(__cplusplus) || defined(__STDC__)
176 const short yydgoto[] =
177 #else
178 short yydgoto[] =
179 #endif
180         {                                       1,
181    45,   11,   12,   13,   14,   15,   16,   17,   18,
182 };
183 #if defined(__cplusplus) || defined(__STDC__)
184 const short yysindex[] =
185 #else
186 short yysindex[] =
187 #endif
188         {                                      0,
189  -249,  -38,    0,    0, -260,    0,    0, -240,  -47, -248,
190     0,    0,    0,    0,    0,    0,    0, -237,    0,  -18,
191     0,    0,    0,    0,    0,    0, -262,    0,    0, -239,
192  -238, -236,    0,    0, -235,    0,    0,    0,  -56,  -19,
193     0,    0,    0, -234,    0, -232, -258,    0,    0,    0,};
194 #if defined(__cplusplus) || defined(__STDC__)
195 const short yyrindex[] =
196 #else
197 short yyrindex[] =
198 #endif
199         {                                      0,
200     0,    1,    0,    0,    0,    0,    0,    0,   69,   12,
201     0,    0,    0,    0,    0,    0,    0,   23,    0,   34,
202     0,    0,    0,    0,    0,    0,   67,    0,    0,    0,
203     0,    0,    0,    0,    0,    0,    0,    0,   56,   45,
204     0,    0,    0,    0,    0,    0,   56,    0,    0,    0,};
205 #if defined(__cplusplus) || defined(__STDC__)
206 const short yygindex[] =
207 #else
208 short yygindex[] =
209 #endif
210         {                                      0,
211   -17,    0,    0,    0,    0,    0,    0,    0,    0,
212 };
213 #define YYTABLESIZE 337
214 #if defined(__cplusplus) || defined(__STDC__)
215 const short yytable[] =
216 #else
217 short yytable[] =
218 #endif
219         {                                      32,
220    17,   44,   42,   36,   37,   19,   20,   49,    2,    3,
221    31,   14,    4,    5,    6,    7,    8,    9,   10,   34,
222    33,   21,   29,   22,   23,   35,   38,   46,   39,   50,
223    40,   41,   47,   24,   48,    0,    0,    0,    0,    0,
224     0,    0,    0,    0,   20,    0,    0,    0,    0,    0,
225     0,    0,    0,    0,    0,   40,    0,    0,    0,    0,
226     0,    0,    0,    0,    0,    0,   26,    0,   39,    0,
227     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
228     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
229     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
230     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
231     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
232     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
233     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
234     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
235     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
236     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
237     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
238     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
239     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
240     0,    0,    0,    0,   42,    0,    0,    0,    0,   43,
241    24,    0,    0,   25,   26,   27,   28,   29,   30,    0,
242     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
243     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
244     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
245     0,    0,    0,    0,    0,    0,    0,    0,   17,   17,
246     0,    0,   17,   17,   17,   17,   17,   17,   17,   14,
247    14,    0,    0,   14,   14,   14,   14,   14,   14,   14,
248    29,   29,    0,    0,   29,   29,   29,   29,   29,   29,
249    29,   24,   24,    0,    0,   24,   24,   24,   24,   24,
250    24,   24,   20,   20,    0,    0,   20,   20,   20,   20,
251    20,   20,   20,   40,   40,    0,    0,   40,   40,   40,
252    40,    0,   40,   40,   26,   26,    0,   39,   26,   26,
253    26,   26,    0,    0,   26,   39,   39,
254 };
255 #if defined(__cplusplus) || defined(__STDC__)
256 const short yycheck[] =
257 #else
258 short yycheck[] =
259 #endif
260         {                                      47,
261     0,   58,  261,  266,  267,   44,  267,  266,  258,  259,
262    58,    0,  262,  263,  264,  265,  266,  267,  268,  257,
263   269,  262,    0,  264,  265,   44,  266,   47,  267,   47,
264   267,  267,  267,    0,  267,   -1,   -1,   -1,   -1,   -1,
265    -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,
266    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
267    -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,    0,   -1,
268    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
269    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
270    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
271    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
272    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
273    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
274    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
275    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
276    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
277    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
278    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
279    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
280    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
281    -1,   -1,   -1,   -1,  261,   -1,   -1,   -1,   -1,  266,
282   258,   -1,   -1,  261,  262,  263,  264,  265,  266,   -1,
283    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
284    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
285    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
286    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,  259,
287    -1,   -1,  262,  263,  264,  265,  266,  267,  268,  258,
288   259,   -1,   -1,  262,  263,  264,  265,  266,  267,  268,
289   258,  259,   -1,   -1,  262,  263,  264,  265,  266,  267,
290   268,  258,  259,   -1,   -1,  262,  263,  264,  265,  266,
291   267,  268,  258,  259,   -1,   -1,  262,  263,  264,  265,
292   266,  267,  268,  258,  259,   -1,   -1,  262,  263,  264,
293   265,   -1,  267,  268,  258,  259,   -1,  259,  262,  263,
294   264,  265,   -1,   -1,  268,  267,  268,
295 };
296 #define YYFINAL 1
297 #ifndef YYDEBUG
298 #define YYDEBUG 0
299 #endif
300 #define YYMAXTOKEN 269
301 #if YYDEBUG
302 #if defined(__cplusplus) || defined(__STDC__)
303 const char * const yyname[] =
304 #else
305 char *yyname[] =
306 #endif
307         {
308 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
309 0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0,0,0,
310 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
311 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
312 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
313 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
314 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"tAGO","tDAY",
315 "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
316 "tSNUMBER","tUNUMBER","tZONE","tDST",
317 };
318 #if defined(__cplusplus) || defined(__STDC__)
319 const char * const yyrule[] =
320 #else
321 char *yyrule[] =
322 #endif
323         {"$accept : spec",
324 "spec :",
325 "spec : spec item",
326 "item : time",
327 "item : zone",
328 "item : date",
329 "item : day",
330 "item : rel",
331 "item : number",
332 "time : tUNUMBER tMERIDIAN",
333 "time : tUNUMBER ':' tUNUMBER o_merid",
334 "time : tUNUMBER ':' tUNUMBER tSNUMBER",
335 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
336 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
337 "zone : tZONE",
338 "zone : tDAYZONE",
339 "zone : tZONE tDST",
340 "day : tDAY",
341 "day : tDAY ','",
342 "day : tUNUMBER tDAY",
343 "date : tUNUMBER '/' tUNUMBER",
344 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
345 "date : tUNUMBER tSNUMBER tSNUMBER",
346 "date : tUNUMBER tMONTH tSNUMBER",
347 "date : tMONTH tUNUMBER",
348 "date : tMONTH tUNUMBER ',' tUNUMBER",
349 "date : tUNUMBER tMONTH",
350 "date : tUNUMBER tMONTH tUNUMBER",
351 "rel : relunit tAGO",
352 "rel : relunit",
353 "relunit : tUNUMBER tMINUTE_UNIT",
354 "relunit : tSNUMBER tMINUTE_UNIT",
355 "relunit : tMINUTE_UNIT",
356 "relunit : tSNUMBER tSEC_UNIT",
357 "relunit : tUNUMBER tSEC_UNIT",
358 "relunit : tSEC_UNIT",
359 "relunit : tSNUMBER tMONTH_UNIT",
360 "relunit : tUNUMBER tMONTH_UNIT",
361 "relunit : tMONTH_UNIT",
362 "number : tUNUMBER",
363 "o_merid :",
364 "o_merid : tMERIDIAN",
365 };
366 #endif
367 #ifdef YYSTACKSIZE
368 #undef YYMAXDEPTH
369 #define YYMAXDEPTH YYSTACKSIZE
370 #else
371 #ifdef YYMAXDEPTH
372 #define YYSTACKSIZE YYMAXDEPTH
373 #else
374 #define YYSTACKSIZE 10000
375 #define YYMAXDEPTH 10000
376 #endif
377 #endif
378 #define YYINITSTACKSIZE 200
379 /* LINTUSED */
380 int yydebug;
381 int yynerrs;
382 int yyerrflag;
383 int yychar;
384 short *yyssp;
385 YYSTYPE *yyvsp;
386 YYSTYPE yyval;
387 YYSTYPE yylval;
388 short *yyss;
389 short *yysslim;
390 YYSTYPE *yyvs;
391 int yystacksize;
392 #line 326 "getdate.y"
393
394 /* Month and day table. */
395 static TABLE const MonthDayTable[] = {
396     { "january",        tMONTH,  1 },
397     { "february",       tMONTH,  2 },
398     { "march",          tMONTH,  3 },
399     { "april",          tMONTH,  4 },
400     { "may",            tMONTH,  5 },
401     { "june",           tMONTH,  6 },
402     { "july",           tMONTH,  7 },
403     { "august",         tMONTH,  8 },
404     { "september",      tMONTH,  9 },
405     { "sept",           tMONTH,  9 },
406     { "october",        tMONTH, 10 },
407     { "november",       tMONTH, 11 },
408     { "december",       tMONTH, 12 },
409     { "sunday",         tDAY, 0 },
410     { "monday",         tDAY, 1 },
411     { "tuesday",        tDAY, 2 },
412     { "tues",           tDAY, 2 },
413     { "wednesday",      tDAY, 3 },
414     { "wednes",         tDAY, 3 },
415     { "thursday",       tDAY, 4 },
416     { "thur",           tDAY, 4 },
417     { "thurs",          tDAY, 4 },
418     { "friday",         tDAY, 5 },
419     { "saturday",       tDAY, 6 },
420     { NULL }
421 };
422
423 /* Time units table. */
424 static TABLE const UnitsTable[] = {
425     { "year",           tMONTH_UNIT,    12 },
426     { "month",          tMONTH_UNIT,    1 },
427     { "fortnight",      tMINUTE_UNIT,   14 * 24 * 60 },
428     { "week",           tMINUTE_UNIT,   7 * 24 * 60 },
429     { "day",            tMINUTE_UNIT,   1 * 24 * 60 },
430     { "hour",           tMINUTE_UNIT,   60 },
431     { "minute",         tMINUTE_UNIT,   1 },
432     { "min",            tMINUTE_UNIT,   1 },
433     { "second",         tSEC_UNIT,      1 },
434     { "sec",            tSEC_UNIT,      1 },
435     { NULL }
436 };
437
438 /* Assorted relative-time words. */
439 static TABLE const OtherTable[] = {
440     { "tomorrow",       tMINUTE_UNIT,   1 * 24 * 60 },
441     { "yesterday",      tMINUTE_UNIT,   -1 * 24 * 60 },
442     { "today",          tMINUTE_UNIT,   0 },
443     { "now",            tMINUTE_UNIT,   0 },
444     { "last",           tUNUMBER,       -1 },
445     { "this",           tMINUTE_UNIT,   0 },
446     { "next",           tUNUMBER,       2 },
447     { "first",          tUNUMBER,       1 },
448 /*  { "second",         tUNUMBER,       2 }, */
449     { "third",          tUNUMBER,       3 },
450     { "fourth",         tUNUMBER,       4 },
451     { "fifth",          tUNUMBER,       5 },
452     { "sixth",          tUNUMBER,       6 },
453     { "seventh",        tUNUMBER,       7 },
454     { "eighth",         tUNUMBER,       8 },
455     { "ninth",          tUNUMBER,       9 },
456     { "tenth",          tUNUMBER,       10 },
457     { "eleventh",       tUNUMBER,       11 },
458     { "twelfth",        tUNUMBER,       12 },
459     { "ago",            tAGO,   1 },
460     { NULL }
461 };
462
463 /* The timezone table. */
464 /* Some of these are commented out because a time_t can't store a float. */
465 static TABLE const TimezoneTable[] = {
466     { "gmt",    tZONE,     HOUR( 0) },  /* Greenwich Mean */
467     { "ut",     tZONE,     HOUR( 0) },  /* Universal (Coordinated) */
468     { "utc",    tZONE,     HOUR( 0) },
469     { "wet",    tZONE,     HOUR( 0) },  /* Western European */
470     { "bst",    tDAYZONE,  HOUR( 0) },  /* British Summer */
471     { "wat",    tZONE,     HOUR( 1) },  /* West Africa */
472     { "at",     tZONE,     HOUR( 2) },  /* Azores */
473 #if     0
474     /* For completeness.  BST is also British Summer, and GST is
475      * also Guam Standard. */
476     { "bst",    tZONE,     HOUR( 3) },  /* Brazil Standard */
477     { "gst",    tZONE,     HOUR( 3) },  /* Greenland Standard */
478 #endif
479 #if 0
480     { "nft",    tZONE,     HOUR(3.5) }, /* Newfoundland */
481     { "nst",    tZONE,     HOUR(3.5) }, /* Newfoundland Standard */
482     { "ndt",    tDAYZONE,  HOUR(3.5) }, /* Newfoundland Daylight */
483 #endif
484     { "ast",    tZONE,     HOUR( 4) },  /* Atlantic Standard */
485     { "adt",    tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
486     { "est",    tZONE,     HOUR( 5) },  /* Eastern Standard */
487     { "edt",    tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
488     { "cst",    tZONE,     HOUR( 6) },  /* Central Standard */
489     { "cdt",    tDAYZONE,  HOUR( 6) },  /* Central Daylight */
490     { "mst",    tZONE,     HOUR( 7) },  /* Mountain Standard */
491     { "mdt",    tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
492     { "pst",    tZONE,     HOUR( 8) },  /* Pacific Standard */
493     { "pdt",    tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
494     { "yst",    tZONE,     HOUR( 9) },  /* Yukon Standard */
495     { "ydt",    tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
496     { "hst",    tZONE,     HOUR(10) },  /* Hawaii Standard */
497     { "hdt",    tDAYZONE,  HOUR(10) },  /* Hawaii Daylight */
498     { "cat",    tZONE,     HOUR(10) },  /* Central Alaska */
499     { "ahst",   tZONE,     HOUR(10) },  /* Alaska-Hawaii Standard */
500     { "nt",     tZONE,     HOUR(11) },  /* Nome */
501     { "idlw",   tZONE,     HOUR(12) },  /* International Date Line West */
502     { "cet",    tZONE,     -HOUR(1) },  /* Central European */
503     { "met",    tZONE,     -HOUR(1) },  /* Middle European */
504     { "mewt",   tZONE,     -HOUR(1) },  /* Middle European Winter */
505     { "mest",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
506     { "swt",    tZONE,     -HOUR(1) },  /* Swedish Winter */
507     { "sst",    tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
508     { "fwt",    tZONE,     -HOUR(1) },  /* French Winter */
509     { "fst",    tDAYZONE,  -HOUR(1) },  /* French Summer */
510     { "eet",    tZONE,     -HOUR(2) },  /* Eastern Europe, USSR Zone 1 */
511     { "bt",     tZONE,     -HOUR(3) },  /* Baghdad, USSR Zone 2 */
512 #if 0
513     { "it",     tZONE,     -HOUR(3.5) },/* Iran */
514 #endif
515     { "zp4",    tZONE,     -HOUR(4) },  /* USSR Zone 3 */
516     { "zp5",    tZONE,     -HOUR(5) },  /* USSR Zone 4 */
517 #if 0
518     { "ist",    tZONE,     -HOUR(5.5) },/* Indian Standard */
519 #endif
520     { "zp6",    tZONE,     -HOUR(6) },  /* USSR Zone 5 */
521 #if     0
522     /* For completeness.  NST is also Newfoundland Stanard, and SST is
523      * also Swedish Summer. */
524     { "nst",    tZONE,     -HOUR(6.5) },/* North Sumatra */
525     { "sst",    tZONE,     -HOUR(7) },  /* South Sumatra, USSR Zone 6 */
526 #endif  /* 0 */
527     { "wast",   tZONE,     -HOUR(7) },  /* West Australian Standard */
528     { "wadt",   tDAYZONE,  -HOUR(7) },  /* West Australian Daylight */
529 #if 0
530     { "jt",     tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
531 #endif
532     { "cct",    tZONE,     -HOUR(8) },  /* China Coast, USSR Zone 7 */
533     { "jst",    tZONE,     -HOUR(9) },  /* Japan Standard, USSR Zone 8 */
534 #if 0
535     { "cast",   tZONE,     -HOUR(9.5) },/* Central Australian Standard */
536     { "cadt",   tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
537 #endif
538     { "east",   tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
539     { "eadt",   tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
540     { "gst",    tZONE,     -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
541     { "nzt",    tZONE,     -HOUR(12) }, /* New Zealand */
542     { "nzst",   tZONE,     -HOUR(12) }, /* New Zealand Standard */
543     { "nzdt",   tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
544     { "idle",   tZONE,     -HOUR(12) }, /* International Date Line East */
545     {  NULL  }
546 };
547
548 /* Military timezone table. */
549 static TABLE const MilitaryTable[] = {
550     { "a",      tZONE,  HOUR(  1) },
551     { "b",      tZONE,  HOUR(  2) },
552     { "c",      tZONE,  HOUR(  3) },
553     { "d",      tZONE,  HOUR(  4) },
554     { "e",      tZONE,  HOUR(  5) },
555     { "f",      tZONE,  HOUR(  6) },
556     { "g",      tZONE,  HOUR(  7) },
557     { "h",      tZONE,  HOUR(  8) },
558     { "i",      tZONE,  HOUR(  9) },
559     { "k",      tZONE,  HOUR( 10) },
560     { "l",      tZONE,  HOUR( 11) },
561     { "m",      tZONE,  HOUR( 12) },
562     { "n",      tZONE,  HOUR(- 1) },
563     { "o",      tZONE,  HOUR(- 2) },
564     { "p",      tZONE,  HOUR(- 3) },
565     { "q",      tZONE,  HOUR(- 4) },
566     { "r",      tZONE,  HOUR(- 5) },
567     { "s",      tZONE,  HOUR(- 6) },
568     { "t",      tZONE,  HOUR(- 7) },
569     { "u",      tZONE,  HOUR(- 8) },
570     { "v",      tZONE,  HOUR(- 9) },
571     { "w",      tZONE,  HOUR(-10) },
572     { "x",      tZONE,  HOUR(-11) },
573     { "y",      tZONE,  HOUR(-12) },
574     { "z",      tZONE,  HOUR(  0) },
575     { NULL }
576 };
577
578 \f
579
580
581 /* ARGSUSED */
582 static int
583 yyerror(s)
584     char        *s;
585 {
586   return 0;
587 }
588
589
590 static time_t
591 ToSeconds(Hours, Minutes, Seconds, Meridian)
592     time_t      Hours;
593     time_t      Minutes;
594     time_t      Seconds;
595     MERIDIAN    Meridian;
596 {
597     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
598         return -1;
599     switch (Meridian) {
600     case MER24:
601         if (Hours < 0 || Hours > 23)
602             return -1;
603         return (Hours * 60L + Minutes) * 60L + Seconds;
604     case MERam:
605         if (Hours < 1 || Hours > 12)
606             return -1;
607         if (Hours == 12)
608             Hours = 0;
609         return (Hours * 60L + Minutes) * 60L + Seconds;
610     case MERpm:
611         if (Hours < 1 || Hours > 12)
612             return -1;
613         if (Hours == 12)
614             Hours = 0;
615         return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
616     default:
617         abort ();
618     }
619     /* NOTREACHED */
620 }
621
622
623 /* Year is either
624    * A negative number, which means to use its absolute value (why?)
625    * A number from 0 to 99, which means a year from 1900 to 1999, or
626    * The actual year (>=100).  */
627 static time_t
628 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
629     time_t      Month;
630     time_t      Day;
631     time_t      Year;
632     time_t      Hours;
633     time_t      Minutes;
634     time_t      Seconds;
635     MERIDIAN    Meridian;
636     DSTMODE     DSTmode;
637 {
638     static int DaysInMonth[12] = {
639         31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
640     };
641     time_t      tod;
642     time_t      Julian;
643     int         i;
644
645     if (Year < 0)
646         Year = -Year;
647     if (Year < 69)
648         Year += 2000;
649     else if (Year < 100) {
650         Year += 1900;
651         if (Year < EPOCH)
652                 Year += 100;
653     }
654     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
655                     ? 29 : 28;
656     /* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
657        I'm too lazy to try to check for time_t overflow in another way.  */
658     if (Year < EPOCH || Year > 2038
659      || Month < 1 || Month > 12
660      /* Lint fluff:  "conversion from long may lose accuracy" */
661      || Day < 1 || Day > DaysInMonth[(int)--Month])
662         return -1;
663
664     for (Julian = Day - 1, i = 0; i < Month; i++)
665         Julian += DaysInMonth[i];
666     for (i = EPOCH; i < Year; i++)
667         Julian += 365 + (i % 4 == 0);
668     Julian *= SECSPERDAY;
669     Julian += yyTimezone * 60L;
670     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
671         return -1;
672     Julian += tod;
673     if (DSTmode == DSTon
674      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
675         Julian -= 60 * 60;
676     return Julian;
677 }
678
679
680 static time_t
681 DSTcorrect(Start, Future)
682     time_t      Start;
683     time_t      Future;
684 {
685     time_t      StartDay;
686     time_t      FutureDay;
687
688     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
689     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
690     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
691 }
692
693
694 static time_t
695 RelativeDate(Start, DayOrdinal, DayNumber)
696     time_t      Start;
697     time_t      DayOrdinal;
698     time_t      DayNumber;
699 {
700     struct tm   *tm;
701     time_t      now;
702
703     now = Start;
704     tm = localtime(&now);
705     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
706     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
707     return DSTcorrect(Start, now);
708 }
709
710
711 static time_t
712 RelativeMonth(Start, RelMonth)
713     time_t      Start;
714     time_t      RelMonth;
715 {
716     struct tm   *tm;
717     time_t      Month;
718     time_t      Year;
719
720     if (RelMonth == 0)
721         return 0;
722     tm = localtime(&Start);
723     Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
724     Year = Month / 12;
725     Month = Month % 12 + 1;
726     return DSTcorrect(Start,
727             Convert(Month, (time_t)tm->tm_mday, Year,
728                 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
729                 MER24, DSTmaybe));
730 }
731
732
733 static int
734 LookupWord(buff)
735     char                *buff;
736 {
737     char                *p;
738     char                *q;
739     const TABLE         *tp;
740     int                 i;
741     int                 abbrev;
742
743     /* Make it lowercase. */
744     for (p = buff; *p; p++)
745         if (isupper((unsigned char)*p))
746             *p = tolower((unsigned char)*p);
747
748     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
749         yylval.Meridian = MERam;
750         return tMERIDIAN;
751     }
752     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
753         yylval.Meridian = MERpm;
754         return tMERIDIAN;
755     }
756
757     /* See if we have an abbreviation for a month. */
758     if (strlen(buff) == 3)
759         abbrev = 1;
760     else if (strlen(buff) == 4 && buff[3] == '.') {
761         abbrev = 1;
762         buff[3] = '\0';
763     }
764     else
765         abbrev = 0;
766
767     for (tp = MonthDayTable; tp->name; tp++) {
768         if (abbrev) {
769             if (strncmp(buff, tp->name, 3) == 0) {
770                 yylval.Number = tp->value;
771                 return tp->type;
772             }
773         }
774         else if (strcmp(buff, tp->name) == 0) {
775             yylval.Number = tp->value;
776             return tp->type;
777         }
778     }
779
780     for (tp = TimezoneTable; tp->name; tp++)
781         if (strcmp(buff, tp->name) == 0) {
782             yylval.Number = tp->value;
783             return tp->type;
784         }
785
786     if (strcmp(buff, "dst") == 0) 
787         return tDST;
788
789     for (tp = UnitsTable; tp->name; tp++)
790         if (strcmp(buff, tp->name) == 0) {
791             yylval.Number = tp->value;
792             return tp->type;
793         }
794
795     /* Strip off any plural and try the units table again. */
796     i = strlen(buff) - 1;
797     if (buff[i] == 's') {
798         buff[i] = '\0';
799         for (tp = UnitsTable; tp->name; tp++)
800             if (strcmp(buff, tp->name) == 0) {
801                 yylval.Number = tp->value;
802                 return tp->type;
803             }
804         buff[i] = 's';          /* Put back for "this" in OtherTable. */
805     }
806
807     for (tp = OtherTable; tp->name; tp++)
808         if (strcmp(buff, tp->name) == 0) {
809             yylval.Number = tp->value;
810             return tp->type;
811         }
812
813     /* Military timezones. */
814     if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
815         for (tp = MilitaryTable; tp->name; tp++)
816             if (strcmp(buff, tp->name) == 0) {
817                 yylval.Number = tp->value;
818                 return tp->type;
819             }
820     }
821
822     /* Drop out any periods and try the timezone table again. */
823     for (i = 0, p = q = buff; *q; q++)
824         if (*q != '.')
825             *p++ = *q;
826         else
827             i++;
828     *p = '\0';
829     if (i)
830         for (tp = TimezoneTable; tp->name; tp++)
831             if (strcmp(buff, tp->name) == 0) {
832                 yylval.Number = tp->value;
833                 return tp->type;
834             }
835
836     return tID;
837 }
838
839
840 static int
841 yylex()
842 {
843     char                c;
844     char                *p;
845     char                buff[20];
846     int                 Count;
847     int                 sign;
848
849     for ( ; ; ) {
850         while (isspace((unsigned char)*yyInput))
851             yyInput++;
852
853         if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
854             if (c == '-' || c == '+') {
855                 sign = c == '-' ? -1 : 1;
856                 if (!isdigit((unsigned char)*++yyInput))
857                     /* skip the '-' sign */
858                     continue;
859             }
860             else
861                 sign = 0;
862             for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
863                 yylval.Number = 10 * yylval.Number + c - '0';
864             yyInput--;
865             if (sign < 0)
866                 yylval.Number = -yylval.Number;
867             return sign ? tSNUMBER : tUNUMBER;
868         }
869         if (isalpha((unsigned char)c)) {
870             for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
871                 if (p < &buff[sizeof buff - 1])
872                     *p++ = c;
873             *p = '\0';
874             yyInput--;
875             return LookupWord(buff);
876         }
877         if (c != '(')
878             return *yyInput++;
879         Count = 0;
880         do {
881             c = *yyInput++;
882             if (c == '\0')
883                 return c;
884             if (c == '(')
885                 Count++;
886             else if (c == ')')
887                 Count--;
888         } while (Count > 0);
889     }
890 }
891
892 #define TM_YEAR_ORIGIN 1900
893
894 /* Yield A - B, measured in seconds.  */
895 static long
896 difftm (a, b)
897      struct tm *a, *b;
898 {
899   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
900   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
901   int days = (
902               /* difference in day of year */
903               a->tm_yday - b->tm_yday
904               /* + intervening leap days */
905               +  ((ay >> 2) - (by >> 2))
906               -  (ay/100 - by/100)
907               +  ((ay/100 >> 2) - (by/100 >> 2))
908               /* + difference in years * 365 */
909               +  (long)(ay-by) * 365
910               );
911   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
912               + (a->tm_min - b->tm_min))
913           + (a->tm_sec - b->tm_sec));
914 }
915
916 time_t
917 get_date(p)
918     char                *p;
919 {
920     struct tm           *tm, *gmt, gmtbuf;
921     time_t              Start;
922     time_t              tod;
923     time_t              now;
924     time_t              timezone;
925
926     yyInput = p;
927     (void)time (&now);
928
929     gmt = gmtime (&now);
930     if (gmt != NULL)
931     {
932         /* Make a copy, in case localtime modifies *tm (I think
933            that comment now applies to *gmt, but I am too
934            lazy to dig into how gmtime and locatime allocate the
935            structures they return pointers to).  */
936         gmtbuf = *gmt;
937         gmt = &gmtbuf;
938     }
939
940     if (! (tm = localtime (&now)))
941         return -1;
942
943     if (gmt != NULL)
944         timezone = difftm (gmt, tm) / 60;
945     else
946         /* We are on a system like VMS, where the system clock is
947            in local time and the system has no concept of timezones.
948            Hopefully we can fake this out (for the case in which the
949            user specifies no timezone) by just saying the timezone
950            is zero.  */
951         timezone = 0;
952
953     if(tm->tm_isdst)
954         timezone += 60;
955
956     tm = localtime(&now);
957     yyYear = tm->tm_year + 1900;
958     yyMonth = tm->tm_mon + 1;
959     yyDay = tm->tm_mday;
960     yyTimezone = timezone;
961     yyDSTmode = DSTmaybe;
962     yyHour = 0;
963     yyMinutes = 0;
964     yySeconds = 0;
965     yyMeridian = MER24;
966     yyRelSeconds = 0;
967     yyRelMonth = 0;
968     yyHaveDate = 0;
969     yyHaveDay = 0;
970     yyHaveRel = 0;
971     yyHaveTime = 0;
972     yyHaveZone = 0;
973
974     if (yyparse()
975      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
976         return -1;
977
978     if (yyHaveDate || yyHaveTime || yyHaveDay) {
979         Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
980                     yyMeridian, yyDSTmode);
981         if (Start < 0)
982             return -1;
983     }
984     else {
985         Start = now;
986         if (!yyHaveRel)
987             Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
988     }
989
990     Start += yyRelSeconds;
991     Start += RelativeMonth(Start, yyRelMonth);
992
993     if (yyHaveDay && !yyHaveDate) {
994         tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
995         Start += tod;
996     }
997
998     /* Have to do *something* with a legitimate -1 so it's distinguishable
999      * from the error return value.  (Alternately could set errno on error.) */
1000     return Start == -1 ? 0 : Start;
1001 }
1002
1003
1004 #if     defined(TEST)
1005
1006 /* ARGSUSED */
1007 int
1008 main(ac, av)
1009     int         ac;
1010     char        *av[];
1011 {
1012     char        buff[128];
1013     time_t      d;
1014
1015     (void)printf("Enter date, or blank line to exit.\n\t> ");
1016     (void)fflush(stdout);
1017     while (gets(buff) && buff[0]) {
1018         d = get_date(buff);
1019         if (d == -1)
1020             (void)printf("Bad format - couldn't convert.\n");
1021         else
1022             (void)printf("%s", ctime(&d));
1023         (void)printf("\t> ");
1024         (void)fflush(stdout);
1025     }
1026     exit(0);
1027     /* NOTREACHED */
1028 }
1029 #endif  /* defined(TEST) */
1030 #line 979 "y.tab.c"
1031 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
1032 #if defined(__cplusplus) || defined(__STDC__)
1033 static int yygrowstack(void)
1034 #else
1035 static int yygrowstack()
1036 #endif
1037 {
1038     int newsize, i;
1039     short *newss;
1040     YYSTYPE *newvs;
1041
1042     if ((newsize = yystacksize) == 0)
1043         newsize = YYINITSTACKSIZE;
1044     else if (newsize >= YYMAXDEPTH)
1045         return -1;
1046     else if ((newsize *= 2) > YYMAXDEPTH)
1047         newsize = YYMAXDEPTH;
1048     i = yyssp - yyss;
1049 #ifdef SIZE_MAX
1050 #define YY_SIZE_MAX SIZE_MAX
1051 #else
1052 #define YY_SIZE_MAX 0x7fffffff
1053 #endif
1054     if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
1055         goto bail;
1056     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1057       (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1058     if (newss == NULL)
1059         goto bail;
1060     yyss = newss;
1061     yyssp = newss + i;
1062     if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
1063         goto bail;
1064     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1065       (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1066     if (newvs == NULL)
1067         goto bail;
1068     yyvs = newvs;
1069     yyvsp = newvs + i;
1070     yystacksize = newsize;
1071     yysslim = yyss + newsize - 1;
1072     return 0;
1073 bail:
1074     if (yyss)
1075             free(yyss);
1076     if (yyvs)
1077             free(yyvs);
1078     yyss = yyssp = NULL;
1079     yyvs = yyvsp = NULL;
1080     yystacksize = 0;
1081     return -1;
1082 }
1083
1084 #define YYABORT goto yyabort
1085 #define YYREJECT goto yyabort
1086 #define YYACCEPT goto yyaccept
1087 #define YYERROR goto yyerrlab
1088 int
1089 #if defined(__cplusplus) || defined(__STDC__)
1090 yyparse(void)
1091 #else
1092 yyparse()
1093 #endif
1094 {
1095     int yym, yyn, yystate;
1096 #if YYDEBUG
1097 #if defined(__cplusplus) || defined(__STDC__)
1098     const char *yys;
1099 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1100     char *yys;
1101 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1102
1103     if ((yys = getenv("YYDEBUG")))
1104     {
1105         yyn = *yys;
1106         if (yyn >= '0' && yyn <= '9')
1107             yydebug = yyn - '0';
1108     }
1109 #endif /* YYDEBUG */
1110
1111     yynerrs = 0;
1112     yyerrflag = 0;
1113     yychar = (-1);
1114
1115     if (yyss == NULL && yygrowstack()) goto yyoverflow;
1116     yyssp = yyss;
1117     yyvsp = yyvs;
1118     *yyssp = yystate = 0;
1119
1120 yyloop:
1121     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1122     if (yychar < 0)
1123     {
1124         if ((yychar = yylex()) < 0) yychar = 0;
1125 #if YYDEBUG
1126         if (yydebug)
1127         {
1128             yys = 0;
1129             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1130             if (!yys) yys = "illegal-symbol";
1131             printf("%sdebug: state %d, reading %d (%s)\n",
1132                     YYPREFIX, yystate, yychar, yys);
1133         }
1134 #endif
1135     }
1136     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1137             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1138     {
1139 #if YYDEBUG
1140         if (yydebug)
1141             printf("%sdebug: state %d, shifting to state %d\n",
1142                     YYPREFIX, yystate, yytable[yyn]);
1143 #endif
1144         if (yyssp >= yysslim && yygrowstack())
1145         {
1146             goto yyoverflow;
1147         }
1148         *++yyssp = yystate = yytable[yyn];
1149         *++yyvsp = yylval;
1150         yychar = (-1);
1151         if (yyerrflag > 0)  --yyerrflag;
1152         goto yyloop;
1153     }
1154     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1155             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1156     {
1157         yyn = yytable[yyn];
1158         goto yyreduce;
1159     }
1160     if (yyerrflag) goto yyinrecovery;
1161 #if defined(lint) || defined(__GNUC__)
1162     goto yynewerror;
1163 #endif
1164 yynewerror:
1165     yyerror("syntax error");
1166 #if defined(lint) || defined(__GNUC__)
1167     goto yyerrlab;
1168 #endif
1169 yyerrlab:
1170     ++yynerrs;
1171 yyinrecovery:
1172     if (yyerrflag < 3)
1173     {
1174         yyerrflag = 3;
1175         for (;;)
1176         {
1177             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1178                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1179             {
1180 #if YYDEBUG
1181                 if (yydebug)
1182                     printf("%sdebug: state %d, error recovery shifting\
1183  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1184 #endif
1185                 if (yyssp >= yysslim && yygrowstack())
1186                 {
1187                     goto yyoverflow;
1188                 }
1189                 *++yyssp = yystate = yytable[yyn];
1190                 *++yyvsp = yylval;
1191                 goto yyloop;
1192             }
1193             else
1194             {
1195 #if YYDEBUG
1196                 if (yydebug)
1197                     printf("%sdebug: error recovery discarding state %d\n",
1198                             YYPREFIX, *yyssp);
1199 #endif
1200                 if (yyssp <= yyss) goto yyabort;
1201                 --yyssp;
1202                 --yyvsp;
1203             }
1204         }
1205     }
1206     else
1207     {
1208         if (yychar == 0) goto yyabort;
1209 #if YYDEBUG
1210         if (yydebug)
1211         {
1212             yys = 0;
1213             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1214             if (!yys) yys = "illegal-symbol";
1215             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1216                     YYPREFIX, yystate, yychar, yys);
1217         }
1218 #endif
1219         yychar = (-1);
1220         goto yyloop;
1221     }
1222 yyreduce:
1223 #if YYDEBUG
1224     if (yydebug)
1225         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1226                 YYPREFIX, yystate, yyn, yyrule[yyn]);
1227 #endif
1228     yym = yylen[yyn];
1229     if (yym)
1230         yyval = yyvsp[1-yym];
1231     else
1232         memset(&yyval, 0, sizeof yyval);
1233     switch (yyn)
1234     {
1235 case 3:
1236 #line 125 "getdate.y"
1237 {
1238             yyHaveTime++;
1239         }
1240 break;
1241 case 4:
1242 #line 128 "getdate.y"
1243 {
1244             yyHaveZone++;
1245         }
1246 break;
1247 case 5:
1248 #line 131 "getdate.y"
1249 {
1250             yyHaveDate++;
1251         }
1252 break;
1253 case 6:
1254 #line 134 "getdate.y"
1255 {
1256             yyHaveDay++;
1257         }
1258 break;
1259 case 7:
1260 #line 137 "getdate.y"
1261 {
1262             yyHaveRel++;
1263         }
1264 break;
1265 case 9:
1266 #line 143 "getdate.y"
1267 {
1268             yyHour = yyvsp[-1].Number;
1269             yyMinutes = 0;
1270             yySeconds = 0;
1271             yyMeridian = yyvsp[0].Meridian;
1272         }
1273 break;
1274 case 10:
1275 #line 149 "getdate.y"
1276 {
1277             yyHour = yyvsp[-3].Number;
1278             yyMinutes = yyvsp[-1].Number;
1279             yySeconds = 0;
1280             yyMeridian = yyvsp[0].Meridian;
1281         }
1282 break;
1283 case 11:
1284 #line 155 "getdate.y"
1285 {
1286             yyHour = yyvsp[-3].Number;
1287             yyMinutes = yyvsp[-1].Number;
1288             yyMeridian = MER24;
1289             yyDSTmode = DSToff;
1290             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1291         }
1292 break;
1293 case 12:
1294 #line 162 "getdate.y"
1295 {
1296             yyHour = yyvsp[-5].Number;
1297             yyMinutes = yyvsp[-3].Number;
1298             yySeconds = yyvsp[-1].Number;
1299             yyMeridian = yyvsp[0].Meridian;
1300         }
1301 break;
1302 case 13:
1303 #line 168 "getdate.y"
1304 {
1305             yyHour = yyvsp[-5].Number;
1306             yyMinutes = yyvsp[-3].Number;
1307             yySeconds = yyvsp[-1].Number;
1308             yyMeridian = MER24;
1309             yyDSTmode = DSToff;
1310             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1311         }
1312 break;
1313 case 14:
1314 #line 178 "getdate.y"
1315 {
1316             yyTimezone = yyvsp[0].Number;
1317             yyDSTmode = DSToff;
1318         }
1319 break;
1320 case 15:
1321 #line 182 "getdate.y"
1322 {
1323             yyTimezone = yyvsp[0].Number;
1324             yyDSTmode = DSTon;
1325         }
1326 break;
1327 case 16:
1328 #line 187 "getdate.y"
1329 {
1330             yyTimezone = yyvsp[-1].Number;
1331             yyDSTmode = DSTon;
1332         }
1333 break;
1334 case 17:
1335 #line 193 "getdate.y"
1336 {
1337             yyDayOrdinal = 1;
1338             yyDayNumber = yyvsp[0].Number;
1339         }
1340 break;
1341 case 18:
1342 #line 197 "getdate.y"
1343 {
1344             yyDayOrdinal = 1;
1345             yyDayNumber = yyvsp[-1].Number;
1346         }
1347 break;
1348 case 19:
1349 #line 201 "getdate.y"
1350 {
1351             yyDayOrdinal = yyvsp[-1].Number;
1352             yyDayNumber = yyvsp[0].Number;
1353         }
1354 break;
1355 case 20:
1356 #line 207 "getdate.y"
1357 {
1358             yyMonth = yyvsp[-2].Number;
1359             yyDay = yyvsp[0].Number;
1360         }
1361 break;
1362 case 21:
1363 #line 211 "getdate.y"
1364 {
1365             if (yyvsp[-4].Number >= 100) {
1366                 yyYear = yyvsp[-4].Number;
1367                 yyMonth = yyvsp[-2].Number;
1368                 yyDay = yyvsp[0].Number;
1369             } else {
1370                 yyMonth = yyvsp[-4].Number;
1371                 yyDay = yyvsp[-2].Number;
1372                 yyYear = yyvsp[0].Number;
1373             }
1374         }
1375 break;
1376 case 22:
1377 #line 222 "getdate.y"
1378 {
1379             /* ISO 8601 format.  yyyy-mm-dd.  */
1380             yyYear = yyvsp[-2].Number;
1381             yyMonth = -yyvsp[-1].Number;
1382             yyDay = -yyvsp[0].Number;
1383         }
1384 break;
1385 case 23:
1386 #line 228 "getdate.y"
1387 {
1388             /* e.g. 17-JUN-1992.  */
1389             yyDay = yyvsp[-2].Number;
1390             yyMonth = yyvsp[-1].Number;
1391             yyYear = -yyvsp[0].Number;
1392         }
1393 break;
1394 case 24:
1395 #line 234 "getdate.y"
1396 {
1397             yyMonth = yyvsp[-1].Number;
1398             yyDay = yyvsp[0].Number;
1399         }
1400 break;
1401 case 25:
1402 #line 238 "getdate.y"
1403 {
1404             yyMonth = yyvsp[-3].Number;
1405             yyDay = yyvsp[-2].Number;
1406             yyYear = yyvsp[0].Number;
1407         }
1408 break;
1409 case 26:
1410 #line 243 "getdate.y"
1411 {
1412             yyMonth = yyvsp[0].Number;
1413             yyDay = yyvsp[-1].Number;
1414         }
1415 break;
1416 case 27:
1417 #line 247 "getdate.y"
1418 {
1419             yyMonth = yyvsp[-1].Number;
1420             yyDay = yyvsp[-2].Number;
1421             yyYear = yyvsp[0].Number;
1422         }
1423 break;
1424 case 28:
1425 #line 254 "getdate.y"
1426 {
1427             yyRelSeconds = -yyRelSeconds;
1428             yyRelMonth = -yyRelMonth;
1429         }
1430 break;
1431 case 30:
1432 #line 261 "getdate.y"
1433 {
1434             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1435         }
1436 break;
1437 case 31:
1438 #line 264 "getdate.y"
1439 {
1440             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1441         }
1442 break;
1443 case 32:
1444 #line 267 "getdate.y"
1445 {
1446             yyRelSeconds += yyvsp[0].Number * 60L;
1447         }
1448 break;
1449 case 33:
1450 #line 270 "getdate.y"
1451 {
1452             yyRelSeconds += yyvsp[-1].Number;
1453         }
1454 break;
1455 case 34:
1456 #line 273 "getdate.y"
1457 {
1458             yyRelSeconds += yyvsp[-1].Number;
1459         }
1460 break;
1461 case 35:
1462 #line 276 "getdate.y"
1463 {
1464             yyRelSeconds++;
1465         }
1466 break;
1467 case 36:
1468 #line 279 "getdate.y"
1469 {
1470             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1471         }
1472 break;
1473 case 37:
1474 #line 282 "getdate.y"
1475 {
1476             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1477         }
1478 break;
1479 case 38:
1480 #line 285 "getdate.y"
1481 {
1482             yyRelMonth += yyvsp[0].Number;
1483         }
1484 break;
1485 case 39:
1486 #line 290 "getdate.y"
1487 {
1488             if (yyHaveTime && yyHaveDate && !yyHaveRel)
1489                 yyYear = yyvsp[0].Number;
1490             else {
1491                 if(yyvsp[0].Number>10000) {
1492                     yyHaveDate++;
1493                     yyDay= (yyvsp[0].Number)%100;
1494                     yyMonth= (yyvsp[0].Number/100)%100;
1495                     yyYear = yyvsp[0].Number/10000;
1496                 }
1497                 else {
1498                     yyHaveTime++;
1499                     if (yyvsp[0].Number < 100) {
1500                         yyHour = yyvsp[0].Number;
1501                         yyMinutes = 0;
1502                     }
1503                     else {
1504                         yyHour = yyvsp[0].Number / 100;
1505                         yyMinutes = yyvsp[0].Number % 100;
1506                     }
1507                     yySeconds = 0;
1508                     yyMeridian = MER24;
1509                 }
1510             }
1511         }
1512 break;
1513 case 40:
1514 #line 317 "getdate.y"
1515 {
1516             yyval.Meridian = MER24;
1517         }
1518 break;
1519 case 41:
1520 #line 320 "getdate.y"
1521 {
1522             yyval.Meridian = yyvsp[0].Meridian;
1523         }
1524 break;
1525 #line 1474 "y.tab.c"
1526     }
1527     yyssp -= yym;
1528     yystate = *yyssp;
1529     yyvsp -= yym;
1530     yym = yylhs[yyn];
1531     if (yystate == 0 && yym == 0)
1532     {
1533 #if YYDEBUG
1534         if (yydebug)
1535             printf("%sdebug: after reduction, shifting from state 0 to\
1536  state %d\n", YYPREFIX, YYFINAL);
1537 #endif
1538         yystate = YYFINAL;
1539         *++yyssp = YYFINAL;
1540         *++yyvsp = yyval;
1541         if (yychar < 0)
1542         {
1543             if ((yychar = yylex()) < 0) yychar = 0;
1544 #if YYDEBUG
1545             if (yydebug)
1546             {
1547                 yys = 0;
1548                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1549                 if (!yys) yys = "illegal-symbol";
1550                 printf("%sdebug: state %d, reading %d (%s)\n",
1551                         YYPREFIX, YYFINAL, yychar, yys);
1552             }
1553 #endif
1554         }
1555         if (yychar == 0) goto yyaccept;
1556         goto yyloop;
1557     }
1558     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1559             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1560         yystate = yytable[yyn];
1561     else
1562         yystate = yydgoto[yym];
1563 #if YYDEBUG
1564     if (yydebug)
1565         printf("%sdebug: after reduction, shifting from state %d \
1566 to state %d\n", YYPREFIX, *yyssp, yystate);
1567 #endif
1568     if (yyssp >= yysslim && yygrowstack())
1569     {
1570         goto yyoverflow;
1571     }
1572     *++yyssp = yystate;
1573     *++yyvsp = yyval;
1574     goto yyloop;
1575 yyoverflow:
1576     yyerror("yacc stack overflow");
1577 yyabort:
1578     if (yyss)
1579             free(yyss);
1580     if (yyvs)
1581             free(yyvs);
1582     yyss = yyssp = NULL;
1583     yyvs = yyvsp = NULL;
1584     yystacksize = 0;
1585     return (1);
1586 yyaccept:
1587     if (yyss)
1588             free(yyss);
1589     if (yyvs)
1590             free(yyvs);
1591     yyss = yyssp = NULL;
1592     yyvs = yyvsp = NULL;
1593     yystacksize = 0;
1594     return (0);
1595 }