1 /* original parser id follows */
2 /* yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93" */
3 /* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */
4 
5 #define YYBYACC 1
6 #define YYMAJOR 1
7 #define YYMINOR 9
8 #define YYPATCH 20170709
9 
10 #define YYEMPTY        (-1)
11 #define yyclearin      (yychar = YYEMPTY)
12 #define yyerrok        (yyerrflag = 0)
13 #define YYRECOVERING() (yyerrflag != 0)
14 #define YYENOMEM       (-2)
15 #define YYEOF          0
16 #define YYPREFIX "yy"
17 
18 #define YYPURE 0
19 
20 #line 2 "./parsdate.y"
21 
22 #include <LYLeaks.h>
23 
24 /*
25  *  $LynxId: parsdate.c,v 1.18 2018/04/01 22:22:06 tom Exp $
26  *
27  *  This module is adapted and extended from tin, to use for LYmktime().
28  *
29  *  Project   : tin - a Usenet reader
30  *  Module    : parsedate.y
31  *  Author    : S. Bellovin, R. $alz, J. Berets, P. Eggert
32  *  Created   : 1990-08-01
33  *  Updated   : 2008-06-30 (by Thomas Dickey, for Lynx)
34  *  Notes     : This grammar has 8 shift/reduce conflicts.
35  *
36  *              Originally written by Steven M. Bellovin <smb@research.att.com>
37  *              while at the University of North Carolina at Chapel Hill.
38  *              Later tweaked by a couple of people on Usenet.  Completely
39  *              overhauled by Rich $alz <rsalz@osf.org> and Jim Berets
40  *              <jberets@bbn.com> in August, 1990.
41  *
42  *              Further revised (removed obsolete constructs and cleaned up
43  *              timezone names) in August, 1991, by Rich.
44  *              Paul Eggert <eggert@twinsun.com> helped in September 1992.
45  *              Roland Rosenfeld added MET DST code in April 1994.
46  *
47  *  Revision  : 1.13
48  *  Copyright : This code is in the public domain and has no copyright.
49  */
50 
51 /* SUPPRESS 530 */ /* Empty body for statement */
52 /* SUPPRESS 593 on yyerrlab */ /* Label was not used */
53 /* SUPPRESS 593 on yynewstate */ /* Label was not used */
54 /* SUPPRESS 595 on yypvt */ /* Automatic variable may be used before set */
55 
56 #undef alloca			/* conflicting def may be set by yacc */
57 #include <parsdate.h>
58 
59 /*
60 **  Get the number of elements in a fixed-size array, or a pointer just
61 **  past the end of it.
62 */
63 #define ENDOF(array)	(&array[ARRAY_SIZE(array)])
64 
65 #ifdef EBCDIC
66 #define TO_ASCII(c)	TOASCII(c)
67 #define TO_LOCAL(c)	FROMASCII(c)
68 #else
69 #define TO_ASCII(c)	(c)
70 #define TO_LOCAL(c)	(c)
71 #endif
72 
73 #define IS7BIT(x)		((unsigned) TO_ASCII(x) < 128)
74 #define CTYPE(isXXXXX, c)	(IS7BIT(c) && isXXXXX(((unsigned char)c)))
75 
76 typedef char *PD_STRING;
77 
78 extern int date_parse(void);
79 
80 #define yyparse		date_parse
81 #define yylex		date_lex
82 #define yyerror		date_error
83 
84     /* See the LeapYears table in Convert. */
85 #define EPOCH		1970
86 #define END_OF_TIME	2038
87 
88     /* Constants for general time calculations. */
89 #define DST_OFFSET	1
90 #define SECSPERDAY	(24L * 60L * 60L)
91     /* Readability for TABLE stuff. */
92 #define HOUR(x)		(x * 60)
93 
94 #define LPAREN		'('
95 #define RPAREN		')'
96 
97 /*
98 **  Daylight-savings mode:  on, off, or not yet known.
99 */
100 typedef enum _DSTMODE {
101     DSTon, DSToff, DSTmaybe
102 } DSTMODE;
103 
104 /*
105 **  Meridian:  am, pm, or 24-hour style.
106 */
107 typedef enum _MERIDIAN {
108     MERam, MERpm, MER24
109 } MERIDIAN;
110 
111 /*
112 **  Global variables.  We could get rid of most of them by using a yacc
113 **  union, but this is more efficient.  (This routine predates the
114 **  yacc %union construct.)
115 */
116 static char *yyInput;
117 static DSTMODE yyDSTmode;
118 static int yyHaveDate;
119 static int yyHaveRel;
120 static int yyHaveTime;
121 static time_t yyTimezone;
122 static time_t yyDay;
123 static time_t yyHour;
124 static time_t yyMinutes;
125 static time_t yyMonth;
126 static time_t yySeconds;
127 static time_t yyYear;
128 static MERIDIAN yyMeridian;
129 static time_t yyRelMonth;
130 static time_t yyRelSeconds;
131 
132 static time_t ToSeconds(time_t, time_t, time_t, MERIDIAN);
133 static time_t Convert(time_t, time_t, time_t, time_t, time_t, time_t,
134 		      MERIDIAN, DSTMODE);
135 static time_t DSTcorrect(time_t, time_t);
136 static time_t RelativeMonth(time_t, time_t);
137 static int LookupWord(char *, int);
138 static int date_lex(void);
139 static int GetTimeInfo(TIMEINFO * Now);
140 
141 /*
142  * The 'date_error()' function is declared here to work around a defect in
143  * bison 1.22, which redefines 'const' further down in this file, making it
144  * impossible to put a prototype here, and the function later.  We're using
145  * 'const' on the parameter to quiet gcc's -Wwrite-strings warning.
146  */
147 /*ARGSUSED*/
date_error(const char GCC_UNUSED * s)148 static void date_error(const char GCC_UNUSED *s)
149 {
150     /*NOTREACHED */
151 }
152 
153 #ifdef YYSTYPE
154 #undef  YYSTYPE_IS_DECLARED
155 #define YYSTYPE_IS_DECLARED 1
156 #endif
157 #ifndef YYSTYPE_IS_DECLARED
158 #define YYSTYPE_IS_DECLARED 1
159 #line 136 "./parsdate.y"
160 typedef union {
161     time_t		Number;
162     enum _MERIDIAN	Meridian;
163 } YYSTYPE;
164 #endif /* !YYSTYPE_IS_DECLARED */
165 #line 166 "y.tab.c"
166 
167 /* compatibility with bison */
168 #ifdef YYPARSE_PARAM
169 /* compatibility with FreeBSD */
170 # ifdef YYPARSE_PARAM_TYPE
171 #  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
172 # else
173 #  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
174 # endif
175 #else
176 # define YYPARSE_DECL() yyparse(void)
177 #endif
178 
179 /* Parameters sent to lex. */
180 #ifdef YYLEX_PARAM
181 # define YYLEX_DECL() yylex(void *YYLEX_PARAM)
182 # define YYLEX yylex(YYLEX_PARAM)
183 #else
184 # define YYLEX_DECL() yylex(void)
185 # define YYLEX yylex()
186 #endif
187 
188 /* Parameters sent to yyerror. */
189 #ifndef YYERROR_DECL
190 #define YYERROR_DECL() yyerror(const char *s)
191 #endif
192 #ifndef YYERROR_CALL
193 #define YYERROR_CALL(msg) yyerror(msg)
194 #endif
195 
196 extern int YYPARSE_DECL();
197 
198 #define tDAY 257
199 #define tDAYZONE 258
200 #define tMERIDIAN 259
201 #define tMONTH 260
202 #define tMONTH_UNIT 261
203 #define tSEC_UNIT 262
204 #define tSNUMBER 263
205 #define tUNUMBER 264
206 #define tZONE 265
207 #define tDST 266
208 #define YYERRCODE 256
209 typedef short YYINT;
210 static const YYINT yylhs[] = {                           -1,
211     0,    0,    4,    4,    4,    4,    4,    4,    5,    5,
212     5,    5,    5,    2,    2,    2,    2,    2,    1,    6,
213     6,    6,    6,    6,    6,    6,    6,    6,    7,    8,
214     8,    8,    8,    3,    3,
215 };
216 static const YYINT yylen[] = {                            2,
217     0,    2,    1,    2,    1,    1,    2,    1,    2,    4,
218     4,    6,    6,    1,    1,    2,    2,    1,    1,    3,
219     5,    2,    4,    2,    3,    5,    6,    3,    9,    2,
220     2,    2,    2,    0,    1,
221 };
222 static const YYINT yydefred[] = {                         1,
223     0,    0,    0,    0,    0,    2,    0,    5,    0,    8,
224     0,    0,    0,   32,   30,   35,    0,   33,   31,    0,
225     0,    0,    9,    0,   19,    0,   18,    4,    7,    0,
226     0,    0,   25,   28,    0,    0,   16,   17,    0,    0,
227     0,   23,    0,   11,   10,    0,    0,   26,    0,    0,
228    21,    0,   27,   13,   12,    0,    0,   29,
229 };
230 static const YYINT yydgoto[] = {                          1,
231    27,   28,   23,    6,    7,    8,    9,   10,
232 };
233 static const YYINT yysindex[] = {                         0,
234  -240,  -41, -256, -227,  -45,    0, -251,    0, -251,    0,
235  -254, -249,  -22,    0,    0,    0, -237,    0,    0, -235,
236  -228, -226,    0, -236,    0, -224,    0,    0,    0, -223,
237   -39, -222,    0,    0,  -58,   -7,    0,    0,  -15, -220,
238  -215,    0, -218,    0,    0, -217, -216,    0, -214, -234,
239     0,   -8,    0,    0,    0, -213, -212,    0,
240 };
241 static const YYINT yyrindex[] = {                         0,
242     0,    0,    0,    0,    5,    0,   26,    0,   31,    0,
243     0,    0,   11,    0,    0,    0,   37,    0,    0,    0,
244     0,    0,    0,   16,    0,   32,    0,    0,    0,    0,
245     0,    0,    0,    0,    1,   21,    0,    0,    0,    0,
246     0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
247     0,    0,    0,    0,    0,    0,    0,    0,
248 };
249 static const YYINT yygindex[] = {                         0,
250   -17,   44,  -31,    0,    0,    0,    0,    0,
251 };
252 #define YYTABLESIZE 300
253 static const YYINT yytable[] = {                         43,
254    34,   22,   12,   45,   34,   41,   24,   13,   38,   30,
255    22,   25,   21,   26,   31,   15,    2,   44,   55,    3,
256    20,   32,    4,    5,   16,    3,   33,   34,   25,   37,
257     6,   14,   54,   14,   15,   35,   24,   36,   25,   46,
258    39,   42,   47,   48,   49,   50,   51,   52,   53,   56,
259    57,   58,   29,    0,    0,    0,    0,    0,    0,    0,
260     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
261     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
262     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
263     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
264     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
265     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
266     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
267     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
268     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
269     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
270     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
271     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
272     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
273     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
274    16,    0,    0,    0,   25,    0,    0,    0,    0,    0,
275     0,    0,    0,   16,   17,   18,   19,   20,   11,    0,
276    40,    0,    0,    0,    0,    0,    0,    0,    0,    0,
277     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
278     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
279     0,    0,    0,    0,    0,    0,    0,   34,   34,    0,
280    34,   34,   34,    0,   34,   34,    0,   22,   34,   34,
281    22,    0,   15,   22,   22,   15,    0,   20,   15,   15,
282    20,    0,    3,   20,   20,    3,    0,    6,   14,    3,
283     6,   14,    0,   24,    6,   14,   24,    0,    0,   24,
284 };
285 static const YYINT yycheck[] = {                         58,
286     0,   47,   44,   35,    0,   45,  258,  264,   26,  264,
287     0,  263,   58,  265,  264,    0,  257,   35,   50,  260,
288     0,   44,  263,  264,  259,    0,  264,  263,  263,  266,
289     0,    0,   50,  261,  262,  264,    0,  264,  263,   47,
290   264,  264,   58,  264,  260,  264,  264,  264,  263,   58,
291   264,  264,    9,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
292    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -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   259,   -1,   -1,   -1,  263,   -1,   -1,   -1,   -1,   -1,
307    -1,   -1,   -1,  259,  260,  261,  262,  263,  260,   -1,
308   260,   -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,  257,  258,   -1,
312   260,  257,  258,   -1,  264,  265,   -1,  257,  264,  265,
313   260,   -1,  257,  263,  264,  260,   -1,  257,  263,  264,
314   260,   -1,  257,  263,  264,  260,   -1,  257,  257,  264,
315   260,  260,   -1,  257,  264,  264,  260,   -1,   -1,  263,
316 };
317 #define YYFINAL 1
318 #ifndef YYDEBUG
319 #define YYDEBUG 0
320 #endif
321 #define YYMAXTOKEN 266
322 #define YYUNDFTOKEN 277
323 #define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a))
324 #if YYDEBUG
325 static const char *const yyname[] = {
326 
327 "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,
328 0,0,0,0,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,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,"tDAY","tDAYZONE",
334 "tMERIDIAN","tMONTH","tMONTH_UNIT","tSEC_UNIT","tSNUMBER","tUNUMBER","tZONE",
335 "tDST",0,0,0,0,0,0,0,0,0,0,"illegal-symbol",
336 };
337 static const char *const yyrule[] = {
338 "$accept : spec",
339 "spec :",
340 "spec : spec item",
341 "item : time",
342 "item : time zone",
343 "item : date",
344 "item : both",
345 "item : both zone",
346 "item : rel",
347 "time : tUNUMBER o_merid",
348 "time : tUNUMBER ':' tUNUMBER o_merid",
349 "time : tUNUMBER ':' tUNUMBER numzone",
350 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
351 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER numzone",
352 "zone : tZONE",
353 "zone : tDAYZONE",
354 "zone : tDAYZONE tDST",
355 "zone : tZONE numzone",
356 "zone : numzone",
357 "numzone : tSNUMBER",
358 "date : tUNUMBER '/' tUNUMBER",
359 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
360 "date : tMONTH tUNUMBER",
361 "date : tMONTH tUNUMBER ',' tUNUMBER",
362 "date : tUNUMBER tMONTH",
363 "date : tUNUMBER tMONTH tUNUMBER",
364 "date : tDAY ',' tUNUMBER tMONTH tUNUMBER",
365 "date : tDAY ',' tUNUMBER '-' tMONTH tSNUMBER",
366 "date : tUNUMBER tSNUMBER tSNUMBER",
367 "both : tDAY tMONTH tUNUMBER tUNUMBER ':' tUNUMBER ':' tUNUMBER tUNUMBER",
368 "rel : tSNUMBER tSEC_UNIT",
369 "rel : tUNUMBER tSEC_UNIT",
370 "rel : tSNUMBER tMONTH_UNIT",
371 "rel : tUNUMBER tMONTH_UNIT",
372 "o_merid :",
373 "o_merid : tMERIDIAN",
374 
375 };
376 #endif
377 
378 int      yydebug;
379 int      yynerrs;
380 
381 int      yyerrflag;
382 int      yychar;
383 YYSTYPE  yyval;
384 YYSTYPE  yylval;
385 
386 /* define the initial stack-sizes */
387 #ifdef YYSTACKSIZE
388 #undef YYMAXDEPTH
389 #define YYMAXDEPTH  YYSTACKSIZE
390 #else
391 #ifdef YYMAXDEPTH
392 #define YYSTACKSIZE YYMAXDEPTH
393 #else
394 #define YYSTACKSIZE 10000
395 #define YYMAXDEPTH  10000
396 #endif
397 #endif
398 
399 #define YYINITSTACKSIZE 200
400 
401 typedef struct {
402     unsigned stacksize;
403     YYINT    *s_base;
404     YYINT    *s_mark;
405     YYINT    *s_last;
406     YYSTYPE  *l_base;
407     YYSTYPE  *l_mark;
408 } YYSTACKDATA;
409 /* variables for the parser stack */
410 static YYSTACKDATA yystack;
411 #line 358 "./parsdate.y"
412 
413 
414 /*
415 **  An entry in the lexical lookup table.
416 */
417 /* *INDENT-OFF* */
418 typedef struct _TABLE {
419     const char *name;
420     int		type;
421     time_t	value;
422 } TABLE;
423 
424 /* Month and day table. */
425 static const TABLE MonthDayTable[] = {
426     { "january",	tMONTH,  1 },
427     { "february",	tMONTH,  2 },
428     { "march",		tMONTH,  3 },
429     { "april",		tMONTH,  4 },
430     { "may",		tMONTH,  5 },
431     { "june",		tMONTH,  6 },
432     { "july",		tMONTH,  7 },
433     { "august",		tMONTH,  8 },
434     { "september",	tMONTH,  9 },
435     { "october",	tMONTH, 10 },
436     { "november",	tMONTH, 11 },
437     { "december",	tMONTH, 12 },
438 	/* The value of the day isn't used... */
439     { "sunday",		tDAY, 0 },
440     { "monday",		tDAY, 0 },
441     { "tuesday",	tDAY, 0 },
442     { "wednesday",	tDAY, 0 },
443     { "thursday",	tDAY, 0 },
444     { "friday",		tDAY, 0 },
445     { "saturday",	tDAY, 0 },
446 };
447 
448 /* Time units table. */
449 static const TABLE	UnitsTable[] = {
450     { "year",		tMONTH_UNIT,	12 },
451     { "month",		tMONTH_UNIT,	1 },
452     { "week",		tSEC_UNIT,	7 * 24 * 60 * 60 },
453     { "day",		tSEC_UNIT,	1 * 24 * 60 * 60 },
454     { "hour",		tSEC_UNIT,	60 * 60 },
455     { "minute",		tSEC_UNIT,	60 },
456     { "min",		tSEC_UNIT,	60 },
457     { "second",		tSEC_UNIT,	1 },
458     { "sec",		tSEC_UNIT,	1 },
459 };
460 
461 /* Timezone table. */
462 static const TABLE	TimezoneTable[] = {
463     { "gmt",	tZONE,     HOUR( 0) },	/* Greenwich Mean */
464     { "ut",	tZONE,     HOUR( 0) },	/* Universal */
465     { "utc",	tZONE,     HOUR( 0) },	/* Universal Coordinated */
466     { "cut",	tZONE,     HOUR( 0) },	/* Coordinated Universal */
467     { "z",	tZONE,     HOUR( 0) },	/* Greenwich Mean */
468     { "wet",	tZONE,     HOUR( 0) },	/* Western European */
469     { "bst",	tDAYZONE,  HOUR( 0) },	/* British Summer */
470     { "nst",	tZONE,     HOUR(3)+30 }, /* Newfoundland Standard */
471     { "ndt",	tDAYZONE,  HOUR(3)+30 }, /* Newfoundland Daylight */
472     { "ast",	tZONE,     HOUR( 4) },	/* Atlantic Standard */
473     { "adt",	tDAYZONE,  HOUR( 4) },	/* Atlantic Daylight */
474     { "est",	tZONE,     HOUR( 5) },	/* Eastern Standard */
475     { "edt",	tDAYZONE,  HOUR( 5) },	/* Eastern Daylight */
476     { "cst",	tZONE,     HOUR( 6) },	/* Central Standard */
477     { "cdt",	tDAYZONE,  HOUR( 6) },	/* Central Daylight */
478     { "mst",	tZONE,     HOUR( 7) },	/* Mountain Standard */
479     { "mdt",	tDAYZONE,  HOUR( 7) },	/* Mountain Daylight */
480     { "pst",	tZONE,     HOUR( 8) },	/* Pacific Standard */
481     { "pdt",	tDAYZONE,  HOUR( 8) },	/* Pacific Daylight */
482     { "yst",	tZONE,     HOUR( 9) },	/* Yukon Standard */
483     { "ydt",	tDAYZONE,  HOUR( 9) },	/* Yukon Daylight */
484     { "akst",	tZONE,     HOUR( 9) },	/* Alaska Standard */
485     { "akdt",	tDAYZONE,  HOUR( 9) },	/* Alaska Daylight */
486     { "hst",	tZONE,     HOUR(10) },	/* Hawaii Standard */
487     { "hast",	tZONE,     HOUR(10) },	/* Hawaii-Aleutian Standard */
488     { "hadt",	tDAYZONE,  HOUR(10) },	/* Hawaii-Aleutian Daylight */
489     { "ces",	tDAYZONE,  -HOUR(1) },	/* Central European Summer */
490     { "cest",	tDAYZONE,  -HOUR(1) },	/* Central European Summer */
491     { "mez",	tZONE,     -HOUR(1) },	/* Middle European */
492     { "mezt",	tDAYZONE,  -HOUR(1) },	/* Middle European Summer */
493     { "cet",	tZONE,     -HOUR(1) },	/* Central European */
494     { "met",	tZONE,     -HOUR(1) },	/* Middle European */
495 /* Additional aliases for MET / MET DST *************************************/
496     { "mez",    tZONE,     -HOUR(1) },  /* Middle European */
497     { "mewt",   tZONE,     -HOUR(1) },  /* Middle European Winter */
498     { "mest",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
499     { "mes",    tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
500     { "mesz",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
501     { "msz",    tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
502     { "metdst", tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
503 /****************************************************************************/
504     { "eet",	tZONE,     -HOUR(2) },	/* Eastern Europe */
505     { "msk",	tZONE,     -HOUR(3) },	/* Moscow Winter */
506     { "msd",	tDAYZONE,  -HOUR(3) },	/* Moscow Summer */
507     { "wast",	tZONE,     -HOUR(8) },	/* West Australian Standard */
508     { "wadt",	tDAYZONE,  -HOUR(8) },	/* West Australian Daylight */
509     { "hkt",	tZONE,     -HOUR(8) },	/* Hong Kong */
510     { "cct",	tZONE,     -HOUR(8) },	/* China Coast */
511     { "jst",	tZONE,     -HOUR(9) },	/* Japan Standard */
512     { "kst",	tZONE,     -HOUR(9) },	/* Korean Standard */
513     { "kdt",	tZONE,     -HOUR(9) },	/* Korean Daylight */
514     { "cast",	tZONE,     -(HOUR(9)+30) }, /* Central Australian Standard */
515     { "cadt",	tDAYZONE,  -(HOUR(9)+30) }, /* Central Australian Daylight */
516     { "east",	tZONE,     -HOUR(10) },	/* Eastern Australian Standard */
517     { "eadt",	tDAYZONE,  -HOUR(10) },	/* Eastern Australian Daylight */
518     { "nzst",	tZONE,     -HOUR(12) },	/* New Zealand Standard */
519     { "nzdt",	tDAYZONE,  -HOUR(12) },	/* New Zealand Daylight */
520 
521     /* For completeness we include the following entries. */
522 #if	0
523 
524     /* Duplicate names.  Either they conflict with a zone listed above
525      * (which is either more likely to be seen or just been in circulation
526      * longer), or they conflict with another zone in this section and
527      * we could not reasonably choose one over the other. */
528     { "fst",	tZONE,     HOUR( 2) },	/* Fernando De Noronha Standard */
529     { "fdt",	tDAYZONE,  HOUR( 2) },	/* Fernando De Noronha Daylight */
530     { "bst",	tZONE,     HOUR( 3) },	/* Brazil Standard */
531     { "est",	tZONE,     HOUR( 3) },	/* Eastern Standard (Brazil) */
532     { "edt",	tDAYZONE,  HOUR( 3) },	/* Eastern Daylight (Brazil) */
533     { "wst",	tZONE,     HOUR( 4) },	/* Western Standard (Brazil) */
534     { "wdt",	tDAYZONE,  HOUR( 4) },	/* Western Daylight (Brazil) */
535     { "cst",	tZONE,     HOUR( 5) },	/* Chile Standard */
536     { "cdt",	tDAYZONE,  HOUR( 5) },	/* Chile Daylight */
537     { "ast",	tZONE,     HOUR( 5) },	/* Acre Standard */
538     { "adt",	tDAYZONE,  HOUR( 5) },	/* Acre Daylight */
539     { "cst",	tZONE,     HOUR( 5) },	/* Cuba Standard */
540     { "cdt",	tDAYZONE,  HOUR( 5) },	/* Cuba Daylight */
541     { "est",	tZONE,     HOUR( 6) },	/* Easter Island Standard */
542     { "edt",	tDAYZONE,  HOUR( 6) },	/* Easter Island Daylight */
543     { "sst",	tZONE,     HOUR(11) },	/* Samoa Standard */
544     { "ist",	tZONE,     -HOUR(2) },	/* Israel Standard */
545     { "idt",	tDAYZONE,  -HOUR(2) },	/* Israel Daylight */
546     { "idt",	tDAYZONE,  -(HOUR(3)+30) }, /* Iran Daylight */
547     { "ist",	tZONE,     -(HOUR(3)+30) }, /* Iran Standard */
548     { "cst",	 tZONE,     -HOUR(8) },	/* China Standard */
549     { "cdt",	 tDAYZONE,  -HOUR(8) },	/* China Daylight */
550     { "sst",	 tZONE,     -HOUR(8) },	/* Singapore Standard */
551 
552     /* Dubious (e.g., not in Olson's TIMEZONE package) or obsolete. */
553     { "gst",	tZONE,     HOUR( 3) },	/* Greenland Standard */
554     { "wat",	tZONE,     -HOUR(1) },	/* West Africa */
555     { "at",	tZONE,     HOUR( 2) },	/* Azores */
556     { "gst",	tZONE,     -HOUR(10) },	/* Guam Standard */
557     { "nft",	tZONE,     HOUR(3)+30 }, /* Newfoundland */
558     { "idlw",	tZONE,     HOUR(12) },	/* International Date Line West */
559     { "mewt",	tZONE,     -HOUR(1) },	/* Middle European Winter */
560     { "mest",	tDAYZONE,  -HOUR(1) },	/* Middle European Summer */
561     { "swt",	tZONE,     -HOUR(1) },	/* Swedish Winter */
562     { "sst",	tDAYZONE,  -HOUR(1) },	/* Swedish Summer */
563     { "fwt",	tZONE,     -HOUR(1) },	/* French Winter */
564     { "fst",	tDAYZONE,  -HOUR(1) },	/* French Summer */
565     { "bt",	tZONE,     -HOUR(3) },	/* Baghdad */
566     { "it",	tZONE,     -(HOUR(3)+30) }, /* Iran */
567     { "zp4",	tZONE,     -HOUR(4) },	/* USSR Zone 3 */
568     { "zp5",	tZONE,     -HOUR(5) },	/* USSR Zone 4 */
569     { "ist",	tZONE,     -(HOUR(5)+30) }, /* Indian Standard */
570     { "zp6",	tZONE,     -HOUR(6) },	/* USSR Zone 5 */
571     { "nst",	tZONE,     -HOUR(7) },	/* North Sumatra */
572     { "sst",	tZONE,     -HOUR(7) },	/* South Sumatra */
573     { "jt",	tZONE,     -(HOUR(7)+30) }, /* Java (3pm in Cronusland!) */
574     { "nzt",	tZONE,     -HOUR(12) },	/* New Zealand */
575     { "idle",	tZONE,     -HOUR(12) },	/* International Date Line East */
576     { "cat",	tZONE,     HOUR(10) },	/* -- expired 1967 */
577     { "nt",	tZONE,     HOUR(11) },	/* -- expired 1967 */
578     { "ahst",	tZONE,     HOUR(10) },	/* -- expired 1983 */
579     { "hdt",	tDAYZONE,  HOUR(10) },	/* -- expired 1986 */
580 #endif	/* 0 */
581 };
582 /* *INDENT-ON* */
583 
ToSeconds(time_t Hours,time_t Minutes,time_t Seconds,MERIDIAN Meridian)584 static time_t ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
585 {
586     if ((long) Minutes < 0 || Minutes > 59 || (long) Seconds < 0 || Seconds > 61)
587 	return -1;
588     if (Meridian == MER24) {
589 	if ((long) Hours < 0 || Hours > 23)
590 	    return -1;
591     } else {
592 	if (Hours < 1 || Hours > 12)
593 	    return -1;
594 	if (Hours == 12)
595 	    Hours = 0;
596 	if (Meridian == MERpm)
597 	    Hours += 12;
598     }
599     return (Hours * 60L + Minutes) * 60L + Seconds;
600 }
601 
Convert(time_t Month,time_t Day,time_t Year,time_t Hours,time_t Minutes,time_t Seconds,MERIDIAN Meridian,DSTMODE dst)602 static time_t Convert(time_t Month, time_t Day, time_t Year, time_t Hours,
603 		      time_t Minutes, time_t Seconds, MERIDIAN Meridian,
604 		      DSTMODE dst)
605 {
606     static const int DaysNormal[13] =
607     {
608 	0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
609     };
610     static const int DaysLeap[13] =
611     {
612 	0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
613     };
614     static const int LeapYears[] =
615     {
616 	1972, 1976, 1980, 1984, 1988, 1992, 1996,
617 	2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036
618     };
619     const int *yp;
620     const int *mp;
621     int i;
622     time_t Julian;
623     time_t tod;
624 
625     if ((long) Year < 0)
626 	Year = -Year;
627     if (Year < 70)
628 	Year += 2000;
629     if (Year < 100)
630 	Year += 1900;
631     if (Year < EPOCH)
632 	Year += 100;
633     for (mp = DaysNormal, yp = LeapYears; yp < ENDOF(LeapYears); yp++)
634 	if (Year == *yp) {
635 	    mp = DaysLeap;
636 	    break;
637 	}
638     if (Year < EPOCH || Year > END_OF_TIME
639 	|| Month < 1 || Month > 12
640     /* NOSTRICT */
641     /* conversion from long may lose accuracy */
642 	|| Day < 1 || Day > mp[(int) Month]) {
643 	return -1;
644     }
645 
646     Julian = Day - 1 + (Year - EPOCH) * 365;
647     for (yp = LeapYears; yp < ENDOF(LeapYears); yp++, Julian++) {
648 	if (Year <= *yp)
649 	    break;
650     }
651     for (i = 1; i < Month; i++)
652 	Julian += *++mp;
653     Julian *= SECSPERDAY;
654     Julian += yyTimezone * 60L;
655     if ((long) (tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0) {
656 	return -1;
657     }
658     Julian += tod;
659     tod = Julian;
660     if (dst == DSTon || (dst == DSTmaybe && localtime(&tod)->tm_isdst))
661 	Julian -= DST_OFFSET * 60 * 60;
662     return Julian;
663 }
664 
DSTcorrect(time_t Start,time_t Future)665 static time_t DSTcorrect(time_t Start, time_t Future)
666 {
667     time_t StartDay;
668     time_t FutureDay;
669 
670     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
671     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
672     return (Future - Start) + (StartDay - FutureDay) * DST_OFFSET * 60 * 60;
673 }
674 
RelativeMonth(time_t Start,time_t RelMonth)675 static time_t RelativeMonth(time_t Start, time_t RelMonth)
676 {
677     struct tm *tm;
678     time_t Month;
679     time_t Year;
680 
681     tm = localtime(&Start);
682     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
683     Year = Month / 12 + 1900;
684     Month = Month % 12 + 1;
685     return DSTcorrect(Start,
686 		      Convert(Month, (time_t) tm->tm_mday, Year,
687 			      (time_t) tm->tm_hour, (time_t) tm->tm_min,
688 			      (time_t) tm->tm_sec,
689 			      MER24, DSTmaybe));
690 }
691 
LookupWord(char * buff,int length)692 static int LookupWord(char *buff,
693 		      int length)
694 {
695     char *p;
696     const char *q;
697     const TABLE *tp;
698     int c;
699 
700     p = buff;
701     c = p[0];
702 
703     /* See if we have an abbreviation for a month. */
704     if (length == 3 || (length == 4 && p[3] == '.')) {
705 	for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
706 	    q = tp->name;
707 	    if (c == q[0] && p[1] == q[1] && p[2] == q[2]) {
708 		yylval.Number = tp->value;
709 		return tp->type;
710 	    }
711 	}
712     } else {
713 	for (tp = MonthDayTable; tp < ENDOF(MonthDayTable); tp++) {
714 	    if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
715 		yylval.Number = tp->value;
716 		return tp->type;
717 	    }
718 	}
719     }
720 
721     /* Try for a timezone. */
722     for (tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) {
723 	if (c == tp->name[0] && p[1] == tp->name[1]
724 	    && strcmp(p, tp->name) == 0) {
725 	    yylval.Number = tp->value;
726 	    return tp->type;
727 	}
728     }
729 
730     if (strcmp(buff, "dst") == 0)
731 	return tDST;
732 
733     /* Try the units table. */
734     for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) {
735 	if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
736 	    yylval.Number = tp->value;
737 	    return tp->type;
738 	}
739     }
740 
741     /* Strip off any plural and try the units table again. */
742     if (--length > 0 && p[length] == 's') {
743 	p[length] = '\0';
744 	for (tp = UnitsTable; tp < ENDOF(UnitsTable); tp++) {
745 	    if (c == tp->name[0] && strcmp(p, tp->name) == 0) {
746 		p[length] = 's';
747 		yylval.Number = tp->value;
748 		return tp->type;
749 	    }
750 	}
751 	p[length] = 's';
752     }
753     length++;
754 
755     /* Drop out any periods. */
756     for (p = buff, q = (PD_STRING) buff; *q; q++) {
757 	if (*q != '.')
758 	    *p++ = *q;
759     }
760     *p = '\0';
761 
762     /* Try the meridians. */
763     if (buff[1] == 'm' && buff[2] == '\0') {
764 	if (buff[0] == 'a') {
765 	    yylval.Meridian = MERam;
766 	    return tMERIDIAN;
767 	}
768 	if (buff[0] == 'p') {
769 	    yylval.Meridian = MERpm;
770 	    return tMERIDIAN;
771 	}
772     }
773 
774     /* If we saw any periods, try the timezones again. */
775     if (p - buff != length) {
776 	c = buff[0];
777 	for (p = buff, tp = TimezoneTable; tp < ENDOF(TimezoneTable); tp++) {
778 	    if (c == tp->name[0] && p[1] == tp->name[1]
779 		&& strcmp(p, tp->name) == 0) {
780 		yylval.Number = tp->value;
781 		return tp->type;
782 	    }
783 	}
784     }
785 
786     /* Unknown word -- assume GMT timezone. */
787     yylval.Number = 0;
788     return tZONE;
789 }
790 
791 /*
792  * This returns characters as-is (the ones that are not part of some token),
793  * and codes greater than 256 (the token values).
794  *
795  * yacc generates tables that may use the character value.  In particular,
796  * byacc's yycheck[] table contains integer values for the expected codes from
797  * this function, which (unless byacc is run locally) are ASCII codes.
798  *
799  * The TO_LOCAL() function assumes its input is in ASCII, and the output is
800  * whatever native encoding is used on the machine, e.g., EBCDIC.
801  *
802  * The TO_ASCII() function is the inverse of TO_LOCAL().
803  */
date_lex(void)804 static int date_lex(void)
805 {
806     int c;
807     char *p;
808     char buff[20];
809     int sign;
810     int i;
811     int nesting;
812 
813     /* Get first character after the whitespace. */
814     for (;;) {
815 	while (CTYPE(isspace, *yyInput))
816 	    yyInput++;
817 	c = *yyInput;
818 
819 	/* Ignore RFC 822 comments, typically time zone names. */
820 	if (c != LPAREN)
821 	    break;
822 	for (nesting = 1;
823 	     (c = *++yyInput) != RPAREN || --nesting;
824 	    ) {
825 	    if (c == LPAREN) {
826 		nesting++;
827 	    } else if (!IS7BIT(c) || c == '\0' || c == '\r'
828 		       || (c == '\\'
829 			   && ((c = *++yyInput) == '\0'
830 			       || !IS7BIT(c)))) {
831 		/* Lexical error: bad comment. */
832 		return '?';
833 	    }
834 	}
835 	yyInput++;
836     }
837 
838     /* A number? */
839     if (CTYPE(isdigit, c) || c == '-' || c == '+') {
840 	if (c == '-' || c == '+') {
841 	    sign = c == '-' ? -1 : 1;
842 	    yyInput++;
843 	    if (!CTYPE(isdigit, *yyInput)) {
844 		/* Return the isolated plus or minus sign. */
845 		--yyInput;
846 		return *yyInput++;
847 	    }
848 	} else {
849 	    sign = 0;
850 	}
851 	for (p = buff;
852 	     (c = *yyInput++) != '\0' && CTYPE(isdigit, c);
853 	    ) {
854 	    if (p < &buff[sizeof buff - 1])
855 		*p++ = (char) c;
856 	}
857 	*p = '\0';
858 	i = atoi(buff);
859 
860 	yyInput--;
861 	yylval.Number = sign < 0 ? -i : i;
862 	return sign ? tSNUMBER : tUNUMBER;
863     }
864 
865     /* A word? */
866     if (CTYPE(isalpha, c)) {
867 	for (p = buff;
868 	     (c = *yyInput++) == '.' || CTYPE(isalpha, c);
869 	    ) {
870 	    if (p < &buff[sizeof buff - 1])
871 		*p++ = (char) (CTYPE(isupper, c) ? tolower(c) : c);
872 	}
873 	*p = '\0';
874 	yyInput--;
875 	return LookupWord(buff, (int) (p - buff));
876     }
877 
878     return *yyInput++;
879 }
880 
GetTimeInfo(TIMEINFO * Now)881 static int GetTimeInfo(TIMEINFO * Now)
882 {
883     static time_t LastTime;
884     static long LastTzone;
885     struct tm *tm;
886 
887 #if	defined(HAVE_GETTIMEOFDAY)
888     struct timeval tv;
889 #endif /* defined(HAVE_GETTIMEOFDAY) */
890 #if	defined(DONT_HAVE_TM_GMTOFF)
891     struct tm local;
892     struct tm gmt;
893 #endif /* !defined(DONT_HAVE_TM_GMTOFF) */
894 
895     /* Get the basic time. */
896 #if defined(HAVE_GETTIMEOFDAY)
897     if (gettimeofday(&tv, (struct timezone *) NULL) == -1)
898 	return -1;
899     Now->time = tv.tv_sec;
900     Now->usec = tv.tv_usec;
901 #else
902     /* Can't check for -1 since that might be a time, I guess. */
903     (void) time(&Now->time);
904     Now->usec = 0;
905 #endif /* defined(HAVE_GETTIMEOFDAY) */
906 
907     /* Now get the timezone if it's been an hour since the last time. */
908     if (Now->time - LastTime > 60 * 60) {
909 	LastTime = Now->time;
910 	if ((tm = localtime(&Now->time)) == NULL)
911 	    return -1;
912 #if	defined(DONT_HAVE_TM_GMTOFF)
913 	/* To get the timezone, compare localtime with GMT. */
914 	local = *tm;
915 	if ((tm = gmtime(&Now->time)) == NULL)
916 	    return -1;
917 	gmt = *tm;
918 
919 	/* Assume we are never more than 24 hours away. */
920 	LastTzone = gmt.tm_yday - local.tm_yday;
921 	if (LastTzone > 1)
922 	    LastTzone = -24;
923 	else if (LastTzone < -1)
924 	    LastTzone = 24;
925 	else
926 	    LastTzone *= 24;
927 
928 	/* Scale in the hours and minutes; ignore seconds. */
929 	LastTzone += gmt.tm_hour - local.tm_hour;
930 	LastTzone *= 60;
931 	LastTzone += gmt.tm_min - local.tm_min;
932 #else
933 	LastTzone = (0 - tm->tm_gmtoff) / 60;
934 #endif /* defined(DONT_HAVE_TM_GMTOFF) */
935     }
936     Now->tzone = LastTzone;
937     return 0;
938 }
939 
940 #if defined(YYBYACC) && defined(YYPURE) && defined(LY_FIND_LEAKS)
941 #undef YYPURE
942 #define YYPURE 1
943 static void yyfreestack(YYSTACKDATA *);
parsedate_leaks(void)944 static void parsedate_leaks(void)
945 {
946     yyfreestack(&yystack);
947 }
948 #endif
949 
parsedate(char * p,TIMEINFO * now)950 time_t parsedate(char *p,
951 		 TIMEINFO * now)
952 {
953     struct tm *tm;
954     TIMEINFO ti;
955     time_t Start;
956 
957 #if defined(YYBYACC) && defined(YYPURE) && defined(LY_FIND_LEAKS)
958     static int initialized;
959 
960     if (!initialized) {
961 	initialized = 1;
962 	atexit(parsedate_leaks);
963     }
964 #endif
965 
966     yyInput = p;
967     if (now == NULL) {
968 	now = &ti;
969 	(void) GetTimeInfo(&ti);
970     }
971 
972     tm = localtime(&now->time);
973     yyYear = tm->tm_year + 1900;
974     yyMonth = tm->tm_mon + 1;
975     yyDay = tm->tm_mday;
976     yyTimezone = now->tzone;
977     if (tm->tm_isdst)		/* Correct timezone offset for DST */
978 	yyTimezone += DST_OFFSET * 60;
979     yyDSTmode = DSTmaybe;
980     yyHour = 0;
981     yyMinutes = 0;
982     yySeconds = 0;
983     yyMeridian = MER24;
984     yyRelSeconds = 0;
985     yyRelMonth = 0;
986     yyHaveDate = 0;
987     yyHaveRel = 0;
988     yyHaveTime = 0;
989 
990     if (date_parse() || yyHaveTime > 1 || yyHaveDate > 1)
991 	return -1;
992 
993     if (yyHaveDate || yyHaveTime) {
994 	Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
995 			yyMeridian, yyDSTmode);
996 	if ((long) Start < 0)
997 	    return -1;
998     } else {
999 	Start = now->time;
1000 	if (!yyHaveRel)
1001 	    Start -= (tm->tm_hour * 60L + tm->tm_min) * 60L + tm->tm_sec;
1002     }
1003 
1004     Start += yyRelSeconds;
1005     if (yyRelMonth)
1006 	Start += RelativeMonth(Start, yyRelMonth);
1007 
1008     /* Have to do *something* with a legitimate -1 so it's distinguishable
1009      * from the error return value.  (Alternately could set errno on error.) */
1010     return (Start == (time_t) -1) ? 0 : Start;
1011 }
1012 #line 1013 "y.tab.c"
1013 
1014 #if YYDEBUG
1015 #include <stdio.h>	/* needed for printf */
1016 #endif
1017 
1018 #include <stdlib.h>	/* needed for malloc, etc */
1019 #include <string.h>	/* needed for memset */
1020 
1021 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
yygrowstack(YYSTACKDATA * data)1022 static int yygrowstack(YYSTACKDATA *data)
1023 {
1024     int i;
1025     unsigned newsize;
1026     YYINT *newss;
1027     YYSTYPE *newvs;
1028 
1029     if ((newsize = data->stacksize) == 0)
1030         newsize = YYINITSTACKSIZE;
1031     else if (newsize >= YYMAXDEPTH)
1032         return YYENOMEM;
1033     else if ((newsize *= 2) > YYMAXDEPTH)
1034         newsize = YYMAXDEPTH;
1035 
1036     i = (int) (data->s_mark - data->s_base);
1037     newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss));
1038     if (newss == 0)
1039         return YYENOMEM;
1040 
1041     data->s_base = newss;
1042     data->s_mark = newss + i;
1043 
1044     newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs));
1045     if (newvs == 0)
1046         return YYENOMEM;
1047 
1048     data->l_base = newvs;
1049     data->l_mark = newvs + i;
1050 
1051     data->stacksize = newsize;
1052     data->s_last = data->s_base + newsize - 1;
1053     return 0;
1054 }
1055 
1056 #if YYPURE || defined(YY_NO_LEAKS)
yyfreestack(YYSTACKDATA * data)1057 static void yyfreestack(YYSTACKDATA *data)
1058 {
1059     free(data->s_base);
1060     free(data->l_base);
1061     memset(data, 0, sizeof(*data));
1062 }
1063 #else
1064 #define yyfreestack(data) /* nothing */
1065 #endif
1066 
1067 #define YYABORT  goto yyabort
1068 #define YYREJECT goto yyabort
1069 #define YYACCEPT goto yyaccept
1070 #define YYERROR  goto yyerrlab
1071 
1072 int
YYPARSE_DECL()1073 YYPARSE_DECL()
1074 {
1075     int yym, yyn, yystate;
1076 #if YYDEBUG
1077     const char *yys;
1078 
1079     if ((yys = getenv("YYDEBUG")) != 0)
1080     {
1081         yyn = *yys;
1082         if (yyn >= '0' && yyn <= '9')
1083             yydebug = yyn - '0';
1084     }
1085 #endif
1086 
1087     yym = 0;
1088     yyn = 0;
1089     yynerrs = 0;
1090     yyerrflag = 0;
1091     yychar = YYEMPTY;
1092     yystate = 0;
1093 
1094 #if YYPURE
1095     memset(&yystack, 0, sizeof(yystack));
1096 #endif
1097 
1098     if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
1099     yystack.s_mark = yystack.s_base;
1100     yystack.l_mark = yystack.l_base;
1101     yystate = 0;
1102     *yystack.s_mark = 0;
1103 
1104 yyloop:
1105     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
1106     if (yychar < 0)
1107     {
1108         yychar = YYLEX;
1109         if (yychar < 0) yychar = YYEOF;
1110 #if YYDEBUG
1111         if (yydebug)
1112         {
1113             if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
1114             printf("%sdebug: state %d, reading %d (%s)\n",
1115                     YYPREFIX, yystate, yychar, yys);
1116         }
1117 #endif
1118     }
1119     if (((yyn = yysindex[yystate]) != 0) && (yyn += yychar) >= 0 &&
1120             yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar)
1121     {
1122 #if YYDEBUG
1123         if (yydebug)
1124             printf("%sdebug: state %d, shifting to state %d\n",
1125                     YYPREFIX, yystate, yytable[yyn]);
1126 #endif
1127         if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
1128         yystate = yytable[yyn];
1129         *++yystack.s_mark = yytable[yyn];
1130         *++yystack.l_mark = yylval;
1131         yychar = YYEMPTY;
1132         if (yyerrflag > 0)  --yyerrflag;
1133         goto yyloop;
1134     }
1135     if (((yyn = yyrindex[yystate]) != 0) && (yyn += yychar) >= 0 &&
1136             yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yychar)
1137     {
1138         yyn = yytable[yyn];
1139         goto yyreduce;
1140     }
1141     if (yyerrflag != 0) goto yyinrecovery;
1142 
1143     YYERROR_CALL("syntax error");
1144 
1145     goto yyerrlab; /* redundant goto avoids 'unused label' warning */
1146 yyerrlab:
1147     ++yynerrs;
1148 
1149 yyinrecovery:
1150     if (yyerrflag < 3)
1151     {
1152         yyerrflag = 3;
1153         for (;;)
1154         {
1155             if (((yyn = yysindex[*yystack.s_mark]) != 0) && (yyn += YYERRCODE) >= 0 &&
1156                     yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) YYERRCODE)
1157             {
1158 #if YYDEBUG
1159                 if (yydebug)
1160                     printf("%sdebug: state %d, error recovery shifting\
1161  to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
1162 #endif
1163                 if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
1164                 yystate = yytable[yyn];
1165                 *++yystack.s_mark = yytable[yyn];
1166                 *++yystack.l_mark = yylval;
1167                 goto yyloop;
1168             }
1169             else
1170             {
1171 #if YYDEBUG
1172                 if (yydebug)
1173                     printf("%sdebug: error recovery discarding state %d\n",
1174                             YYPREFIX, *yystack.s_mark);
1175 #endif
1176                 if (yystack.s_mark <= yystack.s_base) goto yyabort;
1177                 --yystack.s_mark;
1178                 --yystack.l_mark;
1179             }
1180         }
1181     }
1182     else
1183     {
1184         if (yychar == YYEOF) goto yyabort;
1185 #if YYDEBUG
1186         if (yydebug)
1187         {
1188             if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
1189             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1190                     YYPREFIX, yystate, yychar, yys);
1191         }
1192 #endif
1193         yychar = YYEMPTY;
1194         goto yyloop;
1195     }
1196 
1197 yyreduce:
1198 #if YYDEBUG
1199     if (yydebug)
1200         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1201                 YYPREFIX, yystate, yyn, yyrule[yyn]);
1202 #endif
1203     yym = yylen[yyn];
1204     if (yym > 0)
1205         yyval = yystack.l_mark[1-yym];
1206     else
1207         memset(&yyval, 0, sizeof yyval);
1208 
1209     switch (yyn)
1210     {
1211 case 3:
1212 #line 154 "./parsdate.y"
1213 	{
1214 	    yyHaveTime++;
1215 #if	defined(lint)
1216 	    /* I am compulsive about lint natterings... */
1217 	    if (yyHaveTime == -1) {
1218 		YYERROR;
1219 	    }
1220 #endif	/* defined(lint) */
1221 	}
1222 break;
1223 case 4:
1224 #line 163 "./parsdate.y"
1225 	{
1226 	    yyHaveTime++;
1227 	    yyTimezone = yystack.l_mark[0].Number;
1228 	}
1229 break;
1230 case 5:
1231 #line 167 "./parsdate.y"
1232 	{
1233 	    yyHaveDate++;
1234 	}
1235 break;
1236 case 6:
1237 #line 170 "./parsdate.y"
1238 	{
1239 	    yyHaveDate++;
1240 	    yyHaveTime++;
1241 	}
1242 break;
1243 case 7:
1244 #line 174 "./parsdate.y"
1245 	{
1246 	    yyHaveDate++;
1247 	    yyHaveTime++;
1248 	    yyTimezone = yystack.l_mark[0].Number;
1249 	}
1250 break;
1251 case 8:
1252 #line 179 "./parsdate.y"
1253 	{
1254 	    yyHaveRel = 1;
1255 	}
1256 break;
1257 case 9:
1258 #line 184 "./parsdate.y"
1259 	{
1260 	    if (yystack.l_mark[-1].Number < 100) {
1261 		yyHour = yystack.l_mark[-1].Number;
1262 		yyMinutes = 0;
1263 	    }
1264 	    else {
1265 		yyHour = yystack.l_mark[-1].Number / 100;
1266 		yyMinutes = yystack.l_mark[-1].Number % 100;
1267 	    }
1268 	    yySeconds = 0;
1269 	    yyMeridian = yystack.l_mark[0].Meridian;
1270 	}
1271 break;
1272 case 10:
1273 #line 196 "./parsdate.y"
1274 	{
1275 	    yyHour = yystack.l_mark[-3].Number;
1276 	    yyMinutes = yystack.l_mark[-1].Number;
1277 	    yySeconds = 0;
1278 	    yyMeridian = yystack.l_mark[0].Meridian;
1279 	}
1280 break;
1281 case 11:
1282 #line 202 "./parsdate.y"
1283 	{
1284 	    yyHour = yystack.l_mark[-3].Number;
1285 	    yyMinutes = yystack.l_mark[-1].Number;
1286 	    yyTimezone = yystack.l_mark[0].Number;
1287 	    yyMeridian = MER24;
1288 	    yyDSTmode = DSToff;
1289 	}
1290 break;
1291 case 12:
1292 #line 209 "./parsdate.y"
1293 	{
1294 	    yyHour = yystack.l_mark[-5].Number;
1295 	    yyMinutes = yystack.l_mark[-3].Number;
1296 	    yySeconds = yystack.l_mark[-1].Number;
1297 	    yyMeridian = yystack.l_mark[0].Meridian;
1298 	}
1299 break;
1300 case 13:
1301 #line 215 "./parsdate.y"
1302 	{
1303 	    yyHour = yystack.l_mark[-5].Number;
1304 	    yyMinutes = yystack.l_mark[-3].Number;
1305 	    yySeconds = yystack.l_mark[-1].Number;
1306 	    yyTimezone = yystack.l_mark[0].Number;
1307 	    yyMeridian = MER24;
1308 	    yyDSTmode = DSToff;
1309 	}
1310 break;
1311 case 14:
1312 #line 225 "./parsdate.y"
1313 	{
1314 	    yyval.Number = yystack.l_mark[0].Number;
1315 	    yyDSTmode = DSToff;
1316 	}
1317 break;
1318 case 15:
1319 #line 229 "./parsdate.y"
1320 	{
1321 	    yyval.Number = yystack.l_mark[0].Number;
1322 	    yyDSTmode = DSTon;
1323 	}
1324 break;
1325 case 16:
1326 #line 233 "./parsdate.y"
1327 	{
1328 	    yyTimezone = yystack.l_mark[-1].Number;
1329 	    yyDSTmode = DSTon;
1330 	}
1331 break;
1332 case 17:
1333 #line 237 "./parsdate.y"
1334 	{
1335 	    /* Only allow "GMT+300" and "GMT-0800" */
1336 	    if (yystack.l_mark[-1].Number != 0) {
1337 		YYABORT;
1338 	    }
1339 	    yyval.Number = yystack.l_mark[0].Number;
1340 	    yyDSTmode = DSToff;
1341 	}
1342 break;
1343 case 18:
1344 #line 245 "./parsdate.y"
1345 	{
1346 	    yyval.Number = yystack.l_mark[0].Number;
1347 	    yyDSTmode = DSToff;
1348 	}
1349 break;
1350 case 19:
1351 #line 251 "./parsdate.y"
1352 	{
1353 	    int	i;
1354 
1355 	    /* Unix and GMT and numeric timezones -- a little confusing. */
1356 	    if ((int)yystack.l_mark[0].Number < 0) {
1357 		/* Don't work with negative modulus. */
1358 		yystack.l_mark[0].Number = -(int)yystack.l_mark[0].Number;
1359 		if (yystack.l_mark[0].Number > 9999 || (i = (int) (yystack.l_mark[0].Number % 100)) >= 60) {
1360 			YYABORT;
1361 		}
1362 		yyval.Number = (yystack.l_mark[0].Number / 100) * 60 + i;
1363 	    }
1364 	    else {
1365 		if (yystack.l_mark[0].Number > 9999 || (i = (int) (yystack.l_mark[0].Number % 100)) >= 60) {
1366 			YYABORT;
1367 		}
1368 		yyval.Number = -((yystack.l_mark[0].Number / 100) * 60 + i);
1369 	    }
1370 	}
1371 break;
1372 case 20:
1373 #line 272 "./parsdate.y"
1374 	{
1375 	    yyMonth = yystack.l_mark[-2].Number;
1376 	    yyDay = yystack.l_mark[0].Number;
1377 	}
1378 break;
1379 case 21:
1380 #line 276 "./parsdate.y"
1381 	{
1382 	    if (yystack.l_mark[-4].Number > 100) {
1383 		yyYear = yystack.l_mark[-4].Number;
1384 		yyMonth = yystack.l_mark[-2].Number;
1385 		yyDay = yystack.l_mark[0].Number;
1386 	    }
1387 	    else {
1388 		yyMonth = yystack.l_mark[-4].Number;
1389 		yyDay = yystack.l_mark[-2].Number;
1390 		yyYear = yystack.l_mark[0].Number;
1391 	    }
1392 	}
1393 break;
1394 case 22:
1395 #line 288 "./parsdate.y"
1396 	{
1397 	    yyMonth = yystack.l_mark[-1].Number;
1398 	    yyDay = yystack.l_mark[0].Number;
1399 	}
1400 break;
1401 case 23:
1402 #line 292 "./parsdate.y"
1403 	{
1404 	    yyMonth = yystack.l_mark[-3].Number;
1405 	    yyDay = yystack.l_mark[-2].Number;
1406 	    yyYear = yystack.l_mark[0].Number;
1407 	}
1408 break;
1409 case 24:
1410 #line 297 "./parsdate.y"
1411 	{
1412 	    yyDay = yystack.l_mark[-1].Number;
1413 	    yyMonth = yystack.l_mark[0].Number;
1414 	}
1415 break;
1416 case 25:
1417 #line 301 "./parsdate.y"
1418 	{
1419 	    yyDay = yystack.l_mark[-2].Number;
1420 	    yyMonth = yystack.l_mark[-1].Number;
1421 	    yyYear = yystack.l_mark[0].Number;
1422 	}
1423 break;
1424 case 26:
1425 #line 306 "./parsdate.y"
1426 	{
1427 	    yyDay = yystack.l_mark[-2].Number;
1428 	    yyMonth = yystack.l_mark[-1].Number;
1429 	    yyYear = yystack.l_mark[0].Number;
1430 	}
1431 break;
1432 case 27:
1433 #line 311 "./parsdate.y"
1434 	{
1435 	    yyDay = yystack.l_mark[-3].Number;
1436 	    yyMonth = yystack.l_mark[-1].Number;
1437 	    yyYear = -yystack.l_mark[0].Number;
1438 	}
1439 break;
1440 case 28:
1441 #line 316 "./parsdate.y"
1442 	{
1443 	    yyDay = yystack.l_mark[-2].Number;
1444 	    yyMonth = -yystack.l_mark[-1].Number;
1445 	    yyYear = -yystack.l_mark[0].Number;
1446 	    yyDSTmode = DSToff;	/* assume midnight if no time given */
1447 	    yyTimezone = 0;	/* Lynx assumes GMT for this format */
1448 	}
1449 break;
1450 case 29:
1451 #line 325 "./parsdate.y"
1452 	{
1453 	    yyMonth = yystack.l_mark[-7].Number;
1454 	    yyDay = yystack.l_mark[-6].Number;
1455 	    yyYear = yystack.l_mark[0].Number;
1456 	    yyHour = yystack.l_mark[-5].Number;
1457 	    yyMinutes = yystack.l_mark[-3].Number;
1458 	    yySeconds = yystack.l_mark[-1].Number;
1459 	}
1460 break;
1461 case 30:
1462 #line 335 "./parsdate.y"
1463 	{
1464 	    yyRelSeconds += yystack.l_mark[-1].Number * yystack.l_mark[0].Number;
1465 	}
1466 break;
1467 case 31:
1468 #line 338 "./parsdate.y"
1469 	{
1470 	    yyRelSeconds += yystack.l_mark[-1].Number * yystack.l_mark[0].Number;
1471 	}
1472 break;
1473 case 32:
1474 #line 341 "./parsdate.y"
1475 	{
1476 	    yyRelMonth += yystack.l_mark[-1].Number * yystack.l_mark[0].Number;
1477 	}
1478 break;
1479 case 33:
1480 #line 344 "./parsdate.y"
1481 	{
1482 	    yyRelMonth += yystack.l_mark[-1].Number * yystack.l_mark[0].Number;
1483 	}
1484 break;
1485 case 34:
1486 #line 349 "./parsdate.y"
1487 	{
1488 	    yyval.Meridian = MER24;
1489 	}
1490 break;
1491 case 35:
1492 #line 352 "./parsdate.y"
1493 	{
1494 	    yyval.Meridian = yystack.l_mark[0].Meridian;
1495 	}
1496 break;
1497 #line 1498 "y.tab.c"
1498     }
1499     yystack.s_mark -= yym;
1500     yystate = *yystack.s_mark;
1501     yystack.l_mark -= yym;
1502     yym = yylhs[yyn];
1503     if (yystate == 0 && yym == 0)
1504     {
1505 #if YYDEBUG
1506         if (yydebug)
1507             printf("%sdebug: after reduction, shifting from state 0 to\
1508  state %d\n", YYPREFIX, YYFINAL);
1509 #endif
1510         yystate = YYFINAL;
1511         *++yystack.s_mark = YYFINAL;
1512         *++yystack.l_mark = yyval;
1513         if (yychar < 0)
1514         {
1515             yychar = YYLEX;
1516             if (yychar < 0) yychar = YYEOF;
1517 #if YYDEBUG
1518             if (yydebug)
1519             {
1520                 if ((yys = yyname[YYTRANSLATE(yychar)]) == NULL) yys = yyname[YYUNDFTOKEN];
1521                 printf("%sdebug: state %d, reading %d (%s)\n",
1522                         YYPREFIX, YYFINAL, yychar, yys);
1523             }
1524 #endif
1525         }
1526         if (yychar == YYEOF) goto yyaccept;
1527         goto yyloop;
1528     }
1529     if (((yyn = yygindex[yym]) != 0) && (yyn += yystate) >= 0 &&
1530             yyn <= YYTABLESIZE && yycheck[yyn] == (YYINT) yystate)
1531         yystate = yytable[yyn];
1532     else
1533         yystate = yydgoto[yym];
1534 #if YYDEBUG
1535     if (yydebug)
1536         printf("%sdebug: after reduction, shifting from state %d \
1537 to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
1538 #endif
1539     if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
1540     *++yystack.s_mark = (YYINT) yystate;
1541     *++yystack.l_mark = yyval;
1542     goto yyloop;
1543 
1544 yyoverflow:
1545     YYERROR_CALL("yacc stack overflow");
1546 
1547 yyabort:
1548     yyfreestack(&yystack);
1549     return (1);
1550 
1551 yyaccept:
1552     yyfreestack(&yystack);
1553     return (0);
1554 }
1555