Blame getdate.y

Packit Service 623930
%{
Packit Service 623930
/*
Packit Service 623930
**  Originally written by Steven M. Bellovin <smb@research.att.com> while
Packit Service 623930
**  at the University of North Carolina at Chapel Hill.  Later tweaked by
Packit Service 623930
**  a couple of people on Usenet.  Completely overhauled by Rich $alz
Packit Service 623930
**  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990.
Packit Service 623930
**
Packit Service 623930
**  This code is in the public domain and has no copyright.
Packit Service 623930
*/
Packit Service 623930
Packit Service 623930
#include "config.h"
Packit Service 623930
Packit Service 623930
/* Since the code of getdate.y is not included in the Emacs executable
Packit Service 623930
   itself, there is no need to #define static in this file.  Even if
Packit Service 623930
   the code were included in the Emacs executable, it probably
Packit Service 623930
   wouldn't do any harm to #undef it here; this will only cause
Packit Service 623930
   problems if we try to write to a static variable, which I don't
Packit Service 623930
   think this code needs to do.  */
Packit Service 623930
#ifdef emacs
Packit Service 623930
# undef static
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
#include <stdio.h>
Packit Service 623930
#include <ctype.h>
Packit Service 623930
Packit Service 623930
#if HAVE_STDLIB_H
Packit Service 623930
# include <stdlib.h> /* for `free'; used by Bison 1.27 */
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
Packit Service 623930
# define IN_CTYPE_DOMAIN(c) 1
Packit Service 623930
#else
Packit Service 623930
# define IN_CTYPE_DOMAIN(c) isascii(c)
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
Packit Service 623930
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
Packit Service 623930
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
Packit Service 623930
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
Packit Service 623930
Packit Service 623930
/* ISDIGIT differs from ISDIGIT_LOCALE, as follows:
Packit Service 623930
   - Its arg may be any int or unsigned int; it need not be an unsigned char.
Packit Service 623930
   - It's guaranteed to evaluate its argument exactly once.
Packit Service 623930
   - It's typically faster.
Packit Service 623930
   Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
Packit Service 623930
   only '0' through '9' are digits.  Prefer ISDIGIT to ISDIGIT_LOCALE unless
Packit Service 623930
   it's important to use the locale's definition of `digit' even when the
Packit Service 623930
   host does not conform to Posix.  */
Packit Service 623930
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
Packit Service 623930
Packit Service 623930
#if defined (STDC_HEADERS) || defined (USG)
Packit Service 623930
# include <string.h>
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
Packit Service 623930
# define __attribute__(x)
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
#ifndef ATTRIBUTE_UNUSED
Packit Service 623930
# define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
/* Some old versions of bison generate parsers that use bcopy.
Packit Service 623930
   That loses on systems that don't provide the function, so we have
Packit Service 623930
   to redefine it here.  */
Packit Service 623930
#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
Packit Service 623930
# define bcopy(from, to, len) memcpy ((to), (from), (len))
Packit Service 623930
#endif
Packit Service 623930
Packit Service 623930
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
Packit Service 623930
   as well as gratuitiously global symbol names, so we can have multiple
Packit Service 623930
   yacc generated parsers in the same program.  Note that these are only
Packit Service 623930
   the variables produced by yacc.  If other parser generators (bison,
Packit Service 623930
   byacc, etc) produce additional global names that conflict at link time,
Packit Service 623930
   then those parser generators need to be fixed instead of adding those
Packit Service 623930
   names to this list. */
Packit Service 623930
Packit Service 623930
#define yymaxdepth gd_maxdepth
Packit Service 623930
#define yyparse gd_parse
Packit Service 623930
#define yylex   gd_lex
Packit Service 623930
#define yyerror gd_error
Packit Service 623930
#define yylval  gd_lval
Packit Service 623930
#define yychar  gd_char
Packit Service 623930
#define yydebug gd_debug
Packit Service 623930
#define yypact  gd_pact
Packit Service 623930
#define yyr1    gd_r1
Packit Service 623930
#define yyr2    gd_r2
Packit Service 623930
#define yydef   gd_def
Packit Service 623930
#define yychk   gd_chk
Packit Service 623930
#define yypgo   gd_pgo
Packit Service 623930
#define yyact   gd_act
Packit Service 623930
#define yyexca  gd_exca
Packit Service 623930
#define yyerrflag gd_errflag
Packit Service 623930
#define yynerrs gd_nerrs
Packit Service 623930
#define yyps    gd_ps
Packit Service 623930
#define yypv    gd_pv
Packit Service 623930
#define yys     gd_s
Packit Service 623930
#define yy_yys  gd_yys
Packit Service 623930
#define yystate gd_state
Packit Service 623930
#define yytmp   gd_tmp
Packit Service 623930
#define yyv     gd_v
Packit Service 623930
#define yy_yyv  gd_yyv
Packit Service 623930
#define yyval   gd_val
Packit Service 623930
#define yylloc  gd_lloc
Packit Service 623930
#define yyreds  gd_reds          /* With YYDEBUG defined */
Packit Service 623930
#define yytoks  gd_toks          /* With YYDEBUG defined */
Packit Service 623930
#define yylhs   gd_yylhs
Packit Service 623930
#define yylen   gd_yylen
Packit Service 623930
#define yydefred gd_yydefred
Packit Service 623930
#define yydgoto gd_yydgoto
Packit Service 623930
#define yysindex gd_yysindex
Packit Service 623930
#define yyrindex gd_yyrindex
Packit Service 623930
#define yygindex gd_yygindex
Packit Service 623930
#define yytable  gd_yytable
Packit Service 623930
#define yycheck  gd_yycheck
Packit Service 623930
Packit Service 623930
static int yylex (void);
Packit Service 623930
static int yyerror (char *s);
Packit Service 623930
Packit Service 623930
#define EPOCH		1970
Packit Service 623930
#define HOUR(x)		((x) * 60)
Packit Service 623930
Packit Service 623930
#define MAX_BUFF_LEN    128   /* size of buffer to read the date into */
Packit Service 623930
Packit Service 623930
/*
Packit Service 623930
**  An entry in the lexical lookup table.
Packit Service 623930
*/
Packit Service 623930
typedef struct _TABLE {
Packit Service 623930
    const char	*name;
Packit Service 623930
    int		type;
Packit Service 623930
    int		value;
Packit Service 623930
} TABLE;
Packit Service 623930
Packit Service 623930
Packit Service 623930
/*
Packit Service 623930
**  Meridian:  am, pm, or 24-hour style.
Packit Service 623930
*/
Packit Service 623930
typedef enum _MERIDIAN {
Packit Service 623930
    MERam, MERpm, MER24
Packit Service 623930
} MERIDIAN;
Packit Service 623930
Packit Service 623930
Packit Service 623930
/*
Packit Service 623930
**  Global variables.  We could get rid of most of these by using a good
Packit Service 623930
**  union as the yacc stack.  (This routine was originally written before
Packit Service 623930
**  yacc had the %union construct.)  Maybe someday; right now we only use
Packit Service 623930
**  the %union very rarely.
Packit Service 623930
*/
Packit Service 623930
static const char	*yyInput;
Packit Service 623930
static int	yyDayOrdinal;
Packit Service 623930
static int	yyDayNumber;
Packit Service 623930
static int	yyHaveDate;
Packit Service 623930
static int	yyHaveDay;
Packit Service 623930
static int	yyHaveRel;
Packit Service 623930
static int	yyHaveTime;
Packit Service 623930
static int	yyHaveZone;
Packit Service 623930
static int	yyTimezone;
Packit Service 623930
static int	yyDay;
Packit Service 623930
static int	yyHour;
Packit Service 623930
static int	yyMinutes;
Packit Service 623930
static int	yyMonth;
Packit Service 623930
static int	yySeconds;
Packit Service 623930
static int	yyYear;
Packit Service 623930
static MERIDIAN	yyMeridian;
Packit Service 623930
static int	yyRelDay;
Packit Service 623930
static int	yyRelHour;
Packit Service 623930
static int	yyRelMinutes;
Packit Service 623930
static int	yyRelMonth;
Packit Service 623930
static int	yyRelSeconds;
Packit Service 623930
static int	yyRelYear;
Packit Service 623930
Packit Service 623930
%}
Packit Service 623930
Packit Service 623930
/* This grammar has 13 shift/reduce conflicts. */
Packit Service 623930
%expect 13
Packit Service 623930
Packit Service 623930
%union {
Packit Service 623930
    int			Number;
Packit Service 623930
    enum _MERIDIAN	Meridian;
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
%token	tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID
Packit Service 623930
%token	tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
Packit Service 623930
%token	tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
Packit Service 623930
Packit Service 623930
%type	<Number>	tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tMINUTE_UNIT
Packit Service 623930
%type	<Number>	tMONTH tMONTH_UNIT
Packit Service 623930
%type	<Number>	tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
Packit Service 623930
%type	<Meridian>	tMERIDIAN o_merid
Packit Service 623930
Packit Service 623930
%%
Packit Service 623930
Packit Service 623930
spec	: /* NULL */
Packit Service 623930
	| spec item
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
item	: time {
Packit Service 623930
	    yyHaveTime++;
Packit Service 623930
	}
Packit Service 623930
	| zone {
Packit Service 623930
	    yyHaveZone++;
Packit Service 623930
	}
Packit Service 623930
	| date {
Packit Service 623930
	    yyHaveDate++;
Packit Service 623930
	}
Packit Service 623930
	| day {
Packit Service 623930
	    yyHaveDay++;
Packit Service 623930
	}
Packit Service 623930
	| rel {
Packit Service 623930
	    yyHaveRel++;
Packit Service 623930
	}
Packit Service 623930
	| number
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
time	: tUNUMBER tMERIDIAN {
Packit Service 623930
	    yyHour = $1;
Packit Service 623930
	    yyMinutes = 0;
Packit Service 623930
	    yySeconds = 0;
Packit Service 623930
	    yyMeridian = $2;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER ':' tUNUMBER o_merid {
Packit Service 623930
	    yyHour = $1;
Packit Service 623930
	    yyMinutes = $3;
Packit Service 623930
	    yySeconds = 0;
Packit Service 623930
	    yyMeridian = $4;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER ':' tUNUMBER tSNUMBER {
Packit Service 623930
	    yyHour = $1;
Packit Service 623930
	    yyMinutes = $3;
Packit Service 623930
	    yyMeridian = MER24;
Packit Service 623930
	    yyHaveZone++;
Packit Service 623930
	    yyTimezone = ($4 < 0
Packit Service 623930
			  ? -$4 % 100 + (-$4 / 100) * 60
Packit Service 623930
			  : - ($4 % 100 + ($4 / 100) * 60));
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
Packit Service 623930
	    yyHour = $1;
Packit Service 623930
	    yyMinutes = $3;
Packit Service 623930
	    yySeconds = $5;
Packit Service 623930
	    yyMeridian = $6;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
Packit Service 623930
	    yyHour = $1;
Packit Service 623930
	    yyMinutes = $3;
Packit Service 623930
	    yySeconds = $5;
Packit Service 623930
	    yyMeridian = MER24;
Packit Service 623930
	    yyHaveZone++;
Packit Service 623930
	    yyTimezone = ($6 < 0
Packit Service 623930
			  ? -$6 % 100 + (-$6 / 100) * 60
Packit Service 623930
			  : - ($6 % 100 + ($6 / 100) * 60));
Packit Service 623930
	}
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
zone	: tZONE {
Packit Service 623930
	    yyTimezone = $1;
Packit Service 623930
	}
Packit Service 623930
	| tDAYZONE {
Packit Service 623930
	    yyTimezone = $1 - 60;
Packit Service 623930
	}
Packit Service 623930
	|
Packit Service 623930
	  tZONE tDST {
Packit Service 623930
	    yyTimezone = $1 - 60;
Packit Service 623930
	}
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
day	: tDAY {
Packit Service 623930
	    yyDayOrdinal = 1;
Packit Service 623930
	    yyDayNumber = $1;
Packit Service 623930
	}
Packit Service 623930
	| tDAY ',' {
Packit Service 623930
	    yyDayOrdinal = 1;
Packit Service 623930
	    yyDayNumber = $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tDAY {
Packit Service 623930
	    yyDayOrdinal = $1;
Packit Service 623930
	    yyDayNumber = $2;
Packit Service 623930
	}
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
date	: tUNUMBER '/' tUNUMBER {
Packit Service 623930
	    yyMonth = $1;
Packit Service 623930
	    yyDay = $3;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
Packit Service 623930
	  /* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
Packit Service 623930
	     The goal in recognizing YYYY/MM/DD is solely to support legacy
Packit Service 623930
	     machine-generated dates like those in an RCS log listing.  If
Packit Service 623930
	     you want portability, use the ISO 8601 format.  */
Packit Service 623930
	  if ($1 >= 1000)
Packit Service 623930
	    {
Packit Service 623930
	      yyYear = $1;
Packit Service 623930
	      yyMonth = $3;
Packit Service 623930
	      yyDay = $5;
Packit Service 623930
	    }
Packit Service 623930
	  else
Packit Service 623930
	    {
Packit Service 623930
	      yyMonth = $1;
Packit Service 623930
	      yyDay = $3;
Packit Service 623930
	      yyYear = $5;
Packit Service 623930
	    }
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tSNUMBER tSNUMBER {
Packit Service 623930
	    /* ISO 8601 format.  yyyy-mm-dd.  */
Packit Service 623930
	    yyYear = $1;
Packit Service 623930
	    yyMonth = -$2;
Packit Service 623930
	    yyDay = -$3;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tMONTH tSNUMBER {
Packit Service 623930
	    /* e.g. 17-JUN-1992.  */
Packit Service 623930
	    yyDay = $1;
Packit Service 623930
	    yyMonth = $2;
Packit Service 623930
	    yyYear = -$3;
Packit Service 623930
	}
Packit Service 623930
	| tMONTH tUNUMBER {
Packit Service 623930
	    yyMonth = $1;
Packit Service 623930
	    yyDay = $2;
Packit Service 623930
	}
Packit Service 623930
	| tMONTH tUNUMBER ',' tUNUMBER {
Packit Service 623930
	    yyMonth = $1;
Packit Service 623930
	    yyDay = $2;
Packit Service 623930
	    yyYear = $4;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tMONTH {
Packit Service 623930
	    yyMonth = $2;
Packit Service 623930
	    yyDay = $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tMONTH tUNUMBER {
Packit Service 623930
	    yyMonth = $2;
Packit Service 623930
	    yyDay = $1;
Packit Service 623930
	    yyYear = $3;
Packit Service 623930
	}
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
rel	: relunit tAGO {
Packit Service 623930
	    yyRelSeconds = -yyRelSeconds;
Packit Service 623930
	    yyRelMinutes = -yyRelMinutes;
Packit Service 623930
	    yyRelHour = -yyRelHour;
Packit Service 623930
	    yyRelDay = -yyRelDay;
Packit Service 623930
	    yyRelMonth = -yyRelMonth;
Packit Service 623930
	    yyRelYear = -yyRelYear;
Packit Service 623930
	}
Packit Service 623930
	| relunit
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
relunit	: tUNUMBER tYEAR_UNIT {
Packit Service 623930
	    yyRelYear += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tYEAR_UNIT {
Packit Service 623930
	    yyRelYear += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tYEAR_UNIT {
Packit Service 623930
	    yyRelYear += $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tMONTH_UNIT {
Packit Service 623930
	    yyRelMonth += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tMONTH_UNIT {
Packit Service 623930
	    yyRelMonth += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tMONTH_UNIT {
Packit Service 623930
	    yyRelMonth += $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tDAY_UNIT {
Packit Service 623930
	    yyRelDay += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tDAY_UNIT {
Packit Service 623930
	    yyRelDay += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tDAY_UNIT {
Packit Service 623930
	    yyRelDay += $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tHOUR_UNIT {
Packit Service 623930
	    yyRelHour += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tHOUR_UNIT {
Packit Service 623930
	    yyRelHour += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tHOUR_UNIT {
Packit Service 623930
	    yyRelHour += $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tMINUTE_UNIT {
Packit Service 623930
	    yyRelMinutes += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tMINUTE_UNIT {
Packit Service 623930
	    yyRelMinutes += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tMINUTE_UNIT {
Packit Service 623930
	    yyRelMinutes += $1;
Packit Service 623930
	}
Packit Service 623930
	| tUNUMBER tSEC_UNIT {
Packit Service 623930
	    yyRelSeconds += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSNUMBER tSEC_UNIT {
Packit Service 623930
	    yyRelSeconds += $1 * $2;
Packit Service 623930
	}
Packit Service 623930
	| tSEC_UNIT {
Packit Service 623930
	    yyRelSeconds += $1;
Packit Service 623930
	}
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
number	: tUNUMBER
Packit Service 623930
          {
Packit Service 623930
	    if (yyHaveTime && yyHaveDate && !yyHaveRel)
Packit Service 623930
	      yyYear = $1;
Packit Service 623930
	    else
Packit Service 623930
	      {
Packit Service 623930
		if ($1>10000)
Packit Service 623930
		  {
Packit Service 623930
		    yyHaveDate++;
Packit Service 623930
		    yyDay= ($1)%100;
Packit Service 623930
		    yyMonth= ($1/100)%100;
Packit Service 623930
		    yyYear = $1/10000;
Packit Service 623930
		  }
Packit Service 623930
		else
Packit Service 623930
		  {
Packit Service 623930
		    yyHaveTime++;
Packit Service 623930
		    if ($1 < 100)
Packit Service 623930
		      {
Packit Service 623930
			yyHour = $1;
Packit Service 623930
			yyMinutes = 0;
Packit Service 623930
		      }
Packit Service 623930
		    else
Packit Service 623930
		      {
Packit Service 623930
		    	yyHour = $1 / 100;
Packit Service 623930
		    	yyMinutes = $1 % 100;
Packit Service 623930
		      }
Packit Service 623930
		    yySeconds = 0;
Packit Service 623930
		    yyMeridian = MER24;
Packit Service 623930
		  }
Packit Service 623930
	      }
Packit Service 623930
	  }
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
o_merid	: /* NULL */
Packit Service 623930
	  {
Packit Service 623930
	    $$ = MER24;
Packit Service 623930
	  }
Packit Service 623930
	| tMERIDIAN
Packit Service 623930
	  {
Packit Service 623930
	    $$ = $1;
Packit Service 623930
	  }
Packit Service 623930
	;
Packit Service 623930
Packit Service 623930
%%
Packit Service 623930
Packit Service 623930
/* Include this file down here because bison inserts code above which
Packit Service 623930
   may define-away `const'.  We want the prototype for get_date to have
Packit Service 623930
   the same signature as the function definition does. */
Packit Service 623930
#include "getdate.h"
Packit Service 623930
Packit Service 623930
extern struct tm	*gmtime ();
Packit Service 623930
extern struct tm	*localtime ();
Packit Service 623930
extern time_t		mktime ();
Packit Service 623930
Packit Service 623930
/* Month and day table. */
Packit Service 623930
static TABLE const MonthDayTable[] = {
Packit Service 623930
    { "january",	tMONTH,  1 },
Packit Service 623930
    { "february",	tMONTH,  2 },
Packit Service 623930
    { "march",		tMONTH,  3 },
Packit Service 623930
    { "april",		tMONTH,  4 },
Packit Service 623930
    { "may",		tMONTH,  5 },
Packit Service 623930
    { "june",		tMONTH,  6 },
Packit Service 623930
    { "july",		tMONTH,  7 },
Packit Service 623930
    { "august",		tMONTH,  8 },
Packit Service 623930
    { "september",	tMONTH,  9 },
Packit Service 623930
    { "sept",		tMONTH,  9 },
Packit Service 623930
    { "october",	tMONTH, 10 },
Packit Service 623930
    { "november",	tMONTH, 11 },
Packit Service 623930
    { "december",	tMONTH, 12 },
Packit Service 623930
    { "sunday",		tDAY, 0 },
Packit Service 623930
    { "monday",		tDAY, 1 },
Packit Service 623930
    { "tuesday",	tDAY, 2 },
Packit Service 623930
    { "tues",		tDAY, 2 },
Packit Service 623930
    { "wednesday",	tDAY, 3 },
Packit Service 623930
    { "wednes",		tDAY, 3 },
Packit Service 623930
    { "thursday",	tDAY, 4 },
Packit Service 623930
    { "thur",		tDAY, 4 },
Packit Service 623930
    { "thurs",		tDAY, 4 },
Packit Service 623930
    { "friday",		tDAY, 5 },
Packit Service 623930
    { "saturday",	tDAY, 6 },
Packit Service 623930
    { NULL, 0, 0 }
Packit Service 623930
};
Packit Service 623930
Packit Service 623930
/* Time units table. */
Packit Service 623930
static TABLE const UnitsTable[] = {
Packit Service 623930
    { "year",		tYEAR_UNIT,	1 },
Packit Service 623930
    { "month",		tMONTH_UNIT,	1 },
Packit Service 623930
    { "fortnight",	tDAY_UNIT,	14 },
Packit Service 623930
    { "week",		tDAY_UNIT,	7 },
Packit Service 623930
    { "day",		tDAY_UNIT,	1 },
Packit Service 623930
    { "hour",		tHOUR_UNIT,	1 },
Packit Service 623930
    { "minute",		tMINUTE_UNIT,	1 },
Packit Service 623930
    { "min",		tMINUTE_UNIT,	1 },
Packit Service 623930
    { "second",		tSEC_UNIT,	1 },
Packit Service 623930
    { "sec",		tSEC_UNIT,	1 },
Packit Service 623930
    { NULL, 0, 0 }
Packit Service 623930
};
Packit Service 623930
Packit Service 623930
/* Assorted relative-time words. */
Packit Service 623930
static TABLE const OtherTable[] = {
Packit Service 623930
    { "tomorrow",	tMINUTE_UNIT,	1 * 24 * 60 },
Packit Service 623930
    { "yesterday",	tMINUTE_UNIT,	-1 * 24 * 60 },
Packit Service 623930
    { "today",		tMINUTE_UNIT,	0 },
Packit Service 623930
    { "now",		tMINUTE_UNIT,	0 },
Packit Service 623930
    { "last",		tUNUMBER,	-1 },
Packit Service 623930
    { "this",		tMINUTE_UNIT,	0 },
Packit Service 623930
    { "next",		tUNUMBER,	1 },
Packit Service 623930
    { "first",		tUNUMBER,	1 },
Packit Service 623930
/*  { "second",		tUNUMBER,	2 }, */
Packit Service 623930
    { "third",		tUNUMBER,	3 },
Packit Service 623930
    { "fourth",		tUNUMBER,	4 },
Packit Service 623930
    { "fifth",		tUNUMBER,	5 },
Packit Service 623930
    { "sixth",		tUNUMBER,	6 },
Packit Service 623930
    { "seventh",	tUNUMBER,	7 },
Packit Service 623930
    { "eighth",		tUNUMBER,	8 },
Packit Service 623930
    { "ninth",		tUNUMBER,	9 },
Packit Service 623930
    { "tenth",		tUNUMBER,	10 },
Packit Service 623930
    { "eleventh",	tUNUMBER,	11 },
Packit Service 623930
    { "twelfth",	tUNUMBER,	12 },
Packit Service 623930
    { "ago",		tAGO,	1 },
Packit Service 623930
    { NULL, 0, 0 }
Packit Service 623930
};
Packit Service 623930
Packit Service 623930
/* The timezone table. */
Packit Service 623930
static TABLE const TimezoneTable[] = {
Packit Service 623930
    { "gmt",	tZONE,     HOUR ( 0) },	/* Greenwich Mean */
Packit Service 623930
    { "ut",	tZONE,     HOUR ( 0) },	/* Universal (Coordinated) */
Packit Service 623930
    { "utc",	tZONE,     HOUR ( 0) },
Packit Service 623930
    { "wet",	tZONE,     HOUR ( 0) },	/* Western European */
Packit Service 623930
    { "bst",	tDAYZONE,  HOUR ( 0) },	/* British Summer */
Packit Service 623930
    { "wat",	tZONE,     HOUR ( 1) },	/* West Africa */
Packit Service 623930
    { "at",	tZONE,     HOUR ( 2) },	/* Azores */
Packit Service 623930
#if	0
Packit Service 623930
    /* For completeness.  BST is also British Summer, and GST is
Packit Service 623930
     * also Guam Standard. */
Packit Service 623930
    { "bst",	tZONE,     HOUR ( 3) },	/* Brazil Standard */
Packit Service 623930
    { "gst",	tZONE,     HOUR ( 3) },	/* Greenland Standard */
Packit Service 623930
#endif
Packit Service 623930
#if 0
Packit Service 623930
    { "nft",	tZONE,     HOUR (3.5) },	/* Newfoundland */
Packit Service 623930
    { "nst",	tZONE,     HOUR (3.5) },	/* Newfoundland Standard */
Packit Service 623930
    { "ndt",	tDAYZONE,  HOUR (3.5) },	/* Newfoundland Daylight */
Packit Service 623930
#endif
Packit Service 623930
    { "ast",	tZONE,     HOUR ( 4) },	/* Atlantic Standard */
Packit Service 623930
    { "adt",	tDAYZONE,  HOUR ( 4) },	/* Atlantic Daylight */
Packit Service 623930
    { "est",	tZONE,     HOUR ( 5) },	/* Eastern Standard */
Packit Service 623930
    { "edt",	tDAYZONE,  HOUR ( 5) },	/* Eastern Daylight */
Packit Service 623930
    { "cst",	tZONE,     HOUR ( 6) },	/* Central Standard */
Packit Service 623930
    { "cdt",	tDAYZONE,  HOUR ( 6) },	/* Central Daylight */
Packit Service 623930
    { "mst",	tZONE,     HOUR ( 7) },	/* Mountain Standard */
Packit Service 623930
    { "mdt",	tDAYZONE,  HOUR ( 7) },	/* Mountain Daylight */
Packit Service 623930
    { "pst",	tZONE,     HOUR ( 8) },	/* Pacific Standard */
Packit Service 623930
    { "pdt",	tDAYZONE,  HOUR ( 8) },	/* Pacific Daylight */
Packit Service 623930
    { "yst",	tZONE,     HOUR ( 9) },	/* Yukon Standard */
Packit Service 623930
    { "ydt",	tDAYZONE,  HOUR ( 9) },	/* Yukon Daylight */
Packit Service 623930
    { "hst",	tZONE,     HOUR (10) },	/* Hawaii Standard */
Packit Service 623930
    { "hdt",	tDAYZONE,  HOUR (10) },	/* Hawaii Daylight */
Packit Service 623930
    { "cat",	tZONE,     HOUR (10) },	/* Central Alaska */
Packit Service 623930
    { "ahst",	tZONE,     HOUR (10) },	/* Alaska-Hawaii Standard */
Packit Service 623930
    { "nt",	tZONE,     HOUR (11) },	/* Nome */
Packit Service 623930
    { "idlw",	tZONE,     HOUR (12) },	/* International Date Line West */
Packit Service 623930
    { "cet",	tZONE,     -HOUR (1) },	/* Central European */
Packit Service 623930
    { "met",	tZONE,     -HOUR (1) },	/* Middle European */
Packit Service 623930
    { "mewt",	tZONE,     -HOUR (1) },	/* Middle European Winter */
Packit Service 623930
    { "mest",	tDAYZONE,  -HOUR (1) },	/* Middle European Summer */
Packit Service 623930
    { "mesz",	tDAYZONE,  -HOUR (1) },	/* Middle European Summer */
Packit Service 623930
    { "swt",	tZONE,     -HOUR (1) },	/* Swedish Winter */
Packit Service 623930
    { "sst",	tDAYZONE,  -HOUR (1) },	/* Swedish Summer */
Packit Service 623930
    { "fwt",	tZONE,     -HOUR (1) },	/* French Winter */
Packit Service 623930
    { "fst",	tDAYZONE,  -HOUR (1) },	/* French Summer */
Packit Service 623930
    { "eet",	tZONE,     -HOUR (2) },	/* Eastern Europe, USSR Zone 1 */
Packit Service 623930
    { "bt",	tZONE,     -HOUR (3) },	/* Baghdad, USSR Zone 2 */
Packit Service 623930
#if 0
Packit Service 623930
    { "it",	tZONE,     -HOUR (3.5) },/* Iran */
Packit Service 623930
#endif
Packit Service 623930
    { "zp4",	tZONE,     -HOUR (4) },	/* USSR Zone 3 */
Packit Service 623930
    { "zp5",	tZONE,     -HOUR (5) },	/* USSR Zone 4 */
Packit Service 623930
#if 0
Packit Service 623930
    { "ist",	tZONE,     -HOUR (5.5) },/* Indian Standard */
Packit Service 623930
#endif
Packit Service 623930
    { "zp6",	tZONE,     -HOUR (6) },	/* USSR Zone 5 */
Packit Service 623930
#if	0
Packit Service 623930
    /* For completeness.  NST is also Newfoundland Standard, and SST is
Packit Service 623930
     * also Swedish Summer. */
Packit Service 623930
    { "nst",	tZONE,     -HOUR (6.5) },/* North Sumatra */
Packit Service 623930
    { "sst",	tZONE,     -HOUR (7) },	/* South Sumatra, USSR Zone 6 */
Packit Service 623930
#endif	/* 0 */
Packit Service 623930
    { "wast",	tZONE,     -HOUR (7) },	/* West Australian Standard */
Packit Service 623930
    { "wadt",	tDAYZONE,  -HOUR (7) },	/* West Australian Daylight */
Packit Service 623930
#if 0
Packit Service 623930
    { "jt",	tZONE,     -HOUR (7.5) },/* Java (3pm in Cronusland!) */
Packit Service 623930
#endif
Packit Service 623930
    { "cct",	tZONE,     -HOUR (8) },	/* China Coast, USSR Zone 7 */
Packit Service 623930
    { "jst",	tZONE,     -HOUR (9) },	/* Japan Standard, USSR Zone 8 */
Packit Service 623930
#if 0
Packit Service 623930
    { "cast",	tZONE,     -HOUR (9.5) },/* Central Australian Standard */
Packit Service 623930
    { "cadt",	tDAYZONE,  -HOUR (9.5) },/* Central Australian Daylight */
Packit Service 623930
#endif
Packit Service 623930
    { "east",	tZONE,     -HOUR (10) },	/* Eastern Australian Standard */
Packit Service 623930
    { "eadt",	tDAYZONE,  -HOUR (10) },	/* Eastern Australian Daylight */
Packit Service 623930
    { "gst",	tZONE,     -HOUR (10) },	/* Guam Standard, USSR Zone 9 */
Packit Service 623930
    { "nzt",	tZONE,     -HOUR (12) },	/* New Zealand */
Packit Service 623930
    { "nzst",	tZONE,     -HOUR (12) },	/* New Zealand Standard */
Packit Service 623930
    { "nzdt",	tDAYZONE,  -HOUR (12) },	/* New Zealand Daylight */
Packit Service 623930
    { "idle",	tZONE,     -HOUR (12) },	/* International Date Line East */
Packit Service 623930
    {  NULL, 0, 0  }
Packit Service 623930
};
Packit Service 623930
Packit Service 623930
/* Military timezone table. */
Packit Service 623930
static TABLE const MilitaryTable[] = {
Packit Service 623930
    { "a",	tZONE,	HOUR (  1) },
Packit Service 623930
    { "b",	tZONE,	HOUR (  2) },
Packit Service 623930
    { "c",	tZONE,	HOUR (  3) },
Packit Service 623930
    { "d",	tZONE,	HOUR (  4) },
Packit Service 623930
    { "e",	tZONE,	HOUR (  5) },
Packit Service 623930
    { "f",	tZONE,	HOUR (  6) },
Packit Service 623930
    { "g",	tZONE,	HOUR (  7) },
Packit Service 623930
    { "h",	tZONE,	HOUR (  8) },
Packit Service 623930
    { "i",	tZONE,	HOUR (  9) },
Packit Service 623930
    { "k",	tZONE,	HOUR ( 10) },
Packit Service 623930
    { "l",	tZONE,	HOUR ( 11) },
Packit Service 623930
    { "m",	tZONE,	HOUR ( 12) },
Packit Service 623930
    { "n",	tZONE,	HOUR (- 1) },
Packit Service 623930
    { "o",	tZONE,	HOUR (- 2) },
Packit Service 623930
    { "p",	tZONE,	HOUR (- 3) },
Packit Service 623930
    { "q",	tZONE,	HOUR (- 4) },
Packit Service 623930
    { "r",	tZONE,	HOUR (- 5) },
Packit Service 623930
    { "s",	tZONE,	HOUR (- 6) },
Packit Service 623930
    { "t",	tZONE,	HOUR (- 7) },
Packit Service 623930
    { "u",	tZONE,	HOUR (- 8) },
Packit Service 623930
    { "v",	tZONE,	HOUR (- 9) },
Packit Service 623930
    { "w",	tZONE,	HOUR (-10) },
Packit Service 623930
    { "x",	tZONE,	HOUR (-11) },
Packit Service 623930
    { "y",	tZONE,	HOUR (-12) },
Packit Service 623930
    { "z",	tZONE,	HOUR (  0) },
Packit Service 623930
    { NULL, 0, 0 }
Packit Service 623930
};
Packit Service 623930
Packit Service 623930

Packit Service 623930
Packit Service 623930
Packit Service 623930
/* ARGSUSED */
Packit Service 623930
static int
Packit Service 623930
yyerror (s)
Packit Service 623930
     char *s ATTRIBUTE_UNUSED;
Packit Service 623930
{
Packit Service 623930
  return 0;
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
static int
Packit Service 623930
ToHour (Hours, Meridian)
Packit Service 623930
     int Hours;
Packit Service 623930
     MERIDIAN Meridian;
Packit Service 623930
{
Packit Service 623930
  switch (Meridian)
Packit Service 623930
    {
Packit Service 623930
    case MER24:
Packit Service 623930
      if (Hours < 0 || Hours > 23)
Packit Service 623930
	return -1;
Packit Service 623930
      return Hours;
Packit Service 623930
    case MERam:
Packit Service 623930
      if (Hours < 1 || Hours > 12)
Packit Service 623930
	return -1;
Packit Service 623930
      if (Hours == 12)
Packit Service 623930
	Hours = 0;
Packit Service 623930
      return Hours;
Packit Service 623930
    case MERpm:
Packit Service 623930
      if (Hours < 1 || Hours > 12)
Packit Service 623930
	return -1;
Packit Service 623930
      if (Hours == 12)
Packit Service 623930
	Hours = 0;
Packit Service 623930
      return Hours + 12;
Packit Service 623930
    default:
Packit Service 623930
      abort ();
Packit Service 623930
    }
Packit Service 623930
  /* NOTREACHED */
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
static int
Packit Service 623930
ToYear (Year)
Packit Service 623930
     int Year;
Packit Service 623930
{
Packit Service 623930
  if (Year < 0)
Packit Service 623930
    Year = -Year;
Packit Service 623930
Packit Service 623930
  /* XPG4 suggests that years 00-68 map to 2000-2068, and
Packit Service 623930
     years 69-99 map to 1969-1999.  */
Packit Service 623930
  if (Year < 69)
Packit Service 623930
    Year += 2000;
Packit Service 623930
  else if (Year < 100)
Packit Service 623930
    Year += 1900;
Packit Service 623930
Packit Service 623930
  return Year;
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
static int
Packit Service 623930
LookupWord (buff)
Packit Service 623930
     char *buff;
Packit Service 623930
{
Packit Service 623930
  register char *p;
Packit Service 623930
  register char *q;
Packit Service 623930
  register const TABLE *tp;
Packit Service 623930
  int i;
Packit Service 623930
  int abbrev;
Packit Service 623930
Packit Service 623930
  /* Make it lowercase. */
Packit Service 623930
  for (p = buff; *p; p++)
Packit Service 623930
    if (ISUPPER ((unsigned char) *p))
Packit Service 623930
      *p = tolower ((unsigned char) *p);
Packit Service 623930
Packit Service 623930
  if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0)
Packit Service 623930
    {
Packit Service 623930
      yylval.Meridian = MERam;
Packit Service 623930
      return tMERIDIAN;
Packit Service 623930
    }
Packit Service 623930
  if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0)
Packit Service 623930
    {
Packit Service 623930
      yylval.Meridian = MERpm;
Packit Service 623930
      return tMERIDIAN;
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  /* See if we have an abbreviation for a month. */
Packit Service 623930
  if (strlen (buff) == 3)
Packit Service 623930
    abbrev = 1;
Packit Service 623930
  else if (strlen (buff) == 4 && buff[3] == '.')
Packit Service 623930
    {
Packit Service 623930
      abbrev = 1;
Packit Service 623930
      buff[3] = '\0';
Packit Service 623930
    }
Packit Service 623930
  else
Packit Service 623930
    abbrev = 0;
Packit Service 623930
Packit Service 623930
  for (tp = MonthDayTable; tp->name; tp++)
Packit Service 623930
    {
Packit Service 623930
      if (abbrev)
Packit Service 623930
	{
Packit Service 623930
	  if (strncmp (buff, tp->name, 3) == 0)
Packit Service 623930
	    {
Packit Service 623930
	      yylval.Number = tp->value;
Packit Service 623930
	      return tp->type;
Packit Service 623930
	    }
Packit Service 623930
	}
Packit Service 623930
      else if (strcmp (buff, tp->name) == 0)
Packit Service 623930
	{
Packit Service 623930
	  yylval.Number = tp->value;
Packit Service 623930
	  return tp->type;
Packit Service 623930
	}
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  for (tp = TimezoneTable; tp->name; tp++)
Packit Service 623930
    if (strcmp (buff, tp->name) == 0)
Packit Service 623930
      {
Packit Service 623930
	yylval.Number = tp->value;
Packit Service 623930
	return tp->type;
Packit Service 623930
      }
Packit Service 623930
Packit Service 623930
  if (strcmp (buff, "dst") == 0)
Packit Service 623930
    return tDST;
Packit Service 623930
Packit Service 623930
  for (tp = UnitsTable; tp->name; tp++)
Packit Service 623930
    if (strcmp (buff, tp->name) == 0)
Packit Service 623930
      {
Packit Service 623930
	yylval.Number = tp->value;
Packit Service 623930
	return tp->type;
Packit Service 623930
      }
Packit Service 623930
Packit Service 623930
  /* Strip off any plural and try the units table again. */
Packit Service 623930
  i = strlen (buff) - 1;
Packit Service 623930
  if (buff[i] == 's')
Packit Service 623930
    {
Packit Service 623930
      buff[i] = '\0';
Packit Service 623930
      for (tp = UnitsTable; tp->name; tp++)
Packit Service 623930
	if (strcmp (buff, tp->name) == 0)
Packit Service 623930
	  {
Packit Service 623930
	    yylval.Number = tp->value;
Packit Service 623930
	    return tp->type;
Packit Service 623930
	  }
Packit Service 623930
      buff[i] = 's';		/* Put back for "this" in OtherTable. */
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  for (tp = OtherTable; tp->name; tp++)
Packit Service 623930
    if (strcmp (buff, tp->name) == 0)
Packit Service 623930
      {
Packit Service 623930
	yylval.Number = tp->value;
Packit Service 623930
	return tp->type;
Packit Service 623930
      }
Packit Service 623930
Packit Service 623930
  /* Military timezones. */
Packit Service 623930
  if (buff[1] == '\0' && ISALPHA ((unsigned char) *buff))
Packit Service 623930
    {
Packit Service 623930
      for (tp = MilitaryTable; tp->name; tp++)
Packit Service 623930
	if (strcmp (buff, tp->name) == 0)
Packit Service 623930
	  {
Packit Service 623930
	    yylval.Number = tp->value;
Packit Service 623930
	    return tp->type;
Packit Service 623930
	  }
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  /* Drop out any periods and try the timezone table again. */
Packit Service 623930
  for (i = 0, p = q = buff; *q; q++)
Packit Service 623930
    if (*q != '.')
Packit Service 623930
      *p++ = *q;
Packit Service 623930
    else
Packit Service 623930
      i++;
Packit Service 623930
  *p = '\0';
Packit Service 623930
  if (i)
Packit Service 623930
    for (tp = TimezoneTable; tp->name; tp++)
Packit Service 623930
      if (strcmp (buff, tp->name) == 0)
Packit Service 623930
	{
Packit Service 623930
	  yylval.Number = tp->value;
Packit Service 623930
	  return tp->type;
Packit Service 623930
	}
Packit Service 623930
Packit Service 623930
  return tID;
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
static int
Packit Service 623930
yylex ()
Packit Service 623930
{
Packit Service 623930
  register unsigned char c;
Packit Service 623930
  register char *p;
Packit Service 623930
  char buff[20];
Packit Service 623930
  int Count;
Packit Service 623930
  int sign;
Packit Service 623930
Packit Service 623930
  for (;;)
Packit Service 623930
    {
Packit Service 623930
      while (ISSPACE ((unsigned char) *yyInput))
Packit Service 623930
	yyInput++;
Packit Service 623930
Packit Service 623930
      if (ISDIGIT (c = *yyInput) || c == '-' || c == '+')
Packit Service 623930
	{
Packit Service 623930
	  if (c == '-' || c == '+')
Packit Service 623930
	    {
Packit Service 623930
	      sign = c == '-' ? -1 : 1;
Packit Service 623930
	      if (!ISDIGIT (*++yyInput))
Packit Service 623930
		/* skip the '-' sign */
Packit Service 623930
		continue;
Packit Service 623930
	    }
Packit Service 623930
	  else
Packit Service 623930
	    sign = 0;
Packit Service 623930
	  for (yylval.Number = 0; ISDIGIT (c = *yyInput++);)
Packit Service 623930
	    yylval.Number = 10 * yylval.Number + c - '0';
Packit Service 623930
	  yyInput--;
Packit Service 623930
	  if (sign < 0)
Packit Service 623930
	    yylval.Number = -yylval.Number;
Packit Service 623930
	  return sign ? tSNUMBER : tUNUMBER;
Packit Service 623930
	}
Packit Service 623930
      if (ISALPHA (c))
Packit Service 623930
	{
Packit Service 623930
	  for (p = buff; (c = *yyInput++, ISALPHA (c)) || c == '.';)
Packit Service 623930
	    if (p < &buff[sizeof buff - 1])
Packit Service 623930
	      *p++ = c;
Packit Service 623930
	  *p = '\0';
Packit Service 623930
	  yyInput--;
Packit Service 623930
	  return LookupWord (buff);
Packit Service 623930
	}
Packit Service 623930
      if (c != '(')
Packit Service 623930
	return *yyInput++;
Packit Service 623930
      Count = 0;
Packit Service 623930
      do
Packit Service 623930
	{
Packit Service 623930
	  c = *yyInput++;
Packit Service 623930
	  if (c == '\0')
Packit Service 623930
	    return c;
Packit Service 623930
	  if (c == '(')
Packit Service 623930
	    Count++;
Packit Service 623930
	  else if (c == ')')
Packit Service 623930
	    Count--;
Packit Service 623930
	}
Packit Service 623930
      while (Count > 0);
Packit Service 623930
    }
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
#define TM_YEAR_ORIGIN 1900
Packit Service 623930
Packit Service 623930
/* Yield A - B, measured in seconds.  */
Packit Service 623930
static long
Packit Service 623930
difftm (struct tm *a, struct tm *b)
Packit Service 623930
{
Packit Service 623930
  int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
Packit Service 623930
  int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
Packit Service 623930
  long days = (
Packit Service 623930
  /* difference in day of year */
Packit Service 623930
		a->tm_yday - b->tm_yday
Packit Service 623930
  /* + intervening leap days */
Packit Service 623930
		+ ((ay >> 2) - (by >> 2))
Packit Service 623930
		- (ay / 100 - by / 100)
Packit Service 623930
		+ ((ay / 100 >> 2) - (by / 100 >> 2))
Packit Service 623930
  /* + difference in years * 365 */
Packit Service 623930
		+ (long) (ay - by) * 365
Packit Service 623930
  );
Packit Service 623930
  return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
Packit Service 623930
		+ (a->tm_min - b->tm_min))
Packit Service 623930
	  + (a->tm_sec - b->tm_sec));
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
time_t
Packit Service 623930
get_date (const char *p, const time_t *now)
Packit Service 623930
{
Packit Service 623930
  struct tm tm, tm0, *tmp;
Packit Service 623930
  time_t Start;
Packit Service 623930
Packit Service 623930
  yyInput = p;
Packit Service 623930
  Start = now ? *now : time ((time_t *) NULL);
Packit Service 623930
  tmp = localtime (&Start;;
Packit Service 623930
  if (!tmp)
Packit Service 623930
    return -1;
Packit Service 623930
  yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
Packit Service 623930
  yyMonth = tmp->tm_mon + 1;
Packit Service 623930
  yyDay = tmp->tm_mday;
Packit Service 623930
  yyHour = tmp->tm_hour;
Packit Service 623930
  yyMinutes = tmp->tm_min;
Packit Service 623930
  yySeconds = tmp->tm_sec;
Packit Service 623930
  tm.tm_isdst = tmp->tm_isdst;
Packit Service 623930
  yyMeridian = MER24;
Packit Service 623930
  yyRelSeconds = 0;
Packit Service 623930
  yyRelMinutes = 0;
Packit Service 623930
  yyRelHour = 0;
Packit Service 623930
  yyRelDay = 0;
Packit Service 623930
  yyRelMonth = 0;
Packit Service 623930
  yyRelYear = 0;
Packit Service 623930
  yyHaveDate = 0;
Packit Service 623930
  yyHaveDay = 0;
Packit Service 623930
  yyHaveRel = 0;
Packit Service 623930
  yyHaveTime = 0;
Packit Service 623930
  yyHaveZone = 0;
Packit Service 623930
Packit Service 623930
  if (yyparse ()
Packit Service 623930
      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
Packit Service 623930
    return -1;
Packit Service 623930
Packit Service 623930
  tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
Packit Service 623930
  tm.tm_mon = yyMonth - 1 + yyRelMonth;
Packit Service 623930
  tm.tm_mday = yyDay + yyRelDay;
Packit Service 623930
  if (yyHaveTime || (yyHaveRel && !yyHaveDate && !yyHaveDay))
Packit Service 623930
    {
Packit Service 623930
      tm.tm_hour = ToHour (yyHour, yyMeridian);
Packit Service 623930
      if (tm.tm_hour < 0)
Packit Service 623930
	return -1;
Packit Service 623930
      tm.tm_min = yyMinutes;
Packit Service 623930
      tm.tm_sec = yySeconds;
Packit Service 623930
    }
Packit Service 623930
  else
Packit Service 623930
    {
Packit Service 623930
      tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
Packit Service 623930
    }
Packit Service 623930
  tm.tm_hour += yyRelHour;
Packit Service 623930
  tm.tm_min += yyRelMinutes;
Packit Service 623930
  tm.tm_sec += yyRelSeconds;
Packit Service 623930
Packit Service 623930
  /* Let mktime deduce tm_isdst if we have an absolute timestamp,
Packit Service 623930
     or if the relative timestamp mentions days, months, or years.  */
Packit Service 623930
  if (yyHaveDate | yyHaveDay | yyHaveTime | yyRelDay | yyRelMonth | yyRelYear)
Packit Service 623930
    tm.tm_isdst = -1;
Packit Service 623930
Packit Service 623930
  tm0 = tm;
Packit Service 623930
Packit Service 623930
  Start = mktime (&tm;;
Packit Service 623930
Packit Service 623930
  if (Start == (time_t) -1)
Packit Service 623930
    {
Packit Service 623930
Packit Service 623930
      /* Guard against falsely reporting errors near the time_t boundaries
Packit Service 623930
         when parsing times in other time zones.  For example, if the min
Packit Service 623930
         time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
Packit Service 623930
         of UTC, then the min localtime value is 1970-01-01 08:00:00; if
Packit Service 623930
         we apply mktime to 1970-01-01 00:00:00 we will get an error, so
Packit Service 623930
         we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
Packit Service 623930
         zone by 24 hours to compensate.  This algorithm assumes that
Packit Service 623930
         there is no DST transition within a day of the time_t boundaries.  */
Packit Service 623930
      if (yyHaveZone)
Packit Service 623930
	{
Packit Service 623930
	  tm = tm0;
Packit Service 623930
	  if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
Packit Service 623930
	    {
Packit Service 623930
	      tm.tm_mday++;
Packit Service 623930
	      yyTimezone -= 24 * 60;
Packit Service 623930
	    }
Packit Service 623930
	  else
Packit Service 623930
	    {
Packit Service 623930
	      tm.tm_mday--;
Packit Service 623930
	      yyTimezone += 24 * 60;
Packit Service 623930
	    }
Packit Service 623930
	  Start = mktime (&tm;;
Packit Service 623930
	}
Packit Service 623930
Packit Service 623930
      if (Start == (time_t) -1)
Packit Service 623930
	return Start;
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  if (yyHaveDay && !yyHaveDate)
Packit Service 623930
    {
Packit Service 623930
      tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
Packit Service 623930
		     + 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
Packit Service 623930
      Start = mktime (&tm;;
Packit Service 623930
      if (Start == (time_t) -1)
Packit Service 623930
	return Start;
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  if (yyHaveZone)
Packit Service 623930
    {
Packit Service 623930
      long delta;
Packit Service 623930
      struct tm *gmt = gmtime (&Start;;
Packit Service 623930
      if (!gmt)
Packit Service 623930
	return -1;
Packit Service 623930
      delta = yyTimezone * 60L + difftm (&tm, gmt);
Packit Service 623930
      if ((Start + delta < Start) != (delta < 0))
Packit Service 623930
	return -1;		/* time_t overflow */
Packit Service 623930
      Start += delta;
Packit Service 623930
    }
Packit Service 623930
Packit Service 623930
  return Start;
Packit Service 623930
}
Packit Service 623930
Packit Service 623930
#if	defined (TEST)
Packit Service 623930
Packit Service 623930
/* ARGSUSED */
Packit Service 623930
int
Packit Service 623930
main (ac, av)
Packit Service 623930
     int ac;
Packit Service 623930
     char *av[];
Packit Service 623930
{
Packit Service 623930
  char buff[MAX_BUFF_LEN + 1];
Packit Service 623930
  time_t d;
Packit Service 623930
Packit Service 623930
  (void) printf ("Enter date, or blank line to exit.\n\t> ");
Packit Service 623930
  (void) fflush (stdout);
Packit Service 623930
Packit Service 623930
  buff[MAX_BUFF_LEN] = 0;
Packit Service 623930
  while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
Packit Service 623930
    {
Packit Service 623930
      d = get_date (buff, (time_t *) NULL);
Packit Service 623930
      if (d == -1)
Packit Service 623930
	(void) printf ("Bad format - couldn't convert.\n");
Packit Service 623930
      else
Packit Service 623930
	(void) printf ("%s", ctime (&d);;
Packit Service 623930
      (void) printf ("\t> ");
Packit Service 623930
      (void) fflush (stdout);
Packit Service 623930
    }
Packit Service 623930
  exit (0);
Packit Service 623930
  /* NOTREACHED */
Packit Service 623930
}
Packit Service 623930
#endif /* defined (TEST) */