home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd2.bin
/
dosutils
/
gtar109
/
getdate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-14
|
37KB
|
1,425 lines
/* A Bison parser, made from d:\work\todo\gnu\tar109\getdate.y */
#define ID 258
#define MONTH 259
#define DAY 260
#define MERIDIAN 261
#define NUMBER 262
#define UNIT 263
#define MUNIT 264
#define SUNIT 265
#define ZONE 266
#define DAYZONE 267
#define AGO 268
#define DST 269
#line 2 "d:\work\todo\gnu\tar109\getdate.y"
/* Originally from: Steven M. Bellovin (unc!smb) */
/* Dept. of Computer Science */
/* University of North Carolina at Chapel Hill */
/* @(#)getdate.y 2.17 11/30/87 */
/* #include "defs.h" JF not used any more */
#include <sys/types.h>
#ifdef USG
struct timeb
{
time_t time;
unsigned short millitm;
short timezone;
short dstflag;
};
static void ftime ();
#else
#include <sys/timeb.h>
#endif
#include <ctype.h>
#if defined(BSD4_2) || defined (BSD4_1C)
#include <sys/time.h>
#else /* sane */
#include <time.h>
#endif /* sane */
#if defined (STDC_HEADERS) || defined (USG)
#include <string.h>
#endif
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#ifdef sparc
#include <alloca.h>
#endif
#endif
#ifndef NULL
#define NULL 0
#endif
#define daysec (24L*60L*60L)
static int timeflag, zoneflag, dateflag, dayflag, relflag;
static time_t relsec, relmonth;
static int hh, mm, ss, merid, day_light;
static int dayord, dayreq;
static int month, day, year;
static int ourzone;
#define AM 1
#define PM 2
#define DAYLIGHT 1
#define STANDARD 2
#define MAYBE 3
static time_t timeconv();
static time_t daylcorr();
static lookup();
static yylex();
static yyerror();
static int yylex ();
#define yyparse getdate_yyparse
static int yyerror ();
#ifndef YYLTYPE
typedef
struct yyltype
{
int timestamp;
int first_line;
int first_column;
int last_line;
int last_column;
char *text;
}
yyltype;
#define YYLTYPE yyltype
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
#include <stdio.h>
#ifndef __STDC__
#define const
#endif
#define YYFINAL 44
#define YYFLAG -32768
#define YYNTBASE 18
#define YYTRANSLATE(x) ((unsigned)(x) <= 269 ? yytranslate[x] : 27)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 16, 2, 2, 17, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 15, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14
};
#if YYDEBUG != 0
static const short yyrline[] = { 0,
71, 72, 75, 77, 79, 81, 83, 85, 87, 96,
98, 100, 102, 105, 107, 109, 113, 115, 118, 120,
123, 125, 127, 130, 132, 134, 136, 138, 140, 144,
146, 148, 150, 152, 154, 156
};
static const char * const yytname[] = { 0,
"error","$illegal.","ID","MONTH","DAY","MERIDIAN","NUMBER","UNIT","MUNIT","SUNIT",
"ZONE","DAYZONE","AGO","DST","':'","','","'/'","timedate"
};
#endif
static const short yyr1[] = { 0,
18, 18, 19, 19, 19, 19, 19, 19, 20, 21,
21, 21, 21, 21, 21, 21, 22, 22, 23, 23,
24, 24, 24, 25, 25, 25, 25, 25, 25, 26,
26, 26, 26, 26, 26, 26
};
static const short yyr2[] = { 0,
0, 2, 1, 1, 1, 1, 1, 1, 1, 2,
3, 4, 4, 5, 6, 6, 2, 1, 0, 1,
1, 2, 2, 3, 5, 2, 4, 2, 3, 2,
2, 2, 1, 1, 1, 2
};
static const short yydefact[] = { 1,
0, 0, 21, 9, 33, 34, 35, 19, 18, 2,
8, 3, 4, 6, 5, 7, 26, 22, 28, 23,
10, 30, 31, 32, 0, 0, 20, 17, 36, 0,
29, 11, 24, 27, 12, 13, 0, 0, 14, 25,
15, 16, 0, 0
};
static const short yydefgoto[] = { 1,
10, 11, 12, 13, 28, 14, 15, 16
};
static const short yypact[] = {-32768,
10, 2, -13, -4,-32768,-32768,-32768, -2,-32768,-32768,
-32768,-32768,-32768,-32768,-32768, 12, 11,-32768, 19,-32768,
-32768,-32768,-32768,-32768, 21, 22,-32768,-32768,-32768, 23,
-32768, 1, 14,-32768,-32768,-32768, 25, 26, 17,-32768,
-32768,-32768, 34,-32768
};
static const short yypgoto[] = {-32768,
-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768
};
#define YYLAST 34
static const short yytable[] = { 19,
20, 21, 18, 22, 23, 24, 35, 36, 17, 43,
25, 27, 26, 2, 3, 37, 4, 5, 6, 7,
8, 9, 41, 42, 29, 31, 30, 32, 33, 34,
38, 39, 40, 44
};
static const short yycheck[] = { 4,
5, 6, 16, 8, 9, 10, 6, 7, 7, 0,
15, 14, 17, 4, 5, 15, 7, 8, 9, 10,
11, 12, 6, 7, 13, 7, 16, 7, 7, 7,
17, 7, 7, 0
};
#define YYPURE 1
/* BISON template */
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "simple.bsn"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Bob Corbett and Richard Stallman
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else /* Not GNU C. */
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
#include <alloca.h>
#else
#ifdef MSDOS
#include <malloc.h>
#else
void *alloca(unsigned);
#endif /* MSDOS */
#endif /* Sparc. */
#endif /* Not GNU C. */
#ifndef bcopy
#define bcopy(s,d,x) memcpy(d,s,x)
#endif
/* This is the parser code that is written into each bison parser
when the %semantic_parser declaration is not specified in the grammar.
It was written by Richard Stallman by simplifying the hairy parser
used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
as one case of the switch. */
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
#define YYACCEPT return(0)
#define YYABORT return(1)
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
transition to the new meaning of YYERROR, for GCC.
Once GCC version 2 has supplanted version 1, this can go. */
#define YYFAIL goto yyerrlab
#define YYRECOVERING() (!!yyerrstatus)
#define YYBACKUP(token, value) \
do \
if (yychar == YYEMPTY && yylen == 1) \
{ yychar = (token), yylval = (value); \
yychar1 = YYTRANSLATE (yychar); \
YYPOPSTACK; \
goto yybackup; \
} \
else \
{ yyerror ("syntax error: cannot back up"); YYERROR; } \
while (0)
#define YYTERROR 1
#define YYERRCODE 256
#ifndef YYIMPURE
#define YYLEX yylex()
#endif
#ifndef YYPURE
#define YYLEX yylex(&yylval, &yylloc)
#endif
/* If nonreentrant, generate the variables here */
#ifndef YYIMPURE
int yychar; /* the lookahead symbol */
YYSTYPE yylval; /* the semantic value of the */
/* lookahead symbol */
#ifdef YYLSP_NEEDED
YYLTYPE yylloc; /* location data for the lookahead */
/* symbol */
#endif
int yynerrs; /* number of parse errors so far */
#endif /* YYIMPURE */
#if YYDEBUG != 0
int yydebug; /* nonzero means print parse trace */
/* Since this is uninitialized, it does not stop multiple parsers
from coexisting. */
#endif
/* YYINITDEPTH indicates the initial size of the parser's stacks */
#ifndef YYINITDEPTH
#define YYINITDEPTH 200
#endif
/* YYMAXDEPTH is the maximum size the stacks can grow to
(effective only if the built-in stack extension method is used). */
#if YYMAXDEPTH == 0
#undef YYMAXDEPTH
#endif
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
__yy_bcopy (from, to, count)
char *from;
char *to;
int count;
{
register char *f = from;
register char *t = to;
register int i = count;
while (i-- > 0)
*t++ = *f++;
}
#line 131 "simple.bsn"
int
yyparse()
{
register int yystate;
register int yyn;
register short *yyssp;
register YYSTYPE *yyvsp;
int yyerrstatus; /* number of tokens to shift before error messages enabled */
int yychar1; /* lookahead token as an internal (translated) token number */
short yyssa[YYINITDEPTH]; /* the state stack */
YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
short *yyss = yyssa; /* refer to the stacks thru separate pointers */
YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
#ifdef YYLSP_NEEDED
YYLTYPE *yyls = yylsa;
YYLTYPE *yylsp;
YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
#define YYPOPSTACK (yyvsp--, yysp--, yylsp--)
#else
#define YYPOPSTACK (yyvsp--, yysp--)
#endif
int yystacksize = YYINITDEPTH;
#ifndef YYPURE
int yychar;
YYSTYPE yylval;
int yynerrs;
#ifdef YYLSP_NEEDED
YYLTYPE yylloc;
#endif
#endif
YYSTYPE yyval; /* the variable used to return */
/* semantic values from the action */
/* routines */
int yylen;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Starting parse\n");
#endif
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack. */
yyssp = yyss - 1;
yyvsp = yyvs;
#ifdef YYLSP_NEEDED
yylsp = yyls;
#endif
/* Push a new state, which is found in yystate . */
/* In all cases, when you get here, the value and location stacks
have just been pushed. so pushing a state here evens the stacks. */
yynewstate:
*++yyssp = yystate;
if (yyssp >= yyss + yystacksize - 1)
{
/* Give user a chance to reallocate the stack */
/* Use copies of these so that the &'s don't force the real ones into memory. */
YYSTYPE *yyvs1 = yyvs;
short *yyss1 = yyss;
#ifdef YYLSP_NEEDED
YYLTYPE *yyls1 = yyls;
#endif
/* Get the current used size of the three stacks, in elements. */
int size = yyssp - yyss + 1;
#ifdef yyoverflow
/* Each stack pointer address is followed by the size of
the data in use in that stack, in bytes. */
yyoverflow("parser stack overflow",
&yyss1, size * sizeof (*yyssp),
&yyvs1, size * sizeof (*yyvsp),
#ifdef YYLSP_NEEDED
&yyls1, size * sizeof (*yylsp),
#endif
&yystacksize);
yyss = yyss1; yyvs = yyvs1;
#ifdef YYLSP_NEEDED
yyls = yyls1;
#endif
#else /* no yyoverflow */
/* Extend the stack our own way. */
if (yystacksize >= YYMAXDEPTH)
{
yyerror("parser stack overflow");
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
__yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
__yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
__yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
yyssp = yyss + size - 1;
yyvsp = yyvs + size - 1;
#ifdef YYLSP_NEEDED
yylsp = yyls + size - 1;
#endif
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Stack size increased to %d\n", yystacksize);
#endif
if (yyssp >= yyss + yystacksize - 1)
YYABORT;
}
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Entering state %d\n", yystate);
#endif
yybackup:
/* Do appropriate processing given the current state. */
/* Read a lookahead token if we need one and don't already have one. */
/* yyresume: */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* yychar is either YYEMPTY or YYEOF
or a valid token in external form. */
if (yychar == YYEMPTY)
{
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Reading a token: ");
#endif
yychar = YYLEX;
}
/* Convert token to internal form (in yychar1) for indexing tables with */
if (yychar <= 0) /* This means end of input. */
{
yychar1 = 0;
yychar = YYEOF; /* Don't call YYLEX any more */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Now at end of input.\n");
#endif
}
else
{
yychar1 = YYTRANSLATE(yychar);
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Next token is %d (%s)\n", yychar, yytname[yychar1]);
#endif
}
yyn += yychar1;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
goto yydefault;
yyn = yytable[yyn];
/* yyn is what to do for this token type in this state.
Negative => reduce, -yyn is rule number.
Positive => shift, yyn is new state.
New state is final state => don't bother to shift,
just return success.
0, or most negative number => error. */
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrlab;
if (yyn == YYFINAL)
YYACCEPT;
/* Shift the lookahead token. */
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
#endif
/* Discard the token being shifted unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
/* count tokens shifted since error; after three, turn off error status. */
if (yyerrstatus) yyerrstatus--;
yystate = yyn;
goto yynewstate;
/* Do the default action for the current state. */
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
/* Do a reduction. yyn is the number of a rule to reduce with. */
yyreduce:
yylen = yyr2[yyn];
yyval = yyvsp[1-yylen]; /* implement default value of the action */
#if YYDEBUG != 0
if (yydebug)
{
if (yylen == 1)
fprintf (stderr, "Reducing 1 value via rule %d (line %d), ",
yyn, yyrline[yyn]);
else
fprintf (stderr, "Reducing %d values via rule %d (line %d), ",
yylen, yyn, yyrline[yyn]);
}
#endif
switch (yyn) {
case 3:
#line 76 "d:\work\todo\gnu\tar109\getdate.y"
{timeflag++;;
break;}
case 4:
#line 78 "d:\work\todo\gnu\tar109\getdate.y"
{zoneflag++;;
break;}
case 5:
#line 80 "d:\work\todo\gnu\tar109\getdate.y"
{dateflag++;;
break;}
case 6:
#line 82 "d:\work\todo\gnu\tar109\getdate.y"
{dayflag++;;
break;}
case 7:
#line 84 "d:\work\todo\gnu\tar109\getdate.y"
{relflag++;;
break;}
case 9:
#line 88 "d:\work\todo\gnu\tar109\getdate.y"
{if (timeflag && dateflag && !relflag) year = yyvsp[0];
else if (yyvsp[0] > 10000) {
dateflag++;
day= yyvsp[0]%100;
month= (yyvsp[0]/100)%100;
year = month/10000;
} else {timeflag++;hh = yyvsp[0]/100;mm = yyvsp[0]%100;ss = 0;merid = 24;};
break;}
case 10:
#line 97 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-1]; mm = 0; ss = 0; merid = yyvsp[0];;
break;}
case 11:
#line 99 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-2]; mm = yyvsp[0]; merid = 24;;
break;}
case 12:
#line 101 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-3]; mm = yyvsp[-1]; merid = yyvsp[0];;
break;}
case 13:
#line 103 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-3]; mm = yyvsp[-1]; merid = 24;
day_light = STANDARD; ourzone = -(yyvsp[0]%100 + 60*(yyvsp[0]/100));;
break;}
case 14:
#line 106 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-4]; mm = yyvsp[-2]; ss = yyvsp[0]; merid = 24;;
break;}
case 15:
#line 108 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-5]; mm = yyvsp[-3]; ss = yyvsp[-1]; merid = yyvsp[0];;
break;}
case 16:
#line 110 "d:\work\todo\gnu\tar109\getdate.y"
{hh = yyvsp[-5]; mm = yyvsp[-3]; ss = yyvsp[-1]; merid = 24;
day_light = STANDARD; ourzone = -(yyvsp[0]%100 + 60*(yyvsp[0]/100));;
break;}
case 17:
#line 114 "d:\work\todo\gnu\tar109\getdate.y"
{ourzone = yyvsp[-1]; day_light = yyvsp[0];;
break;}
case 18:
#line 116 "d:\work\todo\gnu\tar109\getdate.y"
{ourzone = yyvsp[0]; day_light = DAYLIGHT;;
break;}
case 19:
#line 119 "d:\work\todo\gnu\tar109\getdate.y"
{ yyval = STANDARD; ;
break;}
case 20:
#line 121 "d:\work\todo\gnu\tar109\getdate.y"
{ yyval = DAYLIGHT; ;
break;}
case 21:
#line 124 "d:\work\todo\gnu\tar109\getdate.y"
{dayord = 1; dayreq = yyvsp[0];;
break;}
case 22:
#line 126 "d:\work\todo\gnu\tar109\getdate.y"
{dayord = 1; dayreq = yyvsp[-1];;
break;}
case 23:
#line 128 "d:\work\todo\gnu\tar109\getdate.y"
{dayord = yyvsp[-1]; dayreq = yyvsp[0];;
break;}
case 24:
#line 131 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[-2]; day = yyvsp[0];;
break;}
case 25:
#line 133 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[-4]; day = yyvsp[-2]; year = yyvsp[0];;
break;}
case 26:
#line 135 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[-1]; day = yyvsp[0];;
break;}
case 27:
#line 137 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[-3]; day = yyvsp[-2]; year = yyvsp[0];;
break;}
case 28:
#line 139 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[0]; day = yyvsp[-1];;
break;}
case 29:
#line 141 "d:\work\todo\gnu\tar109\getdate.y"
{month = yyvsp[-1]; day = yyvsp[-2]; year = yyvsp[0];;
break;}
case 30:
#line 145 "d:\work\todo\gnu\tar109\getdate.y"
{relsec += 60L * yyvsp[-1] * yyvsp[0];;
break;}
case 31:
#line 147 "d:\work\todo\gnu\tar109\getdate.y"
{relmonth += yyvsp[-1] * yyvsp[0];;
break;}
case 32:
#line 149 "d:\work\todo\gnu\tar109\getdate.y"
{relsec += yyvsp[-1];;
break;}
case 33:
#line 151 "d:\work\todo\gnu\tar109\getdate.y"
{relsec += 60L * yyvsp[0];;
break;}
case 34:
#line 153 "d:\work\todo\gnu\tar109\getdate.y"
{relmonth += yyvsp[0];;
break;}
case 35:
#line 155 "d:\work\todo\gnu\tar109\getdate.y"
{relsec++;;
break;}
case 36:
#line 157 "d:\work\todo\gnu\tar109\getdate.y"
{relsec = -relsec; relmonth = -relmonth;;
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 362 "simple.bsn"
yyvsp -= yylen;
yyssp -= yylen;
#ifdef YYLSP_NEEDED
yylsp -= yylen;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
*++yyvsp = yyval;
#ifdef YYLSP_NEEDED
yylsp++;
if (yylen == 0)
{
yylsp->first_line = yylloc.first_line;
yylsp->first_column = yylloc.first_column;
yylsp->last_line = (yylsp-1)->last_line;
yylsp->last_column = (yylsp-1)->last_column;
yylsp->text = 0;
}
else
{
yylsp->last_line = (yylsp+yylen-1)->last_line;
yylsp->last_column = (yylsp+yylen-1)->last_column;
}
#endif
/* Now "shift" the result of the reduction.
Determine what state that goes to,
based on the state we popped back to
and the rule number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTBASE];
goto yynewstate;
yyerrlab: /* here on detecting error */
if (! yyerrstatus)
/* If not already recovering from an error, report this error. */
{
++yynerrs;
#ifdef YYERROR_VERBOSE
yyn = yypact[yystate];
if (yyn > YYFLAG && yyn < YYLAST)
{
int size = 0;
char *msg;
int x, count;
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
size += strlen(yytname[x]) + 15, count++;
msg = (char *) xmalloc(size + 15);
strcpy(msg, "parse error");
if (count < 5)
{
count = 0;
for (x = 0; x < (sizeof(yytname) / sizeof(char *)); x++)
if (yycheck[x + yyn] == x)
{
strcat(msg, count == 0 ? ", expecting `" : " or `");
strcat(msg, yytname[x]);
strcat(msg, "'");
count++;
}
}
yyerror(msg);
free(msg);
}
else
#endif /* YYERROR_VERBOSE */
yyerror("parse error");
}
yyerrlab1: /* here on error raised explicitly by an action */
if (yyerrstatus == 3)
{
/* if just tried and failed to reuse lookahead token after an error, discard it. */
/* return failure if at end of input */
if (yychar == YYEOF)
YYABORT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
#endif
yychar = YYEMPTY;
}
/* Else will try to reuse lookahead token
after shifting the error token. */
yyerrstatus = 3; /* Each real token shifted decrements this */
goto yyerrhandle;
yyerrdefault: /* current state does not do anything special for the error token. */
#if 0
/* This is wrong; only states that explicitly want error tokens
should shift them. */
yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
if (yyn) goto yydefault;
#endif
yyerrpop: /* pop the current state because it cannot handle the error token */
if (yyssp == yyss) YYABORT;
yyvsp--;
yystate = *--yyssp;
#ifdef YYLSP_NEEDED
yylsp--;
#endif
#if YYDEBUG != 0
if (yydebug)
{
short *ssp1 = yyss - 1;
fprintf (stderr, "Error: state stack now");
while (ssp1 != yyssp)
fprintf (stderr, " %d", *++ssp1);
fprintf (stderr, "\n");
}
#endif
yyerrhandle:
yyn = yypact[yystate];
if (yyn == YYFLAG)
goto yyerrdefault;
yyn += YYTERROR;
if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
goto yyerrdefault;
yyn = yytable[yyn];
if (yyn < 0)
{
if (yyn == YYFLAG)
goto yyerrpop;
yyn = -yyn;
goto yyreduce;
}
else if (yyn == 0)
goto yyerrpop;
if (yyn == YYFINAL)
YYACCEPT;
#if YYDEBUG != 0
if (yydebug)
fprintf(stderr, "Shifting error token, ");
#endif
*++yyvsp = yylval;
#ifdef YYLSP_NEEDED
*++yylsp = yylloc;
#endif
yystate = yyn;
goto yynewstate;
}
#line 158 "d:\work\todo\gnu\tar109\getdate.y"
static int mdays[12] =
{31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
#define epoch 1970
extern struct tm *localtime();
static time_t
dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
int mm, dd, yy, h, m, s, mer, zone, dayflag;
{
time_t tod, jdate;
register int i;
if (yy < 0) yy = -yy;
if (yy < 100) yy += 1900;
mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
dd < 1 || dd > mdays[--mm]) return (-1);
jdate = dd-1;
for (i=0; i<mm; i++) jdate += mdays[i];
for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
jdate *= daysec;
jdate += zone * 60L;
if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
jdate += tod;
if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
jdate += -1*60*60;
return (jdate);
}
static time_t
dayconv(ord, day, now)
int ord, day; time_t now;
{
register struct tm *loctime;
time_t tod;
tod = now;
loctime = localtime(&tod);
tod += daysec * ((day - loctime->tm_wday + 7) % 7);
tod += 7*daysec*(ord<=0?ord:ord-1);
return daylcorr(tod, now);
}
static time_t
timeconv(hh, mm, ss, mer)
register int hh, mm, ss, mer;
{
if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
switch (mer) {
case AM: if (hh < 1 || hh > 12) return(-1);
return (60L * ((hh%12)*60L + mm)+ss);
case PM: if (hh < 1 || hh > 12) return(-1);
return (60L * ((hh%12 +12)*60L + mm)+ss);
case 24: if (hh < 0 || hh > 23) return (-1);
return (60L * (hh*60L + mm)+ss);
default: return (-1);
}
}
static time_t
monthadd(sdate, relmonth)
time_t sdate, relmonth;
{
struct tm *ltime;
time_t dateconv();
int mm, yy;
if (relmonth == 0) return 0;
ltime = localtime(&sdate);
mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
yy = mm/12;
mm = mm%12 + 1;
return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
}
static time_t
daylcorr(future, now)
time_t future, now;
{
int fdayl, nowdayl;
nowdayl = (localtime(&now)->tm_hour+1) % 24;
fdayl = (localtime(&future)->tm_hour+1) % 24;
return (future-now) + 60L*60L*(nowdayl-fdayl);
}
static char *lptr;
static int
yylex()
{
extern int yylval;
int sign;
register char c;
register char *p;
char idbuf[20];
int pcnt;
for (;;) {
while (isspace(*lptr))
lptr++;
if (isdigit(c = *lptr) || c == '-' || c == '+') {
if (c== '-' || c == '+') {
if (c=='-') sign = -1;
else sign = 1;
if (!isdigit(*++lptr)) {
/* yylval = sign; return (NUMBER); */
return yylex(); /* skip the '-' sign */
}
} else sign = 1;
yylval = 0;
while (isdigit(c = *lptr++))
yylval = 10*yylval + c - '0';
yylval *= sign;
lptr--;
return (NUMBER);
} else if (isalpha(c)) {
p = idbuf;
while (isalpha(c = *lptr++) || c=='.')
if (p < &idbuf[sizeof(idbuf)-1]) *p++ = c;
*p = '\0';
lptr--;
return (lookup(idbuf));
}
else if (c == '(') {
pcnt = 0;
do {
c = *lptr++;
if (c == '\0') return(c);
else if (c == '(') pcnt++;
else if (c == ')') pcnt--;
} while (pcnt > 0);
}
else return (*lptr++);
}
}
struct table {
char *name;
int type, value;
};
static struct table mdtab[] = {
{"january", MONTH, 1},
{"february", MONTH, 2},
{"march", MONTH, 3},
{"april", MONTH, 4},
{"may", MONTH, 5},
{"june", MONTH, 6},
{"july", MONTH, 7},
{"august", MONTH, 8},
{"september", MONTH, 9},
{"sept", MONTH, 9},
{"october", MONTH, 10},
{"november", MONTH, 11},
{"december", MONTH, 12},
{"sunday", DAY, 0},
{"monday", DAY, 1},
{"tuesday", DAY, 2},
{"tues", DAY, 2},
{"wednesday", DAY, 3},
{"wednes", DAY, 3},
{"thursday", DAY, 4},
{"thur", DAY, 4},
{"thurs", DAY, 4},
{"friday", DAY, 5},
{"saturday", DAY, 6},
{0, 0, 0}
};
#define HRS *60
#define HALFHR 30
static struct table mztab[] = {
{"a.m.", MERIDIAN, AM},
{"am", MERIDIAN, AM},
{"p.m.", MERIDIAN, PM},
{"pm", MERIDIAN, PM},
{"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */
{"n.s.t.", ZONE, 3 HRS + HALFHR},
{"ast", ZONE, 4 HRS}, /* Atlantic */
{"a.s.t.", ZONE, 4 HRS},
{"adt", DAYZONE, 4 HRS},
{"a.d.t.", DAYZONE, 4 HRS},
{"est", ZONE, 5 HRS}, /* Eastern */
{"e.s.t.", ZONE, 5 HRS},
{"edt", DAYZONE, 5 HRS},
{"e.d.t.", DAYZONE, 5 HRS},
{"cst", ZONE, 6 HRS}, /* Central */
{"c.s.t.", ZONE, 6 HRS},
{"cdt", DAYZONE, 6 HRS},
{"c.d.t.", DAYZONE, 6 HRS},
{"mst", ZONE, 7 HRS}, /* Mountain */
{"m.s.t.", ZONE, 7 HRS},
{"mdt", DAYZONE, 7 HRS},
{"m.d.t.", DAYZONE, 7 HRS},
{"pst", ZONE, 8 HRS}, /* Pacific */
{"p.s.t.", ZONE, 8 HRS},
{"pdt", DAYZONE, 8 HRS},
{"p.d.t.", DAYZONE, 8 HRS},
{"yst", ZONE, 9 HRS}, /* Yukon */
{"y.s.t.", ZONE, 9 HRS},
{"ydt", DAYZONE, 9 HRS},
{"y.d.t.", DAYZONE, 9 HRS},
{"hst", ZONE, 10 HRS}, /* Hawaii */
{"h.s.t.", ZONE, 10 HRS},
{"hdt", DAYZONE, 10 HRS},
{"h.d.t.", DAYZONE, 10 HRS},
{"gmt", ZONE, 0 HRS},
{"g.m.t.", ZONE, 0 HRS},
{"bst", DAYZONE, 0 HRS}, /* British Summer Time */
{"b.s.t.", DAYZONE, 0 HRS},
{"eet", ZONE, 0 HRS}, /* European Eastern Time */
{"e.e.t.", ZONE, 0 HRS},
{"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */
{"e.e.s.t.", DAYZONE, 0 HRS},
{"met", ZONE, -1 HRS}, /* Middle European Time */
{"m.e.t.", ZONE, -1 HRS},
{"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */
{"m.e.s.t.", DAYZONE, -1 HRS},
{"wet", ZONE, -2 HRS }, /* Western European Time */
{"w.e.t.", ZONE, -2 HRS },
{"west", DAYZONE, -2 HRS}, /* Western European Summer Time */
{"w.e.s.t.", DAYZONE, -2 HRS},
{"jst", ZONE, -9 HRS}, /* Japan Standard Time */
{"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */
/* No daylight savings time */
{"aest", ZONE, -10 HRS}, /* Australian Eastern Time */
{"a.e.s.t.", ZONE, -10 HRS},
{"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */
{"a.e.s.s.t.", DAYZONE, -10 HRS},
{"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */
{"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
{"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */
{"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
{"awst", ZONE, -8 HRS}, /* Australian Western Time */
{"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */
{"dst", DST, 0}, /* Explicit daylight time */
{0, 0, 0}};
static struct table unittb[] = {
{"year", MUNIT, 12},
{"month", MUNIT, 1},
{"fortnight", UNIT, 14*24*60},
{"week", UNIT, 7*24*60},
{"day", UNIT, 1*24*60},
{"hour", UNIT, 60},
{"minute", UNIT, 1},
{"min", UNIT, 1},
{"second", SUNIT, 1},
{"sec", SUNIT, 1},
{0, 0, 0}};
static struct table othertb[] = {
{"tomorrow", UNIT, 1*24*60},
{"yesterday", UNIT, -1*24*60},
{"today", UNIT, 0},
{"now", UNIT, 0},
{"last", NUMBER, -1},
{"this", UNIT, 0},
{"next", NUMBER, 2},
{"first", NUMBER, 1},
/* {"second", NUMBER, 2}, */
{"third", NUMBER, 3},
{"fourth", NUMBER, 4},
{"fifth", NUMBER, 5},
{"sixth", NUMBER, 6},
{"seventh", NUMBER, 7},
{"eigth", NUMBER, 8},
{"ninth", NUMBER, 9},
{"tenth", NUMBER, 10},
{"eleventh", NUMBER, 11},
{"twelfth", NUMBER, 12},
{"ago", AGO, 1},
{0, 0, 0}};
static struct table milzone[] = {
{"a", ZONE, 1 HRS},
{"b", ZONE, 2 HRS},
{"c", ZONE, 3 HRS},
{"d", ZONE, 4 HRS},
{"e", ZONE, 5 HRS},
{"f", ZONE, 6 HRS},
{"g", ZONE, 7 HRS},
{"h", ZONE, 8 HRS},
{"i", ZONE, 9 HRS},
{"k", ZONE, 10 HRS},
{"l", ZONE, 11 HRS},
{"m", ZONE, 12 HRS},
{"n", ZONE, -1 HRS},
{"o", ZONE, -2 HRS},
{"p", ZONE, -3 HRS},
{"q", ZONE, -4 HRS},
{"r", ZONE, -5 HRS},
{"s", ZONE, -6 HRS},
{"t", ZONE, -7 HRS},
{"u", ZONE, -8 HRS},
{"v", ZONE, -9 HRS},
{"w", ZONE, -10 HRS},
{"x", ZONE, -11 HRS},
{"y", ZONE, -12 HRS},
{"z", ZONE, 0 HRS},
{0, 0, 0}};
static int
lookup(id)
char *id;
{
#define gotit (yylval=i->value, i->type)
char idvar[128];
register char *j, *k;
register struct table *i;
int abbrev;
(void) strcpy(idvar, id);
j = idvar;
k = id - 1;
while (*++k)
*j++ = isupper(*k) ? tolower(*k) : *k;
*j = '\0';
if (strlen(idvar) == 3)
abbrev = 1;
else
if (strlen(idvar) == 4 && idvar[3] == '.' && idvar[1] != '.') {
abbrev = 1;
idvar[3] = '\0';
}
else
abbrev = 0;
for (i = mdtab; i->name; i++) {
k = idvar;
for (j = i->name; *j++ == *k++;) {
if (abbrev && j == i->name+3)
return gotit;
if (j[-1] == 0)
return gotit;
}
}
for (i=mztab; i->name; i++)
if (strcmp(i->name, idvar) == 0)
return gotit;
for (i=unittb; i->name; i++)
if (strcmp(i->name, idvar) == 0)
return gotit;
if (idvar[strlen(idvar)-1] == 's')
idvar[strlen(idvar)-1] = '\0';
for (i=unittb; i->name; i++)
if (strcmp(i->name, idvar) == 0)
return gotit;
for (i = othertb; i->name; i++)
if (strcmp(i->name, idvar) == 0)
return gotit;
if (strlen(idvar) == 1 && isalpha(*idvar)) {
for (i = milzone; i->name; i++)
if (strcmp(i->name, idvar) == 0)
return gotit;
}
return ID;
}
time_t
getdate(p, now)
char *p;
struct timeb *now;
{
#define mcheck(f) if (f>1) err++
time_t monthadd();
int err;
struct tm *lt;
struct timeb ftz;
time_t sdate, tod;
lptr = p;
if (now == ((struct timeb *) NULL)) {
now = &ftz;
ftime(&ftz);
}
lt = localtime(&now->time);
year = lt->tm_year;
month = lt->tm_mon+1;
day = lt->tm_mday;
relsec = 0; relmonth = 0;
timeflag=zoneflag=dateflag=dayflag=relflag=0;
ourzone = now->timezone;
day_light = MAYBE;
hh = mm = ss = 0;
merid = 24;
if (err = yyparse()) return (-1);
mcheck(timeflag);
mcheck(zoneflag);
mcheck(dateflag);
mcheck(dayflag);
if (err) return (-1);
if (dateflag || timeflag || dayflag) {
sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,day_light);
if (sdate < 0) return -1;
}
else {
sdate = now->time;
if (relflag == 0)
sdate -= (lt->tm_sec + lt->tm_min*60 +
lt->tm_hour*(60L*60L));
}
sdate += relsec;
sdate += monthadd(sdate, relmonth);
if (dayflag && !dateflag) {
tod = dayconv(dayord, dayreq, sdate);
sdate += tod;
}
/*
** Have to do *something* with a legitimate -1 so it's distinguishable
** from the error return value. (Alternately could set errno on error.)
*/
return (sdate == -1) ? 0 : sdate;
}
static int
yyerror(s)
char *s;
{
return 0;
}
#ifdef USG
static void
ftime(timeb)
struct timeb *timeb;
{
extern long timezone;
#ifndef DAYLIGHT_MISSING /* Not all non-BSD libraries have `daylight'. */
extern int daylight;
#endif
long t = 0;
localtime(&t); /* Dummy to init timzeone */
time(&(timeb->time));
timeb->millitm=0;
timeb->timezone=timezone/60; /* Timezone is in seconds! */
#ifndef DAYLIGHT_MISSING
timeb->dstflag=daylight;
#else
timeb->dstflag=0;
#endif
}
#endif