lib/getdate.c

Go to the documentation of this file.
00001 /*@-bounds@*/
00002 /*@-globstate -statictrans -unqualifiedtrans -noparams @*/
00003 /*@-retvalint -usedef -varuse -nullderef -nullassign @*/
00004 /*@-readonlytrans -modunconnomods -compdef -noeffectuncon @*/
00005 /*@-globs -evalorderuncon -modobserveruncon -modnomods @*/
00006 /*@unused@*/
00007 #ifndef lint
00008 static char const 
00009 yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28 2000/01/17 02:04:06 bde Exp $";
00010 #endif
00011 #include <stdlib.h>
00012 #define YYBYACC 1
00013 #define YYMAJOR 1
00014 #define YYMINOR 9
00015 #define YYLEX yylex()
00016 #define YYEMPTY -1
00017 #define yyclearin (yychar=(YYEMPTY))
00018 #define yyerrok (yyerrflag=0)
00019 #define YYRECOVERING() (yyerrflag!=0)
00020 static int yygrowstack();
00021 #define YYPREFIX "yy"
00022 #line 2 "./getdate.y"
00023 /*
00024 **  Originally written by Steven M. Bellovin <smb@research.att.com> while
00025 **  at the University of North Carolina at Chapel Hill.  Later tweaked by
00026 **  a couple of people on Usenet.  Completely overhauled by Rich $alz
00027 **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
00028 **
00029 **  This grammar has 10 shift/reduce conflicts.
00030 **
00031 **  This code is in the public domain and has no copyright.
00032 */
00033 /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
00034 /* SUPPRESS 288 on yyerrlab *//* Label unused */
00035 
00036 #ifdef HAVE_CONFIG_H
00037 #if defined (emacs) || defined (CONFIG_BROKETS)
00038 #include <config.h>
00039 #else
00040 #include "config.h"
00041 #endif
00042 #endif
00043 
00044 /* Since the code of getdate.y is not included in the Emacs executable
00045    itself, there is no need to #define static in this file.  Even if
00046    the code were included in the Emacs executable, it probably
00047    wouldn't do any harm to #undef it here; this will only cause
00048    problems if we try to write to a static variable, which I don't
00049    think this code needs to do.  */
00050 #ifdef emacs
00051 #undef static
00052 #endif
00053 
00054 #include <stdio.h>
00055 #include <ctype.h>
00056 
00057 /* The code at the top of get_date which figures out the offset of the
00058    current time zone checks various CPP symbols to see if special
00059    tricks are need, but defaults to using the gettimeofday system call.
00060    Include <sys/time.h> if that will be used.  */
00061 
00062 #if     defined(vms)
00063 
00064 #include <types.h>
00065 #include <time.h>
00066 
00067 #else
00068 
00069 #include <sys/types.h>
00070 
00071 #ifdef TIME_WITH_SYS_TIME
00072 #include <sys/time.h>
00073 #include <time.h>
00074 #else
00075 #ifdef HAVE_SYS_TIME_H
00076 #include <sys/time.h>
00077 #else
00078 #include <time.h>
00079 #endif
00080 #endif
00081 
00082 #ifdef timezone
00083 #undef timezone /* needed for sgi */
00084 #endif
00085 
00086 #if defined(HAVE_SYS_TIMEB_H)
00087 #include <sys/timeb.h>
00088 #else
00089 /*
00090 ** We use the obsolete `struct timeb' as part of our interface!
00091 ** Since the system doesn't have it, we define it here;
00092 ** our callers must do likewise.
00093 */
00094 struct timeb {
00095     time_t              time;           /* Seconds since the epoch      */
00096 /*@unused@*/ unsigned short millitm;    /* Field not used               */
00097     short               timezone;       /* Minutes west of GMT          */
00098 /*@unused@*/ short      dstflag;        /* Field not used               */
00099 };
00100 #endif /* defined(HAVE_SYS_TIMEB_H) */
00101 
00102 #endif  /* defined(vms) */
00103 
00104 #if defined (STDC_HEADERS) || defined (USG)
00105 #include <string.h>
00106 #endif
00107 
00108 /* Some old versions of bison generate parsers that use bcopy.
00109    That loses on systems that don't provide the function, so we have
00110    to redefine it here.  */
00111 #if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
00112 #define bcopy(from, to, len) memcpy ((to), (from), (len))
00113 #endif
00114 
00115 #if defined (STDC_HEADERS)
00116 #include <stdlib.h>
00117 #endif
00118 
00119 /* NOTES on rebuilding getdate.c (particularly for inclusion in CVS
00120    releases):
00121 
00122    We don't want to mess with all the portability hassles of alloca.
00123    In particular, most (all?) versions of bison will use alloca in
00124    their parser.  If bison works on your system (e.g. it should work
00125    with gcc), then go ahead and use it, but the more general solution
00126    is to use byacc instead of bison, which should generate a portable
00127    parser.  I played with adding "#define alloca dont_use_alloca", to
00128    give an error if the parser generator uses alloca (and thus detect
00129    unportable getdate.c's), but that seems to cause as many problems
00130    as it solves.  */
00131 
00132 #if 0
00133 extern struct tm        *gmtime();
00134 extern struct tm        *localtime();
00135 #endif
00136 
00137 /*@-exportheader@*/
00138 extern time_t get_date(char * p, struct timeb * now);
00139 /*@=exportheader@*/
00140 
00141 #define yyparse getdate_yyparse
00142 #define yylex getdate_yylex
00143 #define yyerror getdate_yyerror
00144 
00145 static int yyparse (void);
00146 static int yylex (void);
00147 static int yyerror(const char * s);
00148 
00149 #define EPOCH           1970
00150 #define HOUR(x)         ((time_t)(x) * 60)
00151 #define SECSPERDAY      (24L * 60L * 60L)
00152 
00153 
00154 /*
00155 **  An entry in the lexical lookup table.
00156 */
00157 typedef struct _TABLE {
00158     char        *name;
00159     int         type;
00160     time_t      value;
00161 } TABLE;
00162 
00163 
00164 /*
00165 **  Daylight-savings mode:  on, off, or not yet known.
00166 */
00167 typedef enum _DSTMODE {
00168     DSTon, DSToff, DSTmaybe
00169 } DSTMODE;
00170 
00171 /*
00172 **  Meridian:  am, pm, or 24-hour style.
00173 */
00174 typedef enum _MERIDIAN {
00175     MERam, MERpm, MER24
00176 } MERIDIAN;
00177 
00178 
00179 /*
00180 **  Global variables.  We could get rid of most of these by using a good
00181 **  union as the yacc stack.  (This routine was originally written before
00182 **  yacc had the %union construct.)  Maybe someday; right now we only use
00183 **  the %union very rarely.
00184 */
00185 static char     *yyInput;
00186 static DSTMODE  yyDSTmode;
00187 static time_t   yyDayOrdinal;
00188 static time_t   yyDayNumber;
00189 static int      yyHaveDate;
00190 static int      yyHaveDay;
00191 static int      yyHaveRel;
00192 static int      yyHaveTime;
00193 static int      yyHaveZone;
00194 static time_t   yyTimezone;
00195 static time_t   yyDay;
00196 static time_t   yyHour;
00197 static time_t   yyMinutes;
00198 static time_t   yyMonth;
00199 static time_t   yySeconds;
00200 static time_t   yyYear;
00201 static MERIDIAN yyMeridian;
00202 static time_t   yyRelMonth;
00203 static time_t   yyRelSeconds;
00204 
00205 #line 186 "./getdate.y"
00206 typedef union {
00207     time_t              Number;
00208     enum _MERIDIAN      Meridian;
00209 } YYSTYPE;
00210 #line 205 "getdate.c"
00211 #define YYERRCODE 256
00212 #define tAGO 257
00213 #define tDAY 258
00214 #define tDAYZONE 259
00215 #define tID 260
00216 #define tMERIDIAN 261
00217 #define tMINUTE_UNIT 262
00218 #define tMONTH 263
00219 #define tMONTH_UNIT 264
00220 #define tSEC_UNIT 265
00221 #define tSNUMBER 266
00222 #define tUNUMBER 267
00223 #define tZONE 268
00224 #define tDST 269
00225 static const short yylhs[] = {                                        -1,
00226     0,    0,    2,    2,    2,    2,    2,    2,    3,    3,
00227     3,    3,    3,    4,    4,    4,    6,    6,    6,    5,
00228     5,    5,    5,    5,    5,    5,    5,    7,    7,    9,
00229     9,    9,    9,    9,    9,    9,    9,    9,    8,    1,
00230     1,
00231 };
00232 static const short yylen[] = {                                         2,
00233     0,    2,    1,    1,    1,    1,    1,    1,    2,    4,
00234     4,    6,    6,    1,    1,    2,    1,    2,    2,    3,
00235     5,    3,    3,    2,    4,    2,    3,    2,    1,    2,
00236     2,    1,    2,    2,    1,    2,    2,    1,    1,    0,
00237     1,
00238 };
00239 static const short yydefred[] = {                                      1,
00240     0,    0,   15,   32,    0,   38,   35,    0,    0,    0,
00241     2,    3,    4,    5,    6,    7,    8,    0,   18,    0,
00242    31,   36,   33,   19,    9,   30,    0,   37,   34,    0,
00243     0,    0,   16,   28,    0,   23,   27,   22,    0,    0,
00244    25,   41,   11,    0,   10,    0,    0,   21,   13,   12,
00245 };
00246 static const short yydgoto[] = {                                       1,
00247    45,   11,   12,   13,   14,   15,   16,   17,   18,
00248 };
00249 static const short yysindex[] = {                                      0,
00250  -249,  -38,    0,    0, -260,    0,    0, -240,  -47, -248,
00251     0,    0,    0,    0,    0,    0,    0, -237,    0,  -18,
00252     0,    0,    0,    0,    0,    0, -262,    0,    0, -239,
00253  -238, -236,    0,    0, -235,    0,    0,    0,  -56,  -19,
00254     0,    0,    0, -234,    0, -232, -258,    0,    0,    0,
00255 };
00256 static const short yyrindex[] = {                                      0,
00257     0,    1,    0,    0,    0,    0,    0,    0,   69,   12,
00258     0,    0,    0,    0,    0,    0,    0,   23,    0,   34,
00259     0,    0,    0,    0,    0,    0,   67,    0,    0,    0,
00260     0,    0,    0,    0,    0,    0,    0,    0,   56,   45,
00261     0,    0,    0,    0,    0,    0,   56,    0,    0,    0,
00262 };
00263 static const short yygindex[] = {                                      0,
00264   -17,    0,    0,    0,    0,    0,    0,    0,    0,
00265 };
00266 #define YYTABLESIZE 337
00267 static const short yytable[] = {                                      32,
00268    17,   44,   42,   36,   37,   19,   20,   49,    2,    3,
00269    31,   14,    4,    5,    6,    7,    8,    9,   10,   34,
00270    33,   21,   29,   22,   23,   35,   38,   46,   39,   50,
00271    40,   41,   47,   24,   48,    0,    0,    0,    0,    0,
00272     0,    0,    0,    0,   20,    0,    0,    0,    0,    0,
00273     0,    0,    0,    0,    0,   40,    0,    0,    0,    0,
00274     0,    0,    0,    0,    0,    0,   26,    0,   39,    0,
00275     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00276     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00277     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00278     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00279     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00280     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00281     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00282     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00283     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00284     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00285     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00286     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00287     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00288     0,    0,    0,    0,   42,    0,    0,    0,    0,   43,
00289    24,    0,    0,   25,   26,   27,   28,   29,   30,    0,
00290     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00291     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00292     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
00293     0,    0,    0,    0,    0,    0,    0,    0,   17,   17,
00294     0,    0,   17,   17,   17,   17,   17,   17,   17,   14,
00295    14,    0,    0,   14,   14,   14,   14,   14,   14,   14,
00296    29,   29,    0,    0,   29,   29,   29,   29,   29,   29,
00297    29,   24,   24,    0,    0,   24,   24,   24,   24,   24,
00298    24,   24,   20,   20,    0,    0,   20,   20,   20,   20,
00299    20,   20,   20,   40,   40,    0,    0,   40,   40,   40,
00300    40,    0,   40,   40,   26,   26,    0,   39,   26,   26,
00301    26,   26,    0,    0,   26,   39,   39,
00302 };
00303 static const short yycheck[] = {                                      47,
00304     0,   58,  261,  266,  267,   44,  267,  266,  258,  259,
00305    58,    0,  262,  263,  264,  265,  266,  267,  268,  257,
00306   269,  262,    0,  264,  265,   44,  266,   47,  267,   47,
00307   267,  267,  267,    0,  267,   -1,   -1,   -1,   -1,   -1,
00308    -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,
00309    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
00310    -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,    0,   -1,
00311    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00312    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00313    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00314    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00315    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00316    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00317    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00318    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00319    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00320    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00321    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00322    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00323    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00324    -1,   -1,   -1,   -1,  261,   -1,   -1,   -1,   -1,  266,
00325   258,   -1,   -1,  261,  262,  263,  264,  265,  266,   -1,
00326    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00327    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00328    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
00329    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,  259,
00330    -1,   -1,  262,  263,  264,  265,  266,  267,  268,  258,
00331   259,   -1,   -1,  262,  263,  264,  265,  266,  267,  268,
00332   258,  259,   -1,   -1,  262,  263,  264,  265,  266,  267,
00333   268,  258,  259,   -1,   -1,  262,  263,  264,  265,  266,
00334   267,  268,  258,  259,   -1,   -1,  262,  263,  264,  265,
00335   266,  267,  268,  258,  259,   -1,   -1,  262,  263,  264,
00336   265,   -1,  267,  268,  258,  259,   -1,  259,  262,  263,
00337   264,  265,   -1,   -1,  268,  267,  268,
00338 };
00339 #define YYFINAL 1
00340 #ifndef YYDEBUG
00341 #define YYDEBUG 0
00342 #endif
00343 #define YYMAXTOKEN 269
00344 #if YYDEBUG
00345 const char * const yyname[] = {
00346 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00347 0,0,0,0,0,0,0,0,0,0,"','",0,0,"'/'",0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,0,0,0,0,
00348 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00349 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00350 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00351 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00352 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"tAGO","tDAY",
00353 "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
00354 "tSNUMBER","tUNUMBER","tZONE","tDST",
00355 };
00356 const char * const yyrule[] = {
00357 "$accept : spec",
00358 "spec :",
00359 "spec : spec item",
00360 "item : time",
00361 "item : zone",
00362 "item : date",
00363 "item : day",
00364 "item : rel",
00365 "item : number",
00366 "time : tUNUMBER tMERIDIAN",
00367 "time : tUNUMBER ':' tUNUMBER o_merid",
00368 "time : tUNUMBER ':' tUNUMBER tSNUMBER",
00369 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
00370 "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
00371 "zone : tZONE",
00372 "zone : tDAYZONE",
00373 "zone : tZONE tDST",
00374 "day : tDAY",
00375 "day : tDAY ','",
00376 "day : tUNUMBER tDAY",
00377 "date : tUNUMBER '/' tUNUMBER",
00378 "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
00379 "date : tUNUMBER tSNUMBER tSNUMBER",
00380 "date : tUNUMBER tMONTH tSNUMBER",
00381 "date : tMONTH tUNUMBER",
00382 "date : tMONTH tUNUMBER ',' tUNUMBER",
00383 "date : tUNUMBER tMONTH",
00384 "date : tUNUMBER tMONTH tUNUMBER",
00385 "rel : relunit tAGO",
00386 "rel : relunit",
00387 "relunit : tUNUMBER tMINUTE_UNIT",
00388 "relunit : tSNUMBER tMINUTE_UNIT",
00389 "relunit : tMINUTE_UNIT",
00390 "relunit : tSNUMBER tSEC_UNIT",
00391 "relunit : tUNUMBER tSEC_UNIT",
00392 "relunit : tSEC_UNIT",
00393 "relunit : tSNUMBER tMONTH_UNIT",
00394 "relunit : tUNUMBER tMONTH_UNIT",
00395 "relunit : tMONTH_UNIT",
00396 "number : tUNUMBER",
00397 "o_merid :",
00398 "o_merid : tMERIDIAN",
00399 };
00400 #endif
00401 #if YYDEBUG
00402 #include <stdio.h>
00403 #endif
00404 #ifdef YYSTACKSIZE
00405 #undef YYMAXDEPTH
00406 #define YYMAXDEPTH YYSTACKSIZE
00407 #else
00408 #ifdef YYMAXDEPTH
00409 #define YYSTACKSIZE YYMAXDEPTH
00410 #else
00411 #define YYSTACKSIZE 10000
00412 #define YYMAXDEPTH 10000
00413 #endif
00414 #endif
00415 #define YYINITSTACKSIZE 200
00416 /*@unused@*/ static int yydebug;
00417 static int yynerrs;
00418 static int yyerrflag;
00419 static int yychar;
00420 static short *yyssp;
00421 static YYSTYPE *yyvsp;
00422 static YYSTYPE yyval;
00423 static YYSTYPE yylval;
00424 static short *yyss;
00425 static short *yysslim;
00426 static YYSTYPE *yyvs;
00427 static int yystacksize;
00428 #line 405 "./getdate.y"
00429 
00430 /* Month and day table. */
00431 static TABLE const MonthDayTable[] = {
00432     { "january",        tMONTH,  1 },
00433     { "february",       tMONTH,  2 },
00434     { "march",          tMONTH,  3 },
00435     { "april",          tMONTH,  4 },
00436     { "may",            tMONTH,  5 },
00437     { "june",           tMONTH,  6 },
00438     { "july",           tMONTH,  7 },
00439     { "august",         tMONTH,  8 },
00440     { "september",      tMONTH,  9 },
00441     { "sept",           tMONTH,  9 },
00442     { "october",        tMONTH, 10 },
00443     { "november",       tMONTH, 11 },
00444     { "december",       tMONTH, 12 },
00445     { "sunday",         tDAY, 0 },
00446     { "monday",         tDAY, 1 },
00447     { "tuesday",        tDAY, 2 },
00448     { "tues",           tDAY, 2 },
00449     { "wednesday",      tDAY, 3 },
00450     { "wednes",         tDAY, 3 },
00451     { "thursday",       tDAY, 4 },
00452     { "thur",           tDAY, 4 },
00453     { "thurs",          tDAY, 4 },
00454     { "friday",         tDAY, 5 },
00455     { "saturday",       tDAY, 6 },
00456     { NULL, 0, 0 }
00457 };
00458 
00459 /* Time units table. */
00460 static TABLE const UnitsTable[] = {
00461     { "year",           tMONTH_UNIT,    12 },
00462     { "month",          tMONTH_UNIT,    1 },
00463     { "fortnight",      tMINUTE_UNIT,   14 * 24 * 60 },
00464     { "week",           tMINUTE_UNIT,   7 * 24 * 60 },
00465     { "day",            tMINUTE_UNIT,   1 * 24 * 60 },
00466     { "hour",           tMINUTE_UNIT,   60 },
00467     { "minute",         tMINUTE_UNIT,   1 },
00468     { "min",            tMINUTE_UNIT,   1 },
00469     { "second",         tSEC_UNIT,      1 },
00470     { "sec",            tSEC_UNIT,      1 },
00471     { NULL, 0, 0 }
00472 };
00473 
00474 /* Assorted relative-time words. */
00475 static TABLE const OtherTable[] = {
00476     { "tomorrow",       tMINUTE_UNIT,   1 * 24 * 60 },
00477     { "yesterday",      tMINUTE_UNIT,   -1 * 24 * 60 },
00478     { "today",          tMINUTE_UNIT,   0 },
00479     { "now",            tMINUTE_UNIT,   0 },
00480     { "last",           tUNUMBER,       -1 },
00481     { "this",           tMINUTE_UNIT,   0 },
00482     { "next",           tUNUMBER,       2 },
00483     { "first",          tUNUMBER,       1 },
00484 /*  { "second",         tUNUMBER,       2 }, */
00485     { "third",          tUNUMBER,       3 },
00486     { "fourth",         tUNUMBER,       4 },
00487     { "fifth",          tUNUMBER,       5 },
00488     { "sixth",          tUNUMBER,       6 },
00489     { "seventh",        tUNUMBER,       7 },
00490     { "eighth",         tUNUMBER,       8 },
00491     { "ninth",          tUNUMBER,       9 },
00492     { "tenth",          tUNUMBER,       10 },
00493     { "eleventh",       tUNUMBER,       11 },
00494     { "twelfth",        tUNUMBER,       12 },
00495     { "ago",            tAGO,   1 },
00496     { NULL, 0, 0 }
00497 };
00498 
00499 /* The timezone table. */
00500 /* Some of these are commented out because a time_t can't store a float. */
00501 static TABLE const TimezoneTable[] = {
00502     { "gmt",    tZONE,     HOUR( 0) },  /* Greenwich Mean */
00503     { "ut",     tZONE,     HOUR( 0) },  /* Universal (Coordinated) */
00504     { "utc",    tZONE,     HOUR( 0) },
00505     { "wet",    tZONE,     HOUR( 0) },  /* Western European */
00506     { "bst",    tDAYZONE,  HOUR( 0) },  /* British Summer */
00507     { "wat",    tZONE,     HOUR( 1) },  /* West Africa */
00508     { "at",     tZONE,     HOUR( 2) },  /* Azores */
00509 #if     0
00510     /* For completeness.  BST is also British Summer, and GST is
00511      * also Guam Standard. */
00512     { "bst",    tZONE,     HOUR( 3) },  /* Brazil Standard */
00513     { "gst",    tZONE,     HOUR( 3) },  /* Greenland Standard */
00514 #endif
00515 #if 0
00516     { "nft",    tZONE,     HOUR(3.5) }, /* Newfoundland */
00517     { "nst",    tZONE,     HOUR(3.5) }, /* Newfoundland Standard */
00518     { "ndt",    tDAYZONE,  HOUR(3.5) }, /* Newfoundland Daylight */
00519 #endif
00520     { "ast",    tZONE,     HOUR( 4) },  /* Atlantic Standard */
00521     { "adt",    tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
00522     { "est",    tZONE,     HOUR( 5) },  /* Eastern Standard */
00523     { "edt",    tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
00524     { "cst",    tZONE,     HOUR( 6) },  /* Central Standard */
00525     { "cdt",    tDAYZONE,  HOUR( 6) },  /* Central Daylight */
00526     { "mst",    tZONE,     HOUR( 7) },  /* Mountain Standard */
00527     { "mdt",    tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
00528     { "pst",    tZONE,     HOUR( 8) },  /* Pacific Standard */
00529     { "pdt",    tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
00530     { "yst",    tZONE,     HOUR( 9) },  /* Yukon Standard */
00531     { "ydt",    tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
00532     { "hst",    tZONE,     HOUR(10) },  /* Hawaii Standard */
00533     { "hdt",    tDAYZONE,  HOUR(10) },  /* Hawaii Daylight */
00534     { "cat",    tZONE,     HOUR(10) },  /* Central Alaska */
00535     { "ahst",   tZONE,     HOUR(10) },  /* Alaska-Hawaii Standard */
00536     { "nt",     tZONE,     HOUR(11) },  /* Nome */
00537     { "idlw",   tZONE,     HOUR(12) },  /* International Date Line West */
00538     { "cet",    tZONE,     -HOUR(1) },  /* Central European */
00539     { "met",    tZONE,     -HOUR(1) },  /* Middle European */
00540     { "mewt",   tZONE,     -HOUR(1) },  /* Middle European Winter */
00541     { "mest",   tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
00542     { "swt",    tZONE,     -HOUR(1) },  /* Swedish Winter */
00543     { "sst",    tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
00544     { "fwt",    tZONE,     -HOUR(1) },  /* French Winter */
00545     { "fst",    tDAYZONE,  -HOUR(1) },  /* French Summer */
00546     { "eet",    tZONE,     -HOUR(2) },  /* Eastern Europe, USSR Zone 1 */
00547     { "bt",     tZONE,     -HOUR(3) },  /* Baghdad, USSR Zone 2 */
00548 #if 0
00549     { "it",     tZONE,     -HOUR(3.5) },/* Iran */
00550 #endif
00551     { "zp4",    tZONE,     -HOUR(4) },  /* USSR Zone 3 */
00552     { "zp5",    tZONE,     -HOUR(5) },  /* USSR Zone 4 */
00553 #if 0
00554     { "ist",    tZONE,     -HOUR(5.5) },/* Indian Standard */
00555 #endif
00556     { "zp6",    tZONE,     -HOUR(6) },  /* USSR Zone 5 */
00557 #if     0
00558     /* For completeness.  NST is also Newfoundland Stanard, and SST is
00559      * also Swedish Summer. */
00560     { "nst",    tZONE,     -HOUR(6.5) },/* North Sumatra */
00561     { "sst",    tZONE,     -HOUR(7) },  /* South Sumatra, USSR Zone 6 */
00562 #endif  /* 0 */
00563     { "wast",   tZONE,     -HOUR(7) },  /* West Australian Standard */
00564     { "wadt",   tDAYZONE,  -HOUR(7) },  /* West Australian Daylight */
00565 #if 0
00566     { "jt",     tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
00567 #endif
00568     { "cct",    tZONE,     -HOUR(8) },  /* China Coast, USSR Zone 7 */
00569     { "jst",    tZONE,     -HOUR(9) },  /* Japan Standard, USSR Zone 8 */
00570 #if 0
00571     { "cast",   tZONE,     -HOUR(9.5) },/* Central Australian Standard */
00572     { "cadt",   tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
00573 #endif
00574     { "east",   tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
00575     { "eadt",   tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
00576     { "gst",    tZONE,     -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
00577     { "nzt",    tZONE,     -HOUR(12) }, /* New Zealand */
00578     { "nzst",   tZONE,     -HOUR(12) }, /* New Zealand Standard */
00579     { "nzdt",   tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
00580     { "idle",   tZONE,     -HOUR(12) }, /* International Date Line East */
00581     {  NULL, 0, 0  }
00582 };
00583 
00584 /* Military timezone table. */
00585 static TABLE const MilitaryTable[] = {
00586     { "a",      tZONE,  HOUR(  1) },
00587     { "b",      tZONE,  HOUR(  2) },
00588     { "c",      tZONE,  HOUR(  3) },
00589     { "d",      tZONE,  HOUR(  4) },
00590     { "e",      tZONE,  HOUR(  5) },
00591     { "f",      tZONE,  HOUR(  6) },
00592     { "g",      tZONE,  HOUR(  7) },
00593     { "h",      tZONE,  HOUR(  8) },
00594     { "i",      tZONE,  HOUR(  9) },
00595     { "k",      tZONE,  HOUR( 10) },
00596     { "l",      tZONE,  HOUR( 11) },
00597     { "m",      tZONE,  HOUR( 12) },
00598     { "n",      tZONE,  HOUR(- 1) },
00599     { "o",      tZONE,  HOUR(- 2) },
00600     { "p",      tZONE,  HOUR(- 3) },
00601     { "q",      tZONE,  HOUR(- 4) },
00602     { "r",      tZONE,  HOUR(- 5) },
00603     { "s",      tZONE,  HOUR(- 6) },
00604     { "t",      tZONE,  HOUR(- 7) },
00605     { "u",      tZONE,  HOUR(- 8) },
00606     { "v",      tZONE,  HOUR(- 9) },
00607     { "w",      tZONE,  HOUR(-10) },
00608     { "x",      tZONE,  HOUR(-11) },
00609     { "y",      tZONE,  HOUR(-12) },
00610     { "z",      tZONE,  HOUR(  0) },
00611     { NULL, 0, 0 }
00612 };
00613 
00614 
00615 
00616 
00617 /* ARGSUSED */
00618 static int
00619 yyerror(/*@unused@*/ const char * s)
00620 {
00621   return 0;
00622 }
00623 
00624 
00625 static time_t
00626 ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
00627 {
00628     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
00629         return -1;
00630     switch (Meridian) {
00631     case MER24:
00632         if (Hours < 0 || Hours > 23)
00633             return -1;
00634         return (Hours * 60L + Minutes) * 60L + Seconds;
00635     case MERam:
00636         if (Hours < 1 || Hours > 12)
00637             return -1;
00638         if (Hours == 12)
00639             Hours = 0;
00640         return (Hours * 60L + Minutes) * 60L + Seconds;
00641     case MERpm:
00642         if (Hours < 1 || Hours > 12)
00643             return -1;
00644         if (Hours == 12)
00645             Hours = 0;
00646         return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
00647     default:
00648         abort ();
00649     }
00650     /* NOTREACHED */
00651 }
00652 
00653 
00654 /* Year is either
00655    * A negative number, which means to use its absolute value (why?)
00656    * A number from 0 to 99, which means a year from 1900 to 1999, or
00657    * The actual year (>=100).  */
00658 static time_t
00659 Convert(time_t Month, time_t Day, time_t Year,
00660         time_t Hours, time_t Minutes, time_t Seconds,
00661         MERIDIAN Meridian, DSTMODE DSTmode)
00662 {
00663     static int DaysInMonth[12] = {
00664         31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
00665     };
00666     time_t      tod;
00667     time_t      Julian;
00668     int         i;
00669 
00670     if (Year < 0)
00671         Year = -Year;
00672     if (Year < 69)
00673         Year += 2000;
00674     else if (Year < 100)
00675         Year += 1900;
00676     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
00677                     ? 29 : 28;
00678     /* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
00679        I'm too lazy to try to check for time_t overflow in another way.  */
00680     if (Year < EPOCH || Year > 2038
00681      || Month < 1 || Month > 12
00682      /* Lint fluff:  "conversion from long may lose accuracy" */
00683      || Day < 1 || Day > DaysInMonth[(int)--Month])
00684         return -1;
00685 
00686     for (Julian = Day - 1, i = 0; i < Month; i++)
00687         Julian += DaysInMonth[i];
00688     for (i = EPOCH; i < Year; i++)
00689         Julian += 365 + (i % 4 == 0);
00690     Julian *= SECSPERDAY;
00691     Julian += yyTimezone * 60L;
00692     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
00693         return -1;
00694     Julian += tod;
00695     if (DSTmode == DSTon
00696      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
00697         Julian -= 60 * 60;
00698     return Julian;
00699 }
00700 
00701 
00702 static time_t
00703 DSTcorrect(time_t Start, time_t Future)
00704 {
00705     time_t      StartDay;
00706     time_t      FutureDay;
00707 
00708     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
00709     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
00710     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
00711 }
00712 
00713 
00714 static time_t
00715 RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
00716 {
00717     struct tm   *tm;
00718     time_t      now;
00719 
00720     now = Start;
00721     tm = localtime(&now);
00722     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
00723     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
00724     return DSTcorrect(Start, now);
00725 }
00726 
00727 
00728 static time_t
00729 RelativeMonth(time_t Start, time_t RelMonth)
00730 {
00731     struct tm   *tm;
00732     time_t      Month;
00733     time_t      Year;
00734 
00735     if (RelMonth == 0)
00736         return 0;
00737     tm = localtime(&Start);
00738     Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
00739     Year = Month / 12;
00740     Month = Month % 12 + 1;
00741     return DSTcorrect(Start,
00742             Convert(Month, (time_t)tm->tm_mday, Year,
00743                 (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
00744                 MER24, DSTmaybe));
00745 }
00746 
00747 
00748 static int
00749 LookupWord(char * buff)
00750 {
00751     register char       *p;
00752     register char       *q;
00753     register const TABLE        *tp;
00754     int                 i;
00755     int                 abbrev;
00756 
00757     /* Make it lowercase. */
00758     for (p = buff; *p != '\0'; p++)
00759         if (isupper(*p))
00760             *p = tolower(*p);
00761 
00762     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
00763         yylval.Meridian = MERam;
00764         return tMERIDIAN;
00765     }
00766     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
00767         yylval.Meridian = MERpm;
00768         return tMERIDIAN;
00769     }
00770 
00771     /* See if we have an abbreviation for a month. */
00772     if (strlen(buff) == 3)
00773         abbrev = 1;
00774     else if (strlen(buff) == 4 && buff[3] == '.') {
00775         abbrev = 1;
00776         buff[3] = '\0';
00777     }
00778     else
00779         abbrev = 0;
00780 
00781     for (tp = MonthDayTable; tp->name; tp++) {
00782         if (abbrev) {
00783             if (strncmp(buff, tp->name, 3) == 0) {
00784                 yylval.Number = tp->value;
00785                 return tp->type;
00786             }
00787         }
00788         else if (strcmp(buff, tp->name) == 0) {
00789             yylval.Number = tp->value;
00790             return tp->type;
00791         }
00792     }
00793 
00794     for (tp = TimezoneTable; tp->name; tp++)
00795         if (strcmp(buff, tp->name) == 0) {
00796             yylval.Number = tp->value;
00797             return tp->type;
00798         }
00799 
00800     if (strcmp(buff, "dst") == 0) 
00801         return tDST;
00802 
00803     for (tp = UnitsTable; tp->name; tp++)
00804         if (strcmp(buff, tp->name) == 0) {
00805             yylval.Number = tp->value;
00806             return tp->type;
00807         }
00808 
00809     /* Strip off any plural and try the units table again. */
00810     i = strlen(buff) - 1;
00811     if (buff[i] == 's') {
00812         buff[i] = '\0';
00813         for (tp = UnitsTable; tp->name; tp++)
00814             if (strcmp(buff, tp->name) == 0) {
00815                 yylval.Number = tp->value;
00816                 return tp->type;
00817             }
00818         buff[i] = 's';          /* Put back for "this" in OtherTable. */
00819     }
00820 
00821     for (tp = OtherTable; tp->name; tp++)
00822         if (strcmp(buff, tp->name) == 0) {
00823             yylval.Number = tp->value;
00824             return tp->type;
00825         }
00826 
00827     /* Military timezones. */
00828     if (buff[1] == '\0' && isalpha(*buff)) {
00829         for (tp = MilitaryTable; tp->name; tp++)
00830             if (strcmp(buff, tp->name) == 0) {
00831                 yylval.Number = tp->value;
00832                 return tp->type;
00833             }
00834     }
00835 
00836     /* Drop out any periods and try the timezone table again. */
00837     for (i = 0, p = q = buff; *q != '\0'; q++)
00838         if (*q != '.')
00839             *p++ = *q;
00840         else
00841             i++;
00842     *p = '\0';
00843     if (i)
00844         for (tp = TimezoneTable; tp->name; tp++)
00845             if (strcmp(buff, tp->name) == 0) {
00846                 yylval.Number = tp->value;
00847                 return tp->type;
00848             }
00849 
00850     return tID;
00851 }
00852 
00853 
00854 static int
00855 yylex(void)
00856 {
00857     register char       c;
00858     register char       *p;
00859     char                buff[20];
00860     int                 Count;
00861     int                 sign;
00862 
00863     for ( ; ; ) {
00864         while (isspace(*yyInput))
00865             yyInput++;
00866 
00867         if (isdigit(c = *yyInput) || c == '-' || c == '+') {
00868             if (c == '-' || c == '+') {
00869                 sign = c == '-' ? -1 : 1;
00870                 if (!isdigit(*++yyInput))
00871                     /* skip the '-' sign */
00872                     continue;
00873             }
00874             else
00875                 sign = 0;
00876             for (yylval.Number = 0; isdigit(c = *yyInput++); )
00877                 yylval.Number = 10 * yylval.Number + c - '0';
00878             yyInput--;
00879             if (sign < 0)
00880                 yylval.Number = -yylval.Number;
00881             return sign ? tSNUMBER : tUNUMBER;
00882         }
00883         if (isalpha(c)) {
00884             for (p = buff; isalpha(c = *yyInput++) || c == '.'; )
00885                 if (p < &buff[sizeof buff - 1])
00886                     *p++ = c;
00887             *p = '\0';
00888             yyInput--;
00889             return LookupWord(buff);
00890         }
00891         if (c != '(')
00892             return *yyInput++;
00893         Count = 0;
00894         do {
00895             c = *yyInput++;
00896             if (c == '\0')
00897                 return c;
00898             if (c == '(')
00899                 Count++;
00900             else if (c == ')')
00901                 Count--;
00902         } while (Count > 0);
00903     }
00904     /*@notreached@*/
00905     return 0;
00906 }
00907 
00908 #define TM_YEAR_ORIGIN 1900
00909 
00910 /* Yield A - B, measured in seconds.  */
00911 static long
00912 difftm (const struct tm * a, const struct tm * b)
00913 {
00914   unsigned ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
00915   unsigned by = b->tm_year + (TM_YEAR_ORIGIN - 1);
00916   int days = (
00917               /* difference in day of year */
00918               a->tm_yday - b->tm_yday
00919               /* + intervening leap days */
00920               +  ((ay >> 2) - (by >> 2))
00921               -  (ay/100 - by/100)
00922               +  ((ay/100 >> 2) - (by/100 >> 2))
00923               /* + difference in years * 365 */
00924               +  (long)(ay-by) * 365
00925               );
00926   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
00927               + (a->tm_min - b->tm_min))
00928           + (a->tm_sec - b->tm_sec));
00929 }
00930 
00931 time_t
00932 get_date(char * p, struct timeb * now)
00933 {
00934     struct tm           *tm, gmt;
00935     struct timeb        ftz;
00936     time_t              Start;
00937     time_t              tod;
00938     time_t nowtime;
00939 
00940     yyInput = p;
00941     memset(&gmt, 0, sizeof(gmt));
00942     if (now == NULL) {
00943         struct tm *gmt_ptr;
00944 
00945         now = &ftz;
00946         (void)time (&nowtime);
00947 
00948         gmt_ptr = gmtime (&nowtime);
00949         if (gmt_ptr != NULL)
00950         {
00951             /* Make a copy, in case localtime modifies *tm (I think
00952                that comment now applies to *gmt_ptr, but I am too
00953                lazy to dig into how gmtime and locatime allocate the
00954                structures they return pointers to).  */
00955             gmt = *gmt_ptr;
00956         }
00957 
00958         if (! (tm = localtime (&nowtime)))
00959             return -1;
00960 
00961         if (gmt_ptr != NULL)
00962             /*@-observertrans -dependenttrans@*/
00963             ftz.timezone = difftm (&gmt, tm) / 60;
00964             /*@=observertrans =dependenttrans@*/
00965         else
00966             /* We are on a system like VMS, where the system clock is
00967                in local time and the system has no concept of timezones.
00968                Hopefully we can fake this out (for the case in which the
00969                user specifies no timezone) by just saying the timezone
00970                is zero.  */
00971             ftz.timezone = 0;
00972 
00973         if(tm->tm_isdst)
00974             ftz.timezone += 60;
00975     }
00976     else
00977     {
00978         nowtime = now->time;
00979     }
00980 
00981     tm = localtime(&nowtime);
00982     yyYear = tm->tm_year + 1900;
00983     yyMonth = tm->tm_mon + 1;
00984     yyDay = tm->tm_mday;
00985     yyTimezone = now->timezone;
00986     yyDSTmode = DSTmaybe;
00987     yyHour = 0;
00988     yyMinutes = 0;
00989     yySeconds = 0;
00990     yyMeridian = MER24;
00991     yyRelSeconds = 0;
00992     yyRelMonth = 0;
00993     yyHaveDate = 0;
00994     yyHaveDay = 0;
00995     yyHaveRel = 0;
00996     yyHaveTime = 0;
00997     yyHaveZone = 0;
00998 
00999     /*@-unrecog@*/
01000     if (yyparse()
01001      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
01002         return -1;
01003     /*@=unrecog@*/
01004 
01005     if (yyHaveDate || yyHaveTime || yyHaveDay) {
01006         Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
01007                     yyMeridian, yyDSTmode);
01008         if (Start < 0)
01009             return -1;
01010     }
01011     else {
01012         Start = nowtime;
01013         if (!yyHaveRel)
01014             Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
01015     }
01016 
01017     Start += yyRelSeconds;
01018     Start += RelativeMonth(Start, yyRelMonth);
01019 
01020     if (yyHaveDay && !yyHaveDate) {
01021         tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
01022         Start += tod;
01023     }
01024 
01025     /* Have to do *something* with a legitimate -1 so it's distinguishable
01026      * from the error return value.  (Alternately could set errno on error.) */
01027     return Start == -1 ? 0 : Start;
01028 }
01029 
01030 
01031 #if     defined(TEST)
01032 
01033 /* ARGSUSED */
01034 int
01035 main(ac, av)
01036     int         ac;
01037     char        *av[];
01038 {
01039     char        buff[128];
01040     time_t      d;
01041 
01042     (void)printf("Enter date, or blank line to exit.\n\t> ");
01043     (void)fflush(stdout);
01044     while (gets(buff) && buff[0]) {
01045         d = get_date(buff, (struct timeb *)NULL);
01046         if (d == -1)
01047             (void)printf("Bad format - couldn't convert.\n");
01048         else
01049             (void)printf("%s", ctime(&d));
01050         (void)printf("\t> ");
01051         (void)fflush(stdout);
01052     }
01053     exit(0);
01054     /* NOTREACHED */
01055 }
01056 #endif  /* defined(TEST) */
01057 #line 1052 "getdate.c"
01058 /* allocate initial stack or double stack size, up to YYMAXDEPTH */
01059 static int yygrowstack()
01060 {
01061     int newsize, i;
01062     short *newss;
01063     YYSTYPE *newvs;
01064 
01065     if ((newsize = yystacksize) == 0)
01066         newsize = YYINITSTACKSIZE;
01067     else if (newsize >= YYMAXDEPTH)
01068         return -1;
01069     else if ((newsize *= 2) > YYMAXDEPTH)
01070         newsize = YYMAXDEPTH;
01071     i = yyssp - yyss;
01072     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
01073       (short *)malloc(newsize * sizeof *newss);
01074     if (newss == NULL)
01075         return -1;
01076     yyss = newss;
01077     yyssp = newss + i;
01078     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
01079       (YYSTYPE *)malloc(newsize * sizeof *newvs);
01080     if (newvs == NULL)
01081         return -1;
01082     yyvs = newvs;
01083     yyvsp = newvs + i;
01084     yystacksize = newsize;
01085     yysslim = yyss + newsize - 1;
01086     return 0;
01087 }
01088 
01089 #define YYABORT goto yyabort
01090 #define YYREJECT goto yyabort
01091 #define YYACCEPT goto yyaccept
01092 #define YYERROR goto yyerrlab
01093 
01094 #ifndef YYPARSE_PARAM
01095 #if defined(__cplusplus) || __STDC__
01096 #define YYPARSE_PARAM_ARG void
01097 #define YYPARSE_PARAM_DECL
01098 #else   /* ! ANSI-C/C++ */
01099 #define YYPARSE_PARAM_ARG
01100 #define YYPARSE_PARAM_DECL
01101 #endif  /* ANSI-C/C++ */
01102 #else   /* YYPARSE_PARAM */
01103 #ifndef YYPARSE_PARAM_TYPE
01104 #define YYPARSE_PARAM_TYPE void *
01105 #endif
01106 #if defined(__cplusplus) || __STDC__
01107 #define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM
01108 #define YYPARSE_PARAM_DECL
01109 #else   /* ! ANSI-C/C++ */
01110 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
01111 #define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM;
01112 #endif  /* ANSI-C/C++ */
01113 #endif  /* ! YYPARSE_PARAM */
01114 
01115 int
01116 yyparse (YYPARSE_PARAM_ARG)
01117     YYPARSE_PARAM_DECL
01118 {
01119     register int yym, yyn, yystate;
01120 #if YYDEBUG
01121     register const char *yys;
01122 
01123     if ((yys = getenv("YYDEBUG")))
01124     {
01125         yyn = *yys;
01126         if (yyn >= '0' && yyn <= '9')
01127             yydebug = yyn - '0';
01128     }
01129 #endif
01130 
01131     yynerrs = 0;
01132     yyerrflag = 0;
01133     yychar = (-1);
01134 
01135     if (yyss == NULL && yygrowstack()) goto yyoverflow;
01136     yyssp = yyss;
01137     yyvsp = yyvs;
01138     *yyssp = yystate = 0;
01139 
01140 yyloop:
01141     if ((yyn = yydefred[yystate])) goto yyreduce;
01142     if (yychar < 0)
01143     {
01144         if ((yychar = yylex()) < 0) yychar = 0;
01145 #if YYDEBUG
01146         if (yydebug)
01147         {
01148             yys = 0;
01149             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01150             if (!yys) yys = "illegal-symbol";
01151             printf("%sdebug: state %d, reading %d (%s)\n",
01152                     YYPREFIX, yystate, yychar, yys);
01153         }
01154 #endif
01155     }
01156     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
01157             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
01158     {
01159 #if YYDEBUG
01160         if (yydebug)
01161             printf("%sdebug: state %d, shifting to state %d\n",
01162                     YYPREFIX, yystate, yytable[yyn]);
01163 #endif
01164         if (yyssp >= yysslim && yygrowstack())
01165         {
01166             goto yyoverflow;
01167         }
01168         *++yyssp = yystate = yytable[yyn];
01169         *++yyvsp = yylval;
01170         yychar = (-1);
01171         if (yyerrflag > 0)  --yyerrflag;
01172         goto yyloop;
01173     }
01174     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
01175             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
01176     {
01177         yyn = yytable[yyn];
01178         goto yyreduce;
01179     }
01180     if (yyerrflag) goto yyinrecovery;
01181 #if defined(lint) || defined(__GNUC__)
01182     goto yynewerror;
01183 #endif
01184 yynewerror:
01185     yyerror("syntax error");
01186 #if defined(lint) || defined(__GNUC__)
01187     goto yyerrlab;
01188 #endif
01189 yyerrlab:
01190     ++yynerrs;
01191 yyinrecovery:
01192     if (yyerrflag < 3)
01193     {
01194         yyerrflag = 3;
01195         for (;;)
01196         {
01197             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
01198                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
01199             {
01200 #if YYDEBUG
01201                 if (yydebug)
01202                     printf("%sdebug: state %d, error recovery shifting\
01203  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
01204 #endif
01205                 if (yyssp >= yysslim && yygrowstack())
01206                 {
01207                     goto yyoverflow;
01208                 }
01209                 *++yyssp = yystate = yytable[yyn];
01210                 *++yyvsp = yylval;
01211                 goto yyloop;
01212             }
01213             else
01214             {
01215 #if YYDEBUG
01216                 if (yydebug)
01217                     printf("%sdebug: error recovery discarding state %d\n",
01218                             YYPREFIX, *yyssp);
01219 #endif
01220                 if (yyssp <= yyss) goto yyabort;
01221                 --yyssp;
01222                 --yyvsp;
01223             }
01224         }
01225     }
01226     else
01227     {
01228         if (yychar == 0) goto yyabort;
01229 #if YYDEBUG
01230         if (yydebug)
01231         {
01232             yys = 0;
01233             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01234             if (!yys) yys = "illegal-symbol";
01235             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
01236                     YYPREFIX, yystate, yychar, yys);
01237         }
01238 #endif
01239         yychar = (-1);
01240         goto yyloop;
01241     }
01242 yyreduce:
01243 #if YYDEBUG
01244     if (yydebug)
01245         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
01246                 YYPREFIX, yystate, yyn, yyrule[yyn]);
01247 #endif
01248     yym = yylen[yyn];
01249     yyval = yyvsp[1-yym];
01250     switch (yyn)
01251     {
01252 case 3:
01253 #line 204 "./getdate.y"
01254 {
01255             yyHaveTime++;
01256         }
01257 break;
01258 case 4:
01259 #line 207 "./getdate.y"
01260 {
01261             yyHaveZone++;
01262         }
01263 break;
01264 case 5:
01265 #line 210 "./getdate.y"
01266 {
01267             yyHaveDate++;
01268         }
01269 break;
01270 case 6:
01271 #line 213 "./getdate.y"
01272 {
01273             yyHaveDay++;
01274         }
01275 break;
01276 case 7:
01277 #line 216 "./getdate.y"
01278 {
01279             yyHaveRel++;
01280         }
01281 break;
01282 case 9:
01283 #line 222 "./getdate.y"
01284 {
01285             yyHour = yyvsp[-1].Number;
01286             yyMinutes = 0;
01287             yySeconds = 0;
01288             yyMeridian = yyvsp[0].Meridian;
01289         }
01290 break;
01291 case 10:
01292 #line 228 "./getdate.y"
01293 {
01294             yyHour = yyvsp[-3].Number;
01295             yyMinutes = yyvsp[-1].Number;
01296             yySeconds = 0;
01297             yyMeridian = yyvsp[0].Meridian;
01298         }
01299 break;
01300 case 11:
01301 #line 234 "./getdate.y"
01302 {
01303             yyHour = yyvsp[-3].Number;
01304             yyMinutes = yyvsp[-1].Number;
01305             yyMeridian = MER24;
01306             yyDSTmode = DSToff;
01307             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
01308         }
01309 break;
01310 case 12:
01311 #line 241 "./getdate.y"
01312 {
01313             yyHour = yyvsp[-5].Number;
01314             yyMinutes = yyvsp[-3].Number;
01315             yySeconds = yyvsp[-1].Number;
01316             yyMeridian = yyvsp[0].Meridian;
01317         }
01318 break;
01319 case 13:
01320 #line 247 "./getdate.y"
01321 {
01322             yyHour = yyvsp[-5].Number;
01323             yyMinutes = yyvsp[-3].Number;
01324             yySeconds = yyvsp[-1].Number;
01325             yyMeridian = MER24;
01326             yyDSTmode = DSToff;
01327             yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
01328         }
01329 break;
01330 case 14:
01331 #line 257 "./getdate.y"
01332 {
01333             yyTimezone = yyvsp[0].Number;
01334             yyDSTmode = DSToff;
01335         }
01336 break;
01337 case 15:
01338 #line 261 "./getdate.y"
01339 {
01340             yyTimezone = yyvsp[0].Number;
01341             yyDSTmode = DSTon;
01342         }
01343 break;
01344 case 16:
01345 #line 266 "./getdate.y"
01346 {
01347             yyTimezone = yyvsp[-1].Number;
01348             yyDSTmode = DSTon;
01349         }
01350 break;
01351 case 17:
01352 #line 272 "./getdate.y"
01353 {
01354             yyDayOrdinal = 1;
01355             yyDayNumber = yyvsp[0].Number;
01356         }
01357 break;
01358 case 18:
01359 #line 276 "./getdate.y"
01360 {
01361             yyDayOrdinal = 1;
01362             yyDayNumber = yyvsp[-1].Number;
01363         }
01364 break;
01365 case 19:
01366 #line 280 "./getdate.y"
01367 {
01368             yyDayOrdinal = yyvsp[-1].Number;
01369             yyDayNumber = yyvsp[0].Number;
01370         }
01371 break;
01372 case 20:
01373 #line 286 "./getdate.y"
01374 {
01375             yyMonth = yyvsp[-2].Number;
01376             yyDay = yyvsp[0].Number;
01377         }
01378 break;
01379 case 21:
01380 #line 290 "./getdate.y"
01381 {
01382             if (yyvsp[-4].Number >= 100) {
01383                 yyYear = yyvsp[-4].Number;
01384                 yyMonth = yyvsp[-2].Number;
01385                 yyDay = yyvsp[0].Number;
01386             } else {
01387                 yyMonth = yyvsp[-4].Number;
01388                 yyDay = yyvsp[-2].Number;
01389                 yyYear = yyvsp[0].Number;
01390             }
01391         }
01392 break;
01393 case 22:
01394 #line 301 "./getdate.y"
01395 {
01396             /* ISO 8601 format.  yyyy-mm-dd.  */
01397             yyYear = yyvsp[-2].Number;
01398             yyMonth = -yyvsp[-1].Number;
01399             yyDay = -yyvsp[0].Number;
01400         }
01401 break;
01402 case 23:
01403 #line 307 "./getdate.y"
01404 {
01405             /* e.g. 17-JUN-1992.  */
01406             yyDay = yyvsp[-2].Number;
01407             yyMonth = yyvsp[-1].Number;
01408             yyYear = -yyvsp[0].Number;
01409         }
01410 break;
01411 case 24:
01412 #line 313 "./getdate.y"
01413 {
01414             yyMonth = yyvsp[-1].Number;
01415             yyDay = yyvsp[0].Number;
01416         }
01417 break;
01418 case 25:
01419 #line 317 "./getdate.y"
01420 {
01421             yyMonth = yyvsp[-3].Number;
01422             yyDay = yyvsp[-2].Number;
01423             yyYear = yyvsp[0].Number;
01424         }
01425 break;
01426 case 26:
01427 #line 322 "./getdate.y"
01428 {
01429             yyMonth = yyvsp[0].Number;
01430             yyDay = yyvsp[-1].Number;
01431         }
01432 break;
01433 case 27:
01434 #line 326 "./getdate.y"
01435 {
01436             yyMonth = yyvsp[-1].Number;
01437             yyDay = yyvsp[-2].Number;
01438             yyYear = yyvsp[0].Number;
01439         }
01440 break;
01441 case 28:
01442 #line 333 "./getdate.y"
01443 {
01444             yyRelSeconds = -yyRelSeconds;
01445             yyRelMonth = -yyRelMonth;
01446         }
01447 break;
01448 case 30:
01449 #line 340 "./getdate.y"
01450 {
01451             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
01452         }
01453 break;
01454 case 31:
01455 #line 343 "./getdate.y"
01456 {
01457             yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
01458         }
01459 break;
01460 case 32:
01461 #line 346 "./getdate.y"
01462 {
01463             yyRelSeconds += yyvsp[0].Number * 60L;
01464         }
01465 break;
01466 case 33:
01467 #line 349 "./getdate.y"
01468 {
01469             yyRelSeconds += yyvsp[-1].Number;
01470         }
01471 break;
01472 case 34:
01473 #line 352 "./getdate.y"
01474 {
01475             yyRelSeconds += yyvsp[-1].Number;
01476         }
01477 break;
01478 case 35:
01479 #line 355 "./getdate.y"
01480 {
01481             yyRelSeconds++;
01482         }
01483 break;
01484 case 36:
01485 #line 358 "./getdate.y"
01486 {
01487             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
01488         }
01489 break;
01490 case 37:
01491 #line 361 "./getdate.y"
01492 {
01493             yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
01494         }
01495 break;
01496 case 38:
01497 #line 364 "./getdate.y"
01498 {
01499             yyRelMonth += yyvsp[0].Number;
01500         }
01501 break;
01502 case 39:
01503 #line 369 "./getdate.y"
01504 {
01505             if (yyHaveTime && yyHaveDate && !yyHaveRel)
01506                 yyYear = yyvsp[0].Number;
01507             else {
01508                 if(yyvsp[0].Number>10000) {
01509                     yyHaveDate++;
01510                     yyDay= (yyvsp[0].Number)%100;
01511                     yyMonth= (yyvsp[0].Number/100)%100;
01512                     yyYear = yyvsp[0].Number/10000;
01513                 }
01514                 else {
01515                     yyHaveTime++;
01516                     if (yyvsp[0].Number < 100) {
01517                         yyHour = yyvsp[0].Number;
01518                         yyMinutes = 0;
01519                     }
01520                     else {
01521                         yyHour = yyvsp[0].Number / 100;
01522                         yyMinutes = yyvsp[0].Number % 100;
01523                     }
01524                     yySeconds = 0;
01525                     yyMeridian = MER24;
01526                 }
01527             }
01528         }
01529 break;
01530 case 40:
01531 #line 396 "./getdate.y"
01532 {
01533             yyval.Meridian = MER24;
01534         }
01535 break;
01536 case 41:
01537 #line 399 "./getdate.y"
01538 {
01539             yyval.Meridian = yyvsp[0].Meridian;
01540         }
01541 break;
01542 #line 1537 "getdate.c"
01543     }
01544     yyssp -= yym;
01545     yystate = *yyssp;
01546     yyvsp -= yym;
01547     yym = yylhs[yyn];
01548     if (yystate == 0 && yym == 0)
01549     {
01550 #if YYDEBUG
01551         if (yydebug)
01552             printf("%sdebug: after reduction, shifting from state 0 to\
01553  state %d\n", YYPREFIX, YYFINAL);
01554 #endif
01555         yystate = YYFINAL;
01556         *++yyssp = YYFINAL;
01557         *++yyvsp = yyval;
01558         if (yychar < 0)
01559         {
01560             if ((yychar = yylex()) < 0) yychar = 0;
01561 #if YYDEBUG
01562             if (yydebug)
01563             {
01564                 yys = 0;
01565                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
01566                 if (!yys) yys = "illegal-symbol";
01567                 printf("%sdebug: state %d, reading %d (%s)\n",
01568                         YYPREFIX, YYFINAL, yychar, yys);
01569             }
01570 #endif
01571         }
01572         if (yychar == 0) goto yyaccept;
01573         goto yyloop;
01574     }
01575     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
01576             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
01577         yystate = yytable[yyn];
01578     else
01579         yystate = yydgoto[yym];
01580 #if YYDEBUG
01581     if (yydebug)
01582         printf("%sdebug: after reduction, shifting from state %d \
01583 to state %d\n", YYPREFIX, *yyssp, yystate);
01584 #endif
01585     if (yyssp >= yysslim && yygrowstack())
01586     {
01587         goto yyoverflow;
01588     }
01589     *++yyssp = yystate;
01590     *++yyvsp = yyval;
01591     goto yyloop;
01592 yyoverflow:
01593     yyerror("yacc stack overflow");
01594 yyabort:
01595     return (1);
01596 yyaccept:
01597     return (0);
01598 }
01599 /*@=globs =evalorderuncon =modobserveruncon =modnomods @*/
01600 /*@=readonlytrans =modunconnomods =compdef =noeffectuncon @*/
01601 /*@=retvalint =usedef =varuse =nullderef =nullassign @*/
01602 /*@=globstate =statictrans =unqualifiedtrans =noparams @*/
01603 /*@=bounds@*/

Generated on Mon Mar 5 14:30:57 2007 for rpm by  doxygen 1.5.1