xref: /openbsd/gnu/usr.bin/cvs/lib/getdate.c (revision e79e3062)
1 
2 /*  A Bison parser, made from getdate.y
3     by GNU Bison version 1.28  */
4 
5 #define YYBISON 1  /* Identify Bison output.  */
6 
7 #define	tAGO	257
8 #define	tDAY	258
9 #define	tDAYZONE	259
10 #define	tID	260
11 #define	tMERIDIAN	261
12 #define	tMINUTE_UNIT	262
13 #define	tMONTH	263
14 #define	tMONTH_UNIT	264
15 #define	tSEC_UNIT	265
16 #define	tSNUMBER	266
17 #define	tUNUMBER	267
18 #define	tZONE	268
19 #define	tDST	269
20 
21 #line 1 "getdate.y"
22 
23 /*
24 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
25 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
26 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
27 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
28 **
29 **  This grammar has 10 shift/reduce conflicts.
30 **
31 **  This code is in the public domain and has no copyright.
32 */
33 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
34 /* SUPPRESS 288 on yyerrlab *//* Label unused */
35 
36 #ifdef HAVE_CONFIG_H
37 #if defined (emacs) || defined (CONFIG_BROKETS)
38 #include <config.h>
39 #else
40 #include "config.h"
41 #endif
42 #endif
43 
44 /* Since the code of getdate.y is not included in the Emacs executable
45    itself, there is no need to #define static in this file.  Even if
46    the code were included in the Emacs executable, it probably
47    wouldn't do any harm to #undef it here; this will only cause
48    problems if we try to write to a static variable, which I don't
49    think this code needs to do.  */
50 #ifdef emacs
51 #undef static
52 #endif
53 
54 #include <stdio.h>
55 #include <ctype.h>
56 
57 /* The code at the top of get_date which figures out the offset of the
58    current time zone checks various CPP symbols to see if special
59    tricks are need, but defaults to using the gettimeofday system call.
60    Include <sys/time.h> if that will be used.  */
61 
62 #if	defined(vms)
63 # include <types.h>
64 #else /* defined(vms) */
65 # include <sys/types.h>
66 # include "xtime.h"
67 #endif	/* !defined(vms) */
68 
69 #if defined (STDC_HEADERS) || defined (USG)
70 #include <string.h>
71 #endif
72 
73 /* Some old versions of bison generate parsers that use bcopy.
74    That loses on systems that don't provide the function, so we have
75    to redefine it here.  */
76 #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
77 #define bcopy(from, to, len) memcpy ((to), (from), (len))
78 #endif
79 
80 #if defined (STDC_HEADERS)
81 #include <stdlib.h>
82 #endif
83 
84 /* NOTES on rebuilding getdate.c (particularly for inclusion in CVS
85    releases):
86 
87    We don't want to mess with all the portability hassles of alloca.
88    In particular, most (all?) versions of bison will use alloca in
89    their parser.  If bison works on your system (e.g. it should work
90    with gcc), then go ahead and use it, but the more general solution
91    is to use byacc instead of bison, which should generate a portable
92    parser.  I played with adding "#define alloca dont_use_alloca", to
93    give an error if the parser generator uses alloca (and thus detect
94    unportable getdate.c's), but that seems to cause as many problems
95    as it solves.  */
96 
97 extern struct tm	*gmtime();
98 extern struct tm	*localtime();
99 
100 #define yyparse getdate_yyparse
101 #define yylex getdate_yylex
102 #define yyerror getdate_yyerror
103 
104 static int yyparse ();
105 static int yylex ();
106 static int yyerror ();
107 
108 #define EPOCH		1970
109 #define HOUR(x)		((time_t)(x) * 60)
110 #define SECSPERDAY	(24L * 60L * 60L)
111 
112 
113 /*
114 **  An entry in the lexical lookup table.
115 */
116 typedef struct _TABLE {
117     char	*name;
118     int		type;
119     time_t	value;
120 } TABLE;
121 
122 
123 /*
124 **  Daylight-savings mode:  on, off, or not yet known.
125 */
126 typedef enum _DSTMODE {
127     DSTon, DSToff, DSTmaybe
128 } DSTMODE;
129 
130 /*
131 **  Meridian:  am, pm, or 24-hour style.
132 */
133 typedef enum _MERIDIAN {
134     MERam, MERpm, MER24
135 } MERIDIAN;
136 
137 
138 /*
139 **  Global variables.  We could get rid of most of these by using a good
140 **  union as the yacc stack.  (This routine was originally written before
141 **  yacc had the %union construct.)  Maybe someday; right now we only use
142 **  the %union very rarely.
143 */
144 static char	*yyInput;
145 static DSTMODE	yyDSTmode;
146 static time_t	yyDayOrdinal;
147 static time_t	yyDayNumber;
148 static int	yyHaveDate;
149 static int	yyHaveDay;
150 static int	yyHaveRel;
151 static int	yyHaveTime;
152 static int	yyHaveZone;
153 static time_t	yyTimezone;
154 static time_t	yyDay;
155 static time_t	yyHour;
156 static time_t	yyMinutes;
157 static time_t	yyMonth;
158 static time_t	yySeconds;
159 static time_t	yyYear;
160 static MERIDIAN	yyMeridian;
161 static time_t	yyRelMonth;
162 static time_t	yyRelSeconds;
163 
164 
165 #line 145 "getdate.y"
166 typedef union {
167     time_t		Number;
168     enum _MERIDIAN	Meridian;
169 } YYSTYPE;
170 #include <stdio.h>
171 
172 #ifndef __cplusplus
173 #ifndef __STDC__
174 #define const
175 #endif
176 #endif
177 
178 
179 
180 #define	YYFINAL		52
181 #define	YYFLAG		-32768
182 #define	YYNTBASE	19
183 
184 #define YYTRANSLATE(x) ((unsigned)(x) <= 269 ? yytranslate[x] : 29)
185 
186 static const char yytranslate[] = {     0,
187      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
188      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
189      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
190      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
191      2,     2,     2,    17,     2,     2,    18,     2,     2,     2,
192      2,     2,     2,     2,     2,     2,     2,    16,     2,     2,
193      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
194      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
195      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
196      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
197      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
198      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
199      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
200      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
201      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
202      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
203      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
204      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
205      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
206      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
207      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
208      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
209      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
210      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
211      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
212      2,     2,     2,     2,     2,     1,     3,     4,     5,     6,
213      7,     8,     9,    10,    11,    12,    13,    14,    15
214 };
215 
216 #if YYDEBUG != 0
217 static const short yyprhs[] = {     0,
218      0,     1,     4,     6,     8,    10,    12,    14,    16,    19,
219     24,    29,    36,    43,    45,    47,    50,    52,    55,    58,
220     62,    68,    72,    76,    79,    84,    87,    91,    94,    96,
221     99,   102,   104,   107,   110,   112,   115,   118,   120,   122,
222    123
223 };
224 
225 static const short yyrhs[] = {    -1,
226     19,    20,     0,    21,     0,    22,     0,    24,     0,    23,
227      0,    25,     0,    27,     0,    13,     7,     0,    13,    16,
228     13,    28,     0,    13,    16,    13,    12,     0,    13,    16,
229     13,    16,    13,    28,     0,    13,    16,    13,    16,    13,
230     12,     0,    14,     0,     5,     0,    14,    15,     0,     4,
231      0,     4,    17,     0,    13,     4,     0,    13,    18,    13,
232      0,    13,    18,    13,    18,    13,     0,    13,    12,    12,
233      0,    13,     9,    12,     0,     9,    13,     0,     9,    13,
234     17,    13,     0,    13,     9,     0,    13,     9,    13,     0,
235     26,     3,     0,    26,     0,    13,     8,     0,    12,     8,
236      0,     8,     0,    12,    11,     0,    13,    11,     0,    11,
237      0,    12,    10,     0,    13,    10,     0,    10,     0,    13,
238      0,     0,     7,     0
239 };
240 
241 #endif
242 
243 #if YYDEBUG != 0
244 static const short yyrline[] = { 0,
245    159,   160,   163,   166,   169,   172,   175,   178,   181,   187,
246    193,   200,   206,   216,   220,   224,   231,   235,   239,   245,
247    249,   260,   266,   272,   276,   281,   285,   292,   296,   299,
248    302,   305,   308,   311,   314,   317,   320,   323,   328,   355,
249    358
250 };
251 #endif
252 
253 
254 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
255 
256 static const char * const yytname[] = {   "$","error","$undefined.","tAGO","tDAY",
257 "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
258 "tSNUMBER","tUNUMBER","tZONE","tDST","':'","','","'/'","spec","item","time",
259 "zone","day","date","rel","relunit","number","o_merid", NULL
260 };
261 #endif
262 
263 static const short yyr1[] = {     0,
264     19,    19,    20,    20,    20,    20,    20,    20,    21,    21,
265     21,    21,    21,    22,    22,    22,    23,    23,    23,    24,
266     24,    24,    24,    24,    24,    24,    24,    25,    25,    26,
267     26,    26,    26,    26,    26,    26,    26,    26,    27,    28,
268     28
269 };
270 
271 static const short yyr2[] = {     0,
272      0,     2,     1,     1,     1,     1,     1,     1,     2,     4,
273      4,     6,     6,     1,     1,     2,     1,     2,     2,     3,
274      5,     3,     3,     2,     4,     2,     3,     2,     1,     2,
275      2,     1,     2,     2,     1,     2,     2,     1,     1,     0,
276      1
277 };
278 
279 static const short yydefact[] = {     1,
280      0,    17,    15,    32,     0,    38,    35,     0,    39,    14,
281      2,     3,     4,     6,     5,     7,    29,     8,    18,    24,
282     31,    36,    33,    19,     9,    30,    26,    37,    34,     0,
283      0,     0,    16,    28,     0,    23,    27,    22,    40,    20,
284     25,    41,    11,     0,    10,     0,    40,    21,    13,    12,
285      0,     0
286 };
287 
288 static const short yydefgoto[] = {     1,
289     11,    12,    13,    14,    15,    16,    17,    18,    45
290 };
291 
292 static const short yypact[] = {-32768,
293      0,    -1,-32768,-32768,     4,-32768,-32768,    25,    11,    -8,
294 -32768,-32768,-32768,-32768,-32768,-32768,    21,-32768,-32768,     9,
295 -32768,-32768,-32768,-32768,-32768,-32768,   -10,-32768,-32768,    16,
296     19,    24,-32768,-32768,    26,-32768,-32768,-32768,    18,    13,
297 -32768,-32768,-32768,    27,-32768,    28,    -6,-32768,-32768,-32768,
298     38,-32768
299 };
300 
301 static const short yypgoto[] = {-32768,
302 -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    -5
303 };
304 
305 
306 #define	YYLAST		42
307 
308 
309 static const short yytable[] = {    51,
310     42,    36,    37,     2,     3,    49,    33,     4,     5,     6,
311      7,     8,     9,    10,    24,    19,    20,    25,    26,    27,
312     28,    29,    30,    34,    42,    35,    31,    38,    32,    43,
313     46,    39,    21,    44,    22,    23,    40,    52,    41,    47,
314     48,    50
315 };
316 
317 static const short yycheck[] = {     0,
318      7,    12,    13,     4,     5,    12,    15,     8,     9,    10,
319     11,    12,    13,    14,     4,    17,    13,     7,     8,     9,
320     10,    11,    12,     3,     7,    17,    16,    12,    18,    12,
321     18,    13,     8,    16,    10,    11,    13,     0,    13,    13,
322     13,    47
323 };
324 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
325 #line 3 "/usr/lib/bison.simple"
326 /* This file comes from bison-1.28.  */
327 
328 /* Skeleton output parser for bison,
329    Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
330 
331    This program is free software; you can redistribute it and/or modify
332    it under the terms of the GNU General Public License as published by
333    the Free Software Foundation; either version 2, or (at your option)
334    any later version.
335 
336    This program is distributed in the hope that it will be useful,
337    but WITHOUT ANY WARRANTY; without even the implied warranty of
338    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
339    GNU General Public License for more details.
340 
341    You should have received a copy of the GNU General Public License
342    along with this program; if not, write to the Free Software
343    Foundation, Inc., 59 Temple Place - Suite 330,
344    Boston, MA 02111-1307, USA.  */
345 
346 /* As a special exception, when this file is copied by Bison into a
347    Bison output file, you may use that output file without restriction.
348    This special exception was added by the Free Software Foundation
349    in version 1.24 of Bison.  */
350 
351 /* This is the parser code that is written into each bison parser
352   when the %semantic_parser declaration is not specified in the grammar.
353   It was written by Richard Stallman by simplifying the hairy parser
354   used when %semantic_parser is specified.  */
355 
356 #ifndef YYSTACK_USE_ALLOCA
357 #ifdef alloca
358 #define YYSTACK_USE_ALLOCA
359 #else /* alloca not defined */
360 #ifdef __GNUC__
361 #define YYSTACK_USE_ALLOCA
362 #define alloca __builtin_alloca
363 #else /* not GNU C.  */
364 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
365 #define YYSTACK_USE_ALLOCA
366 #include <alloca.h>
367 #else /* not sparc */
368 /* We think this test detects Watcom and Microsoft C.  */
369 /* This used to test MSDOS, but that is a bad idea
370    since that symbol is in the user namespace.  */
371 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
372 #if 0 /* No need for malloc.h, which pollutes the namespace;
373 	 instead, just don't use alloca.  */
374 #include <malloc.h>
375 #endif
376 #else /* not MSDOS, or __TURBOC__ */
377 #if defined(_AIX)
378 /* I don't know what this was needed for, but it pollutes the namespace.
379    So I turned it off.   rms, 2 May 1997.  */
380 /* #include <malloc.h>  */
381  #pragma alloca
382 #define YYSTACK_USE_ALLOCA
383 #else /* not MSDOS, or __TURBOC__, or _AIX */
384 #if 0
385 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
386 		 and on HPUX 10.  Eventually we can turn this on.  */
387 #define YYSTACK_USE_ALLOCA
388 #define alloca __builtin_alloca
389 #endif /* __hpux */
390 #endif
391 #endif /* not _AIX */
392 #endif /* not MSDOS, or __TURBOC__ */
393 #endif /* not sparc */
394 #endif /* not GNU C */
395 #endif /* alloca not defined */
396 #endif /* YYSTACK_USE_ALLOCA not defined */
397 
398 #ifdef YYSTACK_USE_ALLOCA
399 #define YYSTACK_ALLOC alloca
400 #else
401 #define YYSTACK_ALLOC malloc
402 #endif
403 
404 /* Note: there must be only one dollar sign in this file.
405    It is replaced by the list of actions, each action
406    as one case of the switch.  */
407 
408 #define yyerrok		(yyerrstatus = 0)
409 #define yyclearin	(yychar = YYEMPTY)
410 #define YYEMPTY		-2
411 #define YYEOF		0
412 #define YYACCEPT	goto yyacceptlab
413 #define YYABORT 	goto yyabortlab
414 #define YYERROR		goto yyerrlab1
415 /* Like YYERROR except do call yyerror.
416    This remains here temporarily to ease the
417    transition to the new meaning of YYERROR, for GCC.
418    Once GCC version 2 has supplanted version 1, this can go.  */
419 #define YYFAIL		goto yyerrlab
420 #define YYRECOVERING()  (!!yyerrstatus)
421 #define YYBACKUP(token, value) \
422 do								\
423   if (yychar == YYEMPTY && yylen == 1)				\
424     { yychar = (token), yylval = (value);			\
425       yychar1 = YYTRANSLATE (yychar);				\
426       YYPOPSTACK;						\
427       goto yybackup;						\
428     }								\
429   else								\
430     { yyerror ("syntax error: cannot back up"); YYERROR; }	\
431 while (0)
432 
433 #define YYTERROR	1
434 #define YYERRCODE	256
435 
436 #ifndef YYPURE
437 #define YYLEX		yylex()
438 #endif
439 
440 #ifdef YYPURE
441 #ifdef YYLSP_NEEDED
442 #ifdef YYLEX_PARAM
443 #define YYLEX		yylex(&yylval, &yylloc, YYLEX_PARAM)
444 #else
445 #define YYLEX		yylex(&yylval, &yylloc)
446 #endif
447 #else /* not YYLSP_NEEDED */
448 #ifdef YYLEX_PARAM
449 #define YYLEX		yylex(&yylval, YYLEX_PARAM)
450 #else
451 #define YYLEX		yylex(&yylval)
452 #endif
453 #endif /* not YYLSP_NEEDED */
454 #endif
455 
456 /* If nonreentrant, generate the variables here */
457 
458 #ifndef YYPURE
459 
460 int	yychar;			/*  the lookahead symbol		*/
461 YYSTYPE	yylval;			/*  the semantic value of the		*/
462 				/*  lookahead symbol			*/
463 
464 #ifdef YYLSP_NEEDED
465 YYLTYPE yylloc;			/*  location data for the lookahead	*/
466 				/*  symbol				*/
467 #endif
468 
469 int yynerrs;			/*  number of parse errors so far       */
470 #endif  /* not YYPURE */
471 
472 #if YYDEBUG != 0
473 int yydebug;			/*  nonzero means print parse trace	*/
474 /* Since this is uninitialized, it does not stop multiple parsers
475    from coexisting.  */
476 #endif
477 
478 /*  YYINITDEPTH indicates the initial size of the parser's stacks	*/
479 
480 #ifndef	YYINITDEPTH
481 #define YYINITDEPTH 200
482 #endif
483 
484 /*  YYMAXDEPTH is the maximum size the stacks can grow to
485     (effective only if the built-in stack extension method is used).  */
486 
487 #if YYMAXDEPTH == 0
488 #undef YYMAXDEPTH
489 #endif
490 
491 #ifndef YYMAXDEPTH
492 #define YYMAXDEPTH 10000
493 #endif
494 
495 /* Define __yy_memcpy.  Note that the size argument
496    should be passed with type unsigned int, because that is what the non-GCC
497    definitions require.  With GCC, __builtin_memcpy takes an arg
498    of type size_t, but it can handle unsigned int.  */
499 
500 #if __GNUC__ > 1		/* GNU C and GNU C++ define this.  */
501 #define __yy_memcpy(TO,FROM,COUNT)	__builtin_memcpy(TO,FROM,COUNT)
502 #else				/* not GNU C or C++ */
503 #ifndef __cplusplus
504 
505 /* This is the most reliable way to avoid incompatibilities
506    in available built-in functions on various systems.  */
507 static void
__yy_memcpy(to,from,count)508 __yy_memcpy (to, from, count)
509      char *to;
510      char *from;
511      unsigned int count;
512 {
513   register char *f = from;
514   register char *t = to;
515   register int i = count;
516 
517   while (i-- > 0)
518     *t++ = *f++;
519 }
520 
521 #else /* __cplusplus */
522 
523 /* This is the most reliable way to avoid incompatibilities
524    in available built-in functions on various systems.  */
525 static void
__yy_memcpy(char * to,char * from,unsigned int count)526 __yy_memcpy (char *to, char *from, unsigned int count)
527 {
528   register char *t = to;
529   register char *f = from;
530   register int i = count;
531 
532   while (i-- > 0)
533     *t++ = *f++;
534 }
535 
536 #endif
537 #endif
538 
539 #line 217 "/usr/lib/bison.simple"
540 
541 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
542    into yyparse.  The argument should have type void *.
543    It should actually point to an object.
544    Grammar actions can access the variable by casting it
545    to the proper pointer type.  */
546 
547 #ifdef YYPARSE_PARAM
548 #ifdef __cplusplus
549 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
550 #define YYPARSE_PARAM_DECL
551 #else /* not __cplusplus */
552 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
553 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
554 #endif /* not __cplusplus */
555 #else /* not YYPARSE_PARAM */
556 #define YYPARSE_PARAM_ARG
557 #define YYPARSE_PARAM_DECL
558 #endif /* not YYPARSE_PARAM */
559 
560 /* Prevent warning if -Wstrict-prototypes.  */
561 #ifdef __GNUC__
562 #ifdef YYPARSE_PARAM
563 int yyparse (void *);
564 #else
565 int yyparse (void);
566 #endif
567 #endif
568 
569 int
yyparse(YYPARSE_PARAM_ARG)570 yyparse(YYPARSE_PARAM_ARG)
571      YYPARSE_PARAM_DECL
572 {
573   register int yystate;
574   register int yyn;
575   register short *yyssp;
576   register YYSTYPE *yyvsp;
577   int yyerrstatus;	/*  number of tokens to shift before error messages enabled */
578   int yychar1 = 0;		/*  lookahead token as an internal (translated) token number */
579 
580   short	yyssa[YYINITDEPTH];	/*  the state stack			*/
581   YYSTYPE yyvsa[YYINITDEPTH];	/*  the semantic value stack		*/
582 
583   short *yyss = yyssa;		/*  refer to the stacks thru separate pointers */
584   YYSTYPE *yyvs = yyvsa;	/*  to allow yyoverflow to reallocate them elsewhere */
585 
586 #ifdef YYLSP_NEEDED
587   YYLTYPE yylsa[YYINITDEPTH];	/*  the location stack			*/
588   YYLTYPE *yyls = yylsa;
589   YYLTYPE *yylsp;
590 
591 #define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
592 #else
593 #define YYPOPSTACK   (yyvsp--, yyssp--)
594 #endif
595 
596   int yystacksize = YYINITDEPTH;
597   int yyfree_stacks = 0;
598 
599 #ifdef YYPURE
600   int yychar;
601   YYSTYPE yylval;
602   int yynerrs;
603 #ifdef YYLSP_NEEDED
604   YYLTYPE yylloc;
605 #endif
606 #endif
607 
608   YYSTYPE yyval;		/*  the variable used to return		*/
609 				/*  semantic values from the action	*/
610 				/*  routines				*/
611 
612   int yylen;
613 
614 #if YYDEBUG != 0
615   if (yydebug)
616     fprintf(stderr, "Starting parse\n");
617 #endif
618 
619   yystate = 0;
620   yyerrstatus = 0;
621   yynerrs = 0;
622   yychar = YYEMPTY;		/* Cause a token to be read.  */
623 
624   /* Initialize stack pointers.
625      Waste one element of value and location stack
626      so that they stay on the same level as the state stack.
627      The wasted elements are never initialized.  */
628 
629   yyssp = yyss - 1;
630   yyvsp = yyvs;
631 #ifdef YYLSP_NEEDED
632   yylsp = yyls;
633 #endif
634 
635 /* Push a new state, which is found in  yystate  .  */
636 /* In all cases, when you get here, the value and location stacks
637    have just been pushed. so pushing a state here evens the stacks.  */
638 yynewstate:
639 
640   *++yyssp = yystate;
641 
642   if (yyssp >= yyss + yystacksize - 1)
643     {
644       /* Give user a chance to reallocate the stack */
645       /* Use copies of these so that the &'s don't force the real ones into memory. */
646       YYSTYPE *yyvs1 = yyvs;
647       short *yyss1 = yyss;
648 #ifdef YYLSP_NEEDED
649       YYLTYPE *yyls1 = yyls;
650 #endif
651 
652       /* Get the current used size of the three stacks, in elements.  */
653       int size = yyssp - yyss + 1;
654 
655 #ifdef yyoverflow
656       /* Each stack pointer address is followed by the size of
657 	 the data in use in that stack, in bytes.  */
658 #ifdef YYLSP_NEEDED
659       /* This used to be a conditional around just the two extra args,
660 	 but that might be undefined if yyoverflow is a macro.  */
661       yyoverflow("parser stack overflow",
662 		 &yyss1, size * sizeof (*yyssp),
663 		 &yyvs1, size * sizeof (*yyvsp),
664 		 &yyls1, size * sizeof (*yylsp),
665 		 &yystacksize);
666 #else
667       yyoverflow("parser stack overflow",
668 		 &yyss1, size * sizeof (*yyssp),
669 		 &yyvs1, size * sizeof (*yyvsp),
670 		 &yystacksize);
671 #endif
672 
673       yyss = yyss1; yyvs = yyvs1;
674 #ifdef YYLSP_NEEDED
675       yyls = yyls1;
676 #endif
677 #else /* no yyoverflow */
678       /* Extend the stack our own way.  */
679       if (yystacksize >= YYMAXDEPTH)
680 	{
681 	  yyerror("parser stack overflow");
682 	  if (yyfree_stacks)
683 	    {
684 	      free (yyss);
685 	      free (yyvs);
686 #ifdef YYLSP_NEEDED
687 	      free (yyls);
688 #endif
689 	    }
690 	  return 2;
691 	}
692       yystacksize *= 2;
693       if (yystacksize > YYMAXDEPTH)
694 	yystacksize = YYMAXDEPTH;
695 #ifndef YYSTACK_USE_ALLOCA
696       yyfree_stacks = 1;
697 #endif
698       yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
699       __yy_memcpy ((char *)yyss, (char *)yyss1,
700 		   size * (unsigned int) sizeof (*yyssp));
701       yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
702       __yy_memcpy ((char *)yyvs, (char *)yyvs1,
703 		   size * (unsigned int) sizeof (*yyvsp));
704 #ifdef YYLSP_NEEDED
705       yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
706       __yy_memcpy ((char *)yyls, (char *)yyls1,
707 		   size * (unsigned int) sizeof (*yylsp));
708 #endif
709 #endif /* no yyoverflow */
710 
711       yyssp = yyss + size - 1;
712       yyvsp = yyvs + size - 1;
713 #ifdef YYLSP_NEEDED
714       yylsp = yyls + size - 1;
715 #endif
716 
717 #if YYDEBUG != 0
718       if (yydebug)
719 	fprintf(stderr, "Stack size increased to %d\n", yystacksize);
720 #endif
721 
722       if (yyssp >= yyss + yystacksize - 1)
723 	YYABORT;
724     }
725 
726 #if YYDEBUG != 0
727   if (yydebug)
728     fprintf(stderr, "Entering state %d\n", yystate);
729 #endif
730 
731   goto yybackup;
732  yybackup:
733 
734 /* Do appropriate processing given the current state.  */
735 /* Read a lookahead token if we need one and don't already have one.  */
736 /* yyresume: */
737 
738   /* First try to decide what to do without reference to lookahead token.  */
739 
740   yyn = yypact[yystate];
741   if (yyn == YYFLAG)
742     goto yydefault;
743 
744   /* Not known => get a lookahead token if don't already have one.  */
745 
746   /* yychar is either YYEMPTY or YYEOF
747      or a valid token in external form.  */
748 
749   if (yychar == YYEMPTY)
750     {
751 #if YYDEBUG != 0
752       if (yydebug)
753 	fprintf(stderr, "Reading a token: ");
754 #endif
755       yychar = YYLEX;
756     }
757 
758   /* Convert token to internal form (in yychar1) for indexing tables with */
759 
760   if (yychar <= 0)		/* This means end of input. */
761     {
762       yychar1 = 0;
763       yychar = YYEOF;		/* Don't call YYLEX any more */
764 
765 #if YYDEBUG != 0
766       if (yydebug)
767 	fprintf(stderr, "Now at end of input.\n");
768 #endif
769     }
770   else
771     {
772       yychar1 = YYTRANSLATE(yychar);
773 
774 #if YYDEBUG != 0
775       if (yydebug)
776 	{
777 	  fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
778 	  /* Give the individual parser a way to print the precise meaning
779 	     of a token, for further debugging info.  */
780 #ifdef YYPRINT
781 	  YYPRINT (stderr, yychar, yylval);
782 #endif
783 	  fprintf (stderr, ")\n");
784 	}
785 #endif
786     }
787 
788   yyn += yychar1;
789   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
790     goto yydefault;
791 
792   yyn = yytable[yyn];
793 
794   /* yyn is what to do for this token type in this state.
795      Negative => reduce, -yyn is rule number.
796      Positive => shift, yyn is new state.
797        New state is final state => don't bother to shift,
798        just return success.
799      0, or most negative number => error.  */
800 
801   if (yyn < 0)
802     {
803       if (yyn == YYFLAG)
804 	goto yyerrlab;
805       yyn = -yyn;
806       goto yyreduce;
807     }
808   else if (yyn == 0)
809     goto yyerrlab;
810 
811   if (yyn == YYFINAL)
812     YYACCEPT;
813 
814   /* Shift the lookahead token.  */
815 
816 #if YYDEBUG != 0
817   if (yydebug)
818     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
819 #endif
820 
821   /* Discard the token being shifted unless it is eof.  */
822   if (yychar != YYEOF)
823     yychar = YYEMPTY;
824 
825   *++yyvsp = yylval;
826 #ifdef YYLSP_NEEDED
827   *++yylsp = yylloc;
828 #endif
829 
830   /* count tokens shifted since error; after three, turn off error status.  */
831   if (yyerrstatus) yyerrstatus--;
832 
833   yystate = yyn;
834   goto yynewstate;
835 
836 /* Do the default action for the current state.  */
837 yydefault:
838 
839   yyn = yydefact[yystate];
840   if (yyn == 0)
841     goto yyerrlab;
842 
843 /* Do a reduction.  yyn is the number of a rule to reduce with.  */
844 yyreduce:
845   yylen = yyr2[yyn];
846   if (yylen > 0)
847     yyval = yyvsp[1-yylen]; /* implement default value of the action */
848 
849 #if YYDEBUG != 0
850   if (yydebug)
851     {
852       int i;
853 
854       fprintf (stderr, "Reducing via rule %d (line %d), ",
855 	       yyn, yyrline[yyn]);
856 
857       /* Print the symbols being reduced, and their result.  */
858       for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
859 	fprintf (stderr, "%s ", yytname[yyrhs[i]]);
860       fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
861     }
862 #endif
863 
864 
865   switch (yyn) {
866 
867 case 3:
868 #line 163 "getdate.y"
869 {
870 	    yyHaveTime++;
871 	;
872     break;}
873 case 4:
874 #line 166 "getdate.y"
875 {
876 	    yyHaveZone++;
877 	;
878     break;}
879 case 5:
880 #line 169 "getdate.y"
881 {
882 	    yyHaveDate++;
883 	;
884     break;}
885 case 6:
886 #line 172 "getdate.y"
887 {
888 	    yyHaveDay++;
889 	;
890     break;}
891 case 7:
892 #line 175 "getdate.y"
893 {
894 	    yyHaveRel++;
895 	;
896     break;}
897 case 9:
898 #line 181 "getdate.y"
899 {
900 	    yyHour = yyvsp[-1].Number;
901 	    yyMinutes = 0;
902 	    yySeconds = 0;
903 	    yyMeridian = yyvsp[0].Meridian;
904 	;
905     break;}
906 case 10:
907 #line 187 "getdate.y"
908 {
909 	    yyHour = yyvsp[-3].Number;
910 	    yyMinutes = yyvsp[-1].Number;
911 	    yySeconds = 0;
912 	    yyMeridian = yyvsp[0].Meridian;
913 	;
914     break;}
915 case 11:
916 #line 193 "getdate.y"
917 {
918 	    yyHour = yyvsp[-3].Number;
919 	    yyMinutes = yyvsp[-1].Number;
920 	    yyMeridian = MER24;
921 	    yyDSTmode = DSToff;
922 	    yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
923 	;
924     break;}
925 case 12:
926 #line 200 "getdate.y"
927 {
928 	    yyHour = yyvsp[-5].Number;
929 	    yyMinutes = yyvsp[-3].Number;
930 	    yySeconds = yyvsp[-1].Number;
931 	    yyMeridian = yyvsp[0].Meridian;
932 	;
933     break;}
934 case 13:
935 #line 206 "getdate.y"
936 {
937 	    yyHour = yyvsp[-5].Number;
938 	    yyMinutes = yyvsp[-3].Number;
939 	    yySeconds = yyvsp[-1].Number;
940 	    yyMeridian = MER24;
941 	    yyDSTmode = DSToff;
942 	    yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
943 	;
944     break;}
945 case 14:
946 #line 216 "getdate.y"
947 {
948 	    yyTimezone = yyvsp[0].Number;
949 	    yyDSTmode = DSToff;
950 	;
951     break;}
952 case 15:
953 #line 220 "getdate.y"
954 {
955 	    yyTimezone = yyvsp[0].Number;
956 	    yyDSTmode = DSTon;
957 	;
958     break;}
959 case 16:
960 #line 225 "getdate.y"
961 {
962 	    yyTimezone = yyvsp[-1].Number;
963 	    yyDSTmode = DSTon;
964 	;
965     break;}
966 case 17:
967 #line 231 "getdate.y"
968 {
969 	    yyDayOrdinal = 1;
970 	    yyDayNumber = yyvsp[0].Number;
971 	;
972     break;}
973 case 18:
974 #line 235 "getdate.y"
975 {
976 	    yyDayOrdinal = 1;
977 	    yyDayNumber = yyvsp[-1].Number;
978 	;
979     break;}
980 case 19:
981 #line 239 "getdate.y"
982 {
983 	    yyDayOrdinal = yyvsp[-1].Number;
984 	    yyDayNumber = yyvsp[0].Number;
985 	;
986     break;}
987 case 20:
988 #line 245 "getdate.y"
989 {
990 	    yyMonth = yyvsp[-2].Number;
991 	    yyDay = yyvsp[0].Number;
992 	;
993     break;}
994 case 21:
995 #line 249 "getdate.y"
996 {
997 	    if (yyvsp[-4].Number >= 100) {
998 		yyYear = yyvsp[-4].Number;
999 		yyMonth = yyvsp[-2].Number;
1000 		yyDay = yyvsp[0].Number;
1001 	    } else {
1002 		yyMonth = yyvsp[-4].Number;
1003 		yyDay = yyvsp[-2].Number;
1004 		yyYear = yyvsp[0].Number;
1005 	    }
1006 	;
1007     break;}
1008 case 22:
1009 #line 260 "getdate.y"
1010 {
1011 	    /* ISO 8601 format.  yyyy-mm-dd.  */
1012 	    yyYear = yyvsp[-2].Number;
1013 	    yyMonth = -yyvsp[-1].Number;
1014 	    yyDay = -yyvsp[0].Number;
1015 	;
1016     break;}
1017 case 23:
1018 #line 266 "getdate.y"
1019 {
1020 	    /* e.g. 17-JUN-1992.  */
1021 	    yyDay = yyvsp[-2].Number;
1022 	    yyMonth = yyvsp[-1].Number;
1023 	    yyYear = -yyvsp[0].Number;
1024 	;
1025     break;}
1026 case 24:
1027 #line 272 "getdate.y"
1028 {
1029 	    yyMonth = yyvsp[-1].Number;
1030 	    yyDay = yyvsp[0].Number;
1031 	;
1032     break;}
1033 case 25:
1034 #line 276 "getdate.y"
1035 {
1036 	    yyMonth = yyvsp[-3].Number;
1037 	    yyDay = yyvsp[-2].Number;
1038 	    yyYear = yyvsp[0].Number;
1039 	;
1040     break;}
1041 case 26:
1042 #line 281 "getdate.y"
1043 {
1044 	    yyMonth = yyvsp[0].Number;
1045 	    yyDay = yyvsp[-1].Number;
1046 	;
1047     break;}
1048 case 27:
1049 #line 285 "getdate.y"
1050 {
1051 	    yyMonth = yyvsp[-1].Number;
1052 	    yyDay = yyvsp[-2].Number;
1053 	    yyYear = yyvsp[0].Number;
1054 	;
1055     break;}
1056 case 28:
1057 #line 292 "getdate.y"
1058 {
1059 	    yyRelSeconds = -yyRelSeconds;
1060 	    yyRelMonth = -yyRelMonth;
1061 	;
1062     break;}
1063 case 30:
1064 #line 299 "getdate.y"
1065 {
1066 	    yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1067 	;
1068     break;}
1069 case 31:
1070 #line 302 "getdate.y"
1071 {
1072 	    yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
1073 	;
1074     break;}
1075 case 32:
1076 #line 305 "getdate.y"
1077 {
1078 	    yyRelSeconds += yyvsp[0].Number * 60L;
1079 	;
1080     break;}
1081 case 33:
1082 #line 308 "getdate.y"
1083 {
1084 	    yyRelSeconds += yyvsp[-1].Number;
1085 	;
1086     break;}
1087 case 34:
1088 #line 311 "getdate.y"
1089 {
1090 	    yyRelSeconds += yyvsp[-1].Number;
1091 	;
1092     break;}
1093 case 35:
1094 #line 314 "getdate.y"
1095 {
1096 	    yyRelSeconds++;
1097 	;
1098     break;}
1099 case 36:
1100 #line 317 "getdate.y"
1101 {
1102 	    yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1103 	;
1104     break;}
1105 case 37:
1106 #line 320 "getdate.y"
1107 {
1108 	    yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
1109 	;
1110     break;}
1111 case 38:
1112 #line 323 "getdate.y"
1113 {
1114 	    yyRelMonth += yyvsp[0].Number;
1115 	;
1116     break;}
1117 case 39:
1118 #line 328 "getdate.y"
1119 {
1120 	    if (yyHaveTime && yyHaveDate && !yyHaveRel)
1121 		yyYear = yyvsp[0].Number;
1122 	    else {
1123 		if(yyvsp[0].Number>10000) {
1124 		    yyHaveDate++;
1125 		    yyDay= (yyvsp[0].Number)%100;
1126 		    yyMonth= (yyvsp[0].Number/100)%100;
1127 		    yyYear = yyvsp[0].Number/10000;
1128 		}
1129 		else {
1130 		    yyHaveTime++;
1131 		    if (yyvsp[0].Number < 100) {
1132 			yyHour = yyvsp[0].Number;
1133 			yyMinutes = 0;
1134 		    }
1135 		    else {
1136 		    	yyHour = yyvsp[0].Number / 100;
1137 		    	yyMinutes = yyvsp[0].Number % 100;
1138 		    }
1139 		    yySeconds = 0;
1140 		    yyMeridian = MER24;
1141 	        }
1142 	    }
1143 	;
1144     break;}
1145 case 40:
1146 #line 355 "getdate.y"
1147 {
1148 	    yyval.Meridian = MER24;
1149 	;
1150     break;}
1151 case 41:
1152 #line 358 "getdate.y"
1153 {
1154 	    yyval.Meridian = yyvsp[0].Meridian;
1155 	;
1156     break;}
1157 }
1158    /* the action file gets copied in in place of this dollarsign */
1159 #line 543 "/usr/lib/bison.simple"
1160 
1161   yyvsp -= yylen;
1162   yyssp -= yylen;
1163 #ifdef YYLSP_NEEDED
1164   yylsp -= yylen;
1165 #endif
1166 
1167 #if YYDEBUG != 0
1168   if (yydebug)
1169     {
1170       short *ssp1 = yyss - 1;
1171       fprintf (stderr, "state stack now");
1172       while (ssp1 != yyssp)
1173 	fprintf (stderr, " %d", *++ssp1);
1174       fprintf (stderr, "\n");
1175     }
1176 #endif
1177 
1178   *++yyvsp = yyval;
1179 
1180 #ifdef YYLSP_NEEDED
1181   yylsp++;
1182   if (yylen == 0)
1183     {
1184       yylsp->first_line = yylloc.first_line;
1185       yylsp->first_column = yylloc.first_column;
1186       yylsp->last_line = (yylsp-1)->last_line;
1187       yylsp->last_column = (yylsp-1)->last_column;
1188       yylsp->text = 0;
1189     }
1190   else
1191     {
1192       yylsp->last_line = (yylsp+yylen-1)->last_line;
1193       yylsp->last_column = (yylsp+yylen-1)->last_column;
1194     }
1195 #endif
1196 
1197   /* Now "shift" the result of the reduction.
1198      Determine what state that goes to,
1199      based on the state we popped back to
1200      and the rule number reduced by.  */
1201 
1202   yyn = yyr1[yyn];
1203 
1204   yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1205   if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1206     yystate = yytable[yystate];
1207   else
1208     yystate = yydefgoto[yyn - YYNTBASE];
1209 
1210   goto yynewstate;
1211 
1212 yyerrlab:   /* here on detecting error */
1213 
1214   if (! yyerrstatus)
1215     /* If not already recovering from an error, report this error.  */
1216     {
1217       ++yynerrs;
1218 
1219 #ifdef YYERROR_VERBOSE
1220       yyn = yypact[yystate];
1221 
1222       if (yyn > YYFLAG && yyn < YYLAST)
1223 	{
1224 	  int size = 0;
1225 	  char *msg;
1226 	  int x, count;
1227 
1228 	  count = 0;
1229 	  /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
1230 	  for (x = (yyn < 0 ? -yyn : 0);
1231 	       x < (sizeof(yytname) / sizeof(char *)); x++)
1232 	    if (yycheck[x + yyn] == x)
1233 	      size += strlen(yytname[x]) + 15, count++;
1234 	  msg = (char *) malloc(size + 15);
1235 	  if (msg != 0)
1236 	    {
1237 	      strcpy(msg, "parse error");
1238 
1239 	      if (count < 5)
1240 		{
1241 		  count = 0;
1242 		  for (x = (yyn < 0 ? -yyn : 0);
1243 		       x < (sizeof(yytname) / sizeof(char *)); x++)
1244 		    if (yycheck[x + yyn] == x)
1245 		      {
1246 			strcat(msg, count == 0 ? ", expecting `" : " or `");
1247 			strcat(msg, yytname[x]);
1248 			strcat(msg, "'");
1249 			count++;
1250 		      }
1251 		}
1252 	      yyerror(msg);
1253 	      free(msg);
1254 	    }
1255 	  else
1256 	    yyerror ("parse error; also virtual memory exceeded");
1257 	}
1258       else
1259 #endif /* YYERROR_VERBOSE */
1260 	yyerror("parse error");
1261     }
1262 
1263   goto yyerrlab1;
1264 yyerrlab1:   /* here on error raised explicitly by an action */
1265 
1266   if (yyerrstatus == 3)
1267     {
1268       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
1269 
1270       /* return failure if at end of input */
1271       if (yychar == YYEOF)
1272 	YYABORT;
1273 
1274 #if YYDEBUG != 0
1275       if (yydebug)
1276 	fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1277 #endif
1278 
1279       yychar = YYEMPTY;
1280     }
1281 
1282   /* Else will try to reuse lookahead token
1283      after shifting the error token.  */
1284 
1285   yyerrstatus = 3;		/* Each real token shifted decrements this */
1286 
1287   goto yyerrhandle;
1288 
1289 yyerrdefault:  /* current state does not do anything special for the error token. */
1290 
1291 #if 0
1292   /* This is wrong; only states that explicitly want error tokens
1293      should shift them.  */
1294   yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
1295   if (yyn) goto yydefault;
1296 #endif
1297 
1298 yyerrpop:   /* pop the current state because it cannot handle the error token */
1299 
1300   if (yyssp == yyss) YYABORT;
1301   yyvsp--;
1302   yystate = *--yyssp;
1303 #ifdef YYLSP_NEEDED
1304   yylsp--;
1305 #endif
1306 
1307 #if YYDEBUG != 0
1308   if (yydebug)
1309     {
1310       short *ssp1 = yyss - 1;
1311       fprintf (stderr, "Error: state stack now");
1312       while (ssp1 != yyssp)
1313 	fprintf (stderr, " %d", *++ssp1);
1314       fprintf (stderr, "\n");
1315     }
1316 #endif
1317 
1318 yyerrhandle:
1319 
1320   yyn = yypact[yystate];
1321   if (yyn == YYFLAG)
1322     goto yyerrdefault;
1323 
1324   yyn += YYTERROR;
1325   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1326     goto yyerrdefault;
1327 
1328   yyn = yytable[yyn];
1329   if (yyn < 0)
1330     {
1331       if (yyn == YYFLAG)
1332 	goto yyerrpop;
1333       yyn = -yyn;
1334       goto yyreduce;
1335     }
1336   else if (yyn == 0)
1337     goto yyerrpop;
1338 
1339   if (yyn == YYFINAL)
1340     YYACCEPT;
1341 
1342 #if YYDEBUG != 0
1343   if (yydebug)
1344     fprintf(stderr, "Shifting error token, ");
1345 #endif
1346 
1347   *++yyvsp = yylval;
1348 #ifdef YYLSP_NEEDED
1349   *++yylsp = yylloc;
1350 #endif
1351 
1352   yystate = yyn;
1353   goto yynewstate;
1354 
1355  yyacceptlab:
1356   /* YYACCEPT comes here.  */
1357   if (yyfree_stacks)
1358     {
1359       free (yyss);
1360       free (yyvs);
1361 #ifdef YYLSP_NEEDED
1362       free (yyls);
1363 #endif
1364     }
1365   return 0;
1366 
1367  yyabortlab:
1368   /* YYABORT comes here.  */
1369   if (yyfree_stacks)
1370     {
1371       free (yyss);
1372       free (yyvs);
1373 #ifdef YYLSP_NEEDED
1374       free (yyls);
1375 #endif
1376     }
1377   return 1;
1378 }
1379 #line 363 "getdate.y"
1380 
1381 
1382 /* Month and day table. */
1383 static TABLE const MonthDayTable[] = {
1384     { "january",	tMONTH,  1 },
1385     { "february",	tMONTH,  2 },
1386     { "march",		tMONTH,  3 },
1387     { "april",		tMONTH,  4 },
1388     { "may",		tMONTH,  5 },
1389     { "june",		tMONTH,  6 },
1390     { "july",		tMONTH,  7 },
1391     { "august",		tMONTH,  8 },
1392     { "september",	tMONTH,  9 },
1393     { "sept",		tMONTH,  9 },
1394     { "october",	tMONTH, 10 },
1395     { "november",	tMONTH, 11 },
1396     { "december",	tMONTH, 12 },
1397     { "sunday",		tDAY, 0 },
1398     { "monday",		tDAY, 1 },
1399     { "tuesday",	tDAY, 2 },
1400     { "tues",		tDAY, 2 },
1401     { "wednesday",	tDAY, 3 },
1402     { "wednes",		tDAY, 3 },
1403     { "thursday",	tDAY, 4 },
1404     { "thur",		tDAY, 4 },
1405     { "thurs",		tDAY, 4 },
1406     { "friday",		tDAY, 5 },
1407     { "saturday",	tDAY, 6 },
1408     { NULL }
1409 };
1410 
1411 /* Time units table. */
1412 static TABLE const UnitsTable[] = {
1413     { "year",		tMONTH_UNIT,	12 },
1414     { "month",		tMONTH_UNIT,	1 },
1415     { "fortnight",	tMINUTE_UNIT,	14 * 24 * 60 },
1416     { "week",		tMINUTE_UNIT,	7 * 24 * 60 },
1417     { "day",		tMINUTE_UNIT,	1 * 24 * 60 },
1418     { "hour",		tMINUTE_UNIT,	60 },
1419     { "minute",		tMINUTE_UNIT,	1 },
1420     { "min",		tMINUTE_UNIT,	1 },
1421     { "second",		tSEC_UNIT,	1 },
1422     { "sec",		tSEC_UNIT,	1 },
1423     { NULL }
1424 };
1425 
1426 /* Assorted relative-time words. */
1427 static TABLE const OtherTable[] = {
1428     { "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
1429     { "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
1430     { "today",		tMINUTE_UNIT,	0 },
1431     { "now",		tMINUTE_UNIT,	0 },
1432     { "last",		tUNUMBER,	-1 },
1433     { "this",		tMINUTE_UNIT,	0 },
1434     { "next",		tUNUMBER,	2 },
1435     { "first",		tUNUMBER,	1 },
1436 /*  { "second",		tUNUMBER,	2 }, */
1437     { "third",		tUNUMBER,	3 },
1438     { "fourth",		tUNUMBER,	4 },
1439     { "fifth",		tUNUMBER,	5 },
1440     { "sixth",		tUNUMBER,	6 },
1441     { "seventh",	tUNUMBER,	7 },
1442     { "eighth",		tUNUMBER,	8 },
1443     { "ninth",		tUNUMBER,	9 },
1444     { "tenth",		tUNUMBER,	10 },
1445     { "eleventh",	tUNUMBER,	11 },
1446     { "twelfth",	tUNUMBER,	12 },
1447     { "ago",		tAGO,	1 },
1448     { NULL }
1449 };
1450 
1451 /* The timezone table. */
1452 /* Some of these are commented out because a time_t can't store a float. */
1453 static TABLE const TimezoneTable[] = {
1454     { "gmt",	tZONE,     HOUR( 0) },	/* Greenwich Mean */
1455     { "ut",	tZONE,     HOUR( 0) },	/* Universal (Coordinated) */
1456     { "utc",	tZONE,     HOUR( 0) },
1457     { "wet",	tZONE,     HOUR( 0) },	/* Western European */
1458     { "bst",	tDAYZONE,  HOUR( 0) },	/* British Summer */
1459     { "wat",	tZONE,     HOUR( 1) },	/* West Africa */
1460     { "at",	tZONE,     HOUR( 2) },	/* Azores */
1461 #if	0
1462     /* For completeness.  BST is also British Summer, and GST is
1463      * also Guam Standard. */
1464     { "bst",	tZONE,     HOUR( 3) },	/* Brazil Standard */
1465     { "gst",	tZONE,     HOUR( 3) },	/* Greenland Standard */
1466 #endif
1467 #if 0
1468     { "nft",	tZONE,     HOUR(3.5) },	/* Newfoundland */
1469     { "nst",	tZONE,     HOUR(3.5) },	/* Newfoundland Standard */
1470     { "ndt",	tDAYZONE,  HOUR(3.5) },	/* Newfoundland Daylight */
1471 #endif
1472     { "ast",	tZONE,     HOUR( 4) },	/* Atlantic Standard */
1473     { "adt",	tDAYZONE,  HOUR( 4) },	/* Atlantic Daylight */
1474     { "est",	tZONE,     HOUR( 5) },	/* Eastern Standard */
1475     { "edt",	tDAYZONE,  HOUR( 5) },	/* Eastern Daylight */
1476     { "cst",	tZONE,     HOUR( 6) },	/* Central Standard */
1477     { "cdt",	tDAYZONE,  HOUR( 6) },	/* Central Daylight */
1478     { "mst",	tZONE,     HOUR( 7) },	/* Mountain Standard */
1479     { "mdt",	tDAYZONE,  HOUR( 7) },	/* Mountain Daylight */
1480     { "pst",	tZONE,     HOUR( 8) },	/* Pacific Standard */
1481     { "pdt",	tDAYZONE,  HOUR( 8) },	/* Pacific Daylight */
1482     { "yst",	tZONE,     HOUR( 9) },	/* Yukon Standard */
1483     { "ydt",	tDAYZONE,  HOUR( 9) },	/* Yukon Daylight */
1484     { "hst",	tZONE,     HOUR(10) },	/* Hawaii Standard */
1485     { "hdt",	tDAYZONE,  HOUR(10) },	/* Hawaii Daylight */
1486     { "cat",	tZONE,     HOUR(10) },	/* Central Alaska */
1487     { "ahst",	tZONE,     HOUR(10) },	/* Alaska-Hawaii Standard */
1488     { "nt",	tZONE,     HOUR(11) },	/* Nome */
1489     { "idlw",	tZONE,     HOUR(12) },	/* International Date Line West */
1490     { "cet",	tZONE,     -HOUR(1) },	/* Central European */
1491     { "met",	tZONE,     -HOUR(1) },	/* Middle European */
1492     { "mewt",	tZONE,     -HOUR(1) },	/* Middle European Winter */
1493     { "mest",	tDAYZONE,  -HOUR(1) },	/* Middle European Summer */
1494     { "swt",	tZONE,     -HOUR(1) },	/* Swedish Winter */
1495     { "sst",	tDAYZONE,  -HOUR(1) },	/* Swedish Summer */
1496     { "fwt",	tZONE,     -HOUR(1) },	/* French Winter */
1497     { "fst",	tDAYZONE,  -HOUR(1) },	/* French Summer */
1498     { "eet",	tZONE,     -HOUR(2) },	/* Eastern Europe, USSR Zone 1 */
1499     { "bt",	tZONE,     -HOUR(3) },	/* Baghdad, USSR Zone 2 */
1500 #if 0
1501     { "it",	tZONE,     -HOUR(3.5) },/* Iran */
1502 #endif
1503     { "zp4",	tZONE,     -HOUR(4) },	/* USSR Zone 3 */
1504     { "zp5",	tZONE,     -HOUR(5) },	/* USSR Zone 4 */
1505 #if 0
1506     { "ist",	tZONE,     -HOUR(5.5) },/* Indian Standard */
1507 #endif
1508     { "zp6",	tZONE,     -HOUR(6) },	/* USSR Zone 5 */
1509 #if	0
1510     /* For completeness.  NST is also Newfoundland Stanard, and SST is
1511      * also Swedish Summer. */
1512     { "nst",	tZONE,     -HOUR(6.5) },/* North Sumatra */
1513     { "sst",	tZONE,     -HOUR(7) },	/* South Sumatra, USSR Zone 6 */
1514 #endif	/* 0 */
1515     { "wast",	tZONE,     -HOUR(7) },	/* West Australian Standard */
1516     { "wadt",	tDAYZONE,  -HOUR(7) },	/* West Australian Daylight */
1517 #if 0
1518     { "jt",	tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
1519 #endif
1520     { "cct",	tZONE,     -HOUR(8) },	/* China Coast, USSR Zone 7 */
1521     { "jst",	tZONE,     -HOUR(9) },	/* Japan Standard, USSR Zone 8 */
1522 #if 0
1523     { "cast",	tZONE,     -HOUR(9.5) },/* Central Australian Standard */
1524     { "cadt",	tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
1525 #endif
1526     { "east",	tZONE,     -HOUR(10) },	/* Eastern Australian Standard */
1527     { "eadt",	tDAYZONE,  -HOUR(10) },	/* Eastern Australian Daylight */
1528     { "gst",	tZONE,     -HOUR(10) },	/* Guam Standard, USSR Zone 9 */
1529     { "nzt",	tZONE,     -HOUR(12) },	/* New Zealand */
1530     { "nzst",	tZONE,     -HOUR(12) },	/* New Zealand Standard */
1531     { "nzdt",	tDAYZONE,  -HOUR(12) },	/* New Zealand Daylight */
1532     { "idle",	tZONE,     -HOUR(12) },	/* International Date Line East */
1533     {  NULL  }
1534 };
1535 
1536 /* Military timezone table. */
1537 static TABLE const MilitaryTable[] = {
1538     { "a",	tZONE,	HOUR(  1) },
1539     { "b",	tZONE,	HOUR(  2) },
1540     { "c",	tZONE,	HOUR(  3) },
1541     { "d",	tZONE,	HOUR(  4) },
1542     { "e",	tZONE,	HOUR(  5) },
1543     { "f",	tZONE,	HOUR(  6) },
1544     { "g",	tZONE,	HOUR(  7) },
1545     { "h",	tZONE,	HOUR(  8) },
1546     { "i",	tZONE,	HOUR(  9) },
1547     { "k",	tZONE,	HOUR( 10) },
1548     { "l",	tZONE,	HOUR( 11) },
1549     { "m",	tZONE,	HOUR( 12) },
1550     { "n",	tZONE,	HOUR(- 1) },
1551     { "o",	tZONE,	HOUR(- 2) },
1552     { "p",	tZONE,	HOUR(- 3) },
1553     { "q",	tZONE,	HOUR(- 4) },
1554     { "r",	tZONE,	HOUR(- 5) },
1555     { "s",	tZONE,	HOUR(- 6) },
1556     { "t",	tZONE,	HOUR(- 7) },
1557     { "u",	tZONE,	HOUR(- 8) },
1558     { "v",	tZONE,	HOUR(- 9) },
1559     { "w",	tZONE,	HOUR(-10) },
1560     { "x",	tZONE,	HOUR(-11) },
1561     { "y",	tZONE,	HOUR(-12) },
1562     { "z",	tZONE,	HOUR(  0) },
1563     { NULL }
1564 };
1565 
1566 
1567 
1568 
1569 /* ARGSUSED */
1570 static int
yyerror(s)1571 yyerror(s)
1572     char	*s;
1573 {
1574   return 0;
1575 }
1576 
1577 
1578 static time_t
ToSeconds(Hours,Minutes,Seconds,Meridian)1579 ToSeconds(Hours, Minutes, Seconds, Meridian)
1580     time_t	Hours;
1581     time_t	Minutes;
1582     time_t	Seconds;
1583     MERIDIAN	Meridian;
1584 {
1585     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
1586 	return -1;
1587     switch (Meridian) {
1588     case MER24:
1589 	if (Hours < 0 || Hours > 23)
1590 	    return -1;
1591 	return (Hours * 60L + Minutes) * 60L + Seconds;
1592     case MERam:
1593 	if (Hours < 1 || Hours > 12)
1594 	    return -1;
1595 	if (Hours == 12)
1596 	    Hours = 0;
1597 	return (Hours * 60L + Minutes) * 60L + Seconds;
1598     case MERpm:
1599 	if (Hours < 1 || Hours > 12)
1600 	    return -1;
1601 	if (Hours == 12)
1602 	    Hours = 0;
1603 	return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
1604     default:
1605 	abort ();
1606     }
1607     /* NOTREACHED */
1608 }
1609 
1610 
1611 /* Year is either
1612    * A negative number, which means to use its absolute value (why?)
1613    * A number from 0 to 99, which means a year from 1900 to 1999, or
1614    * The actual year (>=100).  */
1615 static time_t
Convert(Month,Day,Year,Hours,Minutes,Seconds,Meridian,DSTmode)1616 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
1617     time_t	Month;
1618     time_t	Day;
1619     time_t	Year;
1620     time_t	Hours;
1621     time_t	Minutes;
1622     time_t	Seconds;
1623     MERIDIAN	Meridian;
1624     DSTMODE	DSTmode;
1625 {
1626     static int DaysInMonth[12] = {
1627 	31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
1628     };
1629     time_t	tod;
1630     time_t	Julian;
1631     int		i;
1632 
1633     if (Year < 0)
1634 	Year = -Year;
1635     if (Year < 69)
1636 	Year += 2000;
1637     else if (Year < 100)
1638 	Year += 1900;
1639     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
1640 		    ? 29 : 28;
1641     /* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
1642        I'm too lazy to try to check for time_t overflow in another way.  */
1643     if (Year < EPOCH || Year > 2038
1644      || Month < 1 || Month > 12
1645      /* Lint fluff:  "conversion from long may lose accuracy" */
1646      || Day < 1 || Day > DaysInMonth[(int)--Month])
1647 	return -1;
1648 
1649     for (Julian = Day - 1, i = 0; i < Month; i++)
1650 	Julian += DaysInMonth[i];
1651     for (i = EPOCH; i < Year; i++)
1652 	Julian += 365 + (i % 4 == 0);
1653     Julian *= SECSPERDAY;
1654     Julian += yyTimezone * 60L;
1655     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
1656 	return -1;
1657     Julian += tod;
1658     if (DSTmode == DSTon
1659      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
1660 	Julian -= 60 * 60;
1661     return Julian;
1662 }
1663 
1664 
1665 static time_t
DSTcorrect(Start,Future)1666 DSTcorrect(Start, Future)
1667     time_t	Start;
1668     time_t	Future;
1669 {
1670     time_t	StartDay;
1671     time_t	FutureDay;
1672 
1673     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
1674     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
1675     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
1676 }
1677 
1678 
1679 static time_t
RelativeDate(Start,DayOrdinal,DayNumber)1680 RelativeDate(Start, DayOrdinal, DayNumber)
1681     time_t	Start;
1682     time_t	DayOrdinal;
1683     time_t	DayNumber;
1684 {
1685     struct tm	*tm;
1686     time_t	now;
1687 
1688     now = Start;
1689     tm = localtime(&now);
1690     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
1691     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
1692     return DSTcorrect(Start, now);
1693 }
1694 
1695 
1696 static time_t
RelativeMonth(Start,RelMonth)1697 RelativeMonth(Start, RelMonth)
1698     time_t	Start;
1699     time_t	RelMonth;
1700 {
1701     struct tm	*tm;
1702     time_t	Month;
1703     time_t	Year;
1704 
1705     if (RelMonth == 0)
1706 	return 0;
1707     tm = localtime(&Start);
1708     Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
1709     Year = Month / 12;
1710     Month = Month % 12 + 1;
1711     return DSTcorrect(Start,
1712 	    Convert(Month, (time_t)tm->tm_mday, Year,
1713 		(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
1714 		MER24, DSTmaybe));
1715 }
1716 
1717 
1718 static int
LookupWord(buff)1719 LookupWord(buff)
1720     char		*buff;
1721 {
1722     register char	*p;
1723     register char	*q;
1724     register const TABLE	*tp;
1725     int			i;
1726     int			abbrev;
1727 
1728     /* Make it lowercase. */
1729     for (p = buff; *p; p++)
1730 	if (isupper(*p))
1731 	    *p = tolower(*p);
1732 
1733     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
1734 	yylval.Meridian = MERam;
1735 	return tMERIDIAN;
1736     }
1737     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
1738 	yylval.Meridian = MERpm;
1739 	return tMERIDIAN;
1740     }
1741 
1742     /* See if we have an abbreviation for a month. */
1743     if (strlen(buff) == 3)
1744 	abbrev = 1;
1745     else if (strlen(buff) == 4 && buff[3] == '.') {
1746 	abbrev = 1;
1747 	buff[3] = '\0';
1748     }
1749     else
1750 	abbrev = 0;
1751 
1752     for (tp = MonthDayTable; tp->name; tp++) {
1753 	if (abbrev) {
1754 	    if (strncmp(buff, tp->name, 3) == 0) {
1755 		yylval.Number = tp->value;
1756 		return tp->type;
1757 	    }
1758 	}
1759 	else if (strcmp(buff, tp->name) == 0) {
1760 	    yylval.Number = tp->value;
1761 	    return tp->type;
1762 	}
1763     }
1764 
1765     for (tp = TimezoneTable; tp->name; tp++)
1766 	if (strcmp(buff, tp->name) == 0) {
1767 	    yylval.Number = tp->value;
1768 	    return tp->type;
1769 	}
1770 
1771     if (strcmp(buff, "dst") == 0)
1772 	return tDST;
1773 
1774     for (tp = UnitsTable; tp->name; tp++)
1775 	if (strcmp(buff, tp->name) == 0) {
1776 	    yylval.Number = tp->value;
1777 	    return tp->type;
1778 	}
1779 
1780     /* Strip off any plural and try the units table again. */
1781     i = strlen(buff) - 1;
1782     if (buff[i] == 's') {
1783 	buff[i] = '\0';
1784 	for (tp = UnitsTable; tp->name; tp++)
1785 	    if (strcmp(buff, tp->name) == 0) {
1786 		yylval.Number = tp->value;
1787 		return tp->type;
1788 	    }
1789 	buff[i] = 's';		/* Put back for "this" in OtherTable. */
1790     }
1791 
1792     for (tp = OtherTable; tp->name; tp++)
1793 	if (strcmp(buff, tp->name) == 0) {
1794 	    yylval.Number = tp->value;
1795 	    return tp->type;
1796 	}
1797 
1798     /* Military timezones. */
1799     if (buff[1] == '\0' && isalpha(*buff)) {
1800 	for (tp = MilitaryTable; tp->name; tp++)
1801 	    if (strcmp(buff, tp->name) == 0) {
1802 		yylval.Number = tp->value;
1803 		return tp->type;
1804 	    }
1805     }
1806 
1807     /* Drop out any periods and try the timezone table again. */
1808     for (i = 0, p = q = buff; *q; q++)
1809 	if (*q != '.')
1810 	    *p++ = *q;
1811 	else
1812 	    i++;
1813     *p = '\0';
1814     if (i)
1815 	for (tp = TimezoneTable; tp->name; tp++)
1816 	    if (strcmp(buff, tp->name) == 0) {
1817 		yylval.Number = tp->value;
1818 		return tp->type;
1819 	    }
1820 
1821     return tID;
1822 }
1823 
1824 
1825 static int
yylex()1826 yylex()
1827 {
1828     register char	c;
1829     register char	*p;
1830     char		buff[20];
1831     int			Count;
1832     int			sign;
1833 
1834     for ( ; ; ) {
1835 	while (isspace(*yyInput))
1836 	    yyInput++;
1837 
1838 	if (isdigit(c = *yyInput) || c == '-' || c == '+') {
1839 	    if (c == '-' || c == '+') {
1840 		sign = c == '-' ? -1 : 1;
1841 		if (!isdigit(*++yyInput))
1842 		    /* skip the '-' sign */
1843 		    continue;
1844 	    }
1845 	    else
1846 		sign = 0;
1847 	    for (yylval.Number = 0; isdigit(c = *yyInput++); )
1848 		yylval.Number = 10 * yylval.Number + c - '0';
1849 	    yyInput--;
1850 	    if (sign < 0)
1851 		yylval.Number = -yylval.Number;
1852 	    return sign ? tSNUMBER : tUNUMBER;
1853 	}
1854 	if (isalpha(c)) {
1855 	    for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
1856 		if (p < &buff[sizeof buff - 1])
1857 		    *p++ = c;
1858 	    *p = '\0';
1859 	    yyInput--;
1860 	    return LookupWord(buff);
1861 	}
1862 	if (c != '(')
1863 	    return *yyInput++;
1864 	Count = 0;
1865 	do {
1866 	    c = *yyInput++;
1867 	    if (c == '\0')
1868 		return c;
1869 	    if (c == '(')
1870 		Count++;
1871 	    else if (c == ')')
1872 		Count--;
1873 	} while (Count > 0);
1874     }
1875 }
1876 
1877 #define TM_YEAR_ORIGIN 1900
1878 
1879 /* Yield A - B, measured in seconds.  */
1880 static long
difftm(a,b)1881 difftm (a, b)
1882      struct tm *a, *b;
1883 {
1884   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
1885   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
1886   int days = (
1887 	      /* difference in day of year */
1888 	      a->tm_yday - b->tm_yday
1889 	      /* + intervening leap days */
1890 	      +  ((ay >> 2) - (by >> 2))
1891 	      -  (ay/100 - by/100)
1892 	      +  ((ay/100 >> 2) - (by/100 >> 2))
1893 	      /* + difference in years * 365 */
1894 	      +  (long)(ay-by) * 365
1895 	      );
1896   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
1897 	      + (a->tm_min - b->tm_min))
1898 	  + (a->tm_sec - b->tm_sec));
1899 }
1900 
1901 time_t
get_date(p)1902 get_date(p)
1903      char *p;
1904 {
1905     struct tm		*tm, *gmt, gmtbuf;
1906     time_t		Start;
1907     time_t		tod;
1908     time_t		now;
1909     time_t		timezone;
1910 
1911     yyInput = p;
1912     (void)time (&now);
1913 
1914     gmt = gmtime (&now);
1915     if (gmt != NULL)
1916     {
1917 	/* Make a copy, in case localtime modifies *tm (I think
1918 	   that comment now applies to *gmt, but I am too
1919 	   lazy to dig into how gmtime and locatime allocate the
1920 	   structures they return pointers to).  */
1921 	gmtbuf = *gmt;
1922 	gmt = &gmtbuf;
1923     }
1924 
1925     if (! (tm = localtime (&now)))
1926 	return -1;
1927 
1928     if (gmt != NULL)
1929 	timezone = difftm (gmt, tm) / 60;
1930     else
1931 	/* We are on a system like VMS, where the system clock is
1932 	   in local time and the system has no concept of timezones.
1933 	   Hopefully we can fake this out (for the case in which the
1934 	   user specifies no timezone) by just saying the timezone
1935 	   is zero.  */
1936 	timezone = 0;
1937 
1938     if(tm->tm_isdst)
1939 	timezone += 60;
1940 
1941     tm = localtime(&now);
1942     yyYear = tm->tm_year + 1900;
1943     yyMonth = tm->tm_mon + 1;
1944     yyDay = tm->tm_mday;
1945     yyTimezone = timezone;
1946     yyDSTmode = DSTmaybe;
1947     yyHour = 0;
1948     yyMinutes = 0;
1949     yySeconds = 0;
1950     yyMeridian = MER24;
1951     yyRelSeconds = 0;
1952     yyRelMonth = 0;
1953     yyHaveDate = 0;
1954     yyHaveDay = 0;
1955     yyHaveRel = 0;
1956     yyHaveTime = 0;
1957     yyHaveZone = 0;
1958 
1959     if (yyparse()
1960      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
1961 	return -1;
1962 
1963     if (yyHaveDate || yyHaveTime || yyHaveDay) {
1964 	Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
1965 		    yyMeridian, yyDSTmode);
1966 	if (Start < 0)
1967 	    return -1;
1968     }
1969     else {
1970 	Start = now;
1971 	if (!yyHaveRel)
1972 	    Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
1973     }
1974 
1975     Start += yyRelSeconds;
1976     Start += RelativeMonth(Start, yyRelMonth);
1977 
1978     if (yyHaveDay && !yyHaveDate) {
1979 	tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
1980 	Start += tod;
1981     }
1982 
1983     /* Have to do *something* with a legitimate -1 so it's distinguishable
1984      * from the error return value.  (Alternately could set errno on error.) */
1985     return Start == -1 ? 0 : Start;
1986 }
1987 
1988 
1989 #if	defined(TEST)
1990 
1991 /* ARGSUSED */
1992 int
main(ac,av)1993 main(ac, av)
1994     int		ac;
1995     char	*av[];
1996 {
1997     char	buff[128];
1998     time_t	d;
1999 
2000     (void)printf("Enter date, or blank line to exit.\n\t> ");
2001     (void)fflush(stdout);
2002     while (gets(buff) && buff[0]) {
2003 	d = get_date(buff);
2004 	if (d == -1)
2005 	    (void)printf("Bad format - couldn't convert.\n");
2006 	else
2007 	    (void)printf("%s", ctime(&d));
2008 	(void)printf("\t> ");
2009 	(void)fflush(stdout);
2010     }
2011     exit(0);
2012     /* NOTREACHED */
2013 }
2014 #endif	/* defined(TEST) */
2015