Imported Upstream version 1.8.7
[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     /* 32-bit time_t cannot represent years past 2038 */
658     if (Year < EPOCH || (sizeof(time_t) == sizeof(int) && 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 978 "getdate.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     newsize = yystacksize ? yystacksize : YYINITSTACKSIZE;
1043     if (newsize >= YYMAXDEPTH)
1044         return -1;
1045     else if ((newsize *= 2) > YYMAXDEPTH)
1046         newsize = YYMAXDEPTH;
1047 #ifdef SIZE_MAX
1048 #define YY_SIZE_MAX SIZE_MAX
1049 #else
1050 #define YY_SIZE_MAX 0x7fffffff
1051 #endif
1052     if (YY_SIZE_MAX / newsize < sizeof *newss)
1053         goto bail;
1054     i = yyssp - yyss;
1055     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
1056       (short *)malloc(newsize * sizeof *newss); /* overflow check above */
1057     if (newss == NULL)
1058         goto bail;
1059     yyss = newss;
1060     yyssp = newss + i;
1061     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
1062       (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
1063     if (newvs == NULL)
1064         goto bail;
1065     yyvs = newvs;
1066     yyvsp = newvs + i;
1067     yystacksize = newsize;
1068     yysslim = yyss + newsize - 1;
1069     return 0;
1070 bail:
1071     if (yyss)
1072             free(yyss);
1073     if (yyvs)
1074             free(yyvs);
1075     yyss = yyssp = NULL;
1076     yyvs = yyvsp = NULL;
1077     yystacksize = 0;
1078     return -1;
1079 }
1080
1081 #define YYABORT goto yyabort
1082 #define YYREJECT goto yyabort
1083 #define YYACCEPT goto yyaccept
1084 #define YYERROR goto yyerrlab
1085 int
1086 #if defined(__cplusplus) || defined(__STDC__)
1087 yyparse(void)
1088 #else
1089 yyparse()
1090 #endif
1091 {
1092     int yym, yyn, yystate;
1093 #if YYDEBUG
1094 #if defined(__cplusplus) || defined(__STDC__)
1095     const char *yys;
1096 #else /* !(defined(__cplusplus) || defined(__STDC__)) */
1097     char *yys;
1098 #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
1099
1100     if ((yys = getenv("YYDEBUG")))
1101     {
1102         yyn = *yys;
1103         if (yyn >= '0' && yyn <= '9')
1104             yydebug = yyn - '0';
1105     }
1106 #endif /* YYDEBUG */
1107
1108     yynerrs = 0;
1109     yyerrflag = 0;
1110     yychar = (-1);
1111
1112     if (yyss == NULL && yygrowstack()) goto yyoverflow;
1113     yyssp = yyss;
1114     yyvsp = yyvs;
1115     *yyssp = yystate = 0;
1116
1117 yyloop:
1118     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1119     if (yychar < 0)
1120     {
1121         if ((yychar = yylex()) < 0) yychar = 0;
1122 #if YYDEBUG
1123         if (yydebug)
1124         {
1125             yys = 0;
1126             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1127             if (!yys) yys = "illegal-symbol";
1128             printf("%sdebug: state %d, reading %d (%s)\n",
1129                     YYPREFIX, yystate, yychar, yys);
1130         }
1131 #endif
1132     }
1133     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
1134             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1135     {
1136 #if YYDEBUG
1137         if (yydebug)
1138             printf("%sdebug: state %d, shifting to state %d\n",
1139                     YYPREFIX, yystate, yytable[yyn]);
1140 #endif
1141         if (yyssp >= yysslim && yygrowstack())
1142         {
1143             goto yyoverflow;
1144         }
1145         *++yyssp = yystate = yytable[yyn];
1146         *++yyvsp = yylval;
1147         yychar = (-1);
1148         if (yyerrflag > 0)  --yyerrflag;
1149         goto yyloop;
1150     }
1151     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1152             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
1153     {
1154         yyn = yytable[yyn];
1155         goto yyreduce;
1156     }
1157     if (yyerrflag) goto yyinrecovery;
1158 #if defined(lint) || defined(__GNUC__)
1159     goto yynewerror;
1160 #endif
1161 yynewerror:
1162     yyerror("syntax error");
1163 #if defined(lint) || defined(__GNUC__)
1164     goto yyerrlab;
1165 #endif
1166 yyerrlab:
1167     ++yynerrs;
1168 yyinrecovery:
1169     if (yyerrflag < 3)
1170     {
1171         yyerrflag = 3;
1172         for (;;)
1173         {
1174             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
1175                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
1176             {
1177 #if YYDEBUG
1178                 if (yydebug)
1179                     printf("%sdebug: state %d, error recovery shifting\
1180  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
1181 #endif
1182                 if (yyssp >= yysslim && yygrowstack())
1183                 {
1184                     goto yyoverflow;
1185                 }
1186                 *++yyssp = yystate = yytable[yyn];
1187                 *++yyvsp = yylval;
1188                 goto yyloop;
1189             }
1190             else
1191             {
1192 #if YYDEBUG
1193                 if (yydebug)
1194                     printf("%sdebug: error recovery discarding state %d\n",
1195                             YYPREFIX, *yyssp);
1196 #endif
1197                 if (yyssp <= yyss) goto yyabort;
1198                 --yyssp;
1199                 --yyvsp;
1200             }
1201         }
1202     }
1203     else
1204     {
1205         if (yychar == 0) goto yyabort;
1206 #if YYDEBUG
1207         if (yydebug)
1208         {
1209             yys = 0;
1210             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1211             if (!yys) yys = "illegal-symbol";
1212             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1213                     YYPREFIX, yystate, yychar, yys);
1214         }
1215 #endif
1216         yychar = (-1);
1217         goto yyloop;
1218     }
1219 yyreduce:
1220 #if YYDEBUG
1221     if (yydebug)
1222         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1223                 YYPREFIX, yystate, yyn, yyrule[yyn]);
1224 #endif
1225     yym = yylen[yyn];
1226     if (yym)
1227         yyval = yyvsp[1-yym];
1228     else
1229         memset(&yyval, 0, sizeof yyval);
1230     switch (yyn)
1231     {
1232 case 3:
1233 #line 125 "getdate.y"
1234 {
1235             yyHaveTime++;
1236         }
1237 break;
1238 case 4:
1239 #line 128 "getdate.y"
1240 {
1241             yyHaveZone++;
1242         }
1243 break;
1244 case 5:
1245 #line 131 "getdate.y"
1246 {
1247             yyHaveDate++;
1248         }
1249 break;
1250 case 6:
1251 #line 134 "getdate.y"
1252 {
1253             yyHaveDay++;
1254         }
1255 break;
1256 case 7:
1257 #line 137 "getdate.y"
1258 {
1259             yyHaveRel++;
1260         }
1261 break;
1262 case 9:
1263 #line 143 "getdate.y"
1264 {
1265             yyHour = yyvsp[-1].Number;
1266             yyMinutes = 0;
1267             yySeconds = 0;
1268             yyMeridian = yyvsp[0].Meridian;
1269         }
1270 break;
1271 case 10:
1272 #line 149 "getdate.y"
1273 {
1274             yyHour = yyvsp[-3].Number;
1275             yyMinutes = yyvsp[-1].Number;
1276             yySeconds = 0;
1277             yyMeridian = yyvsp[0].Meridian;
1278         }
1279 break;
1280 case 11:
1281 #line 155 "getdate.y"
1282 {
1283             yyHour = yyvsp[-3].Number;
1284             yyMinutes = yyvsp[-1].Number;
1285             yyMeridian = MER24;
1286             yyDSTmode = DSToff;
1287             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1288         }
1289 break;
1290 case 12:
1291 #line 162 "getdate.y"
1292 {
1293             yyHour = yyvsp[-5].Number;
1294             yyMinutes = yyvsp[-3].Number;
1295             yySeconds = yyvsp[-1].Number;
1296             yyMeridian = yyvsp[0].Meridian;
1297         }
1298 break;
1299 case 13:
1300 #line 168 "getdate.y"
1301 {
1302             yyHour = yyvsp[-5].Number;
1303             yyMinutes = yyvsp[-3].Number;
1304             yySeconds = yyvsp[-1].Number;
1305             yyMeridian = MER24;
1306             yyDSTmode = DSToff;
1307             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
1308         }
1309 break;
1310 case 14:
1311 #line 178 "getdate.y"
1312 {
1313             yyTimezone = yyvsp[0].Number;
1314             yyDSTmode = DSToff;
1315         }
1316 break;
1317 case 15:
1318 #line 182 "getdate.y"
1319 {
1320             yyTimezone = yyvsp[0].Number;
1321             yyDSTmode = DSTon;
1322         }
1323 break;
1324 case 16:
1325 #line 187 "getdate.y"
1326 {
1327             yyTimezone = yyvsp[-1].Number;
1328             yyDSTmode = DSTon;
1329         }
1330 break;
1331 case 17:
1332 #line 193 "getdate.y"
1333 {
1334             yyDayOrdinal = 1;
1335             yyDayNumber = yyvsp[0].Number;
1336         }
1337 break;
1338 case 18:
1339 #line 197 "getdate.y"
1340 {
1341             yyDayOrdinal = 1;
1342             yyDayNumber = yyvsp[-1].Number;
1343         }
1344 break;
1345 case 19:
1346 #line 201 "getdate.y"
1347 {
1348             yyDayOrdinal = yyvsp[-1].Number;
1349             yyDayNumber = yyvsp[0].Number;
1350         }
1351 break;
1352 case 20:
1353 #line 207 "getdate.y"
1354 {
1355             yyMonth = yyvsp[-2].Number;
1356             yyDay = yyvsp[0].Number;
1357         }
1358 break;
1359 case 21:
1360 #line 211 "getdate.y"
1361 {
1362             if (yyvsp[-4].Number >= 100) {
1363                 yyYear = yyvsp[-4].Number;
1364                 yyMonth = yyvsp[-2].Number;
1365                 yyDay = yyvsp[0].Number;
1366             } else {
1367                 yyMonth = yyvsp[-4].Number;
1368                 yyDay = yyvsp[-2].Number;
1369                 yyYear = yyvsp[0].Number;
1370             }
1371         }
1372 break;
1373 case 22:
1374 #line 222 "getdate.y"
1375 {
1376             /* ISO 8601 format.  yyyy-mm-dd.  */
1377             yyYear = yyvsp[-2].Number;
1378             yyMonth = -yyvsp[-1].Number;
1379             yyDay = -yyvsp[0].Number;
1380         }
1381 break;
1382 case 23:
1383 #line 228 "getdate.y"
1384 {
1385             /* e.g. 17-JUN-1992.  */
1386             yyDay = yyvsp[-2].Number;
1387             yyMonth = yyvsp[-1].Number;
1388             yyYear = -yyvsp[0].Number;
1389         }
1390 break;
1391 case 24:
1392 #line 234 "getdate.y"
1393 {
1394             yyMonth = yyvsp[-1].Number;
1395             yyDay = yyvsp[0].Number;
1396         }
1397 break;
1398 case 25:
1399 #line 238 "getdate.y"
1400 {
1401             yyMonth = yyvsp[-3].Number;
1402             yyDay = yyvsp[-2].Number;
1403             yyYear = yyvsp[0].Number;
1404         }
1405 break;
1406 case 26:
1407 #line 243 "getdate.y"
1408 {
1409             yyMonth = yyvsp[0].Number;
1410             yyDay = yyvsp[-1].Number;
1411         }
1412 break;
1413 case 27:
1414 #line 247 "getdate.y"
1415 {
1416             yyMonth = yyvsp[-1].Number;
1417             yyDay = yyvsp[-2].Number;
1418             yyYear = yyvsp[0].Number;
1419         }
1420 break;
1421 case 28:
1422 #line 254 "getdate.y"
1423 {
1424             yyRelSeconds = -yyRelSeconds;
1425             yyRelMonth = -yyRelMonth;
1426         }
1427 break;
1428 case 30:
1429 #line 261 "getdate.y"
1430 {
1431             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1432         }
1433 break;
1434 case 31:
1435 #line 264 "getdate.y"
1436 {
1437             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1438         }
1439 break;
1440 case 32:
1441 #line 267 "getdate.y"
1442 {
1443             yyRelSeconds += yyvsp[0].Number * 60L;
1444         }
1445 break;
1446 case 33:
1447 #line 270 "getdate.y"
1448 {
1449             yyRelSeconds += yyvsp[-1].Number;
1450         }
1451 break;
1452 case 34:
1453 #line 273 "getdate.y"
1454 {
1455             yyRelSeconds += yyvsp[-1].Number;
1456         }
1457 break;
1458 case 35:
1459 #line 276 "getdate.y"
1460 {
1461             yyRelSeconds++;
1462         }
1463 break;
1464 case 36:
1465 #line 279 "getdate.y"
1466 {
1467             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1468         }
1469 break;
1470 case 37:
1471 #line 282 "getdate.y"
1472 {
1473             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1474         }
1475 break;
1476 case 38:
1477 #line 285 "getdate.y"
1478 {
1479             yyRelMonth += yyvsp[0].Number;
1480         }
1481 break;
1482 case 39:
1483 #line 290 "getdate.y"
1484 {
1485             if (yyHaveTime && yyHaveDate && !yyHaveRel)
1486                 yyYear = yyvsp[0].Number;
1487             else {
1488                 if(yyvsp[0].Number>10000) {
1489                     yyHaveDate++;
1490                     yyDay= (yyvsp[0].Number)%100;
1491                     yyMonth= (yyvsp[0].Number/100)%100;
1492                     yyYear = yyvsp[0].Number/10000;
1493                 }
1494                 else {
1495                     yyHaveTime++;
1496                     if (yyvsp[0].Number < 100) {
1497                         yyHour = yyvsp[0].Number;
1498                         yyMinutes = 0;
1499                     }
1500                     else {
1501                         yyHour = yyvsp[0].Number / 100;
1502                         yyMinutes = yyvsp[0].Number % 100;
1503                     }
1504                     yySeconds = 0;
1505                     yyMeridian = MER24;
1506                 }
1507             }
1508         }
1509 break;
1510 case 40:
1511 #line 317 "getdate.y"
1512 {
1513             yyval.Meridian = MER24;
1514         }
1515 break;
1516 case 41:
1517 #line 320 "getdate.y"
1518 {
1519             yyval.Meridian = yyvsp[0].Meridian;
1520         }
1521 break;
1522 #line 1470 "getdate.c"
1523     }
1524     yyssp -= yym;
1525     yystate = *yyssp;
1526     yyvsp -= yym;
1527     yym = yylhs[yyn];
1528     if (yystate == 0 && yym == 0)
1529     {
1530 #if YYDEBUG
1531         if (yydebug)
1532             printf("%sdebug: after reduction, shifting from state 0 to\
1533  state %d\n", YYPREFIX, YYFINAL);
1534 #endif
1535         yystate = YYFINAL;
1536         *++yyssp = YYFINAL;
1537         *++yyvsp = yyval;
1538         if (yychar < 0)
1539         {
1540             if ((yychar = yylex()) < 0) yychar = 0;
1541 #if YYDEBUG
1542             if (yydebug)
1543             {
1544                 yys = 0;
1545                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1546                 if (!yys) yys = "illegal-symbol";
1547                 printf("%sdebug: state %d, reading %d (%s)\n",
1548                         YYPREFIX, YYFINAL, yychar, yys);
1549             }
1550 #endif
1551         }
1552         if (yychar == 0) goto yyaccept;
1553         goto yyloop;
1554     }
1555     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
1556             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1557         yystate = yytable[yyn];
1558     else
1559         yystate = yydgoto[yym];
1560 #if YYDEBUG
1561     if (yydebug)
1562         printf("%sdebug: after reduction, shifting from state %d \
1563 to state %d\n", YYPREFIX, *yyssp, yystate);
1564 #endif
1565     if (yyssp >= yysslim && yygrowstack())
1566     {
1567         goto yyoverflow;
1568     }
1569     *++yyssp = yystate;
1570     *++yyvsp = yyval;
1571     goto yyloop;
1572 yyoverflow:
1573     yyerror("yacc stack overflow");
1574 yyabort:
1575     if (yyss)
1576             free(yyss);
1577     if (yyvs)
1578             free(yyvs);
1579     yyss = yyssp = NULL;
1580     yyvs = yyvsp = NULL;
1581     yystacksize = 0;
1582     return (1);
1583 yyaccept:
1584     if (yyss)
1585             free(yyss);
1586     if (yyvs)
1587             free(yyvs);
1588     yyss = yyssp = NULL;
1589     yyvs = yyvsp = NULL;
1590     yystacksize = 0;
1591     return (0);
1592 }