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