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