xref: /titanic_51/usr/src/cmd/backup/lib/getdate.y (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate %{
2*7c478bd9Sstevel@tonic-gate /*
3*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1998 by Sun Microsystems, Inc.
4*7c478bd9Sstevel@tonic-gate  * All rights reserved.
5*7c478bd9Sstevel@tonic-gate  */
6*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
7*7c478bd9Sstevel@tonic-gate 
8*7c478bd9Sstevel@tonic-gate /* $OrigRevision: 2.1 $
9*7c478bd9Sstevel@tonic-gate **
10*7c478bd9Sstevel@tonic-gate **  Originally written by Steven M. Bellovin <smb@research.att.com> while
11*7c478bd9Sstevel@tonic-gate **  at the University of North Carolina at Chapel Hill.  Later tweaked by
12*7c478bd9Sstevel@tonic-gate **  a couple of people on Usenet.  Completely overhauled by Rich $alz
13*7c478bd9Sstevel@tonic-gate **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
14*7c478bd9Sstevel@tonic-gate **  send any email to Rich.
15*7c478bd9Sstevel@tonic-gate **
16*7c478bd9Sstevel@tonic-gate **  This grammar has eight shift/reduce conflicts.
17*7c478bd9Sstevel@tonic-gate **
18*7c478bd9Sstevel@tonic-gate **  This code is in the public domain and has no copyright.
19*7c478bd9Sstevel@tonic-gate */
20*7c478bd9Sstevel@tonic-gate /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
21*7c478bd9Sstevel@tonic-gate /* SUPPRESS 288 on yyerrlab *//* Label unused */
22*7c478bd9Sstevel@tonic-gate #include <stdio.h>
23*7c478bd9Sstevel@tonic-gate #include <ctype.h>
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
26*7c478bd9Sstevel@tonic-gate #define NEED_TZSET
27*7c478bd9Sstevel@tonic-gate struct timeb {
28*7c478bd9Sstevel@tonic-gate     time_t		time;		/* Seconds since the epoch	*/
29*7c478bd9Sstevel@tonic-gate     unsigned short	millitm;	/* Field not used		*/
30*7c478bd9Sstevel@tonic-gate     short		timezone;
31*7c478bd9Sstevel@tonic-gate     short		dstflag;	/* Field not used		*/
32*7c478bd9Sstevel@tonic-gate };
33*7c478bd9Sstevel@tonic-gate #include <time.h>
34*7c478bd9Sstevel@tonic-gate 
35*7c478bd9Sstevel@tonic-gate #include <locale.h>
36*7c478bd9Sstevel@tonic-gate #include <string.h>
37*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
38*7c478bd9Sstevel@tonic-gate #include <note.h>
39*7c478bd9Sstevel@tonic-gate #include <libintl.h>
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #if	!defined(lint) && !defined(SABER)
42*7c478bd9Sstevel@tonic-gate static char RCS[] =
43*7c478bd9Sstevel@tonic-gate 	"$Header: /home/laramie/berliner/ws/backup/usr/src/cmd/backup/lib/getdate.y,v 1.5 1992/06/09 21:46:21 sam Exp $";
44*7c478bd9Sstevel@tonic-gate #endif	/* !defined(lint) && !defined(SABER) */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #define EPOCH		1970
48*7c478bd9Sstevel@tonic-gate #define HOURN(x)	(x * 60)
49*7c478bd9Sstevel@tonic-gate #define SECSPERDAY	(24L * 60L * 60L)
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define CHECK_TM(y) (((y) % 100) < 70 ? (y) + 2000 : (y) + 1900)
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate /*
54*7c478bd9Sstevel@tonic-gate **  An entry in the lexical lookup table.
55*7c478bd9Sstevel@tonic-gate */
56*7c478bd9Sstevel@tonic-gate typedef struct _TABLE {
57*7c478bd9Sstevel@tonic-gate     char	*name;
58*7c478bd9Sstevel@tonic-gate     int		type;
59*7c478bd9Sstevel@tonic-gate     time_t	value;
60*7c478bd9Sstevel@tonic-gate } TABLE;
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 
63*7c478bd9Sstevel@tonic-gate /*
64*7c478bd9Sstevel@tonic-gate **  Daylight-savings mode:  on, off, or not yet known.
65*7c478bd9Sstevel@tonic-gate */
66*7c478bd9Sstevel@tonic-gate typedef enum _DSTMODE {
67*7c478bd9Sstevel@tonic-gate     DSTon, DSToff, DSTmaybe
68*7c478bd9Sstevel@tonic-gate } DSTMODE;
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /*
71*7c478bd9Sstevel@tonic-gate **  Meridian:  am, pm, or 24-hour style.
72*7c478bd9Sstevel@tonic-gate */
73*7c478bd9Sstevel@tonic-gate typedef enum _MERIDIAN {
74*7c478bd9Sstevel@tonic-gate     MERam, MERpm, MER24
75*7c478bd9Sstevel@tonic-gate } MERIDIAN;
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate /*
79*7c478bd9Sstevel@tonic-gate **  Global variables.  We could get rid of most of these by using a good
80*7c478bd9Sstevel@tonic-gate **  union as the yacc stack.  (This routine was originally written before
81*7c478bd9Sstevel@tonic-gate **  yacc had the %union construct.)  Maybe someday; right now we only use
82*7c478bd9Sstevel@tonic-gate **  the %union very rarely.
83*7c478bd9Sstevel@tonic-gate */
84*7c478bd9Sstevel@tonic-gate static char	*yyInput;
85*7c478bd9Sstevel@tonic-gate static DSTMODE	yyDSTmode;
86*7c478bd9Sstevel@tonic-gate static time_t	yyDayOrdinal;
87*7c478bd9Sstevel@tonic-gate static time_t	yyDayNumber;
88*7c478bd9Sstevel@tonic-gate static int	yyHaveDate;
89*7c478bd9Sstevel@tonic-gate static int	yyHaveDay;
90*7c478bd9Sstevel@tonic-gate static int	yyHaveRel;
91*7c478bd9Sstevel@tonic-gate static int	yyHaveTime;
92*7c478bd9Sstevel@tonic-gate static int	yyHaveZone;
93*7c478bd9Sstevel@tonic-gate static time_t	yyTimezone;
94*7c478bd9Sstevel@tonic-gate static time_t	yyDay;
95*7c478bd9Sstevel@tonic-gate static time_t	yyHour;
96*7c478bd9Sstevel@tonic-gate static time_t	yyMinutes;
97*7c478bd9Sstevel@tonic-gate static time_t	yyMonth;
98*7c478bd9Sstevel@tonic-gate static time_t	yySeconds;
99*7c478bd9Sstevel@tonic-gate static time_t	yyYear;
100*7c478bd9Sstevel@tonic-gate static MERIDIAN	yyMeridian;
101*7c478bd9Sstevel@tonic-gate static time_t	yyRelMonth;
102*7c478bd9Sstevel@tonic-gate static time_t	yyRelSeconds;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate static char	*domainname = "hsm_libdump";	/* for dgettext() */
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate #define yylex 1					/* suppress yacc's definition */
107*7c478bd9Sstevel@tonic-gate %}
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate %union {
110*7c478bd9Sstevel@tonic-gate     time_t		Number;
111*7c478bd9Sstevel@tonic-gate     enum _MERIDIAN	Meridian;
112*7c478bd9Sstevel@tonic-gate }
113*7c478bd9Sstevel@tonic-gate 
114*7c478bd9Sstevel@tonic-gate %token	tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
115*7c478bd9Sstevel@tonic-gate %token	tSEC_UNIT tSNUMBER tUNUMBER tZONE
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate %type	<Number>	tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
118*7c478bd9Sstevel@tonic-gate %type	<Number>	tSEC_UNIT tSNUMBER tUNUMBER tZONE
119*7c478bd9Sstevel@tonic-gate %type	<Meridian>	tMERIDIAN o_merid
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate %%
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate spec	: /* NULL */
124*7c478bd9Sstevel@tonic-gate 	| spec item
125*7c478bd9Sstevel@tonic-gate 	;
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate item	: time {
128*7c478bd9Sstevel@tonic-gate 	    yyHaveTime++;
129*7c478bd9Sstevel@tonic-gate 	}
130*7c478bd9Sstevel@tonic-gate 	| zone {
131*7c478bd9Sstevel@tonic-gate 	    yyHaveZone++;
132*7c478bd9Sstevel@tonic-gate 	}
133*7c478bd9Sstevel@tonic-gate 	| date {
134*7c478bd9Sstevel@tonic-gate 	    yyHaveDate++;
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate 	| day {
137*7c478bd9Sstevel@tonic-gate 	    yyHaveDay++;
138*7c478bd9Sstevel@tonic-gate 	}
139*7c478bd9Sstevel@tonic-gate 	| rel {
140*7c478bd9Sstevel@tonic-gate 	    yyHaveRel++;
141*7c478bd9Sstevel@tonic-gate 	}
142*7c478bd9Sstevel@tonic-gate 	| number
143*7c478bd9Sstevel@tonic-gate 	;
144*7c478bd9Sstevel@tonic-gate 
145*7c478bd9Sstevel@tonic-gate time	: tUNUMBER tMERIDIAN {
146*7c478bd9Sstevel@tonic-gate 	    yyHour = $1;
147*7c478bd9Sstevel@tonic-gate 	    yyMinutes = 0;
148*7c478bd9Sstevel@tonic-gate 	    yySeconds = 0;
149*7c478bd9Sstevel@tonic-gate 	    yyMeridian = $2;
150*7c478bd9Sstevel@tonic-gate 	}
151*7c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER o_merid {
152*7c478bd9Sstevel@tonic-gate 	    yyHour = $1;
153*7c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
154*7c478bd9Sstevel@tonic-gate 	    yySeconds = 0;
155*7c478bd9Sstevel@tonic-gate 	    yyMeridian = $4;
156*7c478bd9Sstevel@tonic-gate 	}
157*7c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER tSNUMBER {
158*7c478bd9Sstevel@tonic-gate 	    yyHour = $1;
159*7c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
160*7c478bd9Sstevel@tonic-gate 	    yyMeridian = MER24;
161*7c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
162*7c478bd9Sstevel@tonic-gate 	    yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
163*7c478bd9Sstevel@tonic-gate 	}
164*7c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
165*7c478bd9Sstevel@tonic-gate 	    yyHour = $1;
166*7c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
167*7c478bd9Sstevel@tonic-gate 	    yySeconds = $5;
168*7c478bd9Sstevel@tonic-gate 	    yyMeridian = $6;
169*7c478bd9Sstevel@tonic-gate 	}
170*7c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
171*7c478bd9Sstevel@tonic-gate 	    yyHour = $1;
172*7c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
173*7c478bd9Sstevel@tonic-gate 	    yySeconds = $5;
174*7c478bd9Sstevel@tonic-gate 	    yyMeridian = MER24;
175*7c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
176*7c478bd9Sstevel@tonic-gate 	    yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
177*7c478bd9Sstevel@tonic-gate 	}
178*7c478bd9Sstevel@tonic-gate 	;
179*7c478bd9Sstevel@tonic-gate 
180*7c478bd9Sstevel@tonic-gate zone	: tZONE {
181*7c478bd9Sstevel@tonic-gate 	    yyTimezone = $1;
182*7c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
183*7c478bd9Sstevel@tonic-gate 	}
184*7c478bd9Sstevel@tonic-gate 	| tDAYZONE {
185*7c478bd9Sstevel@tonic-gate 	    yyTimezone = $1;
186*7c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSTon;
187*7c478bd9Sstevel@tonic-gate 	}
188*7c478bd9Sstevel@tonic-gate 	;
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate day	: tDAY {
191*7c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = 1;
192*7c478bd9Sstevel@tonic-gate 	    yyDayNumber = $1;
193*7c478bd9Sstevel@tonic-gate 	}
194*7c478bd9Sstevel@tonic-gate 	| tDAY ',' {
195*7c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = 1;
196*7c478bd9Sstevel@tonic-gate 	    yyDayNumber = $1;
197*7c478bd9Sstevel@tonic-gate 	}
198*7c478bd9Sstevel@tonic-gate 	| tUNUMBER tDAY {
199*7c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = $1;
200*7c478bd9Sstevel@tonic-gate 	    yyDayNumber = $2;
201*7c478bd9Sstevel@tonic-gate 	}
202*7c478bd9Sstevel@tonic-gate 	;
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate date	: tUNUMBER '/' tUNUMBER {
205*7c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
206*7c478bd9Sstevel@tonic-gate 	    yyDay = $3;
207*7c478bd9Sstevel@tonic-gate 	}
208*7c478bd9Sstevel@tonic-gate 	| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
209*7c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
210*7c478bd9Sstevel@tonic-gate 	    yyDay = $3;
211*7c478bd9Sstevel@tonic-gate 	    yyYear = $5;
212*7c478bd9Sstevel@tonic-gate 	}
213*7c478bd9Sstevel@tonic-gate 	| tMONTH tUNUMBER {
214*7c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
215*7c478bd9Sstevel@tonic-gate 	    yyDay = $2;
216*7c478bd9Sstevel@tonic-gate 	}
217*7c478bd9Sstevel@tonic-gate 	| tMONTH tUNUMBER ',' tUNUMBER {
218*7c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
219*7c478bd9Sstevel@tonic-gate 	    yyDay = $2;
220*7c478bd9Sstevel@tonic-gate 	    yyYear = $4;
221*7c478bd9Sstevel@tonic-gate 	}
222*7c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH {
223*7c478bd9Sstevel@tonic-gate 	    yyMonth = $2;
224*7c478bd9Sstevel@tonic-gate 	    yyDay = $1;
225*7c478bd9Sstevel@tonic-gate 	}
226*7c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH tUNUMBER {
227*7c478bd9Sstevel@tonic-gate 	    yyMonth = $2;
228*7c478bd9Sstevel@tonic-gate 	    yyDay = $1;
229*7c478bd9Sstevel@tonic-gate 	    yyYear = $3;
230*7c478bd9Sstevel@tonic-gate 	}
231*7c478bd9Sstevel@tonic-gate 	;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate rel	: relunit tAGO {
234*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds = -yyRelSeconds;
235*7c478bd9Sstevel@tonic-gate 	    yyRelMonth = -yyRelMonth;
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 	| relunit
238*7c478bd9Sstevel@tonic-gate 	;
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate relunit	: tUNUMBER tMINUTE_UNIT {
241*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * $2 * 60L;
242*7c478bd9Sstevel@tonic-gate 	}
243*7c478bd9Sstevel@tonic-gate 	| tSNUMBER tMINUTE_UNIT {
244*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * $2 * 60L;
245*7c478bd9Sstevel@tonic-gate 	}
246*7c478bd9Sstevel@tonic-gate 	| tMINUTE_UNIT {
247*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * 60L;
248*7c478bd9Sstevel@tonic-gate 	}
249*7c478bd9Sstevel@tonic-gate 	| tSNUMBER tSEC_UNIT {
250*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1;
251*7c478bd9Sstevel@tonic-gate 	}
252*7c478bd9Sstevel@tonic-gate 	| tUNUMBER tSEC_UNIT {
253*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1;
254*7c478bd9Sstevel@tonic-gate 	}
255*7c478bd9Sstevel@tonic-gate 	| tSEC_UNIT {
256*7c478bd9Sstevel@tonic-gate 	    yyRelSeconds++;
257*7c478bd9Sstevel@tonic-gate 	}
258*7c478bd9Sstevel@tonic-gate 	| tSNUMBER tMONTH_UNIT {
259*7c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1 * $2;
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH_UNIT {
262*7c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1 * $2;
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 	| tMONTH_UNIT {
265*7c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1;
266*7c478bd9Sstevel@tonic-gate 	}
267*7c478bd9Sstevel@tonic-gate 	;
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate number	: tUNUMBER {
270*7c478bd9Sstevel@tonic-gate 	    if (yyHaveTime && yyHaveDate && !yyHaveRel)
271*7c478bd9Sstevel@tonic-gate 		yyYear = $1;
272*7c478bd9Sstevel@tonic-gate 	    else {
273*7c478bd9Sstevel@tonic-gate 		yyHaveTime++;
274*7c478bd9Sstevel@tonic-gate 		if ($1 < 100) {
275*7c478bd9Sstevel@tonic-gate 		    yyHour = $1;
276*7c478bd9Sstevel@tonic-gate 		    yyMinutes = 0;
277*7c478bd9Sstevel@tonic-gate 		}
278*7c478bd9Sstevel@tonic-gate 		else {
279*7c478bd9Sstevel@tonic-gate 		    yyHour = $1 / 100;
280*7c478bd9Sstevel@tonic-gate 		    yyMinutes = $1 % 100;
281*7c478bd9Sstevel@tonic-gate 		}
282*7c478bd9Sstevel@tonic-gate 		yySeconds = 0;
283*7c478bd9Sstevel@tonic-gate 		yyMeridian = MER24;
284*7c478bd9Sstevel@tonic-gate 	    }
285*7c478bd9Sstevel@tonic-gate 	}
286*7c478bd9Sstevel@tonic-gate 	;
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate o_merid	: /* NULL */ {
289*7c478bd9Sstevel@tonic-gate 	    $$ = MER24;
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 	| tMERIDIAN {
292*7c478bd9Sstevel@tonic-gate 	    $$ = $1;
293*7c478bd9Sstevel@tonic-gate 	}
294*7c478bd9Sstevel@tonic-gate 	;
295*7c478bd9Sstevel@tonic-gate 
296*7c478bd9Sstevel@tonic-gate %%
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate /* Month and day table. */
299*7c478bd9Sstevel@tonic-gate static TABLE	MonthDayTable[] = {
300*7c478bd9Sstevel@tonic-gate     { "january",	tMONTH,  1 },
301*7c478bd9Sstevel@tonic-gate     { "february",	tMONTH,  2 },
302*7c478bd9Sstevel@tonic-gate     { "march",		tMONTH,  3 },
303*7c478bd9Sstevel@tonic-gate     { "april",		tMONTH,  4 },
304*7c478bd9Sstevel@tonic-gate     { "may",		tMONTH,  5 },
305*7c478bd9Sstevel@tonic-gate     { "june",		tMONTH,  6 },
306*7c478bd9Sstevel@tonic-gate     { "july",		tMONTH,  7 },
307*7c478bd9Sstevel@tonic-gate     { "august",		tMONTH,  8 },
308*7c478bd9Sstevel@tonic-gate     { "september",	tMONTH,  9 },
309*7c478bd9Sstevel@tonic-gate     { "sept",		tMONTH,  9 },
310*7c478bd9Sstevel@tonic-gate     { "october",	tMONTH, 10 },
311*7c478bd9Sstevel@tonic-gate     { "november",	tMONTH, 11 },
312*7c478bd9Sstevel@tonic-gate     { "december",	tMONTH, 12 },
313*7c478bd9Sstevel@tonic-gate     { "sunday",		tDAY, 0 },
314*7c478bd9Sstevel@tonic-gate     { "monday",		tDAY, 1 },
315*7c478bd9Sstevel@tonic-gate     { "tuesday",	tDAY, 2 },
316*7c478bd9Sstevel@tonic-gate     { "tues",		tDAY, 2 },
317*7c478bd9Sstevel@tonic-gate     { "wednesday",	tDAY, 3 },
318*7c478bd9Sstevel@tonic-gate     { "wednes",		tDAY, 3 },
319*7c478bd9Sstevel@tonic-gate     { "thursday",	tDAY, 4 },
320*7c478bd9Sstevel@tonic-gate     { "thur",		tDAY, 4 },
321*7c478bd9Sstevel@tonic-gate     { "thurs",		tDAY, 4 },
322*7c478bd9Sstevel@tonic-gate     { "friday",		tDAY, 5 },
323*7c478bd9Sstevel@tonic-gate     { "saturday",	tDAY, 6 },
324*7c478bd9Sstevel@tonic-gate     { NULL }
325*7c478bd9Sstevel@tonic-gate };
326*7c478bd9Sstevel@tonic-gate 
327*7c478bd9Sstevel@tonic-gate /* Time units table. */
328*7c478bd9Sstevel@tonic-gate static TABLE	UnitsTable[] = {
329*7c478bd9Sstevel@tonic-gate     { "year",		tMONTH_UNIT,	12 },
330*7c478bd9Sstevel@tonic-gate     { "month",		tMONTH_UNIT,	1 },
331*7c478bd9Sstevel@tonic-gate     { "fortnight",	tMINUTE_UNIT,	14 * 24 * 60 },
332*7c478bd9Sstevel@tonic-gate     { "week",		tMINUTE_UNIT,	7 * 24 * 60 },
333*7c478bd9Sstevel@tonic-gate     { "day",		tMINUTE_UNIT,	1 * 24 * 60 },
334*7c478bd9Sstevel@tonic-gate     { "hour",		tMINUTE_UNIT,	60 },
335*7c478bd9Sstevel@tonic-gate     { "minute",		tMINUTE_UNIT,	1 },
336*7c478bd9Sstevel@tonic-gate     { "min",		tMINUTE_UNIT,	1 },
337*7c478bd9Sstevel@tonic-gate     { "second",		tSEC_UNIT,	1 },
338*7c478bd9Sstevel@tonic-gate     { "sec",		tSEC_UNIT,	1 },
339*7c478bd9Sstevel@tonic-gate     { NULL }
340*7c478bd9Sstevel@tonic-gate };
341*7c478bd9Sstevel@tonic-gate 
342*7c478bd9Sstevel@tonic-gate /* Assorted relative-time words. */
343*7c478bd9Sstevel@tonic-gate static TABLE	OtherTable[] = {
344*7c478bd9Sstevel@tonic-gate     { "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
345*7c478bd9Sstevel@tonic-gate     { "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
346*7c478bd9Sstevel@tonic-gate     { "today",		tMINUTE_UNIT,	0 },
347*7c478bd9Sstevel@tonic-gate     { "now",		tMINUTE_UNIT,	0 },
348*7c478bd9Sstevel@tonic-gate     { "last",		tUNUMBER,	-1 },
349*7c478bd9Sstevel@tonic-gate     { "this",		tMINUTE_UNIT,	0 },
350*7c478bd9Sstevel@tonic-gate     { "next",		tUNUMBER,	2 },
351*7c478bd9Sstevel@tonic-gate     { "first",		tUNUMBER,	1 },
352*7c478bd9Sstevel@tonic-gate /*  { "second",		tUNUMBER,	2 }, */
353*7c478bd9Sstevel@tonic-gate     { "third",		tUNUMBER,	3 },
354*7c478bd9Sstevel@tonic-gate     { "fourth",		tUNUMBER,	4 },
355*7c478bd9Sstevel@tonic-gate     { "fifth",		tUNUMBER,	5 },
356*7c478bd9Sstevel@tonic-gate     { "sixth",		tUNUMBER,	6 },
357*7c478bd9Sstevel@tonic-gate     { "seventh",	tUNUMBER,	7 },
358*7c478bd9Sstevel@tonic-gate     { "eighth",		tUNUMBER,	8 },
359*7c478bd9Sstevel@tonic-gate     { "ninth",		tUNUMBER,	9 },
360*7c478bd9Sstevel@tonic-gate     { "tenth",		tUNUMBER,	10 },
361*7c478bd9Sstevel@tonic-gate     { "eleventh",	tUNUMBER,	11 },
362*7c478bd9Sstevel@tonic-gate     { "twelfth",	tUNUMBER,	12 },
363*7c478bd9Sstevel@tonic-gate     { "ago",		tAGO,	1 },
364*7c478bd9Sstevel@tonic-gate     { NULL }
365*7c478bd9Sstevel@tonic-gate };
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate /* The timezone table. */
368*7c478bd9Sstevel@tonic-gate static TABLE	TimezoneTable[] = {
369*7c478bd9Sstevel@tonic-gate     { "gmt",	tZONE,     HOURN( 0) },	/* Greenwich Mean */
370*7c478bd9Sstevel@tonic-gate     { "ut",	tZONE,     HOURN( 0) },	/* Universal (Coordinated) */
371*7c478bd9Sstevel@tonic-gate     { "utc",	tZONE,     HOURN( 0) },
372*7c478bd9Sstevel@tonic-gate     { "wet",	tZONE,     HOURN( 0) },	/* Western European */
373*7c478bd9Sstevel@tonic-gate     { "bst",	tDAYZONE,  HOURN( 0) },	/* British Summer */
374*7c478bd9Sstevel@tonic-gate     { "wat",	tZONE,     HOURN( 1) },	/* West Africa */
375*7c478bd9Sstevel@tonic-gate     { "at",	tZONE,     HOURN( 2) },	/* Azores */
376*7c478bd9Sstevel@tonic-gate #if	0
377*7c478bd9Sstevel@tonic-gate     /* For completeness.  BST is also British Summer, and GST is
378*7c478bd9Sstevel@tonic-gate      * also Guam Standard. */
379*7c478bd9Sstevel@tonic-gate     { "bst",	tZONE,     HOURN( 3) },	/* Brazil Standard */
380*7c478bd9Sstevel@tonic-gate     { "gst",	tZONE,     HOURN( 3) },	/* Greenland Standard */
381*7c478bd9Sstevel@tonic-gate #endif
382*7c478bd9Sstevel@tonic-gate     { "nft",	tZONE,     HOURN(3.5) },	/* Newfoundland */
383*7c478bd9Sstevel@tonic-gate     { "nst",	tZONE,     HOURN(3.5) },	/* Newfoundland Standard */
384*7c478bd9Sstevel@tonic-gate     { "ndt",	tDAYZONE,  HOURN(3.5) },	/* Newfoundland Daylight */
385*7c478bd9Sstevel@tonic-gate     { "ast",	tZONE,     HOURN( 4) },	/* Atlantic Standard */
386*7c478bd9Sstevel@tonic-gate     { "adt",	tDAYZONE,  HOURN( 4) },	/* Atlantic Daylight */
387*7c478bd9Sstevel@tonic-gate     { "est",	tZONE,     HOURN( 5) },	/* Eastern Standard */
388*7c478bd9Sstevel@tonic-gate     { "edt",	tDAYZONE,  HOURN( 5) },	/* Eastern Daylight */
389*7c478bd9Sstevel@tonic-gate     { "cst",	tZONE,     HOURN( 6) },	/* Central Standard */
390*7c478bd9Sstevel@tonic-gate     { "cdt",	tDAYZONE,  HOURN( 6) },	/* Central Daylight */
391*7c478bd9Sstevel@tonic-gate     { "mst",	tZONE,     HOURN( 7) },	/* Mountain Standard */
392*7c478bd9Sstevel@tonic-gate     { "mdt",	tDAYZONE,  HOURN( 7) },	/* Mountain Daylight */
393*7c478bd9Sstevel@tonic-gate     { "pst",	tZONE,     HOURN( 8) },	/* Pacific Standard */
394*7c478bd9Sstevel@tonic-gate     { "pdt",	tDAYZONE,  HOURN( 8) },	/* Pacific Daylight */
395*7c478bd9Sstevel@tonic-gate     { "yst",	tZONE,     HOURN( 9) },	/* Yukon Standard */
396*7c478bd9Sstevel@tonic-gate     { "ydt",	tDAYZONE,  HOURN( 9) },	/* Yukon Daylight */
397*7c478bd9Sstevel@tonic-gate     { "hst",	tZONE,     HOURN(10) },	/* Hawaii Standard */
398*7c478bd9Sstevel@tonic-gate     { "hdt",	tDAYZONE,  HOURN(10) },	/* Hawaii Daylight */
399*7c478bd9Sstevel@tonic-gate     { "cat",	tZONE,     HOURN(10) },	/* Central Alaska */
400*7c478bd9Sstevel@tonic-gate     { "ahst",	tZONE,     HOURN(10) },	/* Alaska-Hawaii Standard */
401*7c478bd9Sstevel@tonic-gate     { "nt",	tZONE,     HOURN(11) },	/* Nome */
402*7c478bd9Sstevel@tonic-gate     { "idlw",	tZONE,     HOURN(12) },	/* International Date Line West */
403*7c478bd9Sstevel@tonic-gate     { "cet",	tZONE,     -HOURN(1) },	/* Central European */
404*7c478bd9Sstevel@tonic-gate     { "met",	tZONE,     -HOURN(1) },	/* Middle European */
405*7c478bd9Sstevel@tonic-gate     { "mewt",	tZONE,     -HOURN(1) },	/* Middle European Winter */
406*7c478bd9Sstevel@tonic-gate     { "mest",	tDAYZONE,  -HOURN(1) },	/* Middle European Summer */
407*7c478bd9Sstevel@tonic-gate     { "swt",	tZONE,     -HOURN(1) },	/* Swedish Winter */
408*7c478bd9Sstevel@tonic-gate     { "sst",	tDAYZONE,  -HOURN(1) },	/* Swedish Summer */
409*7c478bd9Sstevel@tonic-gate     { "fwt",	tZONE,     -HOURN(1) },	/* French Winter */
410*7c478bd9Sstevel@tonic-gate     { "fst",	tDAYZONE,  -HOURN(1) },	/* French Summer */
411*7c478bd9Sstevel@tonic-gate     { "eet",	tZONE,     -HOURN(2) },	/* Eastern Europe, USSR Zone 1 */
412*7c478bd9Sstevel@tonic-gate     { "bt",	tZONE,     -HOURN(3) },	/* Baghdad, USSR Zone 2 */
413*7c478bd9Sstevel@tonic-gate     { "it",	tZONE,     -HOURN(3.5) },/* Iran */
414*7c478bd9Sstevel@tonic-gate     { "zp4",	tZONE,     -HOURN(4) },	/* USSR Zone 3 */
415*7c478bd9Sstevel@tonic-gate     { "zp5",	tZONE,     -HOURN(5) },	/* USSR Zone 4 */
416*7c478bd9Sstevel@tonic-gate     { "ist",	tZONE,     -HOURN(5.5) },/* Indian Standard */
417*7c478bd9Sstevel@tonic-gate     { "zp6",	tZONE,     -HOURN(6) },	/* USSR Zone 5 */
418*7c478bd9Sstevel@tonic-gate #if	0
419*7c478bd9Sstevel@tonic-gate     /* For completeness.  NST is also Newfoundland Stanard, nad SST is
420*7c478bd9Sstevel@tonic-gate      * also Swedish Summer. */
421*7c478bd9Sstevel@tonic-gate     { "nst",	tZONE,     -HOURN(6.5) },/* North Sumatra */
422*7c478bd9Sstevel@tonic-gate     { "sst",	tZONE,     -HOURN(7) },	/* South Sumatra, USSR Zone 6 */
423*7c478bd9Sstevel@tonic-gate #endif	/* 0 */
424*7c478bd9Sstevel@tonic-gate     { "wast",	tZONE,     -HOURN(7) },	/* West Australian Standard */
425*7c478bd9Sstevel@tonic-gate     { "wadt",	tDAYZONE,  -HOURN(7) },	/* West Australian Daylight */
426*7c478bd9Sstevel@tonic-gate     { "jt",	tZONE,     -HOURN(7.5) },/* Java (3pm in Cronusland!) */
427*7c478bd9Sstevel@tonic-gate     { "cct",	tZONE,     -HOURN(8) },	/* China Coast, USSR Zone 7 */
428*7c478bd9Sstevel@tonic-gate     { "jst",	tZONE,     -HOURN(9) },	/* Japan Standard, USSR Zone 8 */
429*7c478bd9Sstevel@tonic-gate     { "cast",	tZONE,     -HOURN(9.5) },/* Central Australian Standard */
430*7c478bd9Sstevel@tonic-gate     { "cadt",	tDAYZONE,  -HOURN(9.5) },/* Central Australian Daylight */
431*7c478bd9Sstevel@tonic-gate     { "east",	tZONE,     -HOURN(10) },	/* Eastern Australian Standard */
432*7c478bd9Sstevel@tonic-gate     { "eadt",	tDAYZONE,  -HOURN(10) },	/* Eastern Australian Daylight */
433*7c478bd9Sstevel@tonic-gate     { "gst",	tZONE,     -HOURN(10) },	/* Guam Standard, USSR Zone 9 */
434*7c478bd9Sstevel@tonic-gate     { "nzt",	tZONE,     -HOURN(12) },	/* New Zealand */
435*7c478bd9Sstevel@tonic-gate     { "nzst",	tZONE,     -HOURN(12) },	/* New Zealand Standard */
436*7c478bd9Sstevel@tonic-gate     { "nzdt",	tDAYZONE,  -HOURN(12) },	/* New Zealand Daylight */
437*7c478bd9Sstevel@tonic-gate     { "idle",	tZONE,     -HOURN(12) },	/* International Date Line East */
438*7c478bd9Sstevel@tonic-gate     {  NULL  }
439*7c478bd9Sstevel@tonic-gate };
440*7c478bd9Sstevel@tonic-gate 
441*7c478bd9Sstevel@tonic-gate /* Military timezone table. */
442*7c478bd9Sstevel@tonic-gate static TABLE	MilitaryTable[] = {
443*7c478bd9Sstevel@tonic-gate     { "a",	tZONE,	HOURN(  1) },
444*7c478bd9Sstevel@tonic-gate     { "b",	tZONE,	HOURN(  2) },
445*7c478bd9Sstevel@tonic-gate     { "c",	tZONE,	HOURN(  3) },
446*7c478bd9Sstevel@tonic-gate     { "d",	tZONE,	HOURN(  4) },
447*7c478bd9Sstevel@tonic-gate     { "e",	tZONE,	HOURN(  5) },
448*7c478bd9Sstevel@tonic-gate     { "f",	tZONE,	HOURN(  6) },
449*7c478bd9Sstevel@tonic-gate     { "g",	tZONE,	HOURN(  7) },
450*7c478bd9Sstevel@tonic-gate     { "h",	tZONE,	HOURN(  8) },
451*7c478bd9Sstevel@tonic-gate     { "i",	tZONE,	HOURN(  9) },
452*7c478bd9Sstevel@tonic-gate     { "k",	tZONE,	HOURN( 10) },
453*7c478bd9Sstevel@tonic-gate     { "l",	tZONE,	HOURN( 11) },
454*7c478bd9Sstevel@tonic-gate     { "m",	tZONE,	HOURN( 12) },
455*7c478bd9Sstevel@tonic-gate     { "n",	tZONE,	HOURN(- 1) },
456*7c478bd9Sstevel@tonic-gate     { "o",	tZONE,	HOURN(- 2) },
457*7c478bd9Sstevel@tonic-gate     { "p",	tZONE,	HOURN(- 3) },
458*7c478bd9Sstevel@tonic-gate     { "q",	tZONE,	HOURN(- 4) },
459*7c478bd9Sstevel@tonic-gate     { "r",	tZONE,	HOURN(- 5) },
460*7c478bd9Sstevel@tonic-gate     { "s",	tZONE,	HOURN(- 6) },
461*7c478bd9Sstevel@tonic-gate     { "t",	tZONE,	HOURN(- 7) },
462*7c478bd9Sstevel@tonic-gate     { "u",	tZONE,	HOURN(- 8) },
463*7c478bd9Sstevel@tonic-gate     { "v",	tZONE,	HOURN(- 9) },
464*7c478bd9Sstevel@tonic-gate     { "w",	tZONE,	HOURN(-10) },
465*7c478bd9Sstevel@tonic-gate     { "x",	tZONE,	HOURN(-11) },
466*7c478bd9Sstevel@tonic-gate     { "y",	tZONE,	HOURN(-12) },
467*7c478bd9Sstevel@tonic-gate     { "z",	tZONE,	HOURN(  0) },
468*7c478bd9Sstevel@tonic-gate     { NULL }
469*7c478bd9Sstevel@tonic-gate };
470*7c478bd9Sstevel@tonic-gate 
471*7c478bd9Sstevel@tonic-gate 
472*7c478bd9Sstevel@tonic-gate 
473*7c478bd9Sstevel@tonic-gate 
474*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
475*7c478bd9Sstevel@tonic-gate static void
476*7c478bd9Sstevel@tonic-gate yyerror(s)
477*7c478bd9Sstevel@tonic-gate     char	*s;
478*7c478bd9Sstevel@tonic-gate {
479*7c478bd9Sstevel@tonic-gate }
480*7c478bd9Sstevel@tonic-gate 
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate static time_t
483*7c478bd9Sstevel@tonic-gate ToSeconds(Hours, Minutes, Seconds, Meridian)
484*7c478bd9Sstevel@tonic-gate     time_t	Hours;
485*7c478bd9Sstevel@tonic-gate     time_t	Minutes;
486*7c478bd9Sstevel@tonic-gate     time_t	Seconds;
487*7c478bd9Sstevel@tonic-gate     MERIDIAN	Meridian;
488*7c478bd9Sstevel@tonic-gate {
489*7c478bd9Sstevel@tonic-gate     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
490*7c478bd9Sstevel@tonic-gate 	return -1;
491*7c478bd9Sstevel@tonic-gate     switch (Meridian) {
492*7c478bd9Sstevel@tonic-gate     case MER24:
493*7c478bd9Sstevel@tonic-gate 	if (Hours < 0 || Hours > 23)
494*7c478bd9Sstevel@tonic-gate 	    return -1;
495*7c478bd9Sstevel@tonic-gate 	return (Hours * 60L + Minutes) * 60L + Seconds;
496*7c478bd9Sstevel@tonic-gate     case MERam:
497*7c478bd9Sstevel@tonic-gate 	if (Hours < 1 || Hours > 12)
498*7c478bd9Sstevel@tonic-gate 	    return -1;
499*7c478bd9Sstevel@tonic-gate 	if (Hours != 12)
500*7c478bd9Sstevel@tonic-gate 	    return (Hours * 60L + Minutes) * 60L + Seconds;
501*7c478bd9Sstevel@tonic-gate 	else
502*7c478bd9Sstevel@tonic-gate 	    return Minutes * 60L + Seconds;
503*7c478bd9Sstevel@tonic-gate     case MERpm:
504*7c478bd9Sstevel@tonic-gate 	if (Hours < 1 || Hours > 12)
505*7c478bd9Sstevel@tonic-gate 	    return -1;
506*7c478bd9Sstevel@tonic-gate 	if (Hours != 12)
507*7c478bd9Sstevel@tonic-gate 	    return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
508*7c478bd9Sstevel@tonic-gate 	else
509*7c478bd9Sstevel@tonic-gate 	    return (720L + Minutes) * 60L + Seconds;
510*7c478bd9Sstevel@tonic-gate     }
511*7c478bd9Sstevel@tonic-gate     /* NOTREACHED */
512*7c478bd9Sstevel@tonic-gate }
513*7c478bd9Sstevel@tonic-gate 
514*7c478bd9Sstevel@tonic-gate 
515*7c478bd9Sstevel@tonic-gate static time_t
516*7c478bd9Sstevel@tonic-gate Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
517*7c478bd9Sstevel@tonic-gate     time_t	Month;
518*7c478bd9Sstevel@tonic-gate     time_t	Day;
519*7c478bd9Sstevel@tonic-gate     time_t	Year;
520*7c478bd9Sstevel@tonic-gate     time_t	Hours;
521*7c478bd9Sstevel@tonic-gate     time_t	Minutes;
522*7c478bd9Sstevel@tonic-gate     time_t	Seconds;
523*7c478bd9Sstevel@tonic-gate     MERIDIAN	Meridian;
524*7c478bd9Sstevel@tonic-gate     DSTMODE	DSTmode;
525*7c478bd9Sstevel@tonic-gate {
526*7c478bd9Sstevel@tonic-gate     static int	DaysInMonth[12] = {
527*7c478bd9Sstevel@tonic-gate 	31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
528*7c478bd9Sstevel@tonic-gate     };
529*7c478bd9Sstevel@tonic-gate     time_t	tod;
530*7c478bd9Sstevel@tonic-gate     time_t	Julian;
531*7c478bd9Sstevel@tonic-gate     time_t	i;
532*7c478bd9Sstevel@tonic-gate 
533*7c478bd9Sstevel@tonic-gate     if (Year < 0)
534*7c478bd9Sstevel@tonic-gate 	Year = -Year;
535*7c478bd9Sstevel@tonic-gate     if (Year < 138)
536*7c478bd9Sstevel@tonic-gate 	Year += 1900;
537*7c478bd9Sstevel@tonic-gate     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
538*7c478bd9Sstevel@tonic-gate 		    ? 29 : 28;
539*7c478bd9Sstevel@tonic-gate     if (Year < EPOCH || Year > 2037
540*7c478bd9Sstevel@tonic-gate      || Month < 1 || Month > 12
541*7c478bd9Sstevel@tonic-gate      /* LINTED Month is a time_t so intermediate results aren't truncated */
542*7c478bd9Sstevel@tonic-gate      || Day < 1 || Day > DaysInMonth[(int)--Month])
543*7c478bd9Sstevel@tonic-gate 	return -1;
544*7c478bd9Sstevel@tonic-gate 
545*7c478bd9Sstevel@tonic-gate     for (Julian = Day - 1, i = 0; i < Month; i++)
546*7c478bd9Sstevel@tonic-gate 	Julian += DaysInMonth[i];
547*7c478bd9Sstevel@tonic-gate     for (i = EPOCH; i < Year; i++)
548*7c478bd9Sstevel@tonic-gate 	Julian += 365 + (i % 4 == 0);
549*7c478bd9Sstevel@tonic-gate     Julian *= SECSPERDAY;
550*7c478bd9Sstevel@tonic-gate     Julian += yyTimezone * 60L;
551*7c478bd9Sstevel@tonic-gate     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
552*7c478bd9Sstevel@tonic-gate 	return -1;
553*7c478bd9Sstevel@tonic-gate     Julian += tod;
554*7c478bd9Sstevel@tonic-gate     if (DSTmode == DSTon
555*7c478bd9Sstevel@tonic-gate      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
556*7c478bd9Sstevel@tonic-gate 	Julian -= 60 * 60;
557*7c478bd9Sstevel@tonic-gate     return Julian;
558*7c478bd9Sstevel@tonic-gate }
559*7c478bd9Sstevel@tonic-gate 
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate static time_t
562*7c478bd9Sstevel@tonic-gate DSTcorrect(Start, Future)
563*7c478bd9Sstevel@tonic-gate     time_t	Start;
564*7c478bd9Sstevel@tonic-gate     time_t	Future;
565*7c478bd9Sstevel@tonic-gate {
566*7c478bd9Sstevel@tonic-gate     time_t	StartDay;
567*7c478bd9Sstevel@tonic-gate     time_t	FutureDay;
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
570*7c478bd9Sstevel@tonic-gate     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
571*7c478bd9Sstevel@tonic-gate     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
572*7c478bd9Sstevel@tonic-gate }
573*7c478bd9Sstevel@tonic-gate 
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate static time_t
576*7c478bd9Sstevel@tonic-gate RelativeDate(Start, DayOrdinal, DayNumber)
577*7c478bd9Sstevel@tonic-gate     time_t	Start;
578*7c478bd9Sstevel@tonic-gate     time_t	DayOrdinal;
579*7c478bd9Sstevel@tonic-gate     time_t	DayNumber;
580*7c478bd9Sstevel@tonic-gate {
581*7c478bd9Sstevel@tonic-gate     struct tm	*tm;
582*7c478bd9Sstevel@tonic-gate     time_t	now;
583*7c478bd9Sstevel@tonic-gate 
584*7c478bd9Sstevel@tonic-gate     now = Start;
585*7c478bd9Sstevel@tonic-gate     tm = localtime(&now);
586*7c478bd9Sstevel@tonic-gate     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
587*7c478bd9Sstevel@tonic-gate     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
588*7c478bd9Sstevel@tonic-gate     return DSTcorrect(Start, now);
589*7c478bd9Sstevel@tonic-gate }
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 
592*7c478bd9Sstevel@tonic-gate static time_t
593*7c478bd9Sstevel@tonic-gate RelativeMonth(Start, RelMonth)
594*7c478bd9Sstevel@tonic-gate     time_t	Start;
595*7c478bd9Sstevel@tonic-gate     time_t	RelMonth;
596*7c478bd9Sstevel@tonic-gate {
597*7c478bd9Sstevel@tonic-gate     struct tm	*tm;
598*7c478bd9Sstevel@tonic-gate     time_t	Month;
599*7c478bd9Sstevel@tonic-gate     time_t	Year;
600*7c478bd9Sstevel@tonic-gate 
601*7c478bd9Sstevel@tonic-gate     if (RelMonth == 0)
602*7c478bd9Sstevel@tonic-gate 	return 0;
603*7c478bd9Sstevel@tonic-gate     tm = localtime(&Start);
604*7c478bd9Sstevel@tonic-gate     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
605*7c478bd9Sstevel@tonic-gate     Year = Month / 12;
606*7c478bd9Sstevel@tonic-gate     Month = Month % 12 + 1;
607*7c478bd9Sstevel@tonic-gate     return DSTcorrect(Start,
608*7c478bd9Sstevel@tonic-gate 	    Convert(Month, (time_t)tm->tm_mday, Year,
609*7c478bd9Sstevel@tonic-gate 		(time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
610*7c478bd9Sstevel@tonic-gate 		MER24, DSTmaybe));
611*7c478bd9Sstevel@tonic-gate }
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 
614*7c478bd9Sstevel@tonic-gate static int
615*7c478bd9Sstevel@tonic-gate LookupWord(buff)
616*7c478bd9Sstevel@tonic-gate     char		*buff;
617*7c478bd9Sstevel@tonic-gate {
618*7c478bd9Sstevel@tonic-gate     char	*p;
619*7c478bd9Sstevel@tonic-gate     char	*q;
620*7c478bd9Sstevel@tonic-gate     TABLE	*tp;
621*7c478bd9Sstevel@tonic-gate     uint_t	i;
622*7c478bd9Sstevel@tonic-gate     int		abbrev;
623*7c478bd9Sstevel@tonic-gate 
624*7c478bd9Sstevel@tonic-gate     /* Make it lowercase. */
625*7c478bd9Sstevel@tonic-gate     for (p = buff; *p; p++)
626*7c478bd9Sstevel@tonic-gate 	if (isupper((u_char)*p))
627*7c478bd9Sstevel@tonic-gate 	    *p = tolower(*p);
628*7c478bd9Sstevel@tonic-gate 
629*7c478bd9Sstevel@tonic-gate     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
630*7c478bd9Sstevel@tonic-gate 	yylval.Meridian = MERam;
631*7c478bd9Sstevel@tonic-gate 	return tMERIDIAN;
632*7c478bd9Sstevel@tonic-gate     }
633*7c478bd9Sstevel@tonic-gate     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
634*7c478bd9Sstevel@tonic-gate 	yylval.Meridian = MERpm;
635*7c478bd9Sstevel@tonic-gate 	return tMERIDIAN;
636*7c478bd9Sstevel@tonic-gate     }
637*7c478bd9Sstevel@tonic-gate 
638*7c478bd9Sstevel@tonic-gate     /* See if we have an abbreviation for a month. */
639*7c478bd9Sstevel@tonic-gate     if (strlen(buff) == 3)
640*7c478bd9Sstevel@tonic-gate 	abbrev = 1;
641*7c478bd9Sstevel@tonic-gate     else if (strlen(buff) == 4 && buff[3] == '.') {
642*7c478bd9Sstevel@tonic-gate 	abbrev = 1;
643*7c478bd9Sstevel@tonic-gate 	buff[3] = '\0';
644*7c478bd9Sstevel@tonic-gate     }
645*7c478bd9Sstevel@tonic-gate     else
646*7c478bd9Sstevel@tonic-gate 	abbrev = 0;
647*7c478bd9Sstevel@tonic-gate 
648*7c478bd9Sstevel@tonic-gate     for (tp = MonthDayTable; tp->name; tp++) {
649*7c478bd9Sstevel@tonic-gate 	if (abbrev) {
650*7c478bd9Sstevel@tonic-gate 	    if (strncmp(buff, tp->name, 3) == 0) {
651*7c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
652*7c478bd9Sstevel@tonic-gate 		return tp->type;
653*7c478bd9Sstevel@tonic-gate 	    }
654*7c478bd9Sstevel@tonic-gate 	}
655*7c478bd9Sstevel@tonic-gate 	else if (strcmp(buff, tp->name) == 0) {
656*7c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
657*7c478bd9Sstevel@tonic-gate 	    return tp->type;
658*7c478bd9Sstevel@tonic-gate 	}
659*7c478bd9Sstevel@tonic-gate     }
660*7c478bd9Sstevel@tonic-gate 
661*7c478bd9Sstevel@tonic-gate     for (tp = TimezoneTable; tp->name; tp++)
662*7c478bd9Sstevel@tonic-gate 	if (strcmp(buff, tp->name) == 0) {
663*7c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
664*7c478bd9Sstevel@tonic-gate 	    return tp->type;
665*7c478bd9Sstevel@tonic-gate 	}
666*7c478bd9Sstevel@tonic-gate 
667*7c478bd9Sstevel@tonic-gate     for (tp = UnitsTable; tp->name; tp++)
668*7c478bd9Sstevel@tonic-gate 	if (strcmp(buff, tp->name) == 0) {
669*7c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
670*7c478bd9Sstevel@tonic-gate 	    return tp->type;
671*7c478bd9Sstevel@tonic-gate 	}
672*7c478bd9Sstevel@tonic-gate 
673*7c478bd9Sstevel@tonic-gate     /* Strip off any plural and try the units table again. */
674*7c478bd9Sstevel@tonic-gate     i = strlen(buff) - 1;
675*7c478bd9Sstevel@tonic-gate     if (buff[i] == 's') {
676*7c478bd9Sstevel@tonic-gate 	buff[i] = '\0';
677*7c478bd9Sstevel@tonic-gate 	for (tp = UnitsTable; tp->name; tp++)
678*7c478bd9Sstevel@tonic-gate 	    if (strcmp(buff, tp->name) == 0) {
679*7c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
680*7c478bd9Sstevel@tonic-gate 		return tp->type;
681*7c478bd9Sstevel@tonic-gate 	    }
682*7c478bd9Sstevel@tonic-gate     }
683*7c478bd9Sstevel@tonic-gate 
684*7c478bd9Sstevel@tonic-gate     for (tp = OtherTable; tp->name; tp++)
685*7c478bd9Sstevel@tonic-gate 	if (strcmp(buff, tp->name) == 0) {
686*7c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
687*7c478bd9Sstevel@tonic-gate 	    return tp->type;
688*7c478bd9Sstevel@tonic-gate 	}
689*7c478bd9Sstevel@tonic-gate 
690*7c478bd9Sstevel@tonic-gate     /* Military timezones. */
691*7c478bd9Sstevel@tonic-gate     if (buff[1] == '\0' && isalpha((u_char)*buff)) {
692*7c478bd9Sstevel@tonic-gate 	for (tp = MilitaryTable; tp->name; tp++)
693*7c478bd9Sstevel@tonic-gate 	    if (strcmp(buff, tp->name) == 0) {
694*7c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
695*7c478bd9Sstevel@tonic-gate 		return tp->type;
696*7c478bd9Sstevel@tonic-gate 	    }
697*7c478bd9Sstevel@tonic-gate     }
698*7c478bd9Sstevel@tonic-gate 
699*7c478bd9Sstevel@tonic-gate     /* Drop out any periods and try the timezone table again. */
700*7c478bd9Sstevel@tonic-gate     for (i = 0, p = q = buff; *q; q++)
701*7c478bd9Sstevel@tonic-gate 	if (*q != '.')
702*7c478bd9Sstevel@tonic-gate 	    *p++ = *q;
703*7c478bd9Sstevel@tonic-gate 	else
704*7c478bd9Sstevel@tonic-gate 	    i++;
705*7c478bd9Sstevel@tonic-gate     *p = '\0';
706*7c478bd9Sstevel@tonic-gate     if (i)
707*7c478bd9Sstevel@tonic-gate 	for (tp = TimezoneTable; tp->name; tp++)
708*7c478bd9Sstevel@tonic-gate 	    if (strcmp(buff, tp->name) == 0) {
709*7c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
710*7c478bd9Sstevel@tonic-gate 		return tp->type;
711*7c478bd9Sstevel@tonic-gate 	    }
712*7c478bd9Sstevel@tonic-gate 
713*7c478bd9Sstevel@tonic-gate     return tID;
714*7c478bd9Sstevel@tonic-gate }
715*7c478bd9Sstevel@tonic-gate 
716*7c478bd9Sstevel@tonic-gate void
717*7c478bd9Sstevel@tonic-gate pdateerr(p)
718*7c478bd9Sstevel@tonic-gate     char	*p;
719*7c478bd9Sstevel@tonic-gate {
720*7c478bd9Sstevel@tonic-gate     char	*name = "DATEMSK";	/* env variable for date format */
721*7c478bd9Sstevel@tonic-gate     char	*value;
722*7c478bd9Sstevel@tonic-gate     char	fmt[256], line[256];
723*7c478bd9Sstevel@tonic-gate     FILE	*fp;
724*7c478bd9Sstevel@tonic-gate     time_t	now;
725*7c478bd9Sstevel@tonic-gate     struct tm	*tm;
726*7c478bd9Sstevel@tonic-gate 
727*7c478bd9Sstevel@tonic-gate     value = getenv(name);
728*7c478bd9Sstevel@tonic-gate     if (value == (char *)0) {
729*7c478bd9Sstevel@tonic-gate 	fprintf(stderr,
730*7c478bd9Sstevel@tonic-gate 	    dgettext(domainname, "%s: Environment variable %s not set\n"),
731*7c478bd9Sstevel@tonic-gate 		p, name);
732*7c478bd9Sstevel@tonic-gate 	return;
733*7c478bd9Sstevel@tonic-gate     }
734*7c478bd9Sstevel@tonic-gate     switch (getdate_err) {
735*7c478bd9Sstevel@tonic-gate 	case 0:
736*7c478bd9Sstevel@tonic-gate 	default:
737*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr,
738*7c478bd9Sstevel@tonic-gate 		dgettext(domainname, "%s: Unkown getdate() error\n"), p);
739*7c478bd9Sstevel@tonic-gate 	    break;
740*7c478bd9Sstevel@tonic-gate 	case 1:
741*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr,
742*7c478bd9Sstevel@tonic-gate 		dgettext(domainname, "%s: %s null or undefined\n"), p, name);
743*7c478bd9Sstevel@tonic-gate 	    break;
744*7c478bd9Sstevel@tonic-gate 	case 2:
745*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
746*7c478bd9Sstevel@tonic-gate 		"%s: Cannot read template file %s\n"), p, value);
747*7c478bd9Sstevel@tonic-gate 	    break;
748*7c478bd9Sstevel@tonic-gate 	case 3:
749*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
750*7c478bd9Sstevel@tonic-gate 		"%s: Failed to get file status information\n"), p);
751*7c478bd9Sstevel@tonic-gate 	    break;
752*7c478bd9Sstevel@tonic-gate 	case 4:
753*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
754*7c478bd9Sstevel@tonic-gate 		"%s: Template file %s not a regular file\n"), p, value);
755*7c478bd9Sstevel@tonic-gate 	    break;
756*7c478bd9Sstevel@tonic-gate 	case 5:
757*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
758*7c478bd9Sstevel@tonic-gate 		"%s: Error reading template file %s\n"), p, value);
759*7c478bd9Sstevel@tonic-gate 	    break;
760*7c478bd9Sstevel@tonic-gate 	case 6:
761*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
762*7c478bd9Sstevel@tonic-gate 		"%s: %s failed\n"), p, "malloc()");
763*7c478bd9Sstevel@tonic-gate 	    break;
764*7c478bd9Sstevel@tonic-gate 	case 7:
765*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
766*7c478bd9Sstevel@tonic-gate 		"%s: Bad date/time format\n"), p);
767*7c478bd9Sstevel@tonic-gate 	    fp = fopen(value, "r");
768*7c478bd9Sstevel@tonic-gate 	    if (fp == (FILE *)0)
769*7c478bd9Sstevel@tonic-gate 		break;
770*7c478bd9Sstevel@tonic-gate 	    now = time((time_t *)0);
771*7c478bd9Sstevel@tonic-gate 	    tm = localtime(&now);
772*7c478bd9Sstevel@tonic-gate 	    fprintf(stderr, dgettext(domainname,
773*7c478bd9Sstevel@tonic-gate 		"The following are examples of valid formats:\n"));
774*7c478bd9Sstevel@tonic-gate 	    while (fgets(fmt, sizeof (fmt), fp)) {
775*7c478bd9Sstevel@tonic-gate 		if (strchr(fmt, '%') == (char *)0)
776*7c478bd9Sstevel@tonic-gate 		    continue;
777*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "    ");
778*7c478bd9Sstevel@tonic-gate 	        (void) strftime(line, sizeof (line), fmt, tm);
779*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s", line);
780*7c478bd9Sstevel@tonic-gate 	    }
781*7c478bd9Sstevel@tonic-gate 	    (void) fclose(fp);
782*7c478bd9Sstevel@tonic-gate 	    break;
783*7c478bd9Sstevel@tonic-gate 	case 8:
784*7c478bd9Sstevel@tonic-gate 	    (void) fprintf(stderr, dgettext(domainname,
785*7c478bd9Sstevel@tonic-gate 		"%s: Invalid date specification\n"), p);
786*7c478bd9Sstevel@tonic-gate 	    break;
787*7c478bd9Sstevel@tonic-gate     }
788*7c478bd9Sstevel@tonic-gate }
789*7c478bd9Sstevel@tonic-gate 
790*7c478bd9Sstevel@tonic-gate #undef yylex
791*7c478bd9Sstevel@tonic-gate static int
792*7c478bd9Sstevel@tonic-gate yylex()
793*7c478bd9Sstevel@tonic-gate {
794*7c478bd9Sstevel@tonic-gate     char	c;
795*7c478bd9Sstevel@tonic-gate     char	*p;
796*7c478bd9Sstevel@tonic-gate     char	buff[20];
797*7c478bd9Sstevel@tonic-gate     int		Count;
798*7c478bd9Sstevel@tonic-gate     int		sign;
799*7c478bd9Sstevel@tonic-gate 
800*7c478bd9Sstevel@tonic-gate     for ( ; ; ) {
801*7c478bd9Sstevel@tonic-gate 	while (isspace((u_char)*yyInput))
802*7c478bd9Sstevel@tonic-gate 	    yyInput++;
803*7c478bd9Sstevel@tonic-gate 
804*7c478bd9Sstevel@tonic-gate 	if (isdigit((u_char)(c = *yyInput)) || c == '-' || c == '+') {
805*7c478bd9Sstevel@tonic-gate 	    if (c == '-' || c == '+') {
806*7c478bd9Sstevel@tonic-gate 		sign = c == '-' ? -1 : 1;
807*7c478bd9Sstevel@tonic-gate 		if (!isdigit((u_char)*++yyInput))
808*7c478bd9Sstevel@tonic-gate 		    /* skip the '-' sign */
809*7c478bd9Sstevel@tonic-gate 		    continue;
810*7c478bd9Sstevel@tonic-gate 	    }
811*7c478bd9Sstevel@tonic-gate 	    else
812*7c478bd9Sstevel@tonic-gate 		sign = 0;
813*7c478bd9Sstevel@tonic-gate 	    yylval.Number = 0;
814*7c478bd9Sstevel@tonic-gate 	    while (isdigit((u_char)(c = *yyInput++))) {
815*7c478bd9Sstevel@tonic-gate 		int n;
816*7c478bd9Sstevel@tonic-gate 		char digit = c;
817*7c478bd9Sstevel@tonic-gate 		(void) sscanf(&digit, "%1d", &n);
818*7c478bd9Sstevel@tonic-gate 		yylval.Number = 10 * yylval.Number + n;
819*7c478bd9Sstevel@tonic-gate 	    }
820*7c478bd9Sstevel@tonic-gate 	    yyInput--;
821*7c478bd9Sstevel@tonic-gate 	    if (sign < 0)
822*7c478bd9Sstevel@tonic-gate 		yylval.Number = -yylval.Number;
823*7c478bd9Sstevel@tonic-gate 	    return sign ? tSNUMBER : tUNUMBER;
824*7c478bd9Sstevel@tonic-gate 	}
825*7c478bd9Sstevel@tonic-gate 	if (isalpha((u_char)c)) {
826*7c478bd9Sstevel@tonic-gate 	    for (p = buff; isalpha((u_char)(c = *yyInput++)) || c == '.'; )
827*7c478bd9Sstevel@tonic-gate 		if (p < &buff[sizeof (buff) - 1])
828*7c478bd9Sstevel@tonic-gate 		    *p++ = c;
829*7c478bd9Sstevel@tonic-gate 	    *p = '\0';
830*7c478bd9Sstevel@tonic-gate 	    yyInput--;
831*7c478bd9Sstevel@tonic-gate 	    return LookupWord(buff);
832*7c478bd9Sstevel@tonic-gate 	}
833*7c478bd9Sstevel@tonic-gate 	if (c != '(')
834*7c478bd9Sstevel@tonic-gate 	    return *yyInput++;
835*7c478bd9Sstevel@tonic-gate 	Count = 0;
836*7c478bd9Sstevel@tonic-gate 	do {
837*7c478bd9Sstevel@tonic-gate 	    c = *yyInput++;
838*7c478bd9Sstevel@tonic-gate 	    if (c == '\0')
839*7c478bd9Sstevel@tonic-gate 		return c;
840*7c478bd9Sstevel@tonic-gate 	    if (c == '(')
841*7c478bd9Sstevel@tonic-gate 		Count++;
842*7c478bd9Sstevel@tonic-gate 	    else if (c == ')')
843*7c478bd9Sstevel@tonic-gate 		Count--;
844*7c478bd9Sstevel@tonic-gate 	} while (Count > 0);
845*7c478bd9Sstevel@tonic-gate     }
846*7c478bd9Sstevel@tonic-gate }
847*7c478bd9Sstevel@tonic-gate 
848*7c478bd9Sstevel@tonic-gate 
849*7c478bd9Sstevel@tonic-gate time_t
850*7c478bd9Sstevel@tonic-gate getreldate(p, now)
851*7c478bd9Sstevel@tonic-gate     char		*p;
852*7c478bd9Sstevel@tonic-gate     struct timeb	*now;
853*7c478bd9Sstevel@tonic-gate {
854*7c478bd9Sstevel@tonic-gate     struct tm		*tm;
855*7c478bd9Sstevel@tonic-gate     struct timeb	ftz;
856*7c478bd9Sstevel@tonic-gate     time_t		Start;
857*7c478bd9Sstevel@tonic-gate     time_t		tod;
858*7c478bd9Sstevel@tonic-gate 
859*7c478bd9Sstevel@tonic-gate     if (strcmp(setlocale(LC_TIME, NULL), "C")) {
860*7c478bd9Sstevel@tonic-gate 	static char localedate[24];
861*7c478bd9Sstevel@tonic-gate 	struct tm ltm;
862*7c478bd9Sstevel@tonic-gate 
863*7c478bd9Sstevel@tonic-gate 	tm = getdate(p);
864*7c478bd9Sstevel@tonic-gate 	if (getdate_err == 1 /* NODATEMASK */) {
865*7c478bd9Sstevel@tonic-gate 	    char buffy[BUFSIZ];
866*7c478bd9Sstevel@tonic-gate 	    time_t current;
867*7c478bd9Sstevel@tonic-gate 
868*7c478bd9Sstevel@tonic-gate 	    printf(gettext("environment variable %s not set\n"), "DATEMSK");
869*7c478bd9Sstevel@tonic-gate 	    do {
870*7c478bd9Sstevel@tonic-gate 		time(&current);
871*7c478bd9Sstevel@tonic-gate 		tm = localtime(&current);
872*7c478bd9Sstevel@tonic-gate 		memcpy(&ltm, tm, sizeof(ltm));
873*7c478bd9Sstevel@tonic-gate 		tm = &ltm;
874*7c478bd9Sstevel@tonic-gate 
875*7c478bd9Sstevel@tonic-gate 		(void) fputs(gettext("Enter date as mmddhhmm[yy]: "), stdout);
876*7c478bd9Sstevel@tonic-gate 		(void) fflush(stdout);
877*7c478bd9Sstevel@tonic-gate 		if (fgets(buffy, sizeof (buffy), stdin) == NULL) {
878*7c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Encountered EOF on stdin\n"));
879*7c478bd9Sstevel@tonic-gate 			return(-1);
880*7c478bd9Sstevel@tonic-gate 		}
881*7c478bd9Sstevel@tonic-gate 	    } while (sscanf(buffy, "%2d%2d%2d%2d%2d",
882*7c478bd9Sstevel@tonic-gate 		&(tm->tm_mon), &(tm->tm_mday), &(tm->tm_hour),
883*7c478bd9Sstevel@tonic-gate 		&(tm->tm_min), &(tm->tm_year)) < 4);
884*7c478bd9Sstevel@tonic-gate 
885*7c478bd9Sstevel@tonic-gate 	    (tm->tm_mon)--;
886*7c478bd9Sstevel@tonic-gate 	} else if (tm == NULL)
887*7c478bd9Sstevel@tonic-gate 	    return(-1);
888*7c478bd9Sstevel@tonic-gate 
889*7c478bd9Sstevel@tonic-gate 	(void)sprintf(localedate, "%d:%2.2d %d/%d %d",
890*7c478bd9Sstevel@tonic-gate 	    tm->tm_hour, tm->tm_min, tm->tm_mon + 1,
891*7c478bd9Sstevel@tonic-gate 	    tm->tm_mday, CHECK_TM(tm->tm_year));
892*7c478bd9Sstevel@tonic-gate 	p = localedate;
893*7c478bd9Sstevel@tonic-gate     }
894*7c478bd9Sstevel@tonic-gate 
895*7c478bd9Sstevel@tonic-gate     yyInput = p;
896*7c478bd9Sstevel@tonic-gate     if (now == NULL) {
897*7c478bd9Sstevel@tonic-gate 	now = &ftz;
898*7c478bd9Sstevel@tonic-gate 	(void) time(&ftz.time);
899*7c478bd9Sstevel@tonic-gate 	/* Set the timezone global. */
900*7c478bd9Sstevel@tonic-gate 	tzset();
901*7c478bd9Sstevel@tonic-gate 	/* LINTED timezone is time_t so intermediate results aren't truncated */
902*7c478bd9Sstevel@tonic-gate 	ftz.timezone = (int) timezone / 60;
903*7c478bd9Sstevel@tonic-gate     }
904*7c478bd9Sstevel@tonic-gate 
905*7c478bd9Sstevel@tonic-gate     tm = localtime(&now->time);
906*7c478bd9Sstevel@tonic-gate     yyYear = tm->tm_year;
907*7c478bd9Sstevel@tonic-gate     yyMonth = tm->tm_mon + 1;
908*7c478bd9Sstevel@tonic-gate     yyDay = tm->tm_mday;
909*7c478bd9Sstevel@tonic-gate     yyTimezone = now->timezone;
910*7c478bd9Sstevel@tonic-gate     yyDSTmode = DSTmaybe;
911*7c478bd9Sstevel@tonic-gate     yyHour = tm->tm_hour;
912*7c478bd9Sstevel@tonic-gate     yyMinutes = tm->tm_min;
913*7c478bd9Sstevel@tonic-gate     yySeconds = tm->tm_sec;
914*7c478bd9Sstevel@tonic-gate     yyMeridian = MER24;
915*7c478bd9Sstevel@tonic-gate     yyRelSeconds = 0;
916*7c478bd9Sstevel@tonic-gate     yyRelMonth = 0;
917*7c478bd9Sstevel@tonic-gate     yyHaveDate = 0;
918*7c478bd9Sstevel@tonic-gate     yyHaveDay = 0;
919*7c478bd9Sstevel@tonic-gate     yyHaveRel = 0;
920*7c478bd9Sstevel@tonic-gate     yyHaveTime = 0;
921*7c478bd9Sstevel@tonic-gate     yyHaveZone = 0;
922*7c478bd9Sstevel@tonic-gate 
923*7c478bd9Sstevel@tonic-gate     if (yyparse()
924*7c478bd9Sstevel@tonic-gate      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
925*7c478bd9Sstevel@tonic-gate 	return -1;
926*7c478bd9Sstevel@tonic-gate 
927*7c478bd9Sstevel@tonic-gate     if (yyHaveDate || yyHaveTime || yyHaveDay) {
928*7c478bd9Sstevel@tonic-gate 	Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
929*7c478bd9Sstevel@tonic-gate 		    yyMeridian, yyDSTmode);
930*7c478bd9Sstevel@tonic-gate 	if (Start < 0)
931*7c478bd9Sstevel@tonic-gate 	    return -1;
932*7c478bd9Sstevel@tonic-gate     }
933*7c478bd9Sstevel@tonic-gate     else {
934*7c478bd9Sstevel@tonic-gate 	Start = now->time;
935*7c478bd9Sstevel@tonic-gate 	if (!yyHaveRel)
936*7c478bd9Sstevel@tonic-gate 	    Start -= ((tm->tm_hour * 60L) + tm->tm_min * 60L) + tm->tm_sec;
937*7c478bd9Sstevel@tonic-gate     }
938*7c478bd9Sstevel@tonic-gate 
939*7c478bd9Sstevel@tonic-gate     Start += yyRelSeconds;
940*7c478bd9Sstevel@tonic-gate     Start += RelativeMonth(Start, yyRelMonth);
941*7c478bd9Sstevel@tonic-gate 
942*7c478bd9Sstevel@tonic-gate     if (yyHaveDay && !yyHaveDate) {
943*7c478bd9Sstevel@tonic-gate 	tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
944*7c478bd9Sstevel@tonic-gate 	Start += tod;
945*7c478bd9Sstevel@tonic-gate     }
946*7c478bd9Sstevel@tonic-gate 
947*7c478bd9Sstevel@tonic-gate     /* Have to do *something* with a legitimate -1 so it's distinguishable
948*7c478bd9Sstevel@tonic-gate      * from the error return value.  (Alternately could set errno on error.) */
949*7c478bd9Sstevel@tonic-gate     return Start == -1 ? 0 : Start;
950*7c478bd9Sstevel@tonic-gate }
951*7c478bd9Sstevel@tonic-gate 
952*7c478bd9Sstevel@tonic-gate #if	defined(TEST)
953*7c478bd9Sstevel@tonic-gate 
954*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
955*7c478bd9Sstevel@tonic-gate main(ac, av)
956*7c478bd9Sstevel@tonic-gate     int		ac;
957*7c478bd9Sstevel@tonic-gate     char	*av[];
958*7c478bd9Sstevel@tonic-gate {
959*7c478bd9Sstevel@tonic-gate     char	buff[128];
960*7c478bd9Sstevel@tonic-gate     time_t	d;
961*7c478bd9Sstevel@tonic-gate 
962*7c478bd9Sstevel@tonic-gate     (void) setlocale(LC_ALL, "");
963*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
964*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
965*7c478bd9Sstevel@tonic-gate #endif
966*7c478bd9Sstevel@tonic-gate     (void) textdomain(TEXT_DOMAIN);
967*7c478bd9Sstevel@tonic-gate 
968*7c478bd9Sstevel@tonic-gate     (void) printf(gettext("Enter date, or blank line to exit.\n\t> "));
969*7c478bd9Sstevel@tonic-gate     (void) fflush(stdout);
970*7c478bd9Sstevel@tonic-gate     while (gets(buff) && buff[0]) {
971*7c478bd9Sstevel@tonic-gate 	d = getreldate(buff, (struct timeb *)NULL);
972*7c478bd9Sstevel@tonic-gate 	if (d == -1)
973*7c478bd9Sstevel@tonic-gate 	    (void) printf(gettext("Bad format - couldn't convert.\n"));
974*7c478bd9Sstevel@tonic-gate 	else {
975*7c478bd9Sstevel@tonic-gate 	    (void) cftime(buff, "%c\n", &d);
976*7c478bd9Sstevel@tonic-gate 	    (void) printf("%s", buff);
977*7c478bd9Sstevel@tonic-gate 	}
978*7c478bd9Sstevel@tonic-gate 	(void) printf("\t> ");
979*7c478bd9Sstevel@tonic-gate 	(void) fflush(stdout);
980*7c478bd9Sstevel@tonic-gate     }
981*7c478bd9Sstevel@tonic-gate     exit(0);
982*7c478bd9Sstevel@tonic-gate     /* NOTREACHED */
983*7c478bd9Sstevel@tonic-gate }
984*7c478bd9Sstevel@tonic-gate #endif	/* defined(TEST) */
985