1 
2 # line 2 "getdate.y"
3 /*
4  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
5  * Use is subject to license terms.
6  */
7 #pragma ident	"%Z%%M%	%I%	%E% SMI"
8 
9 /* $OrigRevision: 2.1 $
10 **
11 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
12 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
13 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
14 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
15 **  send any email to Rich.
16 **
17 **  This grammar has eight shift/reduce conflicts.
18 **
19 **  This code is in the public domain and has no copyright.
20 */
21 /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
22 /* SUPPRESS 288 on yyerrlab *//* Label unused */
23 #include <stdio.h>
24 #include <ctype.h>
25 
26 #include <sys/types.h>
27 #define NEED_TZSET
28 struct timeb {
29     time_t		time;		/* Seconds since the epoch	*/
30     unsigned short	millitm;	/* Field not used		*/
31     short		timezone;
32     short		dstflag;	/* Field not used		*/
33 };
34 #include <time.h>
35 
36 #include <locale.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <note.h>
40 #include <libintl.h>
41 
42 #if	!defined(lint) && !defined(SABER)
43 static char RCS[] =
44 	"$Header: /home/laramie/berliner/ws/backup/usr/src/cmd/backup/lib/getdate.y,v 1.5 1992/06/09 21:46:21 sam Exp $";
45 #endif	/* !defined(lint) && !defined(SABER) */
46 
47 
48 #define EPOCH		1970
49 #define HOURN(x)	(x * 60)
50 #define SECSPERDAY	(24L * 60L * 60L)
51 
52 #define CHECK_TM(y) (((y) % 100) < 70 ? (y) + 2000 : (y) + 1900)
53 
54 /*
55 **  An entry in the lexical lookup table.
56 */
57 typedef struct _TABLE {
58     char	*name;
59     int		type;
60     time_t	value;
61 } TABLE;
62 
63 
64 /*
65 **  Daylight-savings mode:  on, off, or not yet known.
66 */
67 typedef enum _DSTMODE {
68     DSTon, DSToff, DSTmaybe
69 } DSTMODE;
70 
71 /*
72 **  Meridian:  am, pm, or 24-hour style.
73 */
74 typedef enum _MERIDIAN {
75     MERam, MERpm, MER24
76 } MERIDIAN;
77 
78 
79 /*
80 **  Global variables.  We could get rid of most of these by using a good
81 **  union as the yacc stack.  (This routine was originally written before
82 **  yacc had the %union construct.)  Maybe someday; right now we only use
83 **  the %union very rarely.
84 */
85 static char	*yyInput;
86 static DSTMODE	yyDSTmode;
87 static time_t	yyDayOrdinal;
88 static time_t	yyDayNumber;
89 static int	yyHaveDate;
90 static int	yyHaveDay;
91 static int	yyHaveRel;
92 static int	yyHaveTime;
93 static int	yyHaveZone;
94 static time_t	yyTimezone;
95 static time_t	yyDay;
96 static time_t	yyHour;
97 static time_t	yyMinutes;
98 static time_t	yyMonth;
99 static time_t	yySeconds;
100 static time_t	yyYear;
101 static MERIDIAN	yyMeridian;
102 static time_t	yyRelMonth;
103 static time_t	yyRelSeconds;
104 
105 static char	*domainname = "hsm_libdump";	/* for dgettext() */
106 
107 #define yylex 1					/* suppress yacc's definition */
108 
109 # line 109 "getdate.y"
110 typedef union
111 #ifdef __cplusplus
112 	YYSTYPE
113 #endif
114  {
115     time_t		Number;
116     enum _MERIDIAN	Meridian;
117 } YYSTYPE;
118 # define tAGO 257
119 # define tDAY 258
120 # define tDAYZONE 259
121 # define tID 260
122 # define tMERIDIAN 261
123 # define tMINUTE_UNIT 262
124 # define tMONTH 263
125 # define tMONTH_UNIT 264
126 # define tSEC_UNIT 265
127 # define tSNUMBER 266
128 # define tUNUMBER 267
129 # define tZONE 268
130 
131 #include <inttypes.h>
132 
133 #ifdef __STDC__
134 #include <stdlib.h>
135 #include <string.h>
136 #define	YYCONST	const
137 #else
138 #include <malloc.h>
139 #include <memory.h>
140 #define	YYCONST
141 #endif
142 
143 #include <values.h>
144 
145 #if defined(__cplusplus) || defined(__STDC__)
146 
147 #if defined(__cplusplus) && defined(__EXTERN_C__)
148 extern "C" {
149 #endif
150 #ifndef yyerror
151 #if defined(__cplusplus)
152 	void yyerror(YYCONST char *);
153 #endif
154 #endif
155 #ifndef yylex
156 	int yylex(void);
157 #endif
158 	int yyparse(void);
159 #if defined(__cplusplus) && defined(__EXTERN_C__)
160 }
161 #endif
162 
163 #endif
164 
165 #define yyclearin yychar = -1
166 #define yyerrok yyerrflag = 0
167 extern int yychar;
168 extern int yyerrflag;
169 YYSTYPE yylval;
170 YYSTYPE yyval;
171 typedef int yytabelem;
172 #ifndef YYMAXDEPTH
173 #define YYMAXDEPTH 150
174 #endif
175 #if YYMAXDEPTH > 0
176 int yy_yys[YYMAXDEPTH], *yys = yy_yys;
177 YYSTYPE yy_yyv[YYMAXDEPTH], *yyv = yy_yyv;
178 #else	/* user does initial allocation */
179 int *yys;
180 YYSTYPE *yyv;
181 #endif
182 static int yymaxdepth = YYMAXDEPTH;
183 # define YYERRCODE 256
184 
185 # line 296 "getdate.y"
186 
187 
188 /* Month and day table. */
189 static TABLE	MonthDayTable[] = {
190     { "january",	tMONTH,  1 },
191     { "february",	tMONTH,  2 },
192     { "march",		tMONTH,  3 },
193     { "april",		tMONTH,  4 },
194     { "may",		tMONTH,  5 },
195     { "june",		tMONTH,  6 },
196     { "july",		tMONTH,  7 },
197     { "august",		tMONTH,  8 },
198     { "september",	tMONTH,  9 },
199     { "sept",		tMONTH,  9 },
200     { "october",	tMONTH, 10 },
201     { "november",	tMONTH, 11 },
202     { "december",	tMONTH, 12 },
203     { "sunday",		tDAY, 0 },
204     { "monday",		tDAY, 1 },
205     { "tuesday",	tDAY, 2 },
206     { "tues",		tDAY, 2 },
207     { "wednesday",	tDAY, 3 },
208     { "wednes",		tDAY, 3 },
209     { "thursday",	tDAY, 4 },
210     { "thur",		tDAY, 4 },
211     { "thurs",		tDAY, 4 },
212     { "friday",		tDAY, 5 },
213     { "saturday",	tDAY, 6 },
214     { NULL }
215 };
216 
217 /* Time units table. */
218 static TABLE	UnitsTable[] = {
219     { "year",		tMONTH_UNIT,	12 },
220     { "month",		tMONTH_UNIT,	1 },
221     { "fortnight",	tMINUTE_UNIT,	14 * 24 * 60 },
222     { "week",		tMINUTE_UNIT,	7 * 24 * 60 },
223     { "day",		tMINUTE_UNIT,	1 * 24 * 60 },
224     { "hour",		tMINUTE_UNIT,	60 },
225     { "minute",		tMINUTE_UNIT,	1 },
226     { "min",		tMINUTE_UNIT,	1 },
227     { "second",		tSEC_UNIT,	1 },
228     { "sec",		tSEC_UNIT,	1 },
229     { NULL }
230 };
231 
232 /* Assorted relative-time words. */
233 static TABLE	OtherTable[] = {
234     { "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
235     { "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
236     { "today",		tMINUTE_UNIT,	0 },
237     { "now",		tMINUTE_UNIT,	0 },
238     { "last",		tUNUMBER,	-1 },
239     { "this",		tMINUTE_UNIT,	0 },
240     { "next",		tUNUMBER,	2 },
241     { "first",		tUNUMBER,	1 },
242 /*  { "second",		tUNUMBER,	2 }, */
243     { "third",		tUNUMBER,	3 },
244     { "fourth",		tUNUMBER,	4 },
245     { "fifth",		tUNUMBER,	5 },
246     { "sixth",		tUNUMBER,	6 },
247     { "seventh",	tUNUMBER,	7 },
248     { "eighth",		tUNUMBER,	8 },
249     { "ninth",		tUNUMBER,	9 },
250     { "tenth",		tUNUMBER,	10 },
251     { "eleventh",	tUNUMBER,	11 },
252     { "twelfth",	tUNUMBER,	12 },
253     { "ago",		tAGO,	1 },
254     { NULL }
255 };
256 
257 /* The timezone table. */
258 static TABLE	TimezoneTable[] = {
259     { "gmt",	tZONE,     HOURN( 0) },	/* Greenwich Mean */
260     { "ut",	tZONE,     HOURN( 0) },	/* Universal (Coordinated) */
261     { "utc",	tZONE,     HOURN( 0) },
262     { "wet",	tZONE,     HOURN( 0) },	/* Western European */
263     { "bst",	tDAYZONE,  HOURN( 0) },	/* British Summer */
264     { "wat",	tZONE,     HOURN( 1) },	/* West Africa */
265     { "at",	tZONE,     HOURN( 2) },	/* Azores */
266 #if	0
267     /* For completeness.  BST is also British Summer, and GST is
268      * also Guam Standard. */
269     { "bst",	tZONE,     HOURN( 3) },	/* Brazil Standard */
270     { "gst",	tZONE,     HOURN( 3) },	/* Greenland Standard */
271 #endif
272     { "nft",	tZONE,     HOURN(3.5) },	/* Newfoundland */
273     { "nst",	tZONE,     HOURN(3.5) },	/* Newfoundland Standard */
274     { "ndt",	tDAYZONE,  HOURN(3.5) },	/* Newfoundland Daylight */
275     { "ast",	tZONE,     HOURN( 4) },	/* Atlantic Standard */
276     { "adt",	tDAYZONE,  HOURN( 4) },	/* Atlantic Daylight */
277     { "est",	tZONE,     HOURN( 5) },	/* Eastern Standard */
278     { "edt",	tDAYZONE,  HOURN( 5) },	/* Eastern Daylight */
279     { "cst",	tZONE,     HOURN( 6) },	/* Central Standard */
280     { "cdt",	tDAYZONE,  HOURN( 6) },	/* Central Daylight */
281     { "mst",	tZONE,     HOURN( 7) },	/* Mountain Standard */
282     { "mdt",	tDAYZONE,  HOURN( 7) },	/* Mountain Daylight */
283     { "pst",	tZONE,     HOURN( 8) },	/* Pacific Standard */
284     { "pdt",	tDAYZONE,  HOURN( 8) },	/* Pacific Daylight */
285     { "yst",	tZONE,     HOURN( 9) },	/* Yukon Standard */
286     { "ydt",	tDAYZONE,  HOURN( 9) },	/* Yukon Daylight */
287     { "hst",	tZONE,     HOURN(10) },	/* Hawaii Standard */
288     { "hdt",	tDAYZONE,  HOURN(10) },	/* Hawaii Daylight */
289     { "cat",	tZONE,     HOURN(10) },	/* Central Alaska */
290     { "ahst",	tZONE,     HOURN(10) },	/* Alaska-Hawaii Standard */
291     { "nt",	tZONE,     HOURN(11) },	/* Nome */
292     { "idlw",	tZONE,     HOURN(12) },	/* International Date Line West */
293     { "cet",	tZONE,     -HOURN(1) },	/* Central European */
294     { "met",	tZONE,     -HOURN(1) },	/* Middle European */
295     { "mewt",	tZONE,     -HOURN(1) },	/* Middle European Winter */
296     { "mest",	tDAYZONE,  -HOURN(1) },	/* Middle European Summer */
297     { "swt",	tZONE,     -HOURN(1) },	/* Swedish Winter */
298     { "sst",	tDAYZONE,  -HOURN(1) },	/* Swedish Summer */
299     { "fwt",	tZONE,     -HOURN(1) },	/* French Winter */
300     { "fst",	tDAYZONE,  -HOURN(1) },	/* French Summer */
301     { "eet",	tZONE,     -HOURN(2) },	/* Eastern Europe, USSR Zone 1 */
302     { "bt",	tZONE,     -HOURN(3) },	/* Baghdad, USSR Zone 2 */
303     { "it",	tZONE,     -HOURN(3.5) },/* Iran */
304     { "zp4",	tZONE,     -HOURN(4) },	/* USSR Zone 3 */
305     { "zp5",	tZONE,     -HOURN(5) },	/* USSR Zone 4 */
306     { "ist",	tZONE,     -HOURN(5.5) },/* Indian Standard */
307     { "zp6",	tZONE,     -HOURN(6) },	/* USSR Zone 5 */
308 #if	0
309     /* For completeness.  NST is also Newfoundland Stanard, nad SST is
310      * also Swedish Summer. */
311     { "nst",	tZONE,     -HOURN(6.5) },/* North Sumatra */
312     { "sst",	tZONE,     -HOURN(7) },	/* South Sumatra, USSR Zone 6 */
313 #endif	/* 0 */
314     { "wast",	tZONE,     -HOURN(7) },	/* West Australian Standard */
315     { "wadt",	tDAYZONE,  -HOURN(7) },	/* West Australian Daylight */
316     { "jt",	tZONE,     -HOURN(7.5) },/* Java (3pm in Cronusland!) */
317     { "cct",	tZONE,     -HOURN(8) },	/* China Coast, USSR Zone 7 */
318     { "jst",	tZONE,     -HOURN(9) },	/* Japan Standard, USSR Zone 8 */
319     { "cast",	tZONE,     -HOURN(9.5) },/* Central Australian Standard */
320     { "cadt",	tDAYZONE,  -HOURN(9.5) },/* Central Australian Daylight */
321     { "east",	tZONE,     -HOURN(10) },	/* Eastern Australian Standard */
322     { "eadt",	tDAYZONE,  -HOURN(10) },	/* Eastern Australian Daylight */
323     { "gst",	tZONE,     -HOURN(10) },	/* Guam Standard, USSR Zone 9 */
324     { "nzt",	tZONE,     -HOURN(12) },	/* New Zealand */
325     { "nzst",	tZONE,     -HOURN(12) },	/* New Zealand Standard */
326     { "nzdt",	tDAYZONE,  -HOURN(12) },	/* New Zealand Daylight */
327     { "idle",	tZONE,     -HOURN(12) },	/* International Date Line East */
328     {  NULL  }
329 };
330 
331 /* Military timezone table. */
332 static TABLE	MilitaryTable[] = {
333     { "a",	tZONE,	HOURN(  1) },
334     { "b",	tZONE,	HOURN(  2) },
335     { "c",	tZONE,	HOURN(  3) },
336     { "d",	tZONE,	HOURN(  4) },
337     { "e",	tZONE,	HOURN(  5) },
338     { "f",	tZONE,	HOURN(  6) },
339     { "g",	tZONE,	HOURN(  7) },
340     { "h",	tZONE,	HOURN(  8) },
341     { "i",	tZONE,	HOURN(  9) },
342     { "k",	tZONE,	HOURN( 10) },
343     { "l",	tZONE,	HOURN( 11) },
344     { "m",	tZONE,	HOURN( 12) },
345     { "n",	tZONE,	HOURN(- 1) },
346     { "o",	tZONE,	HOURN(- 2) },
347     { "p",	tZONE,	HOURN(- 3) },
348     { "q",	tZONE,	HOURN(- 4) },
349     { "r",	tZONE,	HOURN(- 5) },
350     { "s",	tZONE,	HOURN(- 6) },
351     { "t",	tZONE,	HOURN(- 7) },
352     { "u",	tZONE,	HOURN(- 8) },
353     { "v",	tZONE,	HOURN(- 9) },
354     { "w",	tZONE,	HOURN(-10) },
355     { "x",	tZONE,	HOURN(-11) },
356     { "y",	tZONE,	HOURN(-12) },
357     { "z",	tZONE,	HOURN(  0) },
358     { NULL }
359 };
360 
361 
362 
363 
364 /* ARGSUSED */
365 static void
366 yyerror(s)
367     char	*s;
368 {
369 }
370 
371 
372 static time_t
373 ToSeconds(Hours, Minutes, Seconds, Meridian)
374     time_t	Hours;
375     time_t	Minutes;
376     time_t	Seconds;
377     MERIDIAN	Meridian;
378 {
379     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
380 	return -1;
381     switch (Meridian) {
382     case MER24:
383 	if (Hours < 0 || Hours > 23)
384 	    return -1;
385 	return (Hours * 60L + Minutes) * 60L + Seconds;
386     case MERam:
387 	if (Hours < 1 || Hours > 12)
388 	    return -1;
389 	if (Hours != 12)
390 	    return (Hours * 60L + Minutes) * 60L + Seconds;
391 	else
392 	    return Minutes * 60L + Seconds;
393     case MERpm:
394 	if (Hours < 1 || Hours > 12)
395 	    return -1;
396 	if (Hours != 12)
397 	    return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
398 	else
399 	    return (720L + Minutes) * 60L + Seconds;
400     }
401     /* NOTREACHED */
402     return (-1);
403 }
404 
405 
406 static time_t
407 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
408     time_t	Month;
409     time_t	Day;
410     time_t	Year;
411     time_t	Hours;
412     time_t	Minutes;
413     time_t	Seconds;
414     MERIDIAN	Meridian;
415     DSTMODE	DSTmode;
416 {
417     static int	DaysInMonth[12] = {
418 	31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
419     };
420     time_t	tod;
421     time_t	Julian;
422     time_t	i;
423 
424     if (Year < 0)
425 	Year = -Year;
426     if (Year < 138)
427 	Year += 1900;
428     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
429 		    ? 29 : 28;
430     if (Year < EPOCH || Year > 2037
431      || Month < 1 || Month > 12
432      /* LINTED Month is a time_t so intermediate results aren't truncated */
433      || Day < 1 || Day > DaysInMonth[(int)--Month])
434 	return -1;
435 
436     for (Julian = Day - 1, i = 0; i < Month; i++)
437 	Julian += DaysInMonth[i];
438     for (i = EPOCH; i < Year; i++)
439 	Julian += 365 + (i % 4 == 0);
440     Julian *= SECSPERDAY;
441     Julian += yyTimezone * 60L;
442     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
443 	return -1;
444     Julian += tod;
445     if (DSTmode == DSTon
446      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
447 	Julian -= 60 * 60;
448     return Julian;
449 }
450 
451 
452 static time_t
453 DSTcorrect(Start, Future)
454     time_t	Start;
455     time_t	Future;
456 {
457     time_t	StartDay;
458     time_t	FutureDay;
459 
460     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
461     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
462     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
463 }
464 
465 
466 static time_t
467 RelativeDate(Start, DayOrdinal, DayNumber)
468     time_t	Start;
469     time_t	DayOrdinal;
470     time_t	DayNumber;
471 {
472     struct tm	*tm;
473     time_t	now;
474 
475     now = Start;
476     tm = localtime(&now);
477     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
478     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
479     return DSTcorrect(Start, now);
480 }
481 
482 
483 static time_t
484 RelativeMonth(Start, RelMonth)
485     time_t	Start;
486     time_t	RelMonth;
487 {
488     struct tm	*tm;
489     time_t	Month;
490     time_t	Year;
491 
492     if (RelMonth == 0)
493 	return 0;
494     tm = localtime(&Start);
495     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
496     Year = Month / 12;
497     Month = Month % 12 + 1;
498     return DSTcorrect(Start,
499 	    Convert(Month, (time_t)tm->tm_mday, Year,
500 		(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
501 		MER24, DSTmaybe));
502 }
503 
504 
505 static int
506 LookupWord(buff)
507     char		*buff;
508 {
509     char	*p;
510     char	*q;
511     TABLE	*tp;
512     uint_t	i;
513     int		abbrev;
514 
515     /* Make it lowercase. */
516     for (p = buff; *p; p++)
517 	if (isupper((u_char)*p))
518 	    *p = tolower(*p);
519 
520     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
521 	yylval.Meridian = MERam;
522 	return tMERIDIAN;
523     }
524     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
525 	yylval.Meridian = MERpm;
526 	return tMERIDIAN;
527     }
528 
529     /* See if we have an abbreviation for a month. */
530     if (strlen(buff) == 3)
531 	abbrev = 1;
532     else if (strlen(buff) == 4 && buff[3] == '.') {
533 	abbrev = 1;
534 	buff[3] = '\0';
535     }
536     else
537 	abbrev = 0;
538 
539     for (tp = MonthDayTable; tp->name; tp++) {
540 	if (abbrev) {
541 	    if (strncmp(buff, tp->name, 3) == 0) {
542 		yylval.Number = tp->value;
543 		return tp->type;
544 	    }
545 	}
546 	else if (strcmp(buff, tp->name) == 0) {
547 	    yylval.Number = tp->value;
548 	    return tp->type;
549 	}
550     }
551 
552     for (tp = TimezoneTable; tp->name; tp++)
553 	if (strcmp(buff, tp->name) == 0) {
554 	    yylval.Number = tp->value;
555 	    return tp->type;
556 	}
557 
558     for (tp = UnitsTable; tp->name; tp++)
559 	if (strcmp(buff, tp->name) == 0) {
560 	    yylval.Number = tp->value;
561 	    return tp->type;
562 	}
563 
564     /* Strip off any plural and try the units table again. */
565     i = strlen(buff) - 1;
566     if (buff[i] == 's') {
567 	buff[i] = '\0';
568 	for (tp = UnitsTable; tp->name; tp++)
569 	    if (strcmp(buff, tp->name) == 0) {
570 		yylval.Number = tp->value;
571 		return tp->type;
572 	    }
573     }
574 
575     for (tp = OtherTable; tp->name; tp++)
576 	if (strcmp(buff, tp->name) == 0) {
577 	    yylval.Number = tp->value;
578 	    return tp->type;
579 	}
580 
581     /* Military timezones. */
582     if (buff[1] == '\0' && isalpha((u_char)*buff)) {
583 	for (tp = MilitaryTable; tp->name; tp++)
584 	    if (strcmp(buff, tp->name) == 0) {
585 		yylval.Number = tp->value;
586 		return tp->type;
587 	    }
588     }
589 
590     /* Drop out any periods and try the timezone table again. */
591     for (i = 0, p = q = buff; *q; q++)
592 	if (*q != '.')
593 	    *p++ = *q;
594 	else
595 	    i++;
596     *p = '\0';
597     if (i)
598 	for (tp = TimezoneTable; tp->name; tp++)
599 	    if (strcmp(buff, tp->name) == 0) {
600 		yylval.Number = tp->value;
601 		return tp->type;
602 	    }
603 
604     return tID;
605 }
606 
607 void
608 pdateerr(p)
609     char	*p;
610 {
611     char	*name = "DATEMSK";	/* env variable for date format */
612     char	*value;
613     char	fmt[256], line[256];
614     FILE	*fp;
615     time_t	now;
616     struct tm	*tm;
617 
618     value = getenv(name);
619     if (value == (char *)0) {
620 	fprintf(stderr,
621 	    dgettext(domainname, "%s: Environment variable %s not set\n"),
622 		p, name);
623 	return;
624     }
625     switch (getdate_err) {
626 	case 0:
627 	default:
628 	    fprintf(stderr,
629 		dgettext(domainname, "%s: Unkown getdate() error\n"), p);
630 	    break;
631 	case 1:
632 	    fprintf(stderr,
633 		dgettext(domainname, "%s: %s null or undefined\n"), p, name);
634 	    break;
635 	case 2:
636 	    fprintf(stderr, dgettext(domainname,
637 		"%s: Cannot read template file %s\n"), p, value);
638 	    break;
639 	case 3:
640 	    fprintf(stderr, dgettext(domainname,
641 		"%s: Failed to get file status information\n"), p);
642 	    break;
643 	case 4:
644 	    fprintf(stderr, dgettext(domainname,
645 		"%s: Template file %s not a regular file\n"), p, value);
646 	    break;
647 	case 5:
648 	    fprintf(stderr, dgettext(domainname,
649 		"%s: Error reading template file %s\n"), p, value);
650 	    break;
651 	case 6:
652 	    fprintf(stderr, dgettext(domainname,
653 		"%s: %s failed\n"), p, "malloc()");
654 	    break;
655 	case 7:
656 	    fprintf(stderr, dgettext(domainname,
657 		"%s: Bad date/time format\n"), p);
658 	    fp = fopen(value, "r");
659 	    if (fp == (FILE *)0)
660 		break;
661 	    now = time((time_t *)0);
662 	    tm = localtime(&now);
663 	    fprintf(stderr, dgettext(domainname,
664 		"The following are examples of valid formats:\n"));
665 	    while (fgets(fmt, sizeof (fmt), fp)) {
666 		if (strchr(fmt, '%') == (char *)0)
667 		    continue;
668 		fprintf(stderr, "    ");
669 	        (void) strftime(line, sizeof (line), fmt, tm);
670 		fprintf(stderr, "%s", line);
671 	    }
672 	    (void) fclose(fp);
673 	    break;
674 	case 8:
675 	    (void) fprintf(stderr, dgettext(domainname,
676 		"%s: Invalid date specification\n"), p);
677 	    break;
678     }
679 }
680 
681 #undef yylex
682 static int
683 yylex()
684 {
685     char	c;
686     char	*p;
687     char	buff[20];
688     int		Count;
689     int		sign;
690 
691     for ( ; ; ) {
692 	while (isspace((u_char)*yyInput))
693 	    yyInput++;
694 
695 	if (isdigit((u_char)(c = *yyInput)) || c == '-' || c == '+') {
696 	    if (c == '-' || c == '+') {
697 		sign = c == '-' ? -1 : 1;
698 		if (!isdigit((u_char)*++yyInput))
699 		    /* skip the '-' sign */
700 		    continue;
701 	    }
702 	    else
703 		sign = 0;
704 	    yylval.Number = 0;
705 	    while (isdigit((u_char)(c = *yyInput++))) {
706 		int n;
707 		char digit = c;
708 		(void) sscanf(&digit, "%1d", &n);
709 		yylval.Number = 10 * yylval.Number + n;
710 	    }
711 	    yyInput--;
712 	    if (sign < 0)
713 		yylval.Number = -yylval.Number;
714 	    return sign ? tSNUMBER : tUNUMBER;
715 	}
716 	if (isalpha((u_char)c)) {
717 	    for (p = buff; isalpha((u_char)(c = *yyInput++)) || c == '.'; )
718 		if (p < &buff[sizeof (buff) - 1])
719 		    *p++ = c;
720 	    *p = '\0';
721 	    yyInput--;
722 	    return LookupWord(buff);
723 	}
724 	if (c != '(')
725 	    return *yyInput++;
726 	Count = 0;
727 	do {
728 	    c = *yyInput++;
729 	    if (c == '\0')
730 		return c;
731 	    if (c == '(')
732 		Count++;
733 	    else if (c == ')')
734 		Count--;
735 	} while (Count > 0);
736     }
737 }
738 
739 
740 time_t
741 getreldate(p, now)
742     char		*p;
743     struct timeb	*now;
744 {
745     struct tm		*tm;
746     struct timeb	ftz;
747     time_t		Start;
748     time_t		tod;
749 
750     if (strcmp(setlocale(LC_TIME, NULL), "C")) {
751 	static char localedate[24];
752 	struct tm ltm;
753 
754 	tm = getdate(p);
755 	if (getdate_err == 1 /* NODATEMASK */) {
756 	    char buffy[BUFSIZ];
757 	    time_t current;
758 
759 	    printf(gettext("environment variable %s not set\n"), "DATEMSK");
760 	    do {
761 		time(&current);
762 		tm = localtime(&current);
763 		memcpy(&ltm, tm, sizeof(ltm));
764 		tm = &ltm;
765 
766 		(void) fputs(gettext("Enter date as mmddhhmm[yy]: "), stdout);
767 		(void) fflush(stdout);
768 		if (fgets(buffy, sizeof (buffy), stdin) == NULL) {
769 			(void) printf(gettext("Encountered EOF on stdin\n"));
770 			return(-1);
771 		}
772 	    } while (sscanf(buffy, "%2d%2d%2d%2d%2d",
773 		&(tm->tm_mon), &(tm->tm_mday), &(tm->tm_hour),
774 		&(tm->tm_min), &(tm->tm_year)) < 4);
775 
776 	    (tm->tm_mon)--;
777 	} else if (tm == NULL)
778 	    return(-1);
779 
780 	(void)sprintf(localedate, "%d:%2.2d %d/%d %d",
781 	    tm->tm_hour, tm->tm_min, tm->tm_mon + 1,
782 	    tm->tm_mday, CHECK_TM(tm->tm_year));
783 	p = localedate;
784     }
785 
786     yyInput = p;
787     if (now == NULL) {
788 	now = &ftz;
789 	(void) time(&ftz.time);
790 	/* Set the timezone global. */
791 	tzset();
792 	/* LINTED timezone is time_t so intermediate results aren't truncated */
793 	ftz.timezone = (int) timezone / 60;
794     }
795 
796     tm = localtime(&now->time);
797     yyYear = tm->tm_year;
798     yyMonth = tm->tm_mon + 1;
799     yyDay = tm->tm_mday;
800     yyTimezone = now->timezone;
801     yyDSTmode = DSTmaybe;
802     yyHour = tm->tm_hour;
803     yyMinutes = tm->tm_min;
804     yySeconds = tm->tm_sec;
805     yyMeridian = MER24;
806     yyRelSeconds = 0;
807     yyRelMonth = 0;
808     yyHaveDate = 0;
809     yyHaveDay = 0;
810     yyHaveRel = 0;
811     yyHaveTime = 0;
812     yyHaveZone = 0;
813 
814     if (yyparse()
815      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
816 	return -1;
817 
818     if (yyHaveDate || yyHaveTime || yyHaveDay) {
819 	Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
820 		    yyMeridian, yyDSTmode);
821 	if (Start < 0)
822 	    return -1;
823     }
824     else {
825 	Start = now->time;
826 	if (!yyHaveRel)
827 	    Start -= ((tm->tm_hour * 60L) + tm->tm_min * 60L) + tm->tm_sec;
828     }
829 
830     Start += yyRelSeconds;
831     Start += RelativeMonth(Start, yyRelMonth);
832 
833     if (yyHaveDay && !yyHaveDate) {
834 	tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
835 	Start += tod;
836     }
837 
838     /* Have to do *something* with a legitimate -1 so it's distinguishable
839      * from the error return value.  (Alternately could set errno on error.) */
840     return Start == -1 ? 0 : Start;
841 }
842 
843 #if	defined(TEST)
844 
845 /* ARGSUSED */
846 main(ac, av)
847     int		ac;
848     char	*av[];
849 {
850     char	buff[128];
851     time_t	d;
852 
853     (void) setlocale(LC_ALL, "");
854 #if !defined(TEXT_DOMAIN)
855 #define	TEXT_DOMAIN "SYS_TEST"
856 #endif
857     (void) textdomain(TEXT_DOMAIN);
858 
859     (void) printf(gettext("Enter date, or blank line to exit.\n\t> "));
860     (void) fflush(stdout);
861     while (gets(buff) && buff[0]) {
862 	d = getreldate(buff, (struct timeb *)NULL);
863 	if (d == -1)
864 	    (void) printf(gettext("Bad format - couldn't convert.\n"));
865 	else {
866 	    (void) cftime(buff, "%c\n", &d);
867 	    (void) printf("%s", buff);
868 	}
869 	(void) printf("\t> ");
870 	(void) fflush(stdout);
871     }
872     exit(0);
873     /* NOTREACHED */
874 }
875 #endif	/* defined(TEST) */
876 static YYCONST yytabelem yyexca[] ={
877 -1, 1,
878 	0, -1,
879 	-2, 0,
880 	};
881 # define YYNPROD 39
882 # define YYLAST 221
883 static YYCONST yytabelem yyact[]={
884 
885     13,    11,    22,    39,    16,    12,    18,    17,    15,     9,
886     10,    40,    44,    20,    43,    42,    46,    29,    35,    34,
887     33,    30,    27,    32,    31,    41,    36,    28,    37,    14,
888      8,     7,     6,     5,     4,     3,     2,     1,     0,     0,
889      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
890      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
891      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
892      0,     0,    45,     0,     0,     0,     0,     0,     0,     0,
893      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
894      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
895      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
896      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
897      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
898      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
899      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
900      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
901      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
902      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
903      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
904      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
905      0,     0,     0,     0,     0,     0,    40,     0,     0,     0,
906      0,    38,     0,    21,     0,     0,    19,    24,    23,    26,
907     25 };
908 static YYCONST yytabelem yypact[]={
909 
910 -10000000,  -258,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,-10000000,   -45,
911 -10000000,-10000000,  -245,   -17,  -240,  -241,-10000000,-10000000,-10000000,-10000000,
912   -247,-10000000,  -248,  -249,-10000000,-10000000,-10000000,   -18,-10000000,-10000000,
913 -10000000,-10000000,-10000000,   -55,   -22,-10000000,  -252,-10000000,-10000000,  -253,
914 -10000000,  -255,-10000000,  -250,-10000000,-10000000,-10000000 };
915 static YYCONST yytabelem yypgo[]={
916 
917      0,    28,    37,    36,    35,    34,    33,    32,    31,    30,
918     29 };
919 static YYCONST yytabelem yyr1[]={
920 
921      0,     2,     2,     3,     3,     3,     3,     3,     3,     4,
922      4,     4,     4,     4,     5,     5,     7,     7,     7,     6,
923      6,     6,     6,     6,     6,     8,     8,    10,    10,    10,
924     10,    10,    10,    10,    10,    10,     9,     1,     1 };
925 static YYCONST yytabelem yyr2[]={
926 
927      0,     0,     4,     3,     3,     3,     3,     3,     2,     5,
928      9,     9,    13,    13,     3,     3,     3,     5,     5,     7,
929     11,     5,     9,     5,     7,     5,     2,     5,     5,     3,
930      5,     5,     3,     5,     5,     3,     3,     1,     3 };
931 static YYCONST yytabelem yychk[]={
932 
933 -10000000,    -2,    -3,    -4,    -5,    -6,    -7,    -8,    -9,   267,
934    268,   259,   263,   258,   -10,   266,   262,   265,   264,   261,
935     58,   258,    47,   263,   262,   265,   264,   267,    44,   257,
936    262,   265,   264,   267,   267,   267,    44,    -1,   266,    58,
937    261,    47,   267,   267,   267,    -1,   266 };
938 static YYCONST yytabelem yydef[]={
939 
940      1,    -2,     2,     3,     4,     5,     6,     7,     8,    36,
941     14,    15,     0,    16,    26,     0,    29,    32,    35,     9,
942      0,    18,     0,    23,    27,    31,    34,    21,    17,    25,
943     28,    30,    33,    37,    19,    24,     0,    10,    11,     0,
944     38,     0,    22,    37,    20,    12,    13 };
945 typedef struct
946 #ifdef __cplusplus
947 	yytoktype
948 #endif
949 {
950 #ifdef __cplusplus
951 const
952 #endif
953 char *t_name; int t_val; } yytoktype;
954 #ifndef YYDEBUG
955 #	define YYDEBUG	0	/* don't allow debugging */
956 #endif
957 
958 #if YYDEBUG
959 
960 yytoktype yytoks[] =
961 {
962 	"tAGO",	257,
963 	"tDAY",	258,
964 	"tDAYZONE",	259,
965 	"tID",	260,
966 	"tMERIDIAN",	261,
967 	"tMINUTE_UNIT",	262,
968 	"tMONTH",	263,
969 	"tMONTH_UNIT",	264,
970 	"tSEC_UNIT",	265,
971 	"tSNUMBER",	266,
972 	"tUNUMBER",	267,
973 	"tZONE",	268,
974 	"-unknown-",	-1	/* ends search */
975 };
976 
977 #ifdef __cplusplus
978 const
979 #endif
980 char * yyreds[] =
981 {
982 	"-no such reduction-",
983 	"spec : /* empty */",
984 	"spec : spec item",
985 	"item : time",
986 	"item : zone",
987 	"item : date",
988 	"item : day",
989 	"item : rel",
990 	"item : number",
991 	"time : tUNUMBER tMERIDIAN",
992 	"time : tUNUMBER ':' tUNUMBER o_merid",
993 	"time : tUNUMBER ':' tUNUMBER tSNUMBER",
994 	"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
995 	"time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
996 	"zone : tZONE",
997 	"zone : tDAYZONE",
998 	"day : tDAY",
999 	"day : tDAY ','",
1000 	"day : tUNUMBER tDAY",
1001 	"date : tUNUMBER '/' tUNUMBER",
1002 	"date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
1003 	"date : tMONTH tUNUMBER",
1004 	"date : tMONTH tUNUMBER ',' tUNUMBER",
1005 	"date : tUNUMBER tMONTH",
1006 	"date : tUNUMBER tMONTH tUNUMBER",
1007 	"rel : relunit tAGO",
1008 	"rel : relunit",
1009 	"relunit : tUNUMBER tMINUTE_UNIT",
1010 	"relunit : tSNUMBER tMINUTE_UNIT",
1011 	"relunit : tMINUTE_UNIT",
1012 	"relunit : tSNUMBER tSEC_UNIT",
1013 	"relunit : tUNUMBER tSEC_UNIT",
1014 	"relunit : tSEC_UNIT",
1015 	"relunit : tSNUMBER tMONTH_UNIT",
1016 	"relunit : tUNUMBER tMONTH_UNIT",
1017 	"relunit : tMONTH_UNIT",
1018 	"number : tUNUMBER",
1019 	"o_merid : /* empty */",
1020 	"o_merid : tMERIDIAN",
1021 };
1022 #endif /* YYDEBUG */
1023 # line	1 "/usr/share/lib/ccs/yaccpar"
1024 /*
1025  * CDDL HEADER START
1026  *
1027  * The contents of this file are subject to the terms of the
1028  * Common Development and Distribution License, Version 1.0 only
1029  * (the "License").  You may not use this file except in compliance
1030  * with the License.
1031  *
1032  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1033  * or http://www.opensolaris.org/os/licensing.
1034  * See the License for the specific language governing permissions
1035  * and limitations under the License.
1036  *
1037  * When distributing Covered Code, include this CDDL HEADER in each
1038  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1039  * If applicable, add the following below this CDDL HEADER, with the
1040  * fields enclosed by brackets "[]" replaced with your own identifying
1041  * information: Portions Copyright [yyyy] [name of copyright owner]
1042  *
1043  * CDDL HEADER END
1044  */
1045 /*
1046  * Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
1047  * Use is subject to license terms.
1048  */
1049 
1050 /* Copyright (c) 1988 AT&T */
1051 /* All Rights Reserved */
1052 
1053 #pragma ident	"%Z%%M%	%I%	%E% SMI"
1054 
1055 /*
1056 ** Skeleton parser driver for yacc output
1057 */
1058 
1059 /*
1060 ** yacc user known macros and defines
1061 */
1062 #define YYERROR		goto yyerrlab
1063 #define YYACCEPT	return(0)
1064 #define YYABORT		return(1)
1065 #define YYBACKUP( newtoken, newvalue )\
1066 {\
1067 	if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
1068 	{\
1069 		yyerror( "syntax error - cannot backup" );\
1070 		goto yyerrlab;\
1071 	}\
1072 	yychar = newtoken;\
1073 	yystate = *yyps;\
1074 	yylval = newvalue;\
1075 	goto yynewstate;\
1076 }
1077 #define YYRECOVERING()	(!!yyerrflag)
1078 #define YYNEW(type)	malloc(sizeof(type) * yynewmax)
1079 #define YYCOPY(to, from, type) \
1080 	(type *) memcpy(to, (char *) from, yymaxdepth * sizeof (type))
1081 #define YYENLARGE( from, type) \
1082 	(type *) realloc((char *) from, yynewmax * sizeof(type))
1083 #ifndef YYDEBUG
1084 #	define YYDEBUG	1	/* make debugging available */
1085 #endif
1086 
1087 /*
1088 ** user known globals
1089 */
1090 int yydebug;			/* set to 1 to get debugging */
1091 
1092 /*
1093 ** driver internal defines
1094 */
1095 #define YYFLAG		(-10000000)
1096 
1097 /*
1098 ** global variables used by the parser
1099 */
1100 YYSTYPE *yypv;			/* top of value stack */
1101 int *yyps;			/* top of state stack */
1102 
1103 int yystate;			/* current state */
1104 int yytmp;			/* extra var (lasts between blocks) */
1105 
1106 int yynerrs;			/* number of errors */
1107 int yyerrflag;			/* error recovery flag */
1108 int yychar;			/* current input token number */
1109 
1110 
1111 
1112 #ifdef YYNMBCHARS
1113 #define YYLEX()		yycvtok(yylex())
1114 /*
1115 ** yycvtok - return a token if i is a wchar_t value that exceeds 255.
1116 **	If i<255, i itself is the token.  If i>255 but the neither
1117 **	of the 30th or 31st bit is on, i is already a token.
1118 */
1119 #if defined(__STDC__) || defined(__cplusplus)
1120 int yycvtok(int i)
1121 #else
1122 int yycvtok(i) int i;
1123 #endif
1124 {
1125 	int first = 0;
1126 	int last = YYNMBCHARS - 1;
1127 	int mid;
1128 	wchar_t j;
1129 
1130 	if(i&0x60000000){/*Must convert to a token. */
1131 		if( yymbchars[last].character < i ){
1132 			return i;/*Giving up*/
1133 		}
1134 		while ((last>=first)&&(first>=0)) {/*Binary search loop*/
1135 			mid = (first+last)/2;
1136 			j = yymbchars[mid].character;
1137 			if( j==i ){/*Found*/
1138 				return yymbchars[mid].tvalue;
1139 			}else if( j<i ){
1140 				first = mid + 1;
1141 			}else{
1142 				last = mid -1;
1143 			}
1144 		}
1145 		/*No entry in the table.*/
1146 		return i;/* Giving up.*/
1147 	}else{/* i is already a token. */
1148 		return i;
1149 	}
1150 }
1151 #else/*!YYNMBCHARS*/
1152 #define YYLEX()		yylex()
1153 #endif/*!YYNMBCHARS*/
1154 
1155 /*
1156 ** yyparse - return 0 if worked, 1 if syntax error not recovered from
1157 */
1158 #if defined(__STDC__) || defined(__cplusplus)
1159 int yyparse(void)
1160 #else
1161 int yyparse()
1162 #endif
1163 {
1164 	register YYSTYPE *yypvt = 0;	/* top of value stack for $vars */
1165 
1166 #if defined(__cplusplus) || defined(lint)
1167 /*
1168 	hacks to please C++ and lint - goto's inside
1169 	switch should never be executed
1170 */
1171 	static int __yaccpar_lint_hack__ = 0;
1172 	switch (__yaccpar_lint_hack__)
1173 	{
1174 		case 1: goto yyerrlab;
1175 		case 2: goto yynewstate;
1176 	}
1177 #endif
1178 
1179 	/*
1180 	** Initialize externals - yyparse may be called more than once
1181 	*/
1182 	yypv = &yyv[-1];
1183 	yyps = &yys[-1];
1184 	yystate = 0;
1185 	yytmp = 0;
1186 	yynerrs = 0;
1187 	yyerrflag = 0;
1188 	yychar = -1;
1189 
1190 #if YYMAXDEPTH <= 0
1191 	if (yymaxdepth <= 0)
1192 	{
1193 		if ((yymaxdepth = YYEXPAND(0)) <= 0)
1194 		{
1195 			yyerror("yacc initialization error");
1196 			YYABORT;
1197 		}
1198 	}
1199 #endif
1200 
1201 	{
1202 		register YYSTYPE *yy_pv;	/* top of value stack */
1203 		register int *yy_ps;		/* top of state stack */
1204 		register int yy_state;		/* current state */
1205 		register int  yy_n;		/* internal state number info */
1206 	goto yystack;	/* moved from 6 lines above to here to please C++ */
1207 
1208 		/*
1209 		** get globals into registers.
1210 		** branch to here only if YYBACKUP was called.
1211 		*/
1212 	yynewstate:
1213 		yy_pv = yypv;
1214 		yy_ps = yyps;
1215 		yy_state = yystate;
1216 		goto yy_newstate;
1217 
1218 		/*
1219 		** get globals into registers.
1220 		** either we just started, or we just finished a reduction
1221 		*/
1222 	yystack:
1223 		yy_pv = yypv;
1224 		yy_ps = yyps;
1225 		yy_state = yystate;
1226 
1227 		/*
1228 		** top of for (;;) loop while no reductions done
1229 		*/
1230 	yy_stack:
1231 		/*
1232 		** put a state and value onto the stacks
1233 		*/
1234 #if YYDEBUG
1235 		/*
1236 		** if debugging, look up token value in list of value vs.
1237 		** name pairs.  0 and negative (-1) are special values.
1238 		** Note: linear search is used since time is not a real
1239 		** consideration while debugging.
1240 		*/
1241 		if ( yydebug )
1242 		{
1243 			register int yy_i;
1244 
1245 			printf( "State %d, token ", yy_state );
1246 			if ( yychar == 0 )
1247 				printf( "end-of-file\n" );
1248 			else if ( yychar < 0 )
1249 				printf( "-none-\n" );
1250 			else
1251 			{
1252 				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
1253 					yy_i++ )
1254 				{
1255 					if ( yytoks[yy_i].t_val == yychar )
1256 						break;
1257 				}
1258 				printf( "%s\n", yytoks[yy_i].t_name );
1259 			}
1260 		}
1261 #endif /* YYDEBUG */
1262 		if ( ++yy_ps >= &yys[ yymaxdepth ] )	/* room on stack? */
1263 		{
1264 			/*
1265 			** reallocate and recover.  Note that pointers
1266 			** have to be reset, or bad things will happen
1267 			*/
1268 			long yyps_index = (yy_ps - yys);
1269 			long yypv_index = (yy_pv - yyv);
1270 			long yypvt_index = (yypvt - yyv);
1271 			int yynewmax;
1272 #ifdef YYEXPAND
1273 			yynewmax = YYEXPAND(yymaxdepth);
1274 #else
1275 			yynewmax = 2 * yymaxdepth;	/* double table size */
1276 			if (yymaxdepth == YYMAXDEPTH)	/* first time growth */
1277 			{
1278 				char *newyys = (char *)YYNEW(int);
1279 				char *newyyv = (char *)YYNEW(YYSTYPE);
1280 				if (newyys != 0 && newyyv != 0)
1281 				{
1282 					yys = YYCOPY(newyys, yys, int);
1283 					yyv = YYCOPY(newyyv, yyv, YYSTYPE);
1284 				}
1285 				else
1286 					yynewmax = 0;	/* failed */
1287 			}
1288 			else				/* not first time */
1289 			{
1290 				yys = YYENLARGE(yys, int);
1291 				yyv = YYENLARGE(yyv, YYSTYPE);
1292 				if (yys == 0 || yyv == 0)
1293 					yynewmax = 0;	/* failed */
1294 			}
1295 #endif
1296 			if (yynewmax <= yymaxdepth)	/* tables not expanded */
1297 			{
1298 				yyerror( "yacc stack overflow" );
1299 				YYABORT;
1300 			}
1301 			yymaxdepth = yynewmax;
1302 
1303 			yy_ps = yys + yyps_index;
1304 			yy_pv = yyv + yypv_index;
1305 			yypvt = yyv + yypvt_index;
1306 		}
1307 		*yy_ps = yy_state;
1308 		*++yy_pv = yyval;
1309 
1310 		/*
1311 		** we have a new state - find out what to do
1312 		*/
1313 	yy_newstate:
1314 		if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
1315 			goto yydefault;		/* simple state */
1316 #if YYDEBUG
1317 		/*
1318 		** if debugging, need to mark whether new token grabbed
1319 		*/
1320 		yytmp = yychar < 0;
1321 #endif
1322 		if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) )
1323 			yychar = 0;		/* reached EOF */
1324 #if YYDEBUG
1325 		if ( yydebug && yytmp )
1326 		{
1327 			register int yy_i;
1328 
1329 			printf( "Received token " );
1330 			if ( yychar == 0 )
1331 				printf( "end-of-file\n" );
1332 			else if ( yychar < 0 )
1333 				printf( "-none-\n" );
1334 			else
1335 			{
1336 				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
1337 					yy_i++ )
1338 				{
1339 					if ( yytoks[yy_i].t_val == yychar )
1340 						break;
1341 				}
1342 				printf( "%s\n", yytoks[yy_i].t_name );
1343 			}
1344 		}
1345 #endif /* YYDEBUG */
1346 		if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
1347 			goto yydefault;
1348 		if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar )	/*valid shift*/
1349 		{
1350 			yychar = -1;
1351 			yyval = yylval;
1352 			yy_state = yy_n;
1353 			if ( yyerrflag > 0 )
1354 				yyerrflag--;
1355 			goto yy_stack;
1356 		}
1357 
1358 	yydefault:
1359 		if ( ( yy_n = yydef[ yy_state ] ) == -2 )
1360 		{
1361 #if YYDEBUG
1362 			yytmp = yychar < 0;
1363 #endif
1364 			if ( ( yychar < 0 ) && ( ( yychar = YYLEX() ) < 0 ) )
1365 				yychar = 0;		/* reached EOF */
1366 #if YYDEBUG
1367 			if ( yydebug && yytmp )
1368 			{
1369 				register int yy_i;
1370 
1371 				printf( "Received token " );
1372 				if ( yychar == 0 )
1373 					printf( "end-of-file\n" );
1374 				else if ( yychar < 0 )
1375 					printf( "-none-\n" );
1376 				else
1377 				{
1378 					for ( yy_i = 0;
1379 						yytoks[yy_i].t_val >= 0;
1380 						yy_i++ )
1381 					{
1382 						if ( yytoks[yy_i].t_val
1383 							== yychar )
1384 						{
1385 							break;
1386 						}
1387 					}
1388 					printf( "%s\n", yytoks[yy_i].t_name );
1389 				}
1390 			}
1391 #endif /* YYDEBUG */
1392 			/*
1393 			** look through exception table
1394 			*/
1395 			{
1396 				register YYCONST int *yyxi = yyexca;
1397 
1398 				while ( ( *yyxi != -1 ) ||
1399 					( yyxi[1] != yy_state ) )
1400 				{
1401 					yyxi += 2;
1402 				}
1403 				while ( ( *(yyxi += 2) >= 0 ) &&
1404 					( *yyxi != yychar ) )
1405 					;
1406 				if ( ( yy_n = yyxi[1] ) < 0 )
1407 					YYACCEPT;
1408 			}
1409 		}
1410 
1411 		/*
1412 		** check for syntax error
1413 		*/
1414 		if ( yy_n == 0 )	/* have an error */
1415 		{
1416 			/* no worry about speed here! */
1417 			switch ( yyerrflag )
1418 			{
1419 			case 0:		/* new error */
1420 				yyerror( "syntax error" );
1421 				goto skip_init;
1422 			yyerrlab:
1423 				/*
1424 				** get globals into registers.
1425 				** we have a user generated syntax type error
1426 				*/
1427 				yy_pv = yypv;
1428 				yy_ps = yyps;
1429 				yy_state = yystate;
1430 			skip_init:
1431 				yynerrs++;
1432 				/* FALLTHRU */
1433 			case 1:
1434 			case 2:		/* incompletely recovered error */
1435 					/* try again... */
1436 				yyerrflag = 3;
1437 				/*
1438 				** find state where "error" is a legal
1439 				** shift action
1440 				*/
1441 				while ( yy_ps >= yys )
1442 				{
1443 					yy_n = yypact[ *yy_ps ] + YYERRCODE;
1444 					if ( yy_n >= 0 && yy_n < YYLAST &&
1445 						yychk[yyact[yy_n]] == YYERRCODE)					{
1446 						/*
1447 						** simulate shift of "error"
1448 						*/
1449 						yy_state = yyact[ yy_n ];
1450 						goto yy_stack;
1451 					}
1452 					/*
1453 					** current state has no shift on
1454 					** "error", pop stack
1455 					*/
1456 #if YYDEBUG
1457 #	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
1458 					if ( yydebug )
1459 						printf( _POP_, *yy_ps,
1460 							yy_ps[-1] );
1461 #	undef _POP_
1462 #endif
1463 					yy_ps--;
1464 					yy_pv--;
1465 				}
1466 				/*
1467 				** there is no state on stack with "error" as
1468 				** a valid shift.  give up.
1469 				*/
1470 				YYABORT;
1471 			case 3:		/* no shift yet; eat a token */
1472 #if YYDEBUG
1473 				/*
1474 				** if debugging, look up token in list of
1475 				** pairs.  0 and negative shouldn't occur,
1476 				** but since timing doesn't matter when
1477 				** debugging, it doesn't hurt to leave the
1478 				** tests here.
1479 				*/
1480 				if ( yydebug )
1481 				{
1482 					register int yy_i;
1483 
1484 					printf( "Error recovery discards " );
1485 					if ( yychar == 0 )
1486 						printf( "token end-of-file\n" );
1487 					else if ( yychar < 0 )
1488 						printf( "token -none-\n" );
1489 					else
1490 					{
1491 						for ( yy_i = 0;
1492 							yytoks[yy_i].t_val >= 0;
1493 							yy_i++ )
1494 						{
1495 							if ( yytoks[yy_i].t_val
1496 								== yychar )
1497 							{
1498 								break;
1499 							}
1500 						}
1501 						printf( "token %s\n",
1502 							yytoks[yy_i].t_name );
1503 					}
1504 				}
1505 #endif /* YYDEBUG */
1506 				if ( yychar == 0 )	/* reached EOF. quit */
1507 					YYABORT;
1508 				yychar = -1;
1509 				goto yy_newstate;
1510 			}
1511 		}/* end if ( yy_n == 0 ) */
1512 		/*
1513 		** reduction by production yy_n
1514 		** put stack tops, etc. so things right after switch
1515 		*/
1516 #if YYDEBUG
1517 		/*
1518 		** if debugging, print the string that is the user's
1519 		** specification of the reduction which is just about
1520 		** to be done.
1521 		*/
1522 		if ( yydebug )
1523 			printf( "Reduce by (%d) \"%s\"\n",
1524 				yy_n, yyreds[ yy_n ] );
1525 #endif
1526 		yytmp = yy_n;			/* value to switch over */
1527 		yypvt = yy_pv;			/* $vars top of value stack */
1528 		/*
1529 		** Look in goto table for next state
1530 		** Sorry about using yy_state here as temporary
1531 		** register variable, but why not, if it works...
1532 		** If yyr2[ yy_n ] doesn't have the low order bit
1533 		** set, then there is no action to be done for
1534 		** this reduction.  So, no saving & unsaving of
1535 		** registers done.  The only difference between the
1536 		** code just after the if and the body of the if is
1537 		** the goto yy_stack in the body.  This way the test
1538 		** can be made before the choice of what to do is needed.
1539 		*/
1540 		{
1541 			/* length of production doubled with extra bit */
1542 			register int yy_len = yyr2[ yy_n ];
1543 
1544 			if ( !( yy_len & 01 ) )
1545 			{
1546 				yy_len >>= 1;
1547 				yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
1548 				yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
1549 					*( yy_ps -= yy_len ) + 1;
1550 				if ( yy_state >= YYLAST ||
1551 					yychk[ yy_state =
1552 					yyact[ yy_state ] ] != -yy_n )
1553 				{
1554 					yy_state = yyact[ yypgo[ yy_n ] ];
1555 				}
1556 				goto yy_stack;
1557 			}
1558 			yy_len >>= 1;
1559 			yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
1560 			yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
1561 				*( yy_ps -= yy_len ) + 1;
1562 			if ( yy_state >= YYLAST ||
1563 				yychk[ yy_state = yyact[ yy_state ] ] != -yy_n )
1564 			{
1565 				yy_state = yyact[ yypgo[ yy_n ] ];
1566 			}
1567 		}
1568 					/* save until reenter driver code */
1569 		yystate = yy_state;
1570 		yyps = yy_ps;
1571 		yypv = yy_pv;
1572 	}
1573 	/*
1574 	** code supplied by user is placed in this switch
1575 	*/
1576 	switch( yytmp )
1577 	{
1578 
1579 case 3:
1580 # line 127 "getdate.y"
1581 {
1582 	    yyHaveTime++;
1583 	} break;
1584 case 4:
1585 # line 130 "getdate.y"
1586 {
1587 	    yyHaveZone++;
1588 	} break;
1589 case 5:
1590 # line 133 "getdate.y"
1591 {
1592 	    yyHaveDate++;
1593 	} break;
1594 case 6:
1595 # line 136 "getdate.y"
1596 {
1597 	    yyHaveDay++;
1598 	} break;
1599 case 7:
1600 # line 139 "getdate.y"
1601 {
1602 	    yyHaveRel++;
1603 	} break;
1604 case 9:
1605 # line 145 "getdate.y"
1606 {
1607 	    yyHour = yypvt[-1].Number;
1608 	    yyMinutes = 0;
1609 	    yySeconds = 0;
1610 	    yyMeridian = yypvt[-0].Meridian;
1611 	} break;
1612 case 10:
1613 # line 151 "getdate.y"
1614 {
1615 	    yyHour = yypvt[-3].Number;
1616 	    yyMinutes = yypvt[-1].Number;
1617 	    yySeconds = 0;
1618 	    yyMeridian = yypvt[-0].Meridian;
1619 	} break;
1620 case 11:
1621 # line 157 "getdate.y"
1622 {
1623 	    yyHour = yypvt[-3].Number;
1624 	    yyMinutes = yypvt[-1].Number;
1625 	    yyMeridian = MER24;
1626 	    yyDSTmode = DSToff;
1627 	    yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60);
1628 	} break;
1629 case 12:
1630 # line 164 "getdate.y"
1631 {
1632 	    yyHour = yypvt[-5].Number;
1633 	    yyMinutes = yypvt[-3].Number;
1634 	    yySeconds = yypvt[-1].Number;
1635 	    yyMeridian = yypvt[-0].Meridian;
1636 	} break;
1637 case 13:
1638 # line 170 "getdate.y"
1639 {
1640 	    yyHour = yypvt[-5].Number;
1641 	    yyMinutes = yypvt[-3].Number;
1642 	    yySeconds = yypvt[-1].Number;
1643 	    yyMeridian = MER24;
1644 	    yyDSTmode = DSToff;
1645 	    yyTimezone = - (yypvt[-0].Number % 100 + (yypvt[-0].Number / 100) * 60);
1646 	} break;
1647 case 14:
1648 # line 180 "getdate.y"
1649 {
1650 	    yyTimezone = yypvt[-0].Number;
1651 	    yyDSTmode = DSToff;
1652 	} break;
1653 case 15:
1654 # line 184 "getdate.y"
1655 {
1656 	    yyTimezone = yypvt[-0].Number;
1657 	    yyDSTmode = DSTon;
1658 	} break;
1659 case 16:
1660 # line 190 "getdate.y"
1661 {
1662 	    yyDayOrdinal = 1;
1663 	    yyDayNumber = yypvt[-0].Number;
1664 	} break;
1665 case 17:
1666 # line 194 "getdate.y"
1667 {
1668 	    yyDayOrdinal = 1;
1669 	    yyDayNumber = yypvt[-1].Number;
1670 	} break;
1671 case 18:
1672 # line 198 "getdate.y"
1673 {
1674 	    yyDayOrdinal = yypvt[-1].Number;
1675 	    yyDayNumber = yypvt[-0].Number;
1676 	} break;
1677 case 19:
1678 # line 204 "getdate.y"
1679 {
1680 	    yyMonth = yypvt[-2].Number;
1681 	    yyDay = yypvt[-0].Number;
1682 	} break;
1683 case 20:
1684 # line 208 "getdate.y"
1685 {
1686 	    yyMonth = yypvt[-4].Number;
1687 	    yyDay = yypvt[-2].Number;
1688 	    yyYear = yypvt[-0].Number;
1689 	} break;
1690 case 21:
1691 # line 213 "getdate.y"
1692 {
1693 	    yyMonth = yypvt[-1].Number;
1694 	    yyDay = yypvt[-0].Number;
1695 	} break;
1696 case 22:
1697 # line 217 "getdate.y"
1698 {
1699 	    yyMonth = yypvt[-3].Number;
1700 	    yyDay = yypvt[-2].Number;
1701 	    yyYear = yypvt[-0].Number;
1702 	} break;
1703 case 23:
1704 # line 222 "getdate.y"
1705 {
1706 	    yyMonth = yypvt[-0].Number;
1707 	    yyDay = yypvt[-1].Number;
1708 	} break;
1709 case 24:
1710 # line 226 "getdate.y"
1711 {
1712 	    yyMonth = yypvt[-1].Number;
1713 	    yyDay = yypvt[-2].Number;
1714 	    yyYear = yypvt[-0].Number;
1715 	} break;
1716 case 25:
1717 # line 233 "getdate.y"
1718 {
1719 	    yyRelSeconds = -yyRelSeconds;
1720 	    yyRelMonth = -yyRelMonth;
1721 	} break;
1722 case 27:
1723 # line 240 "getdate.y"
1724 {
1725 	    yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L;
1726 	} break;
1727 case 28:
1728 # line 243 "getdate.y"
1729 {
1730 	    yyRelSeconds += yypvt[-1].Number * yypvt[-0].Number * 60L;
1731 	} break;
1732 case 29:
1733 # line 246 "getdate.y"
1734 {
1735 	    yyRelSeconds += yypvt[-0].Number * 60L;
1736 	} break;
1737 case 30:
1738 # line 249 "getdate.y"
1739 {
1740 	    yyRelSeconds += yypvt[-1].Number;
1741 	} break;
1742 case 31:
1743 # line 252 "getdate.y"
1744 {
1745 	    yyRelSeconds += yypvt[-1].Number;
1746 	} break;
1747 case 32:
1748 # line 255 "getdate.y"
1749 {
1750 	    yyRelSeconds++;
1751 	} break;
1752 case 33:
1753 # line 258 "getdate.y"
1754 {
1755 	    yyRelMonth += yypvt[-1].Number * yypvt[-0].Number;
1756 	} break;
1757 case 34:
1758 # line 261 "getdate.y"
1759 {
1760 	    yyRelMonth += yypvt[-1].Number * yypvt[-0].Number;
1761 	} break;
1762 case 35:
1763 # line 264 "getdate.y"
1764 {
1765 	    yyRelMonth += yypvt[-0].Number;
1766 	} break;
1767 case 36:
1768 # line 269 "getdate.y"
1769 {
1770 	    if (yyHaveTime && yyHaveDate && !yyHaveRel)
1771 		yyYear = yypvt[-0].Number;
1772 	    else {
1773 		yyHaveTime++;
1774 		if (yypvt[-0].Number < 100) {
1775 		    yyHour = yypvt[-0].Number;
1776 		    yyMinutes = 0;
1777 		}
1778 		else {
1779 		    yyHour = yypvt[-0].Number / 100;
1780 		    yyMinutes = yypvt[-0].Number % 100;
1781 		}
1782 		yySeconds = 0;
1783 		yyMeridian = MER24;
1784 	    }
1785 	} break;
1786 case 37:
1787 # line 288 "getdate.y"
1788 {
1789 	    yyval.Meridian = MER24;
1790 	} break;
1791 case 38:
1792 # line 291 "getdate.y"
1793 {
1794 	    yyval.Meridian = yypvt[-0].Meridian;
1795 	} break;
1796 # line	556 "/usr/share/lib/ccs/yaccpar"
1797 	}
1798 	goto yystack;		/* reset registers in driver code */
1799 }
1800 
1801