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