xref: /titanic_51/usr/src/cmd/krb5/kadmin/cli/getdate.y (revision 56a424cca6b3f91f31bdab72a4626c48c779fe8b)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  *	Openvision retains the copyright to derivative works of
57c478bd9Sstevel@tonic-gate  *	this source code.  Do *NOT* create a derivative of this
67c478bd9Sstevel@tonic-gate  *	source code before consulting with your legal department.
77c478bd9Sstevel@tonic-gate  *	Do *NOT* integrate *ANY* of this source code into another
87c478bd9Sstevel@tonic-gate  *	product before consulting with your legal department.
97c478bd9Sstevel@tonic-gate  *
107c478bd9Sstevel@tonic-gate  *	For further information, read the top-level Openvision
117c478bd9Sstevel@tonic-gate  *	copyright which is contained in the top-level MIT Kerberos
127c478bd9Sstevel@tonic-gate  *	copyright.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  */
177c478bd9Sstevel@tonic-gate 
187c478bd9Sstevel@tonic-gate 
197c478bd9Sstevel@tonic-gate %{
207c478bd9Sstevel@tonic-gate /*
21*56a424ccSmp153739  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
227c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
28*56a424ccSmp153739 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
29*56a424ccSmp153739 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
30*56a424ccSmp153739 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
31*56a424ccSmp153739 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
32*56a424ccSmp153739 **  send any email to Rich.
33*56a424ccSmp153739 **
34*56a424ccSmp153739 **  This grammar has nine shift/reduce conflicts.
35*56a424ccSmp153739 **
36*56a424ccSmp153739 **  This code is in the public domain and has no copyright.
377c478bd9Sstevel@tonic-gate */
387c478bd9Sstevel@tonic-gate /* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
397c478bd9Sstevel@tonic-gate /* SUPPRESS 288 on yyerrlab *//* Label unused */
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #ifdef HAVE_CONFIG_H
427c478bd9Sstevel@tonic-gate #if defined (emacs) || defined (CONFIG_BROKETS)
437c478bd9Sstevel@tonic-gate #include <config.h>
447c478bd9Sstevel@tonic-gate #else
457c478bd9Sstevel@tonic-gate #include "config.h"
467c478bd9Sstevel@tonic-gate #endif
477c478bd9Sstevel@tonic-gate #endif
487c478bd9Sstevel@tonic-gate #include <string.h>
497c478bd9Sstevel@tonic-gate 
50*56a424ccSmp153739 /* Since the code of getdate.y is not included in the Emacs executable
51*56a424ccSmp153739    itself, there is no need to #define static in this file.  Even if
52*56a424ccSmp153739    the code were included in the Emacs executable, it probably
53*56a424ccSmp153739    wouldn't do any harm to #undef it here; this will only cause
54*56a424ccSmp153739    problems if we try to write to a static variable, which I don't
55*56a424ccSmp153739    think this code needs to do.  */
567c478bd9Sstevel@tonic-gate #ifdef emacs
577c478bd9Sstevel@tonic-gate #undef static
587c478bd9Sstevel@tonic-gate #endif
597c478bd9Sstevel@tonic-gate 
60*56a424ccSmp153739 /* The following block of alloca-related preprocessor directives is here
61*56a424ccSmp153739    solely to allow compilation by non GNU-C compilers of the C parser
62*56a424ccSmp153739    produced from this file by old versions of bison.  Newer versions of
63*56a424ccSmp153739    bison include a block similar to this one in bison.simple.  */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate #ifdef __GNUC__
667c478bd9Sstevel@tonic-gate #undef alloca
677c478bd9Sstevel@tonic-gate #define alloca __builtin_alloca
687c478bd9Sstevel@tonic-gate #else
697c478bd9Sstevel@tonic-gate #ifdef HAVE_ALLOCA_H
707c478bd9Sstevel@tonic-gate #include <alloca.h>
717c478bd9Sstevel@tonic-gate #else
727c478bd9Sstevel@tonic-gate #ifdef _AIX /* for Bison */
737c478bd9Sstevel@tonic-gate  #pragma alloca
747c478bd9Sstevel@tonic-gate #else
757c478bd9Sstevel@tonic-gate void *alloca ();
767c478bd9Sstevel@tonic-gate #endif
777c478bd9Sstevel@tonic-gate #endif
787c478bd9Sstevel@tonic-gate #endif
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate #include <stdio.h>
817c478bd9Sstevel@tonic-gate #include <ctype.h>
827c478bd9Sstevel@tonic-gate 
83*56a424ccSmp153739 #if defined(HAVE_STDLIB_H)
84*56a424ccSmp153739 #include <stdlib.h>
85*56a424ccSmp153739 #endif
86*56a424ccSmp153739 
87*56a424ccSmp153739 /* The code at the top of get_date which figures out the offset of the
88*56a424ccSmp153739    current time zone checks various CPP symbols to see if special
89*56a424ccSmp153739    tricks are need, but defaults to using the gettimeofday system call.
90*56a424ccSmp153739    Include <sys/time.h> if that will be used.  */
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate #if	defined(vms)
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate #include <types.h>
957c478bd9Sstevel@tonic-gate #include <time.h>
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate #else
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate #include <sys/types.h>
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate #ifdef TIME_WITH_SYS_TIME
1027c478bd9Sstevel@tonic-gate #include <sys/time.h>
1037c478bd9Sstevel@tonic-gate #include <time.h>
1047c478bd9Sstevel@tonic-gate #else
1057c478bd9Sstevel@tonic-gate #ifdef HAVE_SYS_TIME_H
1067c478bd9Sstevel@tonic-gate #include <sys/time.h>
1077c478bd9Sstevel@tonic-gate #else
1087c478bd9Sstevel@tonic-gate #include <time.h>
1097c478bd9Sstevel@tonic-gate #endif
1107c478bd9Sstevel@tonic-gate #endif
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate #ifdef timezone
1137c478bd9Sstevel@tonic-gate #undef timezone /* needed for sgi */
1147c478bd9Sstevel@tonic-gate #endif
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate /*
117*56a424ccSmp153739 ** We use the obsolete `struct my_timeb' as part of our interface!
118*56a424ccSmp153739 ** Since the system doesn't have it, we define it here;
119*56a424ccSmp153739 ** our callers must do likewise.
1207c478bd9Sstevel@tonic-gate */
1217c478bd9Sstevel@tonic-gate struct my_timeb {
1227c478bd9Sstevel@tonic-gate     time_t		time;		/* Seconds since the epoch	*/
1237c478bd9Sstevel@tonic-gate     unsigned short	millitm;	/* Field not used		*/
1247c478bd9Sstevel@tonic-gate     short		timezone;	/* Minutes west of GMT		*/
1257c478bd9Sstevel@tonic-gate     short		dstflag;	/* Field not used		*/
1267c478bd9Sstevel@tonic-gate };
1277c478bd9Sstevel@tonic-gate #endif	/* defined(vms) */
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate #if defined (STDC_HEADERS) || defined (USG)
1307c478bd9Sstevel@tonic-gate #include <string.h>
1317c478bd9Sstevel@tonic-gate #endif
1327c478bd9Sstevel@tonic-gate 
133*56a424ccSmp153739 /* Some old versions of bison generate parsers that use bcopy.
134*56a424ccSmp153739    That loses on systems that don't provide the function, so we have
135*56a424ccSmp153739    to redefine it here.  */
136*56a424ccSmp153739 #ifndef bcopy
1377c478bd9Sstevel@tonic-gate #define bcopy(from, to, len) memcpy ((to), (from), (len))
1387c478bd9Sstevel@tonic-gate #endif
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate /*
1417c478bd9Sstevel@tonic-gate  * The following is a hack so that it is easy to internationalize
1427c478bd9Sstevel@tonic-gate  * statically declared strings. We define a wrapper function here that
1437c478bd9Sstevel@tonic-gate  * will be a replacement for gettext. We the make gettext a macro that
1447c478bd9Sstevel@tonic-gate  * just returns its argument, which now can be used with statically defined
1457c478bd9Sstevel@tonic-gate  * strings. The conquence of this is that GETTEXT must be used to translate
1467c478bd9Sstevel@tonic-gate  * a string at runtime and gettext must be used around string literals so
1477c478bd9Sstevel@tonic-gate  * that xgettext command can extract them to a portable object database file.
1487c478bd9Sstevel@tonic-gate  *
1497c478bd9Sstevel@tonic-gate  * Thus to translate a string literal that is an argument to a function foo
1507c478bd9Sstevel@tonic-gate  * the following will have to be performed:
1517c478bd9Sstevel@tonic-gate  *
1527c478bd9Sstevel@tonic-gate  *              foo(GETTEXT(gettext("This is a test")));
1537c478bd9Sstevel@tonic-gate  *
1547c478bd9Sstevel@tonic-gate  * The inner gettext call is for xgettext command to extract the string.
1557c478bd9Sstevel@tonic-gate  * The C preprossesor will reduce the above to:
1567c478bd9Sstevel@tonic-gate  *
1577c478bd9Sstevel@tonic-gate  *              foo(GETTEXT(("This ia a test"));
1587c478bd9Sstevel@tonic-gate  */
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate #include <libintl.h>
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate static char *
1637c478bd9Sstevel@tonic-gate GETTEXT(const char *msgid)
1647c478bd9Sstevel@tonic-gate {
1657c478bd9Sstevel@tonic-gate 	return (gettext(msgid));
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate #define	gettext(s) (s)
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate extern struct tm	*gmtime();
1727c478bd9Sstevel@tonic-gate extern struct tm	*localtime();
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate #define yyparse getdate_yyparse
1757c478bd9Sstevel@tonic-gate #define yylex getdate_yylex
1767c478bd9Sstevel@tonic-gate #define yyerror getdate_yyerror
1777c478bd9Sstevel@tonic-gate 
178*56a424ccSmp153739 static int getdate_yylex (void);
179*56a424ccSmp153739 static int getdate_yyerror (char *);
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate #define EPOCH		1970
1837c478bd9Sstevel@tonic-gate #define EPOCH_END	2099  /* Solaris 64 bit can support this at this point */
1847c478bd9Sstevel@tonic-gate #define HOUR(x)		((time_t)(x) * 60)
1857c478bd9Sstevel@tonic-gate #define SECSPERDAY	(24L * 60L * 60L)
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 
1887c478bd9Sstevel@tonic-gate /*
189*56a424ccSmp153739 **  An entry in the lexical lookup table.
1907c478bd9Sstevel@tonic-gate */
1917c478bd9Sstevel@tonic-gate typedef struct _TABLE {
1927c478bd9Sstevel@tonic-gate     char	*name;
1937c478bd9Sstevel@tonic-gate     int		type;
1947c478bd9Sstevel@tonic-gate     time_t	value;
1957c478bd9Sstevel@tonic-gate } TABLE;
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate /*
199*56a424ccSmp153739 **  Daylight-savings mode:  on, off, or not yet known.
2007c478bd9Sstevel@tonic-gate */
2017c478bd9Sstevel@tonic-gate typedef enum _DSTMODE {
2027c478bd9Sstevel@tonic-gate     DSTon, DSToff, DSTmaybe
2037c478bd9Sstevel@tonic-gate } DSTMODE;
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate /*
206*56a424ccSmp153739 **  Meridian:  am, pm, or 24-hour style.
2077c478bd9Sstevel@tonic-gate */
2087c478bd9Sstevel@tonic-gate typedef enum _MERIDIAN {
2097c478bd9Sstevel@tonic-gate     MERam, MERpm, MER24
2107c478bd9Sstevel@tonic-gate } MERIDIAN;
2117c478bd9Sstevel@tonic-gate 
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*
214*56a424ccSmp153739 **  Global variables.  We could get rid of most of these by using a good
215*56a424ccSmp153739 **  union as the yacc stack.  (This routine was originally written before
216*56a424ccSmp153739 **  yacc had the %union construct.)  Maybe someday; right now we only use
217*56a424ccSmp153739 **  the %union very rarely.
2187c478bd9Sstevel@tonic-gate */
2197c478bd9Sstevel@tonic-gate static char	*yyInput;
2207c478bd9Sstevel@tonic-gate static DSTMODE	yyDSTmode;
2217c478bd9Sstevel@tonic-gate static time_t	yyDayOrdinal;
2227c478bd9Sstevel@tonic-gate static time_t	yyDayNumber;
2237c478bd9Sstevel@tonic-gate static int	yyHaveDate;
2247c478bd9Sstevel@tonic-gate static int	yyHaveDay;
2257c478bd9Sstevel@tonic-gate static int	yyHaveRel;
2267c478bd9Sstevel@tonic-gate static int	yyHaveTime;
2277c478bd9Sstevel@tonic-gate static int	yyHaveZone;
2287c478bd9Sstevel@tonic-gate static time_t	yyTimezone;
2297c478bd9Sstevel@tonic-gate static time_t	yyDay;
2307c478bd9Sstevel@tonic-gate static time_t	yyHour;
2317c478bd9Sstevel@tonic-gate static time_t	yyMinutes;
2327c478bd9Sstevel@tonic-gate static time_t	yyMonth;
2337c478bd9Sstevel@tonic-gate static time_t	yySeconds;
2347c478bd9Sstevel@tonic-gate static time_t	yyYear;
2357c478bd9Sstevel@tonic-gate static MERIDIAN	yyMeridian;
2367c478bd9Sstevel@tonic-gate static time_t	yyRelMonth;
2377c478bd9Sstevel@tonic-gate static time_t	yyRelSeconds;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate %}
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate %union {
2427c478bd9Sstevel@tonic-gate     time_t		Number;
2437c478bd9Sstevel@tonic-gate     enum _MERIDIAN	Meridian;
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate %token	tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
2477c478bd9Sstevel@tonic-gate %token	tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST tNEVER
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate %type	<Number>	tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
2507c478bd9Sstevel@tonic-gate %type	<Number>	tSEC_UNIT tSNUMBER tUNUMBER tZONE
2517c478bd9Sstevel@tonic-gate %type	<Meridian>	tMERIDIAN o_merid
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate %%
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate spec	: /* NULL */
2567c478bd9Sstevel@tonic-gate 	| spec item
2577c478bd9Sstevel@tonic-gate         | tNEVER {
2587c478bd9Sstevel@tonic-gate 	    yyYear = 1970;
2597c478bd9Sstevel@tonic-gate 	    yyMonth = 1;
2607c478bd9Sstevel@tonic-gate 	    yyDay = 1;
2617c478bd9Sstevel@tonic-gate 	    yyHour = yyMinutes = yySeconds = 0;
2627c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
2637c478bd9Sstevel@tonic-gate 	    yyTimezone = 0; /* gmt */
2647c478bd9Sstevel@tonic-gate 	    yyHaveDate++;
2657c478bd9Sstevel@tonic-gate         }
2667c478bd9Sstevel@tonic-gate 	;
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate item	: time {
2697c478bd9Sstevel@tonic-gate 	    yyHaveTime++;
2707c478bd9Sstevel@tonic-gate 	}
2717c478bd9Sstevel@tonic-gate 	| zone {
2727c478bd9Sstevel@tonic-gate 	    yyHaveZone++;
2737c478bd9Sstevel@tonic-gate 	}
2747c478bd9Sstevel@tonic-gate 	| date {
2757c478bd9Sstevel@tonic-gate 	    yyHaveDate++;
2767c478bd9Sstevel@tonic-gate 	}
2777c478bd9Sstevel@tonic-gate 	| day {
2787c478bd9Sstevel@tonic-gate 	    yyHaveDay++;
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 	| rel {
2817c478bd9Sstevel@tonic-gate 	    yyHaveRel++;
2827c478bd9Sstevel@tonic-gate 	}
2837c478bd9Sstevel@tonic-gate 	;
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate time	: tUNUMBER tMERIDIAN {
2867c478bd9Sstevel@tonic-gate 	    yyHour = $1;
2877c478bd9Sstevel@tonic-gate 	    yyMinutes = 0;
2887c478bd9Sstevel@tonic-gate 	    yySeconds = 0;
2897c478bd9Sstevel@tonic-gate 	    yyMeridian = $2;
2907c478bd9Sstevel@tonic-gate 	}
2917c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER o_merid {
2927c478bd9Sstevel@tonic-gate 	    yyHour = $1;
2937c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
2947c478bd9Sstevel@tonic-gate 	    yySeconds = 0;
2957c478bd9Sstevel@tonic-gate 	    yyMeridian = $4;
2967c478bd9Sstevel@tonic-gate 	}
2977c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER tSNUMBER {
2987c478bd9Sstevel@tonic-gate 	    yyHour = $1;
2997c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
3007c478bd9Sstevel@tonic-gate 	    yyMeridian = MER24;
3017c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
3027c478bd9Sstevel@tonic-gate 	    yyTimezone = - ($4 % 100 + ($4 / 100) * 60);
3037c478bd9Sstevel@tonic-gate 	}
3047c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
3057c478bd9Sstevel@tonic-gate 	    yyHour = $1;
3067c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
3077c478bd9Sstevel@tonic-gate 	    yySeconds = $5;
3087c478bd9Sstevel@tonic-gate 	    yyMeridian = $6;
3097c478bd9Sstevel@tonic-gate 	}
3107c478bd9Sstevel@tonic-gate 	| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
3117c478bd9Sstevel@tonic-gate 	    yyHour = $1;
3127c478bd9Sstevel@tonic-gate 	    yyMinutes = $3;
3137c478bd9Sstevel@tonic-gate 	    yySeconds = $5;
3147c478bd9Sstevel@tonic-gate 	    yyMeridian = MER24;
3157c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
3167c478bd9Sstevel@tonic-gate 	    yyTimezone = - ($6 % 100 + ($6 / 100) * 60);
3177c478bd9Sstevel@tonic-gate 	}
3187c478bd9Sstevel@tonic-gate 	;
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate zone	: tZONE {
3217c478bd9Sstevel@tonic-gate 	    yyTimezone = $1;
3227c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSToff;
3237c478bd9Sstevel@tonic-gate 	}
3247c478bd9Sstevel@tonic-gate 	| tDAYZONE {
3257c478bd9Sstevel@tonic-gate 	    yyTimezone = $1;
3267c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSTon;
3277c478bd9Sstevel@tonic-gate 	}
3287c478bd9Sstevel@tonic-gate 	|
3297c478bd9Sstevel@tonic-gate 	  tZONE tDST {
3307c478bd9Sstevel@tonic-gate 	    yyTimezone = $1;
3317c478bd9Sstevel@tonic-gate 	    yyDSTmode = DSTon;
3327c478bd9Sstevel@tonic-gate 	}
3337c478bd9Sstevel@tonic-gate 	;
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate day	: tDAY {
3367c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = 1;
3377c478bd9Sstevel@tonic-gate 	    yyDayNumber = $1;
3387c478bd9Sstevel@tonic-gate 	}
3397c478bd9Sstevel@tonic-gate 	| tDAY ',' {
3407c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = 1;
3417c478bd9Sstevel@tonic-gate 	    yyDayNumber = $1;
3427c478bd9Sstevel@tonic-gate 	}
3437c478bd9Sstevel@tonic-gate 	| tUNUMBER tDAY {
3447c478bd9Sstevel@tonic-gate 	    yyDayOrdinal = $1;
3457c478bd9Sstevel@tonic-gate 	    yyDayNumber = $2;
3467c478bd9Sstevel@tonic-gate 	}
3477c478bd9Sstevel@tonic-gate 	;
3487c478bd9Sstevel@tonic-gate 
3497c478bd9Sstevel@tonic-gate date	: tUNUMBER '/' tUNUMBER {
3507c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
3517c478bd9Sstevel@tonic-gate 	    yyDay = $3;
3527c478bd9Sstevel@tonic-gate 	}
3537c478bd9Sstevel@tonic-gate 	| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
3547c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
3557c478bd9Sstevel@tonic-gate 	    yyDay = $3;
3567c478bd9Sstevel@tonic-gate 	    yyYear = $5;
3577c478bd9Sstevel@tonic-gate 	}
3587c478bd9Sstevel@tonic-gate 	| tUNUMBER tSNUMBER tSNUMBER {
3597c478bd9Sstevel@tonic-gate 	    /* ISO 8601 format.  yyyy-mm-dd.  */
3607c478bd9Sstevel@tonic-gate 	    yyYear = $1;
3617c478bd9Sstevel@tonic-gate 	    yyMonth = -$2;
3627c478bd9Sstevel@tonic-gate 	    yyDay = -$3;
3637c478bd9Sstevel@tonic-gate 	}
3647c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH tSNUMBER {
3657c478bd9Sstevel@tonic-gate 	    /* e.g. 17-JUN-1992.  */
3667c478bd9Sstevel@tonic-gate 	    yyDay = $1;
3677c478bd9Sstevel@tonic-gate 	    yyMonth = $2;
3687c478bd9Sstevel@tonic-gate 	    yyYear = -$3;
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 	| tMONTH tUNUMBER {
3717c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
3727c478bd9Sstevel@tonic-gate 	    yyDay = $2;
3737c478bd9Sstevel@tonic-gate 	}
3747c478bd9Sstevel@tonic-gate 	| tMONTH tUNUMBER ',' tUNUMBER {
3757c478bd9Sstevel@tonic-gate 	    yyMonth = $1;
3767c478bd9Sstevel@tonic-gate 	    yyDay = $2;
3777c478bd9Sstevel@tonic-gate 	    yyYear = $4;
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH {
3807c478bd9Sstevel@tonic-gate 	    yyMonth = $2;
3817c478bd9Sstevel@tonic-gate 	    yyDay = $1;
3827c478bd9Sstevel@tonic-gate 	}
3837c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH tUNUMBER {
3847c478bd9Sstevel@tonic-gate 	    yyMonth = $2;
3857c478bd9Sstevel@tonic-gate 	    yyDay = $1;
3867c478bd9Sstevel@tonic-gate 	    yyYear = $3;
3877c478bd9Sstevel@tonic-gate 	}
3887c478bd9Sstevel@tonic-gate 	;
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate rel	: relunit tAGO {
3917c478bd9Sstevel@tonic-gate 	    yyRelSeconds = -yyRelSeconds;
3927c478bd9Sstevel@tonic-gate 	    yyRelMonth = -yyRelMonth;
3937c478bd9Sstevel@tonic-gate 	}
3947c478bd9Sstevel@tonic-gate 	| relunit
3957c478bd9Sstevel@tonic-gate 	;
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate relunit	: tUNUMBER tMINUTE_UNIT {
3987c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * $2 * 60L;
3997c478bd9Sstevel@tonic-gate 	}
4007c478bd9Sstevel@tonic-gate 	| tSNUMBER tMINUTE_UNIT {
4017c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * $2 * 60L;
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	| tMINUTE_UNIT {
4047c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1 * 60L;
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 	| tSNUMBER tSEC_UNIT {
4077c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1;
4087c478bd9Sstevel@tonic-gate 	}
4097c478bd9Sstevel@tonic-gate 	| tUNUMBER tSEC_UNIT {
4107c478bd9Sstevel@tonic-gate 	    yyRelSeconds += $1;
4117c478bd9Sstevel@tonic-gate 	}
4127c478bd9Sstevel@tonic-gate 	| tSEC_UNIT {
4137c478bd9Sstevel@tonic-gate 	    yyRelSeconds++;
4147c478bd9Sstevel@tonic-gate 	}
4157c478bd9Sstevel@tonic-gate 	| tSNUMBER tMONTH_UNIT {
4167c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1 * $2;
4177c478bd9Sstevel@tonic-gate 	}
4187c478bd9Sstevel@tonic-gate 	| tUNUMBER tMONTH_UNIT {
4197c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1 * $2;
4207c478bd9Sstevel@tonic-gate 	}
4217c478bd9Sstevel@tonic-gate 	| tMONTH_UNIT {
4227c478bd9Sstevel@tonic-gate 	    yyRelMonth += $1;
4237c478bd9Sstevel@tonic-gate 	}
4247c478bd9Sstevel@tonic-gate 	;
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate o_merid	: /* NULL */ {
4277c478bd9Sstevel@tonic-gate 	    $$ = MER24;
4287c478bd9Sstevel@tonic-gate 	}
4297c478bd9Sstevel@tonic-gate 	| tMERIDIAN {
4307c478bd9Sstevel@tonic-gate 	    $$ = $1;
4317c478bd9Sstevel@tonic-gate 	}
4327c478bd9Sstevel@tonic-gate 	;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate %%
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate /* Month and day table. */
4377c478bd9Sstevel@tonic-gate static TABLE const MonthDayTable[] = {
4387c478bd9Sstevel@tonic-gate 	{ gettext("january"),	tMONTH,  1 },
4397c478bd9Sstevel@tonic-gate 	{ gettext("february"),	tMONTH,  2 },
4407c478bd9Sstevel@tonic-gate 	{ gettext("march"),	tMONTH,  3 },
4417c478bd9Sstevel@tonic-gate 	{ gettext("april"),	tMONTH,  4 },
4427c478bd9Sstevel@tonic-gate 	{ gettext("may"),	tMONTH,  5 },
4437c478bd9Sstevel@tonic-gate 	{ gettext("june"),	tMONTH,  6 },
4447c478bd9Sstevel@tonic-gate 	{ gettext("july"),	tMONTH,  7 },
4457c478bd9Sstevel@tonic-gate 	{ gettext("august"),	tMONTH,  8 },
4467c478bd9Sstevel@tonic-gate 	{ gettext("september"),	tMONTH,  9 },
4477c478bd9Sstevel@tonic-gate 	{ gettext("sept"),	tMONTH,  9 },
4487c478bd9Sstevel@tonic-gate 	{ gettext("october"),	tMONTH, 10 },
4497c478bd9Sstevel@tonic-gate 	{ gettext("november"),	tMONTH, 11 },
4507c478bd9Sstevel@tonic-gate 	{ gettext("december"),	tMONTH, 12 },
4517c478bd9Sstevel@tonic-gate 	{ gettext("sunday"),	tDAY, 0 },
4527c478bd9Sstevel@tonic-gate 	{ gettext("monday"),	tDAY, 1 },
4537c478bd9Sstevel@tonic-gate 	{ gettext("tuesday"),	tDAY, 2 },
4547c478bd9Sstevel@tonic-gate 	{ gettext("tues"),	tDAY, 2 },
4557c478bd9Sstevel@tonic-gate 	{ gettext("wednesday"),	tDAY, 3 },
4567c478bd9Sstevel@tonic-gate 	{ gettext("wednes"),	tDAY, 3 },
4577c478bd9Sstevel@tonic-gate 	{ gettext("thursday"),	tDAY, 4 },
4587c478bd9Sstevel@tonic-gate 	{ gettext("thur"),	tDAY, 4 },
4597c478bd9Sstevel@tonic-gate 	{ gettext("thurs"),	tDAY, 4 },
4607c478bd9Sstevel@tonic-gate 	{ gettext("friday"),	tDAY, 5 },
4617c478bd9Sstevel@tonic-gate 	{ gettext("saturday"),	tDAY, 6 },
4627c478bd9Sstevel@tonic-gate 	{ NULL }
4637c478bd9Sstevel@tonic-gate };
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate /* Time units table. */
4667c478bd9Sstevel@tonic-gate static TABLE const UnitsTable[] = {
4677c478bd9Sstevel@tonic-gate 	{ gettext("year"),		tMONTH_UNIT,	12 },
4687c478bd9Sstevel@tonic-gate 	{ gettext("month"),		tMONTH_UNIT,	1 },
4697c478bd9Sstevel@tonic-gate 	{ gettext("fortnight"),	tMINUTE_UNIT,	14 * 24 * 60 },
4707c478bd9Sstevel@tonic-gate 	{ gettext("week"),		tMINUTE_UNIT,	7 * 24 * 60 },
4717c478bd9Sstevel@tonic-gate 	{ gettext("day"),		tMINUTE_UNIT,	1 * 24 * 60 },
4727c478bd9Sstevel@tonic-gate 	{ gettext("hour"),		tMINUTE_UNIT,	60 },
4737c478bd9Sstevel@tonic-gate 	{ gettext("minute"),	tMINUTE_UNIT,	1 },
4747c478bd9Sstevel@tonic-gate 	{ gettext("min"),		tMINUTE_UNIT,	1 },
4757c478bd9Sstevel@tonic-gate 	{ gettext("second"),	tSEC_UNIT,	1 },
4767c478bd9Sstevel@tonic-gate 	{ gettext("sec"),		tSEC_UNIT,	1 },
4777c478bd9Sstevel@tonic-gate 	{ NULL }
4787c478bd9Sstevel@tonic-gate };
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate /* Assorted relative-time words. */
4817c478bd9Sstevel@tonic-gate static TABLE const OtherTable[] = {
4827c478bd9Sstevel@tonic-gate 	{ gettext("tomorrow"),	tMINUTE_UNIT,	1 * 24 * 60 },
4837c478bd9Sstevel@tonic-gate 	{ gettext("yesterday"),	tMINUTE_UNIT,	-1 * 24 * 60 },
4847c478bd9Sstevel@tonic-gate 	{ gettext("today"),	tMINUTE_UNIT,	0 },
4857c478bd9Sstevel@tonic-gate 	{ gettext("now"),	tMINUTE_UNIT,	0 },
4867c478bd9Sstevel@tonic-gate 	{ gettext("last"),	tUNUMBER,	-1 },
4877c478bd9Sstevel@tonic-gate 	{ gettext("this"),	tMINUTE_UNIT,	0 },
4887c478bd9Sstevel@tonic-gate 	{ gettext("next"),	tUNUMBER,	2 },
4897c478bd9Sstevel@tonic-gate 	{ gettext("first"),	tUNUMBER,	1 },
4907c478bd9Sstevel@tonic-gate 	/*  { gettext("second"),	tUNUMBER,	2 }, */
4917c478bd9Sstevel@tonic-gate 	{ gettext("third"),	tUNUMBER,	3 },
4927c478bd9Sstevel@tonic-gate 	{ gettext("fourth"),	tUNUMBER,	4 },
4937c478bd9Sstevel@tonic-gate 	{ gettext("fifth"),	tUNUMBER,	5 },
4947c478bd9Sstevel@tonic-gate 	{ gettext("sixth"),	tUNUMBER,	6 },
4957c478bd9Sstevel@tonic-gate 	{ gettext("seventh"),	tUNUMBER,	7 },
4967c478bd9Sstevel@tonic-gate 	{ gettext("eighth"),	tUNUMBER,	8 },
4977c478bd9Sstevel@tonic-gate 	{ gettext("ninth"),	tUNUMBER,	9 },
4987c478bd9Sstevel@tonic-gate 	{ gettext("tenth"),	tUNUMBER,	10 },
4997c478bd9Sstevel@tonic-gate 	{ gettext("eleventh"),	tUNUMBER,	11 },
5007c478bd9Sstevel@tonic-gate 	{ gettext("twelfth"),	tUNUMBER,	12 },
5017c478bd9Sstevel@tonic-gate 	{ gettext("ago"),	tAGO,		1 },
5027c478bd9Sstevel@tonic-gate 	{ gettext("never"),	tNEVER,		0 },
5037c478bd9Sstevel@tonic-gate 	{ NULL }
5047c478bd9Sstevel@tonic-gate };
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate /* The timezone table. */
5077c478bd9Sstevel@tonic-gate /* Some of these are commented out because a time_t can't store a float. */
5087c478bd9Sstevel@tonic-gate static TABLE const TimezoneTable[] = {
5097c478bd9Sstevel@tonic-gate 	{ gettext("gmt"),	tZONE,     HOUR( 0) },	/* Greenwich Mean */
5107c478bd9Sstevel@tonic-gate 	{ gettext("ut"),	tZONE,     HOUR( 0) },	/* Universal (Coordinated) */
5117c478bd9Sstevel@tonic-gate 	{ gettext("utc"),	tZONE,     HOUR( 0) },
5127c478bd9Sstevel@tonic-gate 	{ gettext("wet"),	tZONE,     HOUR( 0) },	/* Western European */
5137c478bd9Sstevel@tonic-gate 	{ gettext("bst"),	tDAYZONE,  HOUR( 0) },	/* British Summer */
5147c478bd9Sstevel@tonic-gate 	{ gettext("wat"),	tZONE,     HOUR( 1) },	/* West Africa */
5157c478bd9Sstevel@tonic-gate 	{ gettext("at"),	tZONE,     HOUR( 2) },	/* Azores */
5167c478bd9Sstevel@tonic-gate #if	0
517*56a424ccSmp153739     /* For completeness.  BST is also British Summer, and GST is
518*56a424ccSmp153739      * also Guam Standard. */
5197c478bd9Sstevel@tonic-gate     { gettext("bst"),	tZONE,     HOUR( 3) },	/* Brazil Standard */
5207c478bd9Sstevel@tonic-gate     { gettext("gst"),	tZONE,     HOUR( 3) },	/* Greenland Standard */
5217c478bd9Sstevel@tonic-gate #endif
5227c478bd9Sstevel@tonic-gate #if 0
5237c478bd9Sstevel@tonic-gate 	{ gettext("nft"),	tZONE,     HOUR(3.5) },	/* Newfoundland */
5247c478bd9Sstevel@tonic-gate 	{ gettext("nst"),	tZONE,     HOUR(3.5) },	/* Newfoundland Standard */
5257c478bd9Sstevel@tonic-gate 	{ gettext("ndt"),	tDAYZONE,  HOUR(3.5) },	/* Newfoundland Daylight */
5267c478bd9Sstevel@tonic-gate #endif
5277c478bd9Sstevel@tonic-gate 	{ gettext("ast"),	tZONE,     HOUR( 4) },	/* Atlantic Standard */
5287c478bd9Sstevel@tonic-gate 	{ gettext("adt"),	tDAYZONE,  HOUR( 4) },	/* Atlantic Daylight */
5297c478bd9Sstevel@tonic-gate 	{ gettext("est"),	tZONE,     HOUR( 5) },	/* Eastern Standard */
5307c478bd9Sstevel@tonic-gate 	{ gettext("edt"),	tDAYZONE,  HOUR( 5) },	/* Eastern Daylight */
5317c478bd9Sstevel@tonic-gate 	{ gettext("cst"),	tZONE,     HOUR( 6) },	/* Central Standard */
5327c478bd9Sstevel@tonic-gate 	{ gettext("cdt"),	tDAYZONE,  HOUR( 6) },	/* Central Daylight */
5337c478bd9Sstevel@tonic-gate 	{ gettext("mst"),	tZONE,     HOUR( 7) },	/* Mountain Standard */
5347c478bd9Sstevel@tonic-gate 	{ gettext("mdt"),	tDAYZONE,  HOUR( 7) },	/* Mountain Daylight */
5357c478bd9Sstevel@tonic-gate 	{ gettext("pst"),	tZONE,     HOUR( 8) },	/* Pacific Standard */
5367c478bd9Sstevel@tonic-gate 	{ gettext("pdt"),	tDAYZONE,  HOUR( 8) },	/* Pacific Daylight */
5377c478bd9Sstevel@tonic-gate 	{ gettext("yst"),	tZONE,     HOUR( 9) },	/* Yukon Standard */
5387c478bd9Sstevel@tonic-gate 	{ gettext("ydt"),	tDAYZONE,  HOUR( 9) },	/* Yukon Daylight */
5397c478bd9Sstevel@tonic-gate 	{ gettext("hst"),	tZONE,     HOUR(10) },	/* Hawaii Standard */
5407c478bd9Sstevel@tonic-gate 	{ gettext("hdt"),	tDAYZONE,  HOUR(10) },	/* Hawaii Daylight */
5417c478bd9Sstevel@tonic-gate 	{ gettext("cat"),	tZONE,     HOUR(10) },	/* Central Alaska */
5427c478bd9Sstevel@tonic-gate 	{ gettext("ahst"),	tZONE,     HOUR(10) },	/* Alaska-Hawaii Standard */
5437c478bd9Sstevel@tonic-gate 	{ gettext("nt"),	tZONE,     HOUR(11) },	/* Nome */
5447c478bd9Sstevel@tonic-gate 	{ gettext("idlw"),	tZONE,     HOUR(12) },	/* International Date Line West */
5457c478bd9Sstevel@tonic-gate 	{ gettext("cet"),	tZONE,     -HOUR(1) },	/* Central European */
5467c478bd9Sstevel@tonic-gate 	{ gettext("met"),	tZONE,     -HOUR(1) },	/* Middle European */
5477c478bd9Sstevel@tonic-gate 	{ gettext("mewt"),	tZONE,     -HOUR(1) },	/* Middle European Winter */
5487c478bd9Sstevel@tonic-gate 	{ gettext("mest"),	tDAYZONE,  -HOUR(1) },	/* Middle European Summer */
5497c478bd9Sstevel@tonic-gate 	{ gettext("swt"),	tZONE,     -HOUR(1) },	/* Swedish Winter */
5507c478bd9Sstevel@tonic-gate 	{ gettext("sst"),	tDAYZONE,  -HOUR(1) },	/* Swedish Summer */
5517c478bd9Sstevel@tonic-gate 	{ gettext("fwt"),	tZONE,     -HOUR(1) },	/* French Winter */
5527c478bd9Sstevel@tonic-gate 	{ gettext("fst"),	tDAYZONE,  -HOUR(1) },	/* French Summer */
5537c478bd9Sstevel@tonic-gate 	{ gettext("eet"),	tZONE,     -HOUR(2) },	/* Eastern Europe, USSR Zone 1 */
5547c478bd9Sstevel@tonic-gate 	{ gettext("bt"),	tZONE,     -HOUR(3) },	/* Baghdad, USSR Zone 2 */
5557c478bd9Sstevel@tonic-gate #if 0
5567c478bd9Sstevel@tonic-gate 	{ gettext("it"),	tZONE,     -HOUR(3.5) },/* Iran */
5577c478bd9Sstevel@tonic-gate #endif
5587c478bd9Sstevel@tonic-gate 	{ gettext("zp4"),	tZONE,     -HOUR(4) },	/* USSR Zone 3 */
5597c478bd9Sstevel@tonic-gate 	{ gettext("zp5"),	tZONE,     -HOUR(5) },	/* USSR Zone 4 */
5607c478bd9Sstevel@tonic-gate #if 0
5617c478bd9Sstevel@tonic-gate 	{ gettext("ist"),	tZONE,     -HOUR(5.5) },/* Indian Standard */
5627c478bd9Sstevel@tonic-gate #endif
5637c478bd9Sstevel@tonic-gate 	{ gettext("zp6"),	tZONE,     -HOUR(6) },	/* USSR Zone 5 */
5647c478bd9Sstevel@tonic-gate #if	0
565*56a424ccSmp153739     /* For completeness.  NST is also Newfoundland Stanard, and SST is
566*56a424ccSmp153739      * also Swedish Summer. */
5677c478bd9Sstevel@tonic-gate     { gettext("nst"),	tZONE,     -HOUR(6.5) },/* North Sumatra */
5687c478bd9Sstevel@tonic-gate     { gettext("sst"),	tZONE,     -HOUR(7) },	/* South Sumatra, USSR Zone 6 */
5697c478bd9Sstevel@tonic-gate #endif	/* 0 */
5707c478bd9Sstevel@tonic-gate 	{ gettext("wast"),	tZONE,     -HOUR(7) },	/* West Australian Standard */
5717c478bd9Sstevel@tonic-gate 	{ gettext("wadt"),	tDAYZONE,  -HOUR(7) },	/* West Australian Daylight */
5727c478bd9Sstevel@tonic-gate #if 0
5737c478bd9Sstevel@tonic-gate 	{ gettext("jt"),	tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
5747c478bd9Sstevel@tonic-gate #endif
5757c478bd9Sstevel@tonic-gate 	{ gettext("cct"),	tZONE,     -HOUR(8) },	/* China Coast, USSR Zone 7 */
5767c478bd9Sstevel@tonic-gate 	{ gettext("jst"),	tZONE,     -HOUR(9) },	/* Japan Standard, USSR Zone 8 */
5777c478bd9Sstevel@tonic-gate 	{ gettext("kst"),	tZONE,     -HOUR(9) },	/* Korean Standard */
5787c478bd9Sstevel@tonic-gate #if 0
5797c478bd9Sstevel@tonic-gate 	{ gettext("cast"),	tZONE,     -HOUR(9.5) },/* Central Australian Standard */
5807c478bd9Sstevel@tonic-gate 	{ gettext("cadt"),	tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
5817c478bd9Sstevel@tonic-gate #endif
5827c478bd9Sstevel@tonic-gate 	{ gettext("east"),	tZONE,     -HOUR(10) },	/* Eastern Australian Standard */
5837c478bd9Sstevel@tonic-gate 	{ gettext("eadt"),	tDAYZONE,  -HOUR(10) },	/* Eastern Australian Daylight */
5847c478bd9Sstevel@tonic-gate 	{ gettext("gst"),	tZONE,     -HOUR(10) },	/* Guam Standard, USSR Zone 9 */
5857c478bd9Sstevel@tonic-gate 	{ gettext("kdt"),	tZONE,     -HOUR(10) },	/* Korean Daylight */
5867c478bd9Sstevel@tonic-gate 	{ gettext("nzt"),	tZONE,     -HOUR(12) },	/* New Zealand */
5877c478bd9Sstevel@tonic-gate 	{ gettext("nzst"),	tZONE,     -HOUR(12) },	/* New Zealand Standard */
5887c478bd9Sstevel@tonic-gate 	{ gettext("nzdt"),	tDAYZONE,  -HOUR(12) },	/* New Zealand Daylight */
5897c478bd9Sstevel@tonic-gate 	{ gettext("idle"),	tZONE,     -HOUR(12) },	/* International Date Line East */
5907c478bd9Sstevel@tonic-gate 	{  NULL  }
5917c478bd9Sstevel@tonic-gate };
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate /* ARGSUSED */
5947c478bd9Sstevel@tonic-gate static int
5957c478bd9Sstevel@tonic-gate yyerror(s)
5967c478bd9Sstevel@tonic-gate     char	*s;
5977c478bd9Sstevel@tonic-gate {
598*56a424ccSmp153739   return 0;
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 
6027c478bd9Sstevel@tonic-gate static time_t
603*56a424ccSmp153739 ToSeconds(Hours, Minutes, Seconds, Meridian)
604*56a424ccSmp153739     time_t	Hours;
605*56a424ccSmp153739     time_t	Minutes;
606*56a424ccSmp153739     time_t	Seconds;
607*56a424ccSmp153739     MERIDIAN	Meridian;
6087c478bd9Sstevel@tonic-gate {
6097c478bd9Sstevel@tonic-gate     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
610*56a424ccSmp153739 	return -1;
6117c478bd9Sstevel@tonic-gate     switch (Meridian) {
6127c478bd9Sstevel@tonic-gate     case MER24:
6137c478bd9Sstevel@tonic-gate 	if (Hours < 0 || Hours > 23)
614*56a424ccSmp153739 	    return -1;
6157c478bd9Sstevel@tonic-gate 	return (Hours * 60L + Minutes) * 60L + Seconds;
6167c478bd9Sstevel@tonic-gate     case MERam:
6177c478bd9Sstevel@tonic-gate 	if (Hours < 1 || Hours > 12)
618*56a424ccSmp153739 	    return -1;
6197c478bd9Sstevel@tonic-gate 	return (Hours * 60L + Minutes) * 60L + Seconds;
6207c478bd9Sstevel@tonic-gate     case MERpm:
6217c478bd9Sstevel@tonic-gate 	if (Hours < 1 || Hours > 12)
622*56a424ccSmp153739 	    return -1;
6237c478bd9Sstevel@tonic-gate 	return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
6247c478bd9Sstevel@tonic-gate     default:
6257c478bd9Sstevel@tonic-gate 	abort ();
6267c478bd9Sstevel@tonic-gate     }
6277c478bd9Sstevel@tonic-gate     /* NOTREACHED */
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate 
6307c478bd9Sstevel@tonic-gate /*
6317c478bd9Sstevel@tonic-gate  * From hh:mm:ss [am|pm] mm/dd/yy [tz], compute and return the number
6327c478bd9Sstevel@tonic-gate  * of seconds since 00:00:00 1/1/70 GMT.
6337c478bd9Sstevel@tonic-gate  */
6347c478bd9Sstevel@tonic-gate static time_t
635*56a424ccSmp153739 Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
636*56a424ccSmp153739     time_t	Month;
637*56a424ccSmp153739     time_t	Day;
638*56a424ccSmp153739     time_t	Year;
639*56a424ccSmp153739     time_t	Hours;
640*56a424ccSmp153739     time_t	Minutes;
641*56a424ccSmp153739     time_t	Seconds;
642*56a424ccSmp153739     MERIDIAN	Meridian;
643*56a424ccSmp153739     DSTMODE	DSTmode;
6447c478bd9Sstevel@tonic-gate {
6457c478bd9Sstevel@tonic-gate     static int DaysInMonth[12] = {
6467c478bd9Sstevel@tonic-gate 	31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
6477c478bd9Sstevel@tonic-gate     };
6487c478bd9Sstevel@tonic-gate     time_t	tod;
6497c478bd9Sstevel@tonic-gate     time_t	Julian;
6507c478bd9Sstevel@tonic-gate     int		i;
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate     if (Year < 0)
6537c478bd9Sstevel@tonic-gate 	Year = -Year;
6547c478bd9Sstevel@tonic-gate     if (Year < 1900)
6557c478bd9Sstevel@tonic-gate 	Year += 1900;
6567c478bd9Sstevel@tonic-gate     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
6577c478bd9Sstevel@tonic-gate 		    ? 29 : 28;
658*56a424ccSmp153739     if (Year < EPOCH
659*56a424ccSmp153739 	|| Year > EPOCH_END
660*56a424ccSmp153739 	|| Month < 1 || Month > 12
6617c478bd9Sstevel@tonic-gate 	/* Lint fluff:  "conversion from long may lose accuracy" */
6627c478bd9Sstevel@tonic-gate 	|| Day < 1 || Day > DaysInMonth[(int)--Month])
663*56a424ccSmp153739 	 return -1;
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate     for (Julian = Day - 1, i = 0; i < Month; i++)
6667c478bd9Sstevel@tonic-gate 	Julian += DaysInMonth[i];
6677c478bd9Sstevel@tonic-gate     for (i = EPOCH; i < Year; i++)
6687c478bd9Sstevel@tonic-gate 	 Julian += 365 + ((i % 4 == 0) && ((Year % 100 != 0) ||
6697c478bd9Sstevel@tonic-gate 					   (Year % 400 == 0)));
6707c478bd9Sstevel@tonic-gate     Julian *= SECSPERDAY;
6717c478bd9Sstevel@tonic-gate     Julian += yyTimezone * 60L;
6727c478bd9Sstevel@tonic-gate     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
673*56a424ccSmp153739 	return -1;
6747c478bd9Sstevel@tonic-gate     Julian += tod;
6757c478bd9Sstevel@tonic-gate     if (DSTmode == DSTon
6767c478bd9Sstevel@tonic-gate      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
6777c478bd9Sstevel@tonic-gate 	Julian -= 60 * 60;
678*56a424ccSmp153739     return Julian;
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate static time_t
6837c478bd9Sstevel@tonic-gate DSTcorrect(Start, Future)
6847c478bd9Sstevel@tonic-gate     time_t	Start;
6857c478bd9Sstevel@tonic-gate     time_t	Future;
6867c478bd9Sstevel@tonic-gate {
6877c478bd9Sstevel@tonic-gate     time_t	StartDay;
6887c478bd9Sstevel@tonic-gate     time_t	FutureDay;
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
6917c478bd9Sstevel@tonic-gate     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
6927c478bd9Sstevel@tonic-gate     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
6937c478bd9Sstevel@tonic-gate }
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate static time_t
6977c478bd9Sstevel@tonic-gate RelativeDate(Start, DayOrdinal, DayNumber)
6987c478bd9Sstevel@tonic-gate     time_t	Start;
6997c478bd9Sstevel@tonic-gate     time_t	DayOrdinal;
7007c478bd9Sstevel@tonic-gate     time_t	DayNumber;
7017c478bd9Sstevel@tonic-gate {
7027c478bd9Sstevel@tonic-gate     struct tm	*tm;
7037c478bd9Sstevel@tonic-gate     time_t	now;
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate     now = Start;
7067c478bd9Sstevel@tonic-gate     tm = localtime(&now);
7077c478bd9Sstevel@tonic-gate     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
7087c478bd9Sstevel@tonic-gate     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
709*56a424ccSmp153739     return DSTcorrect(Start, now);
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate static time_t
714*56a424ccSmp153739 RelativeMonth(Start, RelMonth)
715*56a424ccSmp153739     time_t	Start;
716*56a424ccSmp153739     time_t	RelMonth;
7177c478bd9Sstevel@tonic-gate {
7187c478bd9Sstevel@tonic-gate     struct tm	*tm;
7197c478bd9Sstevel@tonic-gate     time_t	Month;
7207c478bd9Sstevel@tonic-gate     time_t	Year;
7217c478bd9Sstevel@tonic-gate     time_t	ret;
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate     if (RelMonth == 0)
724*56a424ccSmp153739 	return 0;
7257c478bd9Sstevel@tonic-gate     tm = localtime(&Start);
7267c478bd9Sstevel@tonic-gate     Month = 12 * tm->tm_year + tm->tm_mon + RelMonth;
7277c478bd9Sstevel@tonic-gate     Year = Month / 12;
7287c478bd9Sstevel@tonic-gate     Month = Month % 12 + 1;
7297c478bd9Sstevel@tonic-gate     ret = Convert(Month, (time_t)tm->tm_mday, Year,
7307c478bd9Sstevel@tonic-gate 		  (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
7317c478bd9Sstevel@tonic-gate 		  MER24, DSTmaybe);
7327c478bd9Sstevel@tonic-gate     if (ret == -1)
7337c478bd9Sstevel@tonic-gate       return ret;
7347c478bd9Sstevel@tonic-gate     return DSTcorrect(Start, ret);
7357c478bd9Sstevel@tonic-gate }
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate static int
739*56a424ccSmp153739 LookupWord(buff)
740*56a424ccSmp153739     char		*buff;
7417c478bd9Sstevel@tonic-gate {
7427c478bd9Sstevel@tonic-gate     register char	*p;
7437c478bd9Sstevel@tonic-gate     register char	*q;
7447c478bd9Sstevel@tonic-gate     register const TABLE	*tp;
7457c478bd9Sstevel@tonic-gate     int			i;
7467c478bd9Sstevel@tonic-gate     int			abbrev;
7477c478bd9Sstevel@tonic-gate 
7487c478bd9Sstevel@tonic-gate     /* Make it lowercase. */
7497c478bd9Sstevel@tonic-gate     for (p = buff; *p; p++)
750*56a424ccSmp153739 	if (isupper((int) *p))
751*56a424ccSmp153739 	    *p = tolower((int) *p);
7527c478bd9Sstevel@tonic-gate 
753*56a424ccSmp153739     if (strcmp(buff, gettext("am")) == 0 || strcmp(buff, gettext("a.m.")) == 0) {
7547c478bd9Sstevel@tonic-gate 	yylval.Meridian = MERam;
755*56a424ccSmp153739 	return tMERIDIAN;
7567c478bd9Sstevel@tonic-gate     }
7577c478bd9Sstevel@tonic-gate     if (strcmp(buff, gettext("pm")) == 0 ||
7587c478bd9Sstevel@tonic-gate 	    strcmp(buff, gettext("p.m.")) == 0) {
7597c478bd9Sstevel@tonic-gate 	yylval.Meridian = MERpm;
760*56a424ccSmp153739 	return tMERIDIAN;
7617c478bd9Sstevel@tonic-gate     }
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate     /* See if we have an abbreviation for a month. */
7647c478bd9Sstevel@tonic-gate     if (strlen(buff) == 3)
7657c478bd9Sstevel@tonic-gate 	abbrev = 1;
7667c478bd9Sstevel@tonic-gate     else if (strlen(buff) == 4 && buff[3] == '.') {
7677c478bd9Sstevel@tonic-gate 	abbrev = 1;
7687c478bd9Sstevel@tonic-gate 	buff[3] = '\0';
7697c478bd9Sstevel@tonic-gate     }
7707c478bd9Sstevel@tonic-gate     else
7717c478bd9Sstevel@tonic-gate 	abbrev = 0;
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate     for (tp = MonthDayTable; tp->name; tp++) {
7747c478bd9Sstevel@tonic-gate 	if (abbrev) {
7757c478bd9Sstevel@tonic-gate 	    if (strncmp(buff, GETTEXT(tp->name), 3) == 0) {
7767c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
777*56a424ccSmp153739 		return tp->type;
7787c478bd9Sstevel@tonic-gate 	    }
7797c478bd9Sstevel@tonic-gate 	}
7807c478bd9Sstevel@tonic-gate 	else if (strcmp(buff, GETTEXT(tp->name)) == 0) {
7817c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
782*56a424ccSmp153739 	    return tp->type;
7837c478bd9Sstevel@tonic-gate 	}
7847c478bd9Sstevel@tonic-gate     }
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate     for (tp = TimezoneTable; tp->name; tp++)
7877c478bd9Sstevel@tonic-gate 	if (strcmp(buff, GETTEXT(tp->name)) == 0) {
7887c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
789*56a424ccSmp153739 	    return tp->type;
7907c478bd9Sstevel@tonic-gate 	}
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate     if (strcmp(buff, gettext("dst")) == 0)
793*56a424ccSmp153739 	return tDST;
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate     for (tp = UnitsTable; tp->name; tp++)
7967c478bd9Sstevel@tonic-gate 	if (strcmp(buff, GETTEXT(tp->name)) == 0) {
7977c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
798*56a424ccSmp153739 	    return tp->type;
7997c478bd9Sstevel@tonic-gate 	}
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate     /* Strip off any plural and try the units table again. */
8027c478bd9Sstevel@tonic-gate     i = strlen(buff) - 1;
8037c478bd9Sstevel@tonic-gate     if (buff[i] == 's') {
8047c478bd9Sstevel@tonic-gate 	buff[i] = '\0';
8057c478bd9Sstevel@tonic-gate 	for (tp = UnitsTable; tp->name; tp++)
8067c478bd9Sstevel@tonic-gate 	    if (strcmp(buff, GETTEXT(tp->name)) == 0) {
8077c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
808*56a424ccSmp153739 		return tp->type;
8097c478bd9Sstevel@tonic-gate 	    }
8107c478bd9Sstevel@tonic-gate 	buff[i] = 's';		/* Put back for "this" in OtherTable. */
8117c478bd9Sstevel@tonic-gate     }
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate     for (tp = OtherTable; tp->name; tp++)
8147c478bd9Sstevel@tonic-gate 	if (strcmp(buff, GETTEXT(tp->name)) == 0) {
8157c478bd9Sstevel@tonic-gate 	    yylval.Number = tp->value;
816*56a424ccSmp153739 	    return tp->type;
8177c478bd9Sstevel@tonic-gate 	}
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate     /* Drop out any periods and try the timezone table again. */
8207c478bd9Sstevel@tonic-gate     for (i = 0, p = q = buff; *q; q++)
8217c478bd9Sstevel@tonic-gate 	if (*q != '.')
8227c478bd9Sstevel@tonic-gate 	    *p++ = *q;
8237c478bd9Sstevel@tonic-gate 	else
8247c478bd9Sstevel@tonic-gate 	    i++;
8257c478bd9Sstevel@tonic-gate     *p = '\0';
8267c478bd9Sstevel@tonic-gate     if (i)
8277c478bd9Sstevel@tonic-gate 	for (tp = TimezoneTable; tp->name; tp++)
8287c478bd9Sstevel@tonic-gate 	    if (strcmp(buff, GETTEXT(tp->name)) == 0) {
8297c478bd9Sstevel@tonic-gate 		yylval.Number = tp->value;
830*56a424ccSmp153739 		return tp->type;
8317c478bd9Sstevel@tonic-gate 	    }
8327c478bd9Sstevel@tonic-gate 
833*56a424ccSmp153739     return tID;
8347c478bd9Sstevel@tonic-gate }
8357c478bd9Sstevel@tonic-gate 
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate static int
8387c478bd9Sstevel@tonic-gate yylex()
8397c478bd9Sstevel@tonic-gate {
8407c478bd9Sstevel@tonic-gate     register char	c;
8417c478bd9Sstevel@tonic-gate     register char	*p;
8427c478bd9Sstevel@tonic-gate     char		buff[20];
8437c478bd9Sstevel@tonic-gate     int			Count;
8447c478bd9Sstevel@tonic-gate     int			sign;
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate     for ( ; ; ) {
847*56a424ccSmp153739 	while (isspace((int) *yyInput))
8487c478bd9Sstevel@tonic-gate 	    yyInput++;
8497c478bd9Sstevel@tonic-gate 
850*56a424ccSmp153739 	c = *yyInput;
851*56a424ccSmp153739 	if (isdigit((int) c) || c == '-' || c == '+') {
8527c478bd9Sstevel@tonic-gate 	    if (c == '-' || c == '+') {
8537c478bd9Sstevel@tonic-gate 		sign = c == '-' ? -1 : 1;
854*56a424ccSmp153739 		if (!isdigit((int) (*++yyInput)))
8557c478bd9Sstevel@tonic-gate 		    /* skip the '-' sign */
8567c478bd9Sstevel@tonic-gate 		    continue;
8577c478bd9Sstevel@tonic-gate 	    }
8587c478bd9Sstevel@tonic-gate 	    else
8597c478bd9Sstevel@tonic-gate 		sign = 0;
860*56a424ccSmp153739 	    for (yylval.Number = 0; isdigit((int) (c = *yyInput++)); )
8617c478bd9Sstevel@tonic-gate 		yylval.Number = 10 * yylval.Number + c - '0';
8627c478bd9Sstevel@tonic-gate 	    yyInput--;
8637c478bd9Sstevel@tonic-gate 	    if (sign < 0)
8647c478bd9Sstevel@tonic-gate 		yylval.Number = -yylval.Number;
865*56a424ccSmp153739 	    return sign ? tSNUMBER : tUNUMBER;
8667c478bd9Sstevel@tonic-gate 	}
867*56a424ccSmp153739 	if (isalpha((int) c)) {
868*56a424ccSmp153739 	    for (p = buff; isalpha((int) (c = *yyInput++)) || c == '.'; )
8697c478bd9Sstevel@tonic-gate 		if (p < &buff[sizeof buff - 1])
8707c478bd9Sstevel@tonic-gate 		    *p++ = c;
8717c478bd9Sstevel@tonic-gate 	    *p = '\0';
8727c478bd9Sstevel@tonic-gate 	    yyInput--;
873*56a424ccSmp153739 	    return LookupWord(buff);
8747c478bd9Sstevel@tonic-gate 	}
8757c478bd9Sstevel@tonic-gate 	if (c != '(')
876*56a424ccSmp153739 	    return *yyInput++;
8777c478bd9Sstevel@tonic-gate 	Count = 0;
8787c478bd9Sstevel@tonic-gate 	do {
8797c478bd9Sstevel@tonic-gate 	    c = *yyInput++;
8807c478bd9Sstevel@tonic-gate 	    if (c == '\0')
881*56a424ccSmp153739 		return c;
8827c478bd9Sstevel@tonic-gate 	    if (c == '(')
8837c478bd9Sstevel@tonic-gate 		Count++;
8847c478bd9Sstevel@tonic-gate 	    else if (c == ')')
8857c478bd9Sstevel@tonic-gate 		Count--;
8867c478bd9Sstevel@tonic-gate 	} while (Count > 0);
8877c478bd9Sstevel@tonic-gate     }
8887c478bd9Sstevel@tonic-gate }
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate #define TM_YEAR_ORIGIN 1900
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate /* Yield A - B, measured in seconds.  */
8947c478bd9Sstevel@tonic-gate static time_t
895*56a424ccSmp153739 difftm(a, b)
896*56a424ccSmp153739      struct tm *a, *b;
8977c478bd9Sstevel@tonic-gate {
8987c478bd9Sstevel@tonic-gate   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
8997c478bd9Sstevel@tonic-gate   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
900*56a424ccSmp153739   return
901*56a424ccSmp153739     (
902*56a424ccSmp153739      (
903*56a424ccSmp153739       (
9047c478bd9Sstevel@tonic-gate        /* difference in day of year */
9057c478bd9Sstevel@tonic-gate        a->tm_yday - b->tm_yday
9067c478bd9Sstevel@tonic-gate        /* + intervening leap days */
9077c478bd9Sstevel@tonic-gate        +  ((ay >> 2) - (by >> 2))
9087c478bd9Sstevel@tonic-gate        -  (ay/100 - by/100)
9097c478bd9Sstevel@tonic-gate        +  ((ay/100 >> 2) - (by/100 >> 2))
9107c478bd9Sstevel@tonic-gate        /* + difference in years * 365 */
9117c478bd9Sstevel@tonic-gate        +  (time_t)(ay-by) * 365
9127c478bd9Sstevel@tonic-gate        )*24 + (a->tm_hour - b->tm_hour)
9137c478bd9Sstevel@tonic-gate       )*60 + (a->tm_min - b->tm_min)
914*56a424ccSmp153739      )*60 + (a->tm_sec - b->tm_sec);
9157c478bd9Sstevel@tonic-gate }
9167c478bd9Sstevel@tonic-gate 
917*56a424ccSmp153739 /* For get_date extern declaration compatibility check... yuck.  */
918*56a424ccSmp153739 #include <krb5.h>
919*56a424ccSmp153739 #include "kadmin.h"
920*56a424ccSmp153739 
9217c478bd9Sstevel@tonic-gate time_t
922*56a424ccSmp153739 get_date(p)
923*56a424ccSmp153739     char		*p;
9247c478bd9Sstevel@tonic-gate {
925*56a424ccSmp153739     struct my_timeb	*now = NULL;
9267c478bd9Sstevel@tonic-gate     struct tm		*tm, gmt;
9277c478bd9Sstevel@tonic-gate     struct my_timeb	ftz;
9287c478bd9Sstevel@tonic-gate     time_t		Start;
9297c478bd9Sstevel@tonic-gate     time_t		tod;
9307c478bd9Sstevel@tonic-gate     time_t		delta;
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate     yyInput = p;
9337c478bd9Sstevel@tonic-gate     if (now == NULL) {
9347c478bd9Sstevel@tonic-gate         now = &ftz;
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 	ftz.time = time((time_t *) 0);
9377c478bd9Sstevel@tonic-gate 
9387c478bd9Sstevel@tonic-gate 	if (! (tm = gmtime (&ftz.time)))
939*56a424ccSmp153739 	    return -1;
9407c478bd9Sstevel@tonic-gate 	gmt = *tm;	/* Make a copy, in case localtime modifies *tm.  */
9417c478bd9Sstevel@tonic-gate 	ftz.timezone = difftm (&gmt, localtime (&ftz.time)) / 60;
9427c478bd9Sstevel@tonic-gate     }
9437c478bd9Sstevel@tonic-gate 
9447c478bd9Sstevel@tonic-gate     tm = localtime(&now->time);
9457c478bd9Sstevel@tonic-gate     yyYear = tm->tm_year;
9467c478bd9Sstevel@tonic-gate     yyMonth = tm->tm_mon + 1;
9477c478bd9Sstevel@tonic-gate     yyDay = tm->tm_mday;
9487c478bd9Sstevel@tonic-gate     yyTimezone = now->timezone;
9497c478bd9Sstevel@tonic-gate     yyDSTmode = DSTmaybe;
9507c478bd9Sstevel@tonic-gate     yyHour = 0;
9517c478bd9Sstevel@tonic-gate     yyMinutes = 0;
9527c478bd9Sstevel@tonic-gate     yySeconds = 0;
9537c478bd9Sstevel@tonic-gate     yyMeridian = MER24;
9547c478bd9Sstevel@tonic-gate     yyRelSeconds = 0;
9557c478bd9Sstevel@tonic-gate     yyRelMonth = 0;
9567c478bd9Sstevel@tonic-gate     yyHaveDate = 0;
9577c478bd9Sstevel@tonic-gate     yyHaveDay = 0;
9587c478bd9Sstevel@tonic-gate     yyHaveRel = 0;
9597c478bd9Sstevel@tonic-gate     yyHaveTime = 0;
9607c478bd9Sstevel@tonic-gate     yyHaveZone = 0;
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate     /*
9637c478bd9Sstevel@tonic-gate      * When yyparse returns, zero or more of yyHave{Time,Zone,Date,Day,Rel}
9647c478bd9Sstevel@tonic-gate      * will have been incremented.  The value is number of items of
9657c478bd9Sstevel@tonic-gate      * that type that were found; for all but Rel, more than one is
9667c478bd9Sstevel@tonic-gate      * illegal.
9677c478bd9Sstevel@tonic-gate      *
9687c478bd9Sstevel@tonic-gate      * For each yyHave indicator, the following values are set:
9697c478bd9Sstevel@tonic-gate      *
9707c478bd9Sstevel@tonic-gate      * yyHaveTime:
9717c478bd9Sstevel@tonic-gate      *	yyHour, yyMinutes, yySeconds: hh:mm:ss specified, initialized
9727c478bd9Sstevel@tonic-gate      *				      to zeros above
9737c478bd9Sstevel@tonic-gate      *	yyMeridian: MERam, MERpm, or MER24
9747c478bd9Sstevel@tonic-gate      *	yyTimeZone: time zone specified in minutes
9757c478bd9Sstevel@tonic-gate      *  yyDSTmode: DSToff if yyTimeZone is set, otherwise unchanged
9767c478bd9Sstevel@tonic-gate      *		   (initialized above to DSTmaybe)
9777c478bd9Sstevel@tonic-gate      *
9787c478bd9Sstevel@tonic-gate      * yyHaveZone:
9797c478bd9Sstevel@tonic-gate      *  yyTimezone: as above
9807c478bd9Sstevel@tonic-gate      *  yyDSTmode: DSToff if a non-DST zone is specified, otherwise DSTon
9817c478bd9Sstevel@tonic-gate      *	XXX don't understand interaction with yyHaveTime zone info
9827c478bd9Sstevel@tonic-gate      *
9837c478bd9Sstevel@tonic-gate      * yyHaveDay:
9847c478bd9Sstevel@tonic-gate      *	yyDayNumber: 0-6 for Sunday-Saturday
9857c478bd9Sstevel@tonic-gate      *  yyDayOrdinal: val specified with day ("second monday",
9867c478bd9Sstevel@tonic-gate      *		      Ordinal=2), otherwise 1
9877c478bd9Sstevel@tonic-gate      *
9887c478bd9Sstevel@tonic-gate      * yyHaveDate:
9897c478bd9Sstevel@tonic-gate      *	yyMonth, yyDay, yyYear: mm/dd/yy specified, initialized to
9907c478bd9Sstevel@tonic-gate      *				today above
9917c478bd9Sstevel@tonic-gate      *
9927c478bd9Sstevel@tonic-gate      * yyHaveRel:
9937c478bd9Sstevel@tonic-gate      *	yyRelSeconds: seconds specified with MINUTE_UNITs ("3 hours") or
9947c478bd9Sstevel@tonic-gate      *		      SEC_UNITs ("30 seconds")
9957c478bd9Sstevel@tonic-gate      *  yyRelMonth: months specified with MONTH_UNITs ("3 months", "1
9967c478bd9Sstevel@tonic-gate      *		     year")
9977c478bd9Sstevel@tonic-gate      *
9987c478bd9Sstevel@tonic-gate      * The code following yyparse turns these values into a single
9997c478bd9Sstevel@tonic-gate      * date stamp.
10007c478bd9Sstevel@tonic-gate      */
1001*56a424ccSmp153739     if (yyparse()
1002*56a424ccSmp153739      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
1003*56a424ccSmp153739 	return -1;
10047c478bd9Sstevel@tonic-gate 
10057c478bd9Sstevel@tonic-gate     /*
10067c478bd9Sstevel@tonic-gate      * If an absolute time specified, set Start to the equivalent Unix
10077c478bd9Sstevel@tonic-gate      * timestamp.  Otherwise, set Start to now, and if we do not have
10087c478bd9Sstevel@tonic-gate      * a relatime time (ie: only yyHaveZone), decrement Start to the
10097c478bd9Sstevel@tonic-gate      * beginning of today.
10107c478bd9Sstevel@tonic-gate      *
10117c478bd9Sstevel@tonic-gate      * By having yyHaveDay in the "absolute" list, "next Monday" means
10127c478bd9Sstevel@tonic-gate      * midnight next Monday.  Otherwise, "next Monday" would mean the
10137c478bd9Sstevel@tonic-gate      * time right now, next Monday.  It's not clear to me why the
10147c478bd9Sstevel@tonic-gate      * current behavior is preferred.
10157c478bd9Sstevel@tonic-gate      */
10167c478bd9Sstevel@tonic-gate     if (yyHaveDate || yyHaveTime || yyHaveDay) {
1017*56a424ccSmp153739 	Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
10187c478bd9Sstevel@tonic-gate 		    yyMeridian, yyDSTmode);
10197c478bd9Sstevel@tonic-gate 	if (Start < 0)
1020*56a424ccSmp153739 	    return -1;
10217c478bd9Sstevel@tonic-gate     }
10227c478bd9Sstevel@tonic-gate     else {
10237c478bd9Sstevel@tonic-gate 	Start = now->time;
10247c478bd9Sstevel@tonic-gate 	if (!yyHaveRel)
1025*56a424ccSmp153739 	    Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
10267c478bd9Sstevel@tonic-gate     }
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate     /*
10297c478bd9Sstevel@tonic-gate      * Add in the relative time specified.  RelativeMonth adds in the
10307c478bd9Sstevel@tonic-gate      * months, accounting for the fact that the actual length of "3
10317c478bd9Sstevel@tonic-gate      * months" depends on where you start counting.
10327c478bd9Sstevel@tonic-gate      *
10337c478bd9Sstevel@tonic-gate      * XXX By having this separate from the previous block, we are
10347c478bd9Sstevel@tonic-gate      * allowing dates like "10:00am 3 months", which means 3 months
10357c478bd9Sstevel@tonic-gate      * from 10:00am today, or even "1/1/99 two days" which means two
10367c478bd9Sstevel@tonic-gate      * days after 1/1/99.
10377c478bd9Sstevel@tonic-gate      *
10387c478bd9Sstevel@tonic-gate      * XXX Shouldn't this only be done if yyHaveRel, just for
10397c478bd9Sstevel@tonic-gate      * thoroughness?
10407c478bd9Sstevel@tonic-gate      */
10417c478bd9Sstevel@tonic-gate     Start += yyRelSeconds;
10427c478bd9Sstevel@tonic-gate     delta = RelativeMonth(Start, yyRelMonth);
10437c478bd9Sstevel@tonic-gate     if (delta == (time_t) -1)
10447c478bd9Sstevel@tonic-gate       return -1;
10457c478bd9Sstevel@tonic-gate     Start += delta;
10467c478bd9Sstevel@tonic-gate 
10477c478bd9Sstevel@tonic-gate     /*
10487c478bd9Sstevel@tonic-gate      * Now, if you specified a day of week and counter, add it in.  By
10497c478bd9Sstevel@tonic-gate      * disallowing Date but allowing Time, you can say "5pm next
10507c478bd9Sstevel@tonic-gate      * monday".
10517c478bd9Sstevel@tonic-gate      *
10527c478bd9Sstevel@tonic-gate      * XXX The yyHaveDay && !yyHaveDate restriction should be enforced
10537c478bd9Sstevel@tonic-gate      * above and be able to cause failure.
10547c478bd9Sstevel@tonic-gate      */
10557c478bd9Sstevel@tonic-gate     if (yyHaveDay && !yyHaveDate) {
10567c478bd9Sstevel@tonic-gate 	tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
10577c478bd9Sstevel@tonic-gate 	Start += tod;
10587c478bd9Sstevel@tonic-gate     }
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate     /* Have to do *something* with a legitimate -1 so it's distinguishable
10617c478bd9Sstevel@tonic-gate      * from the error return value.  (Alternately could set errno on error.) */
1062*56a424ccSmp153739     return Start == -1 ? 0 : Start;
10637c478bd9Sstevel@tonic-gate }
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 
10667c478bd9Sstevel@tonic-gate #if	defined(TEST)
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate /* ARGSUSED */
1069*56a424ccSmp153739 main(ac, av)
1070*56a424ccSmp153739     int		ac;
1071*56a424ccSmp153739     char	*av[];
10727c478bd9Sstevel@tonic-gate {
10737c478bd9Sstevel@tonic-gate     char	buff[128];
10747c478bd9Sstevel@tonic-gate     time_t	d;
10757c478bd9Sstevel@tonic-gate 
10767c478bd9Sstevel@tonic-gate     (void)printf(gettext("Enter date, or blank line to exit.\n\t> "));
10777c478bd9Sstevel@tonic-gate     (void)fflush(stdout);
10787c478bd9Sstevel@tonic-gate     while (gets(buff) && buff[0]) {
10797c478bd9Sstevel@tonic-gate 	d = get_date(buff, (struct my_timeb *)NULL);
10807c478bd9Sstevel@tonic-gate 	if (d == -1)
10817c478bd9Sstevel@tonic-gate 	    (void)printf(
10827c478bd9Sstevel@tonic-gate 				gettext("Bad format - couldn't convert.\n"));
10837c478bd9Sstevel@tonic-gate 	else
10847c478bd9Sstevel@tonic-gate 	    (void)printf("%s", ctime(&d));
10857c478bd9Sstevel@tonic-gate 	(void)printf("\t> ");
10867c478bd9Sstevel@tonic-gate 	(void)fflush(stdout);
10877c478bd9Sstevel@tonic-gate     }
10887c478bd9Sstevel@tonic-gate     exit(0);
10897c478bd9Sstevel@tonic-gate     /* NOTREACHED */
10907c478bd9Sstevel@tonic-gate }
10917c478bd9Sstevel@tonic-gate #endif	/* defined(TEST) */
1092