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