Annotation of embedaddon/sudo/plugins/sudoers/getdate.c, revision 1.1.1.1

1.1       misho       1: #include <config.h>
                      2: #include <stdlib.h>
                      3: #include <string.h>
                      4: #define YYBYACC 1
                      5: #define YYMAJOR 1
                      6: #define YYMINOR 9
                      7: #define YYLEX yylex()
                      8: #define YYEMPTY -1
                      9: #define yyclearin (yychar=(YYEMPTY))
                     10: #define yyerrok (yyerrflag=0)
                     11: #define YYRECOVERING() (yyerrflag!=0)
                     12: #define YYPREFIX "yy"
                     13: #line 2 "getdate.y"
                     14: /*
                     15: **  Originally written by Steven M. Bellovin <smb@research.att.com> while
                     16: **  at the University of North Carolina at Chapel Hill.  Later tweaked by
                     17: **  a couple of people on Usenet.  Completely overhauled by Rich $alz
                     18: **  <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
                     19: **
                     20: **  This grammar has 10 shift/reduce conflicts.
                     21: **
                     22: **  This code is in the public domain and has no copyright.
                     23: */
                     24: /* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
                     25: /* SUPPRESS 288 on yyerrlab *//* Label unused */
                     26: 
                     27: #include <config.h>
                     28: 
                     29: #include <sys/types.h>
                     30: #include <sys/time.h>
                     31: #include <stdio.h>
                     32: #ifdef STDC_HEADERS
                     33: # include <stdlib.h>
                     34: # include <stddef.h>
                     35: #else
                     36: # ifdef HAVE_STDLIB_H
                     37: #  include <stdlib.h>
                     38: # endif
                     39: #endif /* STDC_HEADERS */
                     40: #ifdef HAVE_STRING_H
                     41: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
                     42: #  include <memory.h>
                     43: # endif
                     44: # include <string.h>
                     45: #endif /* HAVE_STRING_H */
                     46: #ifdef HAVE_STRINGS_H
                     47: # include <strings.h>
                     48: #endif /* HAVE_STRINGS_H */
                     49: #if TIME_WITH_SYS_TIME
                     50: # include <time.h>
                     51: #endif
                     52: #include <ctype.h>
                     53: 
                     54: #include "missing.h"
                     55: 
                     56: 
                     57: #define EPOCH          1970
                     58: #define HOUR(x)                ((time_t)(x) * 60)
                     59: #define SECSPERDAY     (24L * 60L * 60L)
                     60: 
                     61: 
                     62: /*
                     63: **  An entry in the lexical lookup table.
                     64: */
                     65: typedef struct _TABLE {
                     66:     char       *name;
                     67:     int                type;
                     68:     time_t     value;
                     69: } TABLE;
                     70: 
                     71: 
                     72: /*
                     73: **  Daylight-savings mode:  on, off, or not yet known.
                     74: */
                     75: typedef enum _DSTMODE {
                     76:     DSTon, DSToff, DSTmaybe
                     77: } DSTMODE;
                     78: 
                     79: /*
                     80: **  Meridian:  am, pm, or 24-hour style.
                     81: */
                     82: typedef enum _MERIDIAN {
                     83:     MERam, MERpm, MER24
                     84: } MERIDIAN;
                     85: 
                     86: 
                     87: /*
                     88: **  Global variables.  We could get rid of most of these by using a good
                     89: **  union as the yacc stack.  (This routine was originally written before
                     90: **  yacc had the %union construct.)  Maybe someday; right now we only use
                     91: **  the %union very rarely.
                     92: */
                     93: static char    *yyInput;
                     94: static DSTMODE yyDSTmode;
                     95: static time_t  yyDayOrdinal;
                     96: static time_t  yyDayNumber;
                     97: static int     yyHaveDate;
                     98: static int     yyHaveDay;
                     99: static int     yyHaveRel;
                    100: static int     yyHaveTime;
                    101: static int     yyHaveZone;
                    102: static time_t  yyTimezone;
                    103: static time_t  yyDay;
                    104: static time_t  yyHour;
                    105: static time_t  yyMinutes;
                    106: static time_t  yyMonth;
                    107: static time_t  yySeconds;
                    108: static time_t  yyYear;
                    109: static MERIDIAN        yyMeridian;
                    110: static time_t  yyRelMonth;
                    111: static time_t  yyRelSeconds;
                    112: 
                    113: static int     yyerror(char *s);
                    114: static int     yylex(void);
                    115:        int     yyparse(void);
                    116: 
                    117: #line 107 "getdate.y"
                    118: #ifndef YYSTYPE_DEFINED
                    119: #define YYSTYPE_DEFINED
                    120: typedef union {
                    121:     time_t             Number;
                    122:     enum _MERIDIAN     Meridian;
                    123: } YYSTYPE;
                    124: #endif /* YYSTYPE_DEFINED */
                    125: #line 125 "y.tab.c"
                    126: #define tAGO 257
                    127: #define tDAY 258
                    128: #define tDAYZONE 259
                    129: #define tID 260
                    130: #define tMERIDIAN 261
                    131: #define tMINUTE_UNIT 262
                    132: #define tMONTH 263
                    133: #define tMONTH_UNIT 264
                    134: #define tSEC_UNIT 265
                    135: #define tSNUMBER 266
                    136: #define tUNUMBER 267
                    137: #define tZONE 268
                    138: #define tDST 269
                    139: #define YYERRCODE 256
                    140: #if defined(__cplusplus) || defined(__STDC__)
                    141: const short yylhs[] =
                    142: #else
                    143: short yylhs[] =
                    144: #endif
                    145:        {                                        -1,
                    146:     0,    0,    2,    2,    2,    2,    2,    2,    3,    3,
                    147:     3,    3,    3,    4,    4,    4,    6,    6,    6,    5,
                    148:     5,    5,    5,    5,    5,    5,    5,    7,    7,    9,
                    149:     9,    9,    9,    9,    9,    9,    9,    9,    8,    1,
                    150:     1,
                    151: };
                    152: #if defined(__cplusplus) || defined(__STDC__)
                    153: const short yylen[] =
                    154: #else
                    155: short yylen[] =
                    156: #endif
                    157:        {                                         2,
                    158:     0,    2,    1,    1,    1,    1,    1,    1,    2,    4,
                    159:     4,    6,    6,    1,    1,    2,    1,    2,    2,    3,
                    160:     5,    3,    3,    2,    4,    2,    3,    2,    1,    2,
                    161:     2,    1,    2,    2,    1,    2,    2,    1,    1,    0,
                    162:     1,
                    163: };
                    164: #if defined(__cplusplus) || defined(__STDC__)
                    165: const short yydefred[] =
                    166: #else
                    167: short yydefred[] =
                    168: #endif
                    169:        {                                      1,
                    170:     0,    0,   15,   32,    0,   38,   35,    0,    0,    0,
                    171:     2,    3,    4,    5,    6,    7,    8,    0,   18,    0,
                    172:    31,   36,   33,   19,    9,   30,    0,   37,   34,    0,
                    173:     0,    0,   16,   28,    0,   23,   27,   22,    0,    0,
                    174:    25,   41,   11,    0,   10,    0,    0,   21,   13,   12,
                    175: };
                    176: #if defined(__cplusplus) || defined(__STDC__)
                    177: const short yydgoto[] =
                    178: #else
                    179: short yydgoto[] =
                    180: #endif
                    181:        {                                       1,
                    182:    45,   11,   12,   13,   14,   15,   16,   17,   18,
                    183: };
                    184: #if defined(__cplusplus) || defined(__STDC__)
                    185: const short yysindex[] =
                    186: #else
                    187: short yysindex[] =
                    188: #endif
                    189:        {                                      0,
                    190:  -249,  -38,    0,    0, -260,    0,    0, -240,  -47, -248,
                    191:     0,    0,    0,    0,    0,    0,    0, -237,    0,  -18,
                    192:     0,    0,    0,    0,    0,    0, -262,    0,    0, -239,
                    193:  -238, -236,    0,    0, -235,    0,    0,    0,  -56,  -19,
                    194:     0,    0,    0, -234,    0, -232, -258,    0,    0,    0,};
                    195: #if defined(__cplusplus) || defined(__STDC__)
                    196: const short yyrindex[] =
                    197: #else
                    198: short yyrindex[] =
                    199: #endif
                    200:        {                                      0,
                    201:     0,    1,    0,    0,    0,    0,    0,    0,   69,   12,
                    202:     0,    0,    0,    0,    0,    0,    0,   23,    0,   34,
                    203:     0,    0,    0,    0,    0,    0,   67,    0,    0,    0,
                    204:     0,    0,    0,    0,    0,    0,    0,    0,   56,   45,
                    205:     0,    0,    0,    0,    0,    0,   56,    0,    0,    0,};
                    206: #if defined(__cplusplus) || defined(__STDC__)
                    207: const short yygindex[] =
                    208: #else
                    209: short yygindex[] =
                    210: #endif
                    211:        {                                      0,
                    212:   -17,    0,    0,    0,    0,    0,    0,    0,    0,
                    213: };
                    214: #define YYTABLESIZE 337
                    215: #if defined(__cplusplus) || defined(__STDC__)
                    216: const short yytable[] =
                    217: #else
                    218: short yytable[] =
                    219: #endif
                    220:        {                                      32,
                    221:    17,   44,   42,   36,   37,   19,   20,   49,    2,    3,
                    222:    31,   14,    4,    5,    6,    7,    8,    9,   10,   34,
                    223:    33,   21,   29,   22,   23,   35,   38,   46,   39,   50,
                    224:    40,   41,   47,   24,   48,    0,    0,    0,    0,    0,
                    225:     0,    0,    0,    0,   20,    0,    0,    0,    0,    0,
                    226:     0,    0,    0,    0,    0,   40,    0,    0,    0,    0,
                    227:     0,    0,    0,    0,    0,    0,   26,    0,   39,    0,
                    228:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    229:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    230:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    231:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    232:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    233:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    234:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    235:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    236:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    237:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    238:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    239:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    240:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    241:     0,    0,    0,    0,   42,    0,    0,    0,    0,   43,
                    242:    24,    0,    0,   25,   26,   27,   28,   29,   30,    0,
                    243:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    244:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    245:     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
                    246:     0,    0,    0,    0,    0,    0,    0,    0,   17,   17,
                    247:     0,    0,   17,   17,   17,   17,   17,   17,   17,   14,
                    248:    14,    0,    0,   14,   14,   14,   14,   14,   14,   14,
                    249:    29,   29,    0,    0,   29,   29,   29,   29,   29,   29,
                    250:    29,   24,   24,    0,    0,   24,   24,   24,   24,   24,
                    251:    24,   24,   20,   20,    0,    0,   20,   20,   20,   20,
                    252:    20,   20,   20,   40,   40,    0,    0,   40,   40,   40,
                    253:    40,    0,   40,   40,   26,   26,    0,   39,   26,   26,
                    254:    26,   26,    0,    0,   26,   39,   39,
                    255: };
                    256: #if defined(__cplusplus) || defined(__STDC__)
                    257: const short yycheck[] =
                    258: #else
                    259: short yycheck[] =
                    260: #endif
                    261:        {                                      47,
                    262:     0,   58,  261,  266,  267,   44,  267,  266,  258,  259,
                    263:    58,    0,  262,  263,  264,  265,  266,  267,  268,  257,
                    264:   269,  262,    0,  264,  265,   44,  266,   47,  267,   47,
                    265:   267,  267,  267,    0,  267,   -1,   -1,   -1,   -1,   -1,
                    266:    -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,   -1,
                    267:    -1,   -1,   -1,   -1,   -1,    0,   -1,   -1,   -1,   -1,
                    268:    -1,   -1,   -1,   -1,   -1,   -1,    0,   -1,    0,   -1,
                    269:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    270:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    271:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    272:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    273:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    274:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    275:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    276:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    277:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    278:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    279:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    280:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    281:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    282:    -1,   -1,   -1,   -1,  261,   -1,   -1,   -1,   -1,  266,
                    283:   258,   -1,   -1,  261,  262,  263,  264,  265,  266,   -1,
                    284:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    285:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    286:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
                    287:    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,  259,
                    288:    -1,   -1,  262,  263,  264,  265,  266,  267,  268,  258,
                    289:   259,   -1,   -1,  262,  263,  264,  265,  266,  267,  268,
                    290:   258,  259,   -1,   -1,  262,  263,  264,  265,  266,  267,
                    291:   268,  258,  259,   -1,   -1,  262,  263,  264,  265,  266,
                    292:   267,  268,  258,  259,   -1,   -1,  262,  263,  264,  265,
                    293:   266,  267,  268,  258,  259,   -1,   -1,  262,  263,  264,
                    294:   265,   -1,  267,  268,  258,  259,   -1,  259,  262,  263,
                    295:   264,  265,   -1,   -1,  268,  267,  268,
                    296: };
                    297: #define YYFINAL 1
                    298: #ifndef YYDEBUG
                    299: #define YYDEBUG 0
                    300: #endif
                    301: #define YYMAXTOKEN 269
                    302: #if YYDEBUG
                    303: #if defined(__cplusplus) || defined(__STDC__)
                    304: const char * const yyname[] =
                    305: #else
                    306: char *yyname[] =
                    307: #endif
                    308:        {
                    309: "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,
                    310: 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,
                    311: 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,
                    312: 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,
                    313: 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,
                    314: 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,
                    315: 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",
                    316: "tDAYZONE","tID","tMERIDIAN","tMINUTE_UNIT","tMONTH","tMONTH_UNIT","tSEC_UNIT",
                    317: "tSNUMBER","tUNUMBER","tZONE","tDST",
                    318: };
                    319: #if defined(__cplusplus) || defined(__STDC__)
                    320: const char * const yyrule[] =
                    321: #else
                    322: char *yyrule[] =
                    323: #endif
                    324:        {"$accept : spec",
                    325: "spec :",
                    326: "spec : spec item",
                    327: "item : time",
                    328: "item : zone",
                    329: "item : date",
                    330: "item : day",
                    331: "item : rel",
                    332: "item : number",
                    333: "time : tUNUMBER tMERIDIAN",
                    334: "time : tUNUMBER ':' tUNUMBER o_merid",
                    335: "time : tUNUMBER ':' tUNUMBER tSNUMBER",
                    336: "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid",
                    337: "time : tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER",
                    338: "zone : tZONE",
                    339: "zone : tDAYZONE",
                    340: "zone : tZONE tDST",
                    341: "day : tDAY",
                    342: "day : tDAY ','",
                    343: "day : tUNUMBER tDAY",
                    344: "date : tUNUMBER '/' tUNUMBER",
                    345: "date : tUNUMBER '/' tUNUMBER '/' tUNUMBER",
                    346: "date : tUNUMBER tSNUMBER tSNUMBER",
                    347: "date : tUNUMBER tMONTH tSNUMBER",
                    348: "date : tMONTH tUNUMBER",
                    349: "date : tMONTH tUNUMBER ',' tUNUMBER",
                    350: "date : tUNUMBER tMONTH",
                    351: "date : tUNUMBER tMONTH tUNUMBER",
                    352: "rel : relunit tAGO",
                    353: "rel : relunit",
                    354: "relunit : tUNUMBER tMINUTE_UNIT",
                    355: "relunit : tSNUMBER tMINUTE_UNIT",
                    356: "relunit : tMINUTE_UNIT",
                    357: "relunit : tSNUMBER tSEC_UNIT",
                    358: "relunit : tUNUMBER tSEC_UNIT",
                    359: "relunit : tSEC_UNIT",
                    360: "relunit : tSNUMBER tMONTH_UNIT",
                    361: "relunit : tUNUMBER tMONTH_UNIT",
                    362: "relunit : tMONTH_UNIT",
                    363: "number : tUNUMBER",
                    364: "o_merid :",
                    365: "o_merid : tMERIDIAN",
                    366: };
                    367: #endif
                    368: #ifdef YYSTACKSIZE
                    369: #undef YYMAXDEPTH
                    370: #define YYMAXDEPTH YYSTACKSIZE
                    371: #else
                    372: #ifdef YYMAXDEPTH
                    373: #define YYSTACKSIZE YYMAXDEPTH
                    374: #else
                    375: #define YYSTACKSIZE 10000
                    376: #define YYMAXDEPTH 10000
                    377: #endif
                    378: #endif
                    379: #define YYINITSTACKSIZE 200
                    380: /* LINTUSED */
                    381: int yydebug;
                    382: int yynerrs;
                    383: int yyerrflag;
                    384: int yychar;
                    385: short *yyssp;
                    386: YYSTYPE *yyvsp;
                    387: YYSTYPE yyval;
                    388: YYSTYPE yylval;
                    389: short *yyss;
                    390: short *yysslim;
                    391: YYSTYPE *yyvs;
                    392: int yystacksize;
                    393: #line 326 "getdate.y"
                    394: 
                    395: /* Month and day table. */
                    396: static TABLE const MonthDayTable[] = {
                    397:     { "january",       tMONTH,  1 },
                    398:     { "february",      tMONTH,  2 },
                    399:     { "march",         tMONTH,  3 },
                    400:     { "april",         tMONTH,  4 },
                    401:     { "may",           tMONTH,  5 },
                    402:     { "june",          tMONTH,  6 },
                    403:     { "july",          tMONTH,  7 },
                    404:     { "august",                tMONTH,  8 },
                    405:     { "september",     tMONTH,  9 },
                    406:     { "sept",          tMONTH,  9 },
                    407:     { "october",       tMONTH, 10 },
                    408:     { "november",      tMONTH, 11 },
                    409:     { "december",      tMONTH, 12 },
                    410:     { "sunday",                tDAY, 0 },
                    411:     { "monday",                tDAY, 1 },
                    412:     { "tuesday",       tDAY, 2 },
                    413:     { "tues",          tDAY, 2 },
                    414:     { "wednesday",     tDAY, 3 },
                    415:     { "wednes",                tDAY, 3 },
                    416:     { "thursday",      tDAY, 4 },
                    417:     { "thur",          tDAY, 4 },
                    418:     { "thurs",         tDAY, 4 },
                    419:     { "friday",                tDAY, 5 },
                    420:     { "saturday",      tDAY, 6 },
                    421:     { NULL }
                    422: };
                    423: 
                    424: /* Time units table. */
                    425: static TABLE const UnitsTable[] = {
                    426:     { "year",          tMONTH_UNIT,    12 },
                    427:     { "month",         tMONTH_UNIT,    1 },
                    428:     { "fortnight",     tMINUTE_UNIT,   14 * 24 * 60 },
                    429:     { "week",          tMINUTE_UNIT,   7 * 24 * 60 },
                    430:     { "day",           tMINUTE_UNIT,   1 * 24 * 60 },
                    431:     { "hour",          tMINUTE_UNIT,   60 },
                    432:     { "minute",                tMINUTE_UNIT,   1 },
                    433:     { "min",           tMINUTE_UNIT,   1 },
                    434:     { "second",                tSEC_UNIT,      1 },
                    435:     { "sec",           tSEC_UNIT,      1 },
                    436:     { NULL }
                    437: };
                    438: 
                    439: /* Assorted relative-time words. */
                    440: static TABLE const OtherTable[] = {
                    441:     { "tomorrow",      tMINUTE_UNIT,   1 * 24 * 60 },
                    442:     { "yesterday",     tMINUTE_UNIT,   -1 * 24 * 60 },
                    443:     { "today",         tMINUTE_UNIT,   0 },
                    444:     { "now",           tMINUTE_UNIT,   0 },
                    445:     { "last",          tUNUMBER,       -1 },
                    446:     { "this",          tMINUTE_UNIT,   0 },
                    447:     { "next",          tUNUMBER,       2 },
                    448:     { "first",         tUNUMBER,       1 },
                    449: /*  { "second",                tUNUMBER,       2 }, */
                    450:     { "third",         tUNUMBER,       3 },
                    451:     { "fourth",                tUNUMBER,       4 },
                    452:     { "fifth",         tUNUMBER,       5 },
                    453:     { "sixth",         tUNUMBER,       6 },
                    454:     { "seventh",       tUNUMBER,       7 },
                    455:     { "eighth",                tUNUMBER,       8 },
                    456:     { "ninth",         tUNUMBER,       9 },
                    457:     { "tenth",         tUNUMBER,       10 },
                    458:     { "eleventh",      tUNUMBER,       11 },
                    459:     { "twelfth",       tUNUMBER,       12 },
                    460:     { "ago",           tAGO,   1 },
                    461:     { NULL }
                    462: };
                    463: 
                    464: /* The timezone table. */
                    465: /* Some of these are commented out because a time_t can't store a float. */
                    466: static TABLE const TimezoneTable[] = {
                    467:     { "gmt",   tZONE,     HOUR( 0) },  /* Greenwich Mean */
                    468:     { "ut",    tZONE,     HOUR( 0) },  /* Universal (Coordinated) */
                    469:     { "utc",   tZONE,     HOUR( 0) },
                    470:     { "wet",   tZONE,     HOUR( 0) },  /* Western European */
                    471:     { "bst",   tDAYZONE,  HOUR( 0) },  /* British Summer */
                    472:     { "wat",   tZONE,     HOUR( 1) },  /* West Africa */
                    473:     { "at",    tZONE,     HOUR( 2) },  /* Azores */
                    474: #if    0
                    475:     /* For completeness.  BST is also British Summer, and GST is
                    476:      * also Guam Standard. */
                    477:     { "bst",   tZONE,     HOUR( 3) },  /* Brazil Standard */
                    478:     { "gst",   tZONE,     HOUR( 3) },  /* Greenland Standard */
                    479: #endif
                    480: #if 0
                    481:     { "nft",   tZONE,     HOUR(3.5) }, /* Newfoundland */
                    482:     { "nst",   tZONE,     HOUR(3.5) }, /* Newfoundland Standard */
                    483:     { "ndt",   tDAYZONE,  HOUR(3.5) }, /* Newfoundland Daylight */
                    484: #endif
                    485:     { "ast",   tZONE,     HOUR( 4) },  /* Atlantic Standard */
                    486:     { "adt",   tDAYZONE,  HOUR( 4) },  /* Atlantic Daylight */
                    487:     { "est",   tZONE,     HOUR( 5) },  /* Eastern Standard */
                    488:     { "edt",   tDAYZONE,  HOUR( 5) },  /* Eastern Daylight */
                    489:     { "cst",   tZONE,     HOUR( 6) },  /* Central Standard */
                    490:     { "cdt",   tDAYZONE,  HOUR( 6) },  /* Central Daylight */
                    491:     { "mst",   tZONE,     HOUR( 7) },  /* Mountain Standard */
                    492:     { "mdt",   tDAYZONE,  HOUR( 7) },  /* Mountain Daylight */
                    493:     { "pst",   tZONE,     HOUR( 8) },  /* Pacific Standard */
                    494:     { "pdt",   tDAYZONE,  HOUR( 8) },  /* Pacific Daylight */
                    495:     { "yst",   tZONE,     HOUR( 9) },  /* Yukon Standard */
                    496:     { "ydt",   tDAYZONE,  HOUR( 9) },  /* Yukon Daylight */
                    497:     { "hst",   tZONE,     HOUR(10) },  /* Hawaii Standard */
                    498:     { "hdt",   tDAYZONE,  HOUR(10) },  /* Hawaii Daylight */
                    499:     { "cat",   tZONE,     HOUR(10) },  /* Central Alaska */
                    500:     { "ahst",  tZONE,     HOUR(10) },  /* Alaska-Hawaii Standard */
                    501:     { "nt",    tZONE,     HOUR(11) },  /* Nome */
                    502:     { "idlw",  tZONE,     HOUR(12) },  /* International Date Line West */
                    503:     { "cet",   tZONE,     -HOUR(1) },  /* Central European */
                    504:     { "met",   tZONE,     -HOUR(1) },  /* Middle European */
                    505:     { "mewt",  tZONE,     -HOUR(1) },  /* Middle European Winter */
                    506:     { "mest",  tDAYZONE,  -HOUR(1) },  /* Middle European Summer */
                    507:     { "swt",   tZONE,     -HOUR(1) },  /* Swedish Winter */
                    508:     { "sst",   tDAYZONE,  -HOUR(1) },  /* Swedish Summer */
                    509:     { "fwt",   tZONE,     -HOUR(1) },  /* French Winter */
                    510:     { "fst",   tDAYZONE,  -HOUR(1) },  /* French Summer */
                    511:     { "eet",   tZONE,     -HOUR(2) },  /* Eastern Europe, USSR Zone 1 */
                    512:     { "bt",    tZONE,     -HOUR(3) },  /* Baghdad, USSR Zone 2 */
                    513: #if 0
                    514:     { "it",    tZONE,     -HOUR(3.5) },/* Iran */
                    515: #endif
                    516:     { "zp4",   tZONE,     -HOUR(4) },  /* USSR Zone 3 */
                    517:     { "zp5",   tZONE,     -HOUR(5) },  /* USSR Zone 4 */
                    518: #if 0
                    519:     { "ist",   tZONE,     -HOUR(5.5) },/* Indian Standard */
                    520: #endif
                    521:     { "zp6",   tZONE,     -HOUR(6) },  /* USSR Zone 5 */
                    522: #if    0
                    523:     /* For completeness.  NST is also Newfoundland Stanard, and SST is
                    524:      * also Swedish Summer. */
                    525:     { "nst",   tZONE,     -HOUR(6.5) },/* North Sumatra */
                    526:     { "sst",   tZONE,     -HOUR(7) },  /* South Sumatra, USSR Zone 6 */
                    527: #endif /* 0 */
                    528:     { "wast",  tZONE,     -HOUR(7) },  /* West Australian Standard */
                    529:     { "wadt",  tDAYZONE,  -HOUR(7) },  /* West Australian Daylight */
                    530: #if 0
                    531:     { "jt",    tZONE,     -HOUR(7.5) },/* Java (3pm in Cronusland!) */
                    532: #endif
                    533:     { "cct",   tZONE,     -HOUR(8) },  /* China Coast, USSR Zone 7 */
                    534:     { "jst",   tZONE,     -HOUR(9) },  /* Japan Standard, USSR Zone 8 */
                    535: #if 0
                    536:     { "cast",  tZONE,     -HOUR(9.5) },/* Central Australian Standard */
                    537:     { "cadt",  tDAYZONE,  -HOUR(9.5) },/* Central Australian Daylight */
                    538: #endif
                    539:     { "east",  tZONE,     -HOUR(10) }, /* Eastern Australian Standard */
                    540:     { "eadt",  tDAYZONE,  -HOUR(10) }, /* Eastern Australian Daylight */
                    541:     { "gst",   tZONE,     -HOUR(10) }, /* Guam Standard, USSR Zone 9 */
                    542:     { "nzt",   tZONE,     -HOUR(12) }, /* New Zealand */
                    543:     { "nzst",  tZONE,     -HOUR(12) }, /* New Zealand Standard */
                    544:     { "nzdt",  tDAYZONE,  -HOUR(12) }, /* New Zealand Daylight */
                    545:     { "idle",  tZONE,     -HOUR(12) }, /* International Date Line East */
                    546:     {  NULL  }
                    547: };
                    548: 
                    549: /* Military timezone table. */
                    550: static TABLE const MilitaryTable[] = {
                    551:     { "a",     tZONE,  HOUR(  1) },
                    552:     { "b",     tZONE,  HOUR(  2) },
                    553:     { "c",     tZONE,  HOUR(  3) },
                    554:     { "d",     tZONE,  HOUR(  4) },
                    555:     { "e",     tZONE,  HOUR(  5) },
                    556:     { "f",     tZONE,  HOUR(  6) },
                    557:     { "g",     tZONE,  HOUR(  7) },
                    558:     { "h",     tZONE,  HOUR(  8) },
                    559:     { "i",     tZONE,  HOUR(  9) },
                    560:     { "k",     tZONE,  HOUR( 10) },
                    561:     { "l",     tZONE,  HOUR( 11) },
                    562:     { "m",     tZONE,  HOUR( 12) },
                    563:     { "n",     tZONE,  HOUR(- 1) },
                    564:     { "o",     tZONE,  HOUR(- 2) },
                    565:     { "p",     tZONE,  HOUR(- 3) },
                    566:     { "q",     tZONE,  HOUR(- 4) },
                    567:     { "r",     tZONE,  HOUR(- 5) },
                    568:     { "s",     tZONE,  HOUR(- 6) },
                    569:     { "t",     tZONE,  HOUR(- 7) },
                    570:     { "u",     tZONE,  HOUR(- 8) },
                    571:     { "v",     tZONE,  HOUR(- 9) },
                    572:     { "w",     tZONE,  HOUR(-10) },
                    573:     { "x",     tZONE,  HOUR(-11) },
                    574:     { "y",     tZONE,  HOUR(-12) },
                    575:     { "z",     tZONE,  HOUR(  0) },
                    576:     { NULL }
                    577: };
                    578: 
                    579: 
                    580: 
                    581: 
                    582: /* ARGSUSED */
                    583: static int
                    584: yyerror(s)
                    585:     char       *s;
                    586: {
                    587:   return 0;
                    588: }
                    589: 
                    590: 
                    591: static time_t
                    592: ToSeconds(Hours, Minutes, Seconds, Meridian)
                    593:     time_t     Hours;
                    594:     time_t     Minutes;
                    595:     time_t     Seconds;
                    596:     MERIDIAN   Meridian;
                    597: {
                    598:     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
                    599:        return -1;
                    600:     switch (Meridian) {
                    601:     case MER24:
                    602:        if (Hours < 0 || Hours > 23)
                    603:            return -1;
                    604:        return (Hours * 60L + Minutes) * 60L + Seconds;
                    605:     case MERam:
                    606:        if (Hours < 1 || Hours > 12)
                    607:            return -1;
                    608:        if (Hours == 12)
                    609:            Hours = 0;
                    610:        return (Hours * 60L + Minutes) * 60L + Seconds;
                    611:     case MERpm:
                    612:        if (Hours < 1 || Hours > 12)
                    613:            return -1;
                    614:        if (Hours == 12)
                    615:            Hours = 0;
                    616:        return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
                    617:     default:
                    618:        abort ();
                    619:     }
                    620:     /* NOTREACHED */
                    621: }
                    622: 
                    623: 
                    624: /* Year is either
                    625:    * A negative number, which means to use its absolute value (why?)
                    626:    * A number from 0 to 99, which means a year from 1900 to 1999, or
                    627:    * The actual year (>=100).  */
                    628: static time_t
                    629: Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
                    630:     time_t     Month;
                    631:     time_t     Day;
                    632:     time_t     Year;
                    633:     time_t     Hours;
                    634:     time_t     Minutes;
                    635:     time_t     Seconds;
                    636:     MERIDIAN   Meridian;
                    637:     DSTMODE    DSTmode;
                    638: {
                    639:     static int DaysInMonth[12] = {
                    640:        31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
                    641:     };
                    642:     time_t     tod;
                    643:     time_t     Julian;
                    644:     int                i;
                    645: 
                    646:     if (Year < 0)
                    647:        Year = -Year;
                    648:     if (Year < 69)
                    649:        Year += 2000;
                    650:     else if (Year < 100) {
                    651:        Year += 1900;
                    652:        if (Year < EPOCH)
                    653:                Year += 100;
                    654:     }
                    655:     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
                    656:                    ? 29 : 28;
                    657:     /* Checking for 2038 bogusly assumes that time_t is 32 bits.  But
                    658:        I'm too lazy to try to check for time_t overflow in another way.  */
                    659:     if (Year < EPOCH || Year > 2038
                    660:      || Month < 1 || Month > 12
                    661:      /* Lint fluff:  "conversion from long may lose accuracy" */
                    662:      || Day < 1 || Day > DaysInMonth[(int)--Month])
                    663:        return -1;
                    664: 
                    665:     for (Julian = Day - 1, i = 0; i < Month; i++)
                    666:        Julian += DaysInMonth[i];
                    667:     for (i = EPOCH; i < Year; i++)
                    668:        Julian += 365 + (i % 4 == 0);
                    669:     Julian *= SECSPERDAY;
                    670:     Julian += yyTimezone * 60L;
                    671:     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
                    672:        return -1;
                    673:     Julian += tod;
                    674:     if (DSTmode == DSTon
                    675:      || (DSTmode == DSTmaybe && localtime(&Julian)->tm_isdst))
                    676:        Julian -= 60 * 60;
                    677:     return Julian;
                    678: }
                    679: 
                    680: 
                    681: static time_t
                    682: DSTcorrect(Start, Future)
                    683:     time_t     Start;
                    684:     time_t     Future;
                    685: {
                    686:     time_t     StartDay;
                    687:     time_t     FutureDay;
                    688: 
                    689:     StartDay = (localtime(&Start)->tm_hour + 1) % 24;
                    690:     FutureDay = (localtime(&Future)->tm_hour + 1) % 24;
                    691:     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
                    692: }
                    693: 
                    694: 
                    695: static time_t
                    696: RelativeDate(Start, DayOrdinal, DayNumber)
                    697:     time_t     Start;
                    698:     time_t     DayOrdinal;
                    699:     time_t     DayNumber;
                    700: {
                    701:     struct tm  *tm;
                    702:     time_t     now;
                    703: 
                    704:     now = Start;
                    705:     tm = localtime(&now);
                    706:     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
                    707:     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
                    708:     return DSTcorrect(Start, now);
                    709: }
                    710: 
                    711: 
                    712: static time_t
                    713: RelativeMonth(Start, RelMonth)
                    714:     time_t     Start;
                    715:     time_t     RelMonth;
                    716: {
                    717:     struct tm  *tm;
                    718:     time_t     Month;
                    719:     time_t     Year;
                    720: 
                    721:     if (RelMonth == 0)
                    722:        return 0;
                    723:     tm = localtime(&Start);
                    724:     Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
                    725:     Year = Month / 12;
                    726:     Month = Month % 12 + 1;
                    727:     return DSTcorrect(Start,
                    728:            Convert(Month, (time_t)tm->tm_mday, Year,
                    729:                (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
                    730:                MER24, DSTmaybe));
                    731: }
                    732: 
                    733: 
                    734: static int
                    735: LookupWord(buff)
                    736:     char               *buff;
                    737: {
                    738:     char               *p;
                    739:     char               *q;
                    740:     const TABLE                *tp;
                    741:     int                        i;
                    742:     int                        abbrev;
                    743: 
                    744:     /* Make it lowercase. */
                    745:     for (p = buff; *p; p++)
                    746:        if (isupper((unsigned char)*p))
                    747:            *p = tolower((unsigned char)*p);
                    748: 
                    749:     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
                    750:        yylval.Meridian = MERam;
                    751:        return tMERIDIAN;
                    752:     }
                    753:     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
                    754:        yylval.Meridian = MERpm;
                    755:        return tMERIDIAN;
                    756:     }
                    757: 
                    758:     /* See if we have an abbreviation for a month. */
                    759:     if (strlen(buff) == 3)
                    760:        abbrev = 1;
                    761:     else if (strlen(buff) == 4 && buff[3] == '.') {
                    762:        abbrev = 1;
                    763:        buff[3] = '\0';
                    764:     }
                    765:     else
                    766:        abbrev = 0;
                    767: 
                    768:     for (tp = MonthDayTable; tp->name; tp++) {
                    769:        if (abbrev) {
                    770:            if (strncmp(buff, tp->name, 3) == 0) {
                    771:                yylval.Number = tp->value;
                    772:                return tp->type;
                    773:            }
                    774:        }
                    775:        else if (strcmp(buff, tp->name) == 0) {
                    776:            yylval.Number = tp->value;
                    777:            return tp->type;
                    778:        }
                    779:     }
                    780: 
                    781:     for (tp = TimezoneTable; tp->name; tp++)
                    782:        if (strcmp(buff, tp->name) == 0) {
                    783:            yylval.Number = tp->value;
                    784:            return tp->type;
                    785:        }
                    786: 
                    787:     if (strcmp(buff, "dst") == 0) 
                    788:        return tDST;
                    789: 
                    790:     for (tp = UnitsTable; tp->name; tp++)
                    791:        if (strcmp(buff, tp->name) == 0) {
                    792:            yylval.Number = tp->value;
                    793:            return tp->type;
                    794:        }
                    795: 
                    796:     /* Strip off any plural and try the units table again. */
                    797:     i = strlen(buff) - 1;
                    798:     if (buff[i] == 's') {
                    799:        buff[i] = '\0';
                    800:        for (tp = UnitsTable; tp->name; tp++)
                    801:            if (strcmp(buff, tp->name) == 0) {
                    802:                yylval.Number = tp->value;
                    803:                return tp->type;
                    804:            }
                    805:        buff[i] = 's';          /* Put back for "this" in OtherTable. */
                    806:     }
                    807: 
                    808:     for (tp = OtherTable; tp->name; tp++)
                    809:        if (strcmp(buff, tp->name) == 0) {
                    810:            yylval.Number = tp->value;
                    811:            return tp->type;
                    812:        }
                    813: 
                    814:     /* Military timezones. */
                    815:     if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
                    816:        for (tp = MilitaryTable; tp->name; tp++)
                    817:            if (strcmp(buff, tp->name) == 0) {
                    818:                yylval.Number = tp->value;
                    819:                return tp->type;
                    820:            }
                    821:     }
                    822: 
                    823:     /* Drop out any periods and try the timezone table again. */
                    824:     for (i = 0, p = q = buff; *q; q++)
                    825:        if (*q != '.')
                    826:            *p++ = *q;
                    827:        else
                    828:            i++;
                    829:     *p = '\0';
                    830:     if (i)
                    831:        for (tp = TimezoneTable; tp->name; tp++)
                    832:            if (strcmp(buff, tp->name) == 0) {
                    833:                yylval.Number = tp->value;
                    834:                return tp->type;
                    835:            }
                    836: 
                    837:     return tID;
                    838: }
                    839: 
                    840: 
                    841: static int
                    842: yylex()
                    843: {
                    844:     char               c;
                    845:     char               *p;
                    846:     char               buff[20];
                    847:     int                        Count;
                    848:     int                        sign;
                    849: 
                    850:     for ( ; ; ) {
                    851:        while (isspace((unsigned char)*yyInput))
                    852:            yyInput++;
                    853: 
                    854:        if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
                    855:            if (c == '-' || c == '+') {
                    856:                sign = c == '-' ? -1 : 1;
                    857:                if (!isdigit((unsigned char)*++yyInput))
                    858:                    /* skip the '-' sign */
                    859:                    continue;
                    860:            }
                    861:            else
                    862:                sign = 0;
                    863:            for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
                    864:                yylval.Number = 10 * yylval.Number + c - '0';
                    865:            yyInput--;
                    866:            if (sign < 0)
                    867:                yylval.Number = -yylval.Number;
                    868:            return sign ? tSNUMBER : tUNUMBER;
                    869:        }
                    870:        if (isalpha((unsigned char)c)) {
                    871:            for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
                    872:                if (p < &buff[sizeof buff - 1])
                    873:                    *p++ = c;
                    874:            *p = '\0';
                    875:            yyInput--;
                    876:            return LookupWord(buff);
                    877:        }
                    878:        if (c != '(')
                    879:            return *yyInput++;
                    880:        Count = 0;
                    881:        do {
                    882:            c = *yyInput++;
                    883:            if (c == '\0')
                    884:                return c;
                    885:            if (c == '(')
                    886:                Count++;
                    887:            else if (c == ')')
                    888:                Count--;
                    889:        } while (Count > 0);
                    890:     }
                    891: }
                    892: 
                    893: #define TM_YEAR_ORIGIN 1900
                    894: 
                    895: /* Yield A - B, measured in seconds.  */
                    896: static long
                    897: difftm (a, b)
                    898:      struct tm *a, *b;
                    899: {
                    900:   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
                    901:   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
                    902:   int days = (
                    903:              /* difference in day of year */
                    904:              a->tm_yday - b->tm_yday
                    905:              /* + intervening leap days */
                    906:              +  ((ay >> 2) - (by >> 2))
                    907:              -  (ay/100 - by/100)
                    908:              +  ((ay/100 >> 2) - (by/100 >> 2))
                    909:              /* + difference in years * 365 */
                    910:              +  (long)(ay-by) * 365
                    911:              );
                    912:   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
                    913:              + (a->tm_min - b->tm_min))
                    914:          + (a->tm_sec - b->tm_sec));
                    915: }
                    916: 
                    917: time_t
                    918: get_date(p)
                    919:     char               *p;
                    920: {
                    921:     struct tm          *tm, *gmt, gmtbuf;
                    922:     time_t             Start;
                    923:     time_t             tod;
                    924:     time_t             now;
                    925:     time_t             timezone;
                    926: 
                    927:     yyInput = p;
                    928:     (void)time (&now);
                    929: 
                    930:     gmt = gmtime (&now);
                    931:     if (gmt != NULL)
                    932:     {
                    933:        /* Make a copy, in case localtime modifies *tm (I think
                    934:           that comment now applies to *gmt, but I am too
                    935:           lazy to dig into how gmtime and locatime allocate the
                    936:           structures they return pointers to).  */
                    937:        gmtbuf = *gmt;
                    938:        gmt = &gmtbuf;
                    939:     }
                    940: 
                    941:     if (! (tm = localtime (&now)))
                    942:        return -1;
                    943: 
                    944:     if (gmt != NULL)
                    945:        timezone = difftm (gmt, tm) / 60;
                    946:     else
                    947:        /* We are on a system like VMS, where the system clock is
                    948:           in local time and the system has no concept of timezones.
                    949:           Hopefully we can fake this out (for the case in which the
                    950:           user specifies no timezone) by just saying the timezone
                    951:           is zero.  */
                    952:        timezone = 0;
                    953: 
                    954:     if(tm->tm_isdst)
                    955:        timezone += 60;
                    956: 
                    957:     tm = localtime(&now);
                    958:     yyYear = tm->tm_year + 1900;
                    959:     yyMonth = tm->tm_mon + 1;
                    960:     yyDay = tm->tm_mday;
                    961:     yyTimezone = timezone;
                    962:     yyDSTmode = DSTmaybe;
                    963:     yyHour = 0;
                    964:     yyMinutes = 0;
                    965:     yySeconds = 0;
                    966:     yyMeridian = MER24;
                    967:     yyRelSeconds = 0;
                    968:     yyRelMonth = 0;
                    969:     yyHaveDate = 0;
                    970:     yyHaveDay = 0;
                    971:     yyHaveRel = 0;
                    972:     yyHaveTime = 0;
                    973:     yyHaveZone = 0;
                    974: 
                    975:     if (yyparse()
                    976:      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
                    977:        return -1;
                    978: 
                    979:     if (yyHaveDate || yyHaveTime || yyHaveDay) {
                    980:        Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
                    981:                    yyMeridian, yyDSTmode);
                    982:        if (Start < 0)
                    983:            return -1;
                    984:     }
                    985:     else {
                    986:        Start = now;
                    987:        if (!yyHaveRel)
                    988:            Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
                    989:     }
                    990: 
                    991:     Start += yyRelSeconds;
                    992:     Start += RelativeMonth(Start, yyRelMonth);
                    993: 
                    994:     if (yyHaveDay && !yyHaveDate) {
                    995:        tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
                    996:        Start += tod;
                    997:     }
                    998: 
                    999:     /* Have to do *something* with a legitimate -1 so it's distinguishable
                   1000:      * from the error return value.  (Alternately could set errno on error.) */
                   1001:     return Start == -1 ? 0 : Start;
                   1002: }
                   1003: 
                   1004: 
                   1005: #if    defined(TEST)
                   1006: 
                   1007: /* ARGSUSED */
                   1008: int
                   1009: main(ac, av)
                   1010:     int                ac;
                   1011:     char       *av[];
                   1012: {
                   1013:     char       buff[128];
                   1014:     time_t     d;
                   1015: 
                   1016:     (void)printf("Enter date, or blank line to exit.\n\t> ");
                   1017:     (void)fflush(stdout);
                   1018:     while (gets(buff) && buff[0]) {
                   1019:        d = get_date(buff);
                   1020:        if (d == -1)
                   1021:            (void)printf("Bad format - couldn't convert.\n");
                   1022:        else
                   1023:            (void)printf("%s", ctime(&d));
                   1024:        (void)printf("\t> ");
                   1025:        (void)fflush(stdout);
                   1026:     }
                   1027:     exit(0);
                   1028:     /* NOTREACHED */
                   1029: }
                   1030: #endif /* defined(TEST) */
                   1031: #line 979 "y.tab.c"
                   1032: /* allocate initial stack or double stack size, up to YYMAXDEPTH */
                   1033: #if defined(__cplusplus) || defined(__STDC__)
                   1034: static int yygrowstack(void)
                   1035: #else
                   1036: static int yygrowstack()
                   1037: #endif
                   1038: {
                   1039:     int newsize, i;
                   1040:     short *newss;
                   1041:     YYSTYPE *newvs;
                   1042: 
                   1043:     if ((newsize = yystacksize) == 0)
                   1044:         newsize = YYINITSTACKSIZE;
                   1045:     else if (newsize >= YYMAXDEPTH)
                   1046:         return -1;
                   1047:     else if ((newsize *= 2) > YYMAXDEPTH)
                   1048:         newsize = YYMAXDEPTH;
                   1049:     i = yyssp - yyss;
                   1050: #ifdef SIZE_MAX
                   1051: #define YY_SIZE_MAX SIZE_MAX
                   1052: #else
                   1053: #define YY_SIZE_MAX 0x7fffffff
                   1054: #endif
                   1055:     if (newsize && YY_SIZE_MAX / newsize < sizeof *newss)
                   1056:         goto bail;
                   1057:     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
                   1058:       (short *)malloc(newsize * sizeof *newss); /* overflow check above */
                   1059:     if (newss == NULL)
                   1060:         goto bail;
                   1061:     yyss = newss;
                   1062:     yyssp = newss + i;
                   1063:     if (newsize && YY_SIZE_MAX / newsize < sizeof *newvs)
                   1064:         goto bail;
                   1065:     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
                   1066:       (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
                   1067:     if (newvs == NULL)
                   1068:         goto bail;
                   1069:     yyvs = newvs;
                   1070:     yyvsp = newvs + i;
                   1071:     yystacksize = newsize;
                   1072:     yysslim = yyss + newsize - 1;
                   1073:     return 0;
                   1074: bail:
                   1075:     if (yyss)
                   1076:             free(yyss);
                   1077:     if (yyvs)
                   1078:             free(yyvs);
                   1079:     yyss = yyssp = NULL;
                   1080:     yyvs = yyvsp = NULL;
                   1081:     yystacksize = 0;
                   1082:     return -1;
                   1083: }
                   1084: 
                   1085: #define YYABORT goto yyabort
                   1086: #define YYREJECT goto yyabort
                   1087: #define YYACCEPT goto yyaccept
                   1088: #define YYERROR goto yyerrlab
                   1089: int
                   1090: #if defined(__cplusplus) || defined(__STDC__)
                   1091: yyparse(void)
                   1092: #else
                   1093: yyparse()
                   1094: #endif
                   1095: {
                   1096:     int yym, yyn, yystate;
                   1097: #if YYDEBUG
                   1098: #if defined(__cplusplus) || defined(__STDC__)
                   1099:     const char *yys;
                   1100: #else /* !(defined(__cplusplus) || defined(__STDC__)) */
                   1101:     char *yys;
                   1102: #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
                   1103: 
                   1104:     if ((yys = getenv("YYDEBUG")))
                   1105:     {
                   1106:         yyn = *yys;
                   1107:         if (yyn >= '0' && yyn <= '9')
                   1108:             yydebug = yyn - '0';
                   1109:     }
                   1110: #endif /* YYDEBUG */
                   1111: 
                   1112:     yynerrs = 0;
                   1113:     yyerrflag = 0;
                   1114:     yychar = (-1);
                   1115: 
                   1116:     if (yyss == NULL && yygrowstack()) goto yyoverflow;
                   1117:     yyssp = yyss;
                   1118:     yyvsp = yyvs;
                   1119:     *yyssp = yystate = 0;
                   1120: 
                   1121: yyloop:
                   1122:     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
                   1123:     if (yychar < 0)
                   1124:     {
                   1125:         if ((yychar = yylex()) < 0) yychar = 0;
                   1126: #if YYDEBUG
                   1127:         if (yydebug)
                   1128:         {
                   1129:             yys = 0;
                   1130:             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1131:             if (!yys) yys = "illegal-symbol";
                   1132:             printf("%sdebug: state %d, reading %d (%s)\n",
                   1133:                     YYPREFIX, yystate, yychar, yys);
                   1134:         }
                   1135: #endif
                   1136:     }
                   1137:     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
                   1138:             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
                   1139:     {
                   1140: #if YYDEBUG
                   1141:         if (yydebug)
                   1142:             printf("%sdebug: state %d, shifting to state %d\n",
                   1143:                     YYPREFIX, yystate, yytable[yyn]);
                   1144: #endif
                   1145:         if (yyssp >= yysslim && yygrowstack())
                   1146:         {
                   1147:             goto yyoverflow;
                   1148:         }
                   1149:         *++yyssp = yystate = yytable[yyn];
                   1150:         *++yyvsp = yylval;
                   1151:         yychar = (-1);
                   1152:         if (yyerrflag > 0)  --yyerrflag;
                   1153:         goto yyloop;
                   1154:     }
                   1155:     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
                   1156:             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
                   1157:     {
                   1158:         yyn = yytable[yyn];
                   1159:         goto yyreduce;
                   1160:     }
                   1161:     if (yyerrflag) goto yyinrecovery;
                   1162: #if defined(lint) || defined(__GNUC__)
                   1163:     goto yynewerror;
                   1164: #endif
                   1165: yynewerror:
                   1166:     yyerror("syntax error");
                   1167: #if defined(lint) || defined(__GNUC__)
                   1168:     goto yyerrlab;
                   1169: #endif
                   1170: yyerrlab:
                   1171:     ++yynerrs;
                   1172: yyinrecovery:
                   1173:     if (yyerrflag < 3)
                   1174:     {
                   1175:         yyerrflag = 3;
                   1176:         for (;;)
                   1177:         {
                   1178:             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
                   1179:                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
                   1180:             {
                   1181: #if YYDEBUG
                   1182:                 if (yydebug)
                   1183:                     printf("%sdebug: state %d, error recovery shifting\
                   1184:  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
                   1185: #endif
                   1186:                 if (yyssp >= yysslim && yygrowstack())
                   1187:                 {
                   1188:                     goto yyoverflow;
                   1189:                 }
                   1190:                 *++yyssp = yystate = yytable[yyn];
                   1191:                 *++yyvsp = yylval;
                   1192:                 goto yyloop;
                   1193:             }
                   1194:             else
                   1195:             {
                   1196: #if YYDEBUG
                   1197:                 if (yydebug)
                   1198:                     printf("%sdebug: error recovery discarding state %d\n",
                   1199:                             YYPREFIX, *yyssp);
                   1200: #endif
                   1201:                 if (yyssp <= yyss) goto yyabort;
                   1202:                 --yyssp;
                   1203:                 --yyvsp;
                   1204:             }
                   1205:         }
                   1206:     }
                   1207:     else
                   1208:     {
                   1209:         if (yychar == 0) goto yyabort;
                   1210: #if YYDEBUG
                   1211:         if (yydebug)
                   1212:         {
                   1213:             yys = 0;
                   1214:             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1215:             if (!yys) yys = "illegal-symbol";
                   1216:             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
                   1217:                     YYPREFIX, yystate, yychar, yys);
                   1218:         }
                   1219: #endif
                   1220:         yychar = (-1);
                   1221:         goto yyloop;
                   1222:     }
                   1223: yyreduce:
                   1224: #if YYDEBUG
                   1225:     if (yydebug)
                   1226:         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
                   1227:                 YYPREFIX, yystate, yyn, yyrule[yyn]);
                   1228: #endif
                   1229:     yym = yylen[yyn];
                   1230:     if (yym)
                   1231:         yyval = yyvsp[1-yym];
                   1232:     else
                   1233:         memset(&yyval, 0, sizeof yyval);
                   1234:     switch (yyn)
                   1235:     {
                   1236: case 3:
                   1237: #line 125 "getdate.y"
                   1238: {
                   1239:            yyHaveTime++;
                   1240:        }
                   1241: break;
                   1242: case 4:
                   1243: #line 128 "getdate.y"
                   1244: {
                   1245:            yyHaveZone++;
                   1246:        }
                   1247: break;
                   1248: case 5:
                   1249: #line 131 "getdate.y"
                   1250: {
                   1251:            yyHaveDate++;
                   1252:        }
                   1253: break;
                   1254: case 6:
                   1255: #line 134 "getdate.y"
                   1256: {
                   1257:            yyHaveDay++;
                   1258:        }
                   1259: break;
                   1260: case 7:
                   1261: #line 137 "getdate.y"
                   1262: {
                   1263:            yyHaveRel++;
                   1264:        }
                   1265: break;
                   1266: case 9:
                   1267: #line 143 "getdate.y"
                   1268: {
                   1269:            yyHour = yyvsp[-1].Number;
                   1270:            yyMinutes = 0;
                   1271:            yySeconds = 0;
                   1272:            yyMeridian = yyvsp[0].Meridian;
                   1273:        }
                   1274: break;
                   1275: case 10:
                   1276: #line 149 "getdate.y"
                   1277: {
                   1278:            yyHour = yyvsp[-3].Number;
                   1279:            yyMinutes = yyvsp[-1].Number;
                   1280:            yySeconds = 0;
                   1281:            yyMeridian = yyvsp[0].Meridian;
                   1282:        }
                   1283: break;
                   1284: case 11:
                   1285: #line 155 "getdate.y"
                   1286: {
                   1287:            yyHour = yyvsp[-3].Number;
                   1288:            yyMinutes = yyvsp[-1].Number;
                   1289:            yyMeridian = MER24;
                   1290:            yyDSTmode = DSToff;
                   1291:            yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
                   1292:        }
                   1293: break;
                   1294: case 12:
                   1295: #line 162 "getdate.y"
                   1296: {
                   1297:            yyHour = yyvsp[-5].Number;
                   1298:            yyMinutes = yyvsp[-3].Number;
                   1299:            yySeconds = yyvsp[-1].Number;
                   1300:            yyMeridian = yyvsp[0].Meridian;
                   1301:        }
                   1302: break;
                   1303: case 13:
                   1304: #line 168 "getdate.y"
                   1305: {
                   1306:            yyHour = yyvsp[-5].Number;
                   1307:            yyMinutes = yyvsp[-3].Number;
                   1308:            yySeconds = yyvsp[-1].Number;
                   1309:            yyMeridian = MER24;
                   1310:            yyDSTmode = DSToff;
                   1311:            yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
                   1312:        }
                   1313: break;
                   1314: case 14:
                   1315: #line 178 "getdate.y"
                   1316: {
                   1317:            yyTimezone = yyvsp[0].Number;
                   1318:            yyDSTmode = DSToff;
                   1319:        }
                   1320: break;
                   1321: case 15:
                   1322: #line 182 "getdate.y"
                   1323: {
                   1324:            yyTimezone = yyvsp[0].Number;
                   1325:            yyDSTmode = DSTon;
                   1326:        }
                   1327: break;
                   1328: case 16:
                   1329: #line 187 "getdate.y"
                   1330: {
                   1331:            yyTimezone = yyvsp[-1].Number;
                   1332:            yyDSTmode = DSTon;
                   1333:        }
                   1334: break;
                   1335: case 17:
                   1336: #line 193 "getdate.y"
                   1337: {
                   1338:            yyDayOrdinal = 1;
                   1339:            yyDayNumber = yyvsp[0].Number;
                   1340:        }
                   1341: break;
                   1342: case 18:
                   1343: #line 197 "getdate.y"
                   1344: {
                   1345:            yyDayOrdinal = 1;
                   1346:            yyDayNumber = yyvsp[-1].Number;
                   1347:        }
                   1348: break;
                   1349: case 19:
                   1350: #line 201 "getdate.y"
                   1351: {
                   1352:            yyDayOrdinal = yyvsp[-1].Number;
                   1353:            yyDayNumber = yyvsp[0].Number;
                   1354:        }
                   1355: break;
                   1356: case 20:
                   1357: #line 207 "getdate.y"
                   1358: {
                   1359:            yyMonth = yyvsp[-2].Number;
                   1360:            yyDay = yyvsp[0].Number;
                   1361:        }
                   1362: break;
                   1363: case 21:
                   1364: #line 211 "getdate.y"
                   1365: {
                   1366:            if (yyvsp[-4].Number >= 100) {
                   1367:                yyYear = yyvsp[-4].Number;
                   1368:                yyMonth = yyvsp[-2].Number;
                   1369:                yyDay = yyvsp[0].Number;
                   1370:            } else {
                   1371:                yyMonth = yyvsp[-4].Number;
                   1372:                yyDay = yyvsp[-2].Number;
                   1373:                yyYear = yyvsp[0].Number;
                   1374:            }
                   1375:        }
                   1376: break;
                   1377: case 22:
                   1378: #line 222 "getdate.y"
                   1379: {
                   1380:            /* ISO 8601 format.  yyyy-mm-dd.  */
                   1381:            yyYear = yyvsp[-2].Number;
                   1382:            yyMonth = -yyvsp[-1].Number;
                   1383:            yyDay = -yyvsp[0].Number;
                   1384:        }
                   1385: break;
                   1386: case 23:
                   1387: #line 228 "getdate.y"
                   1388: {
                   1389:            /* e.g. 17-JUN-1992.  */
                   1390:            yyDay = yyvsp[-2].Number;
                   1391:            yyMonth = yyvsp[-1].Number;
                   1392:            yyYear = -yyvsp[0].Number;
                   1393:        }
                   1394: break;
                   1395: case 24:
                   1396: #line 234 "getdate.y"
                   1397: {
                   1398:            yyMonth = yyvsp[-1].Number;
                   1399:            yyDay = yyvsp[0].Number;
                   1400:        }
                   1401: break;
                   1402: case 25:
                   1403: #line 238 "getdate.y"
                   1404: {
                   1405:            yyMonth = yyvsp[-3].Number;
                   1406:            yyDay = yyvsp[-2].Number;
                   1407:            yyYear = yyvsp[0].Number;
                   1408:        }
                   1409: break;
                   1410: case 26:
                   1411: #line 243 "getdate.y"
                   1412: {
                   1413:            yyMonth = yyvsp[0].Number;
                   1414:            yyDay = yyvsp[-1].Number;
                   1415:        }
                   1416: break;
                   1417: case 27:
                   1418: #line 247 "getdate.y"
                   1419: {
                   1420:            yyMonth = yyvsp[-1].Number;
                   1421:            yyDay = yyvsp[-2].Number;
                   1422:            yyYear = yyvsp[0].Number;
                   1423:        }
                   1424: break;
                   1425: case 28:
                   1426: #line 254 "getdate.y"
                   1427: {
                   1428:            yyRelSeconds = -yyRelSeconds;
                   1429:            yyRelMonth = -yyRelMonth;
                   1430:        }
                   1431: break;
                   1432: case 30:
                   1433: #line 261 "getdate.y"
                   1434: {
                   1435:            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
                   1436:        }
                   1437: break;
                   1438: case 31:
                   1439: #line 264 "getdate.y"
                   1440: {
                   1441:            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
                   1442:        }
                   1443: break;
                   1444: case 32:
                   1445: #line 267 "getdate.y"
                   1446: {
                   1447:            yyRelSeconds += yyvsp[0].Number * 60L;
                   1448:        }
                   1449: break;
                   1450: case 33:
                   1451: #line 270 "getdate.y"
                   1452: {
                   1453:            yyRelSeconds += yyvsp[-1].Number;
                   1454:        }
                   1455: break;
                   1456: case 34:
                   1457: #line 273 "getdate.y"
                   1458: {
                   1459:            yyRelSeconds += yyvsp[-1].Number;
                   1460:        }
                   1461: break;
                   1462: case 35:
                   1463: #line 276 "getdate.y"
                   1464: {
                   1465:            yyRelSeconds++;
                   1466:        }
                   1467: break;
                   1468: case 36:
                   1469: #line 279 "getdate.y"
                   1470: {
                   1471:            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
                   1472:        }
                   1473: break;
                   1474: case 37:
                   1475: #line 282 "getdate.y"
                   1476: {
                   1477:            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
                   1478:        }
                   1479: break;
                   1480: case 38:
                   1481: #line 285 "getdate.y"
                   1482: {
                   1483:            yyRelMonth += yyvsp[0].Number;
                   1484:        }
                   1485: break;
                   1486: case 39:
                   1487: #line 290 "getdate.y"
                   1488: {
                   1489:            if (yyHaveTime && yyHaveDate && !yyHaveRel)
                   1490:                yyYear = yyvsp[0].Number;
                   1491:            else {
                   1492:                if(yyvsp[0].Number>10000) {
                   1493:                    yyHaveDate++;
                   1494:                    yyDay= (yyvsp[0].Number)%100;
                   1495:                    yyMonth= (yyvsp[0].Number/100)%100;
                   1496:                    yyYear = yyvsp[0].Number/10000;
                   1497:                }
                   1498:                else {
                   1499:                    yyHaveTime++;
                   1500:                    if (yyvsp[0].Number < 100) {
                   1501:                        yyHour = yyvsp[0].Number;
                   1502:                        yyMinutes = 0;
                   1503:                    }
                   1504:                    else {
                   1505:                        yyHour = yyvsp[0].Number / 100;
                   1506:                        yyMinutes = yyvsp[0].Number % 100;
                   1507:                    }
                   1508:                    yySeconds = 0;
                   1509:                    yyMeridian = MER24;
                   1510:                }
                   1511:            }
                   1512:        }
                   1513: break;
                   1514: case 40:
                   1515: #line 317 "getdate.y"
                   1516: {
                   1517:            yyval.Meridian = MER24;
                   1518:        }
                   1519: break;
                   1520: case 41:
                   1521: #line 320 "getdate.y"
                   1522: {
                   1523:            yyval.Meridian = yyvsp[0].Meridian;
                   1524:        }
                   1525: break;
                   1526: #line 1474 "y.tab.c"
                   1527:     }
                   1528:     yyssp -= yym;
                   1529:     yystate = *yyssp;
                   1530:     yyvsp -= yym;
                   1531:     yym = yylhs[yyn];
                   1532:     if (yystate == 0 && yym == 0)
                   1533:     {
                   1534: #if YYDEBUG
                   1535:         if (yydebug)
                   1536:             printf("%sdebug: after reduction, shifting from state 0 to\
                   1537:  state %d\n", YYPREFIX, YYFINAL);
                   1538: #endif
                   1539:         yystate = YYFINAL;
                   1540:         *++yyssp = YYFINAL;
                   1541:         *++yyvsp = yyval;
                   1542:         if (yychar < 0)
                   1543:         {
                   1544:             if ((yychar = yylex()) < 0) yychar = 0;
                   1545: #if YYDEBUG
                   1546:             if (yydebug)
                   1547:             {
                   1548:                 yys = 0;
                   1549:                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1550:                 if (!yys) yys = "illegal-symbol";
                   1551:                 printf("%sdebug: state %d, reading %d (%s)\n",
                   1552:                         YYPREFIX, YYFINAL, yychar, yys);
                   1553:             }
                   1554: #endif
                   1555:         }
                   1556:         if (yychar == 0) goto yyaccept;
                   1557:         goto yyloop;
                   1558:     }
                   1559:     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
                   1560:             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
                   1561:         yystate = yytable[yyn];
                   1562:     else
                   1563:         yystate = yydgoto[yym];
                   1564: #if YYDEBUG
                   1565:     if (yydebug)
                   1566:         printf("%sdebug: after reduction, shifting from state %d \
                   1567: to state %d\n", YYPREFIX, *yyssp, yystate);
                   1568: #endif
                   1569:     if (yyssp >= yysslim && yygrowstack())
                   1570:     {
                   1571:         goto yyoverflow;
                   1572:     }
                   1573:     *++yyssp = yystate;
                   1574:     *++yyvsp = yyval;
                   1575:     goto yyloop;
                   1576: yyoverflow:
                   1577:     yyerror("yacc stack overflow");
                   1578: yyabort:
                   1579:     if (yyss)
                   1580:             free(yyss);
                   1581:     if (yyvs)
                   1582:             free(yyvs);
                   1583:     yyss = yyssp = NULL;
                   1584:     yyvs = yyvsp = NULL;
                   1585:     yystacksize = 0;
                   1586:     return (1);
                   1587: yyaccept:
                   1588:     if (yyss)
                   1589:             free(yyss);
                   1590:     if (yyvs)
                   1591:             free(yyvs);
                   1592:     yyss = yyssp = NULL;
                   1593:     yyvs = yyvsp = NULL;
                   1594:     yystacksize = 0;
                   1595:     return (0);
                   1596: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>