/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Openvision retains the copyright to derivative works of
* this source code. Do *NOT* create a derivative of this
* source code before consulting with your legal department.
* Do *NOT* integrate *ANY* of this source code into another
* product before consulting with your legal department.
*
* For further information, read the top-level Openvision
* copyright which is contained in the top-level MIT Kerberos
* copyright.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
*/
%{
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
** Originally written by Steven M. Bellovin <smb@research.att.com> while
** at the University of North Carolina at Chapel Hill. Later tweaked by
** a couple of people on Usenet. Completely overhauled by Rich $alz
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
** send any email to Rich.
**
**
** This code is in the public domain and has no copyright.
*/
/* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
/* SUPPRESS 288 on yyerrlab *//* Label unused */
#ifdef HAVE_CONFIG_H
#if defined (emacs) || defined (CONFIG_BROKETS)
#include <config.h>
#else
#include "config.h"
#endif
#endif
#include <string.h>
/* Since the code of getdate.y is not included in the Emacs executable
itself, there is no need to #define static in this file. Even if
the code were included in the Emacs executable, it probably
wouldn't do any harm to #undef it here; this will only cause
problems if we try to write to a static variable, which I don't
think this code needs to do. */
#ifdef emacs
#undef static
#endif
/* The following block of alloca-related preprocessor directives is here
solely to allow compilation by non GNU-C compilers of the C parser
produced from this file by old versions of bison. Newer versions of
bison include a block similar to this one in bison.simple. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#else
#ifdef _AIX /* for Bison */
#pragma alloca
#else
void *alloca ();
#endif
#endif
#endif
#include <stdio.h>
#include <ctype.h>
#if defined(HAVE_STDLIB_H)
#include <stdlib.h>
#endif
/* The code at the top of get_date which figures out the offset of the
current time zone checks various CPP symbols to see if special
tricks are need, but defaults to using the gettimeofday system call.
#if defined(vms)
#include <types.h>
#include <time.h>
#else
#ifdef TIME_WITH_SYS_TIME
#include <time.h>
#else
#ifdef HAVE_SYS_TIME_H
#else
#include <time.h>
#endif
#endif
#ifdef timezone
#endif
/*
** We use the obsolete `struct my_timeb' as part of our interface!
** Since the system doesn't have it, we define it here;
** our callers must do likewise.
*/
struct my_timeb {
unsigned short millitm; /* Field not used */
short timezone; /* Minutes west of GMT */
short dstflag; /* Field not used */
};
#endif /* defined(vms) */
#if defined (STDC_HEADERS) || defined (USG)
#include <string.h>
#endif
/* Some old versions of bison generate parsers that use bcopy.
That loses on systems that don't provide the function, so we have
to redefine it here. */
#ifndef bcopy
#endif
/*
* The following is a hack so that it is easy to internationalize
* statically declared strings. We define a wrapper function here that
* will be a replacement for gettext. We the make gettext a macro that
* just returns its argument, which now can be used with statically defined
* strings. The conquence of this is that GETTEXT must be used to translate
* a string at runtime and gettext must be used around string literals so
* that xgettext command can extract them to a portable object database file.
*
* Thus to translate a string literal that is an argument to a function foo
* the following will have to be performed:
*
* foo(GETTEXT(gettext("This is a test")));
*
* The inner gettext call is for xgettext command to extract the string.
* The C preprossesor will reduce the above to:
*
* foo(GETTEXT(("This ia a test"));
*/
#include <libintl.h>
static char *
{
}
#define gettext(s) (s)
#define yyparse getdate_yyparse
#define yylex getdate_yylex
#define yyerror getdate_yyerror
static int getdate_yylex (void);
static int getdate_yyerror (char *);
#define EPOCH 1970
/*
** An entry in the lexical lookup table.
*/
typedef struct _TABLE {
char *name;
int type;
} TABLE;
/*
** Daylight-savings mode: on, off, or not yet known.
*/
typedef enum _DSTMODE {
} DSTMODE;
/*
** Meridian: am, pm, or 24-hour style.
*/
typedef enum _MERIDIAN {
} MERIDIAN;
/*
** Global variables. We could get rid of most of these by using a good
** union as the yacc stack. (This routine was originally written before
** yacc had the %union construct.) Maybe someday; right now we only use
** the %union very rarely.
*/
static char *yyInput;
static time_t yyDayOrdinal;
static time_t yyDayNumber;
static int yyHaveDate;
static int yyHaveDay;
static int yyHaveRel;
static int yyHaveTime;
static int yyHaveZone;
static time_t yyTimezone;
static MERIDIAN yyMeridian;
static time_t yyRelMonth;
static time_t yyRelSeconds;
%}
%union {
}
%%
| tNEVER {
yyYear = 1970;
yyMonth = 1;
yyDay = 1;
yyTimezone = 0; /* gmt */
yyHaveDate++;
}
;
yyHaveTime++;
}
| zone {
yyHaveZone++;
}
| date {
yyHaveDate++;
}
| day {
yyHaveDay++;
}
| rel {
yyHaveRel++;
}
;
yyHour = $1;
yyMinutes = 0;
yySeconds = 0;
yyMeridian = $2;
}
yyHour = $1;
yyMinutes = $3;
yySeconds = 0;
yyMeridian = $4;
}
yyHour = $1;
yyMinutes = $3;
yyMeridian = MER24;
}
yyHour = $1;
yyMinutes = $3;
yySeconds = $5;
yyMeridian = $6;
}
yyHour = $1;
yyMinutes = $3;
yySeconds = $5;
yyMeridian = MER24;
}
;
yyTimezone = $1;
}
| tDAYZONE {
yyTimezone = $1;
}
|
yyTimezone = $1;
}
;
yyDayOrdinal = 1;
yyDayNumber = $1;
}
| tDAY ',' {
yyDayOrdinal = 1;
yyDayNumber = $1;
}
yyDayOrdinal = $1;
yyDayNumber = $2;
}
;
yyMonth = $1;
yyDay = $3;
}
yyMonth = $1;
yyDay = $3;
yyYear = $5;
}
/* ISO 8601 format. yyyy-mm-dd. */
yyYear = $1;
yyMonth = -$2;
yyDay = -$3;
}
/* e.g. 17-JUN-1992. */
yyDay = $1;
yyMonth = $2;
yyYear = -$3;
}
yyMonth = $1;
yyDay = $2;
}
yyMonth = $1;
yyDay = $2;
yyYear = $4;
}
yyMonth = $2;
yyDay = $1;
}
yyMonth = $2;
yyDay = $1;
yyYear = $3;
}
;
yyRelMonth = -yyRelMonth;
}
| relunit
;
}
| tSNUMBER tMINUTE_UNIT {
}
| tMINUTE_UNIT {
}
yyRelSeconds += $1;
}
yyRelSeconds += $1;
}
| tSEC_UNIT {
yyRelSeconds++;
}
| tSNUMBER tMONTH_UNIT {
}
| tUNUMBER tMONTH_UNIT {
}
| tMONTH_UNIT {
yyRelMonth += $1;
}
;
$$ = MER24;
}
| tMERIDIAN {
$$ = $1;
}
;
%%
/* Month and day table. */
static TABLE const MonthDayTable[] = {
{ NULL }
};
/* Time units table. */
static TABLE const UnitsTable[] = {
{ NULL }
};
/* Assorted relative-time words. */
static TABLE const OtherTable[] = {
/* { gettext("second"), tUNUMBER, 2 }, */
{ NULL }
};
/* The timezone table. */
/* Some of these are commented out because a time_t can't store a float. */
static TABLE const TimezoneTable[] = {
#if 0
/* For completeness. BST is also British Summer, and GST is
* also Guam Standard. */
#endif
#if 0
#endif
#if 0
#endif
#if 0
#endif
#if 0
/* For completeness. NST is also Newfoundland Stanard, and SST is
* also Swedish Summer. */
#endif /* 0 */
#if 0
#endif
#if 0
#endif
{ NULL }
};
/* ARGSUSED */
static int
yyerror(s)
char *s;
{
return 0;
}
static time_t
{
return -1;
switch (Meridian) {
case MER24:
return -1;
case MERam:
return -1;
case MERpm:
return -1;
default:
abort ();
}
/* NOTREACHED */
}
/*
* of seconds since 00:00:00 1/1/70 GMT.
*/
static time_t
{
static int DaysInMonth[12] = {
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
int i;
if (Year < 0)
if (Year < 1900)
Year += 1900;
? 29 : 28;
/* Lint fluff: "conversion from long may lose accuracy" */
return -1;
Julian += DaysInMonth[i];
(Year % 400 == 0)));
Julian *= SECSPERDAY;
return -1;
return Julian;
}
static time_t
{
}
static time_t
{
}
static time_t
{
if (RelMonth == 0)
return 0;
if (ret == -1)
return ret;
}
static int
char *buff;
{
register char *p;
register char *q;
int i;
int abbrev;
/* Make it lowercase. */
for (p = buff; *p; p++)
if (isupper((int) *p))
*p = tolower((int) *p);
return tMERIDIAN;
}
return tMERIDIAN;
}
/* See if we have an abbreviation for a month. */
abbrev = 1;
abbrev = 1;
}
else
abbrev = 0;
if (abbrev) {
}
}
}
}
}
return tDST;
}
/* Strip off any plural and try the units table again. */
if (buff[i] == 's') {
buff[i] = '\0';
}
}
}
/* Drop out any periods and try the timezone table again. */
for (i = 0, p = q = buff; *q; q++)
if (*q != '.')
*p++ = *q;
else
i++;
*p = '\0';
if (i)
}
return tID;
}
static int
yylex()
{
register char c;
register char *p;
char buff[20];
int Count;
int sign;
for ( ; ; ) {
yyInput++;
c = *yyInput;
if (c == '-' || c == '+') {
/* skip the '-' sign */
continue;
}
else
sign = 0;
yyInput--;
if (sign < 0)
}
if (isalpha((int) c)) {
*p++ = c;
*p = '\0';
yyInput--;
return LookupWord(buff);
}
if (c != '(')
return *yyInput++;
Count = 0;
do {
c = *yyInput++;
if (c == '\0')
return c;
if (c == '(')
Count++;
else if (c == ')')
Count--;
} while (Count > 0);
}
}
#define TM_YEAR_ORIGIN 1900
/* Yield A - B, measured in seconds. */
static time_t
difftm(a, b)
struct tm *a, *b;
{
return
(
(
(
/* difference in day of year */
/* + intervening leap days */
/* + difference in years * 365 */
}
/* For get_date extern declaration compatibility check... yuck. */
#include <krb5.h>
#include "kadmin.h"
get_date(p)
char *p;
{
yyInput = p;
return -1;
}
yyHour = 0;
yyMinutes = 0;
yySeconds = 0;
yyMeridian = MER24;
yyRelSeconds = 0;
yyRelMonth = 0;
yyHaveDate = 0;
yyHaveDay = 0;
yyHaveRel = 0;
yyHaveTime = 0;
yyHaveZone = 0;
/*
* When yyparse returns, zero or more of yyHave{Time,Zone,Date,Day,Rel}
* will have been incremented. The value is number of items of
* that type that were found; for all but Rel, more than one is
* illegal.
*
* For each yyHave indicator, the following values are set:
*
* yyHaveTime:
* yyHour, yyMinutes, yySeconds: hh:mm:ss specified, initialized
* to zeros above
* yyMeridian: MERam, MERpm, or MER24
* yyTimeZone: time zone specified in minutes
* yyDSTmode: DSToff if yyTimeZone is set, otherwise unchanged
* (initialized above to DSTmaybe)
*
* yyHaveZone:
* yyTimezone: as above
* yyDSTmode: DSToff if a non-DST zone is specified, otherwise DSTon
* XXX don't understand interaction with yyHaveTime zone info
*
* yyHaveDay:
* yyDayNumber: 0-6 for Sunday-Saturday
* yyDayOrdinal: val specified with day ("second monday",
* Ordinal=2), otherwise 1
*
* yyHaveDate:
* today above
*
* yyHaveRel:
* yyRelSeconds: seconds specified with MINUTE_UNITs ("3 hours") or
* SEC_UNITs ("30 seconds")
* yyRelMonth: months specified with MONTH_UNITs ("3 months", "1
* year")
*
* The code following yyparse turns these values into a single
* date stamp.
*/
if (yyparse()
return -1;
/*
* If an absolute time specified, set Start to the equivalent Unix
* timestamp. Otherwise, set Start to now, and if we do not have
* a relatime time (ie: only yyHaveZone), decrement Start to the
* beginning of today.
*
* By having yyHaveDay in the "absolute" list, "next Monday" means
* midnight next Monday. Otherwise, "next Monday" would mean the
* time right now, next Monday. It's not clear to me why the
* current behavior is preferred.
*/
if (Start < 0)
return -1;
}
else {
if (!yyHaveRel)
}
/*
* Add in the relative time specified. RelativeMonth adds in the
* months, accounting for the fact that the actual length of "3
* months" depends on where you start counting.
*
* XXX By having this separate from the previous block, we are
* allowing dates like "10:00am 3 months", which means 3 months
* from 10:00am today, or even "1/1/99 two days" which means two
* days after 1/1/99.
*
* XXX Shouldn't this only be done if yyHaveRel, just for
* thoroughness?
*/
Start += yyRelSeconds;
return -1;
/*
* Now, if you specified a day of week and counter, add it in. By
* disallowing Date but allowing Time, you can say "5pm next
* monday".
*
* XXX The yyHaveDay && !yyHaveDate restriction should be enforced
* above and be able to cause failure.
*/
if (yyHaveDay && !yyHaveDate) {
}
/* Have to do *something* with a legitimate -1 so it's distinguishable
* from the error return value. (Alternately could set errno on error.) */
}
#if defined(TEST)
/* ARGSUSED */
int ac;
char *av[];
{
char buff[128];
time_t d;
if (d == -1)
(void)printf(
gettext("Bad format - couldn't convert.\n"));
else
(void)printf("\t> ");
}
exit(0);
/* NOTREACHED */
}
#endif /* defined(TEST) */