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

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 */
1.1.1.5 ! misho      49: #ifdef TIME_WITH_SYS_TIME
1.1       misho      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: 
1.1.1.5 ! misho     113: static int     yyerror(const char *s);
1.1       misho     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 */
1.1.1.2   misho     125: #line 125 "getdate.c"
1.1       misho     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;
1.1.1.5 ! misho     392: unsigned int yystacksize;
1.1       misho     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 },
1.1.1.4   misho     446:     { "this",          tUNUMBER,       0 },
1.1       misho     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
1.1.1.5 ! misho     584: yyerror(const char *s)
1.1       misho     585: {
                    586:   return 0;
                    587: }
                    588: 
                    589: 
                    590: static time_t
1.1.1.5 ! misho     591: ToSeconds(time_t Hours, time_t Minutes, time_t Seconds, MERIDIAN Meridian)
1.1       misho     592: {
                    593:     if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59)
                    594:        return -1;
                    595:     switch (Meridian) {
                    596:     case MER24:
                    597:        if (Hours < 0 || Hours > 23)
                    598:            return -1;
                    599:        return (Hours * 60L + Minutes) * 60L + Seconds;
                    600:     case MERam:
                    601:        if (Hours < 1 || Hours > 12)
                    602:            return -1;
                    603:        if (Hours == 12)
                    604:            Hours = 0;
                    605:        return (Hours * 60L + Minutes) * 60L + Seconds;
                    606:     case MERpm:
                    607:        if (Hours < 1 || Hours > 12)
                    608:            return -1;
                    609:        if (Hours == 12)
                    610:            Hours = 0;
                    611:        return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
                    612:     default:
                    613:        abort ();
                    614:     }
                    615:     /* NOTREACHED */
                    616: }
                    617: 
                    618: 
                    619: /* Year is either
                    620:    * A negative number, which means to use its absolute value (why?)
                    621:    * A number from 0 to 99, which means a year from 1900 to 1999, or
                    622:    * The actual year (>=100).  */
                    623: static time_t
1.1.1.5 ! misho     624: Convert(time_t Month, time_t Day, time_t Year, time_t Hours, time_t Minutes,
        !           625:     time_t Seconds, MERIDIAN Meridian, DSTMODE DSTmode)
1.1       misho     626: {
                    627:     static int DaysInMonth[12] = {
                    628:        31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
                    629:     };
1.1.1.5 ! misho     630:     struct tm  *tm;
1.1       misho     631:     time_t     tod;
                    632:     time_t     Julian;
                    633:     int                i;
                    634: 
                    635:     if (Year < 0)
                    636:        Year = -Year;
                    637:     if (Year < 69)
                    638:        Year += 2000;
                    639:     else if (Year < 100) {
                    640:        Year += 1900;
                    641:        if (Year < EPOCH)
                    642:                Year += 100;
                    643:     }
                    644:     DaysInMonth[1] = Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0)
                    645:                    ? 29 : 28;
1.1.1.3   misho     646:     /* 32-bit time_t cannot represent years past 2038 */
                    647:     if (Year < EPOCH || (sizeof(time_t) == sizeof(int) && Year > 2038)
1.1       misho     648:      || Month < 1 || Month > 12
                    649:      /* Lint fluff:  "conversion from long may lose accuracy" */
                    650:      || Day < 1 || Day > DaysInMonth[(int)--Month])
                    651:        return -1;
                    652: 
                    653:     for (Julian = Day - 1, i = 0; i < Month; i++)
                    654:        Julian += DaysInMonth[i];
                    655:     for (i = EPOCH; i < Year; i++)
                    656:        Julian += 365 + (i % 4 == 0);
                    657:     Julian *= SECSPERDAY;
                    658:     Julian += yyTimezone * 60L;
                    659:     if ((tod = ToSeconds(Hours, Minutes, Seconds, Meridian)) < 0)
                    660:        return -1;
                    661:     Julian += tod;
                    662:     if (DSTmode == DSTon
1.1.1.5 ! misho     663:      || (DSTmode == DSTmaybe && (tm = localtime(&Julian)) && tm->tm_isdst))
1.1       misho     664:        Julian -= 60 * 60;
                    665:     return Julian;
                    666: }
                    667: 
                    668: 
                    669: static time_t
1.1.1.5 ! misho     670: DSTcorrect(time_t Start, time_t Future)
1.1       misho     671: {
1.1.1.5 ! misho     672:     struct tm  *start_tm;
        !           673:     struct tm  *future_tm;
1.1       misho     674:     time_t     StartDay;
                    675:     time_t     FutureDay;
                    676: 
1.1.1.5 ! misho     677:     start_tm = localtime(&Start);
        !           678:     future_tm = localtime(&Future);
        !           679:     if (!start_tm || !future_tm)
        !           680:        return -1;
        !           681: 
        !           682:     StartDay = (start_tm->tm_hour + 1) % 24;
        !           683:     FutureDay = (future_tm->tm_hour + 1) % 24;
1.1       misho     684:     return (Future - Start) + (StartDay - FutureDay) * 60L * 60L;
                    685: }
                    686: 
                    687: 
                    688: static time_t
1.1.1.5 ! misho     689: RelativeDate(time_t Start, time_t DayOrdinal, time_t DayNumber)
1.1       misho     690: {
                    691:     struct tm  *tm;
                    692:     time_t     now;
                    693: 
                    694:     now = Start;
1.1.1.5 ! misho     695:     if (!(tm = localtime(&now)))
        !           696:        return -1;
1.1       misho     697:     now += SECSPERDAY * ((DayNumber - tm->tm_wday + 7) % 7);
                    698:     now += 7 * SECSPERDAY * (DayOrdinal <= 0 ? DayOrdinal : DayOrdinal - 1);
                    699:     return DSTcorrect(Start, now);
                    700: }
                    701: 
                    702: 
                    703: static time_t
1.1.1.5 ! misho     704: RelativeMonth(time_t Start, time_t RelMonth)
1.1       misho     705: {
                    706:     struct tm  *tm;
                    707:     time_t     Month;
                    708:     time_t     Year;
                    709: 
                    710:     if (RelMonth == 0)
                    711:        return 0;
1.1.1.5 ! misho     712:     if (!(tm = localtime(&Start)))
        !           713:        return -1;
1.1       misho     714:     Month = 12 * (tm->tm_year + 1900) + tm->tm_mon + RelMonth;
                    715:     Year = Month / 12;
                    716:     Month = Month % 12 + 1;
                    717:     return DSTcorrect(Start,
                    718:            Convert(Month, (time_t)tm->tm_mday, Year,
                    719:                (time_t)tm->tm_hour, (time_t)tm->tm_min, (time_t)tm->tm_sec,
                    720:                MER24, DSTmaybe));
                    721: }
                    722: 
                    723: 
                    724: static int
1.1.1.5 ! misho     725: LookupWord(char *buff)
1.1       misho     726: {
                    727:     char               *p;
                    728:     char               *q;
                    729:     const TABLE                *tp;
                    730:     int                        i;
                    731:     int                        abbrev;
                    732: 
                    733:     /* Make it lowercase. */
                    734:     for (p = buff; *p; p++)
                    735:        if (isupper((unsigned char)*p))
                    736:            *p = tolower((unsigned char)*p);
                    737: 
                    738:     if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
                    739:        yylval.Meridian = MERam;
                    740:        return tMERIDIAN;
                    741:     }
                    742:     if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
                    743:        yylval.Meridian = MERpm;
                    744:        return tMERIDIAN;
                    745:     }
                    746: 
                    747:     /* See if we have an abbreviation for a month. */
                    748:     if (strlen(buff) == 3)
                    749:        abbrev = 1;
                    750:     else if (strlen(buff) == 4 && buff[3] == '.') {
                    751:        abbrev = 1;
                    752:        buff[3] = '\0';
                    753:     }
                    754:     else
                    755:        abbrev = 0;
                    756: 
                    757:     for (tp = MonthDayTable; tp->name; tp++) {
                    758:        if (abbrev) {
                    759:            if (strncmp(buff, tp->name, 3) == 0) {
                    760:                yylval.Number = tp->value;
                    761:                return tp->type;
                    762:            }
                    763:        }
                    764:        else if (strcmp(buff, tp->name) == 0) {
                    765:            yylval.Number = tp->value;
                    766:            return tp->type;
                    767:        }
                    768:     }
                    769: 
                    770:     for (tp = TimezoneTable; tp->name; tp++)
                    771:        if (strcmp(buff, tp->name) == 0) {
                    772:            yylval.Number = tp->value;
                    773:            return tp->type;
                    774:        }
                    775: 
                    776:     if (strcmp(buff, "dst") == 0) 
                    777:        return tDST;
                    778: 
                    779:     for (tp = UnitsTable; tp->name; tp++)
                    780:        if (strcmp(buff, tp->name) == 0) {
                    781:            yylval.Number = tp->value;
                    782:            return tp->type;
                    783:        }
                    784: 
                    785:     /* Strip off any plural and try the units table again. */
                    786:     i = strlen(buff) - 1;
                    787:     if (buff[i] == 's') {
                    788:        buff[i] = '\0';
                    789:        for (tp = UnitsTable; tp->name; tp++)
                    790:            if (strcmp(buff, tp->name) == 0) {
                    791:                yylval.Number = tp->value;
                    792:                return tp->type;
                    793:            }
                    794:        buff[i] = 's';          /* Put back for "this" in OtherTable. */
                    795:     }
                    796: 
                    797:     for (tp = OtherTable; tp->name; tp++)
                    798:        if (strcmp(buff, tp->name) == 0) {
                    799:            yylval.Number = tp->value;
                    800:            return tp->type;
                    801:        }
                    802: 
                    803:     /* Military timezones. */
                    804:     if (buff[1] == '\0' && isalpha((unsigned char)*buff)) {
                    805:        for (tp = MilitaryTable; tp->name; tp++)
                    806:            if (strcmp(buff, tp->name) == 0) {
                    807:                yylval.Number = tp->value;
                    808:                return tp->type;
                    809:            }
                    810:     }
                    811: 
                    812:     /* Drop out any periods and try the timezone table again. */
                    813:     for (i = 0, p = q = buff; *q; q++)
                    814:        if (*q != '.')
                    815:            *p++ = *q;
                    816:        else
                    817:            i++;
                    818:     *p = '\0';
                    819:     if (i)
                    820:        for (tp = TimezoneTable; tp->name; tp++)
                    821:            if (strcmp(buff, tp->name) == 0) {
                    822:                yylval.Number = tp->value;
                    823:                return tp->type;
                    824:            }
                    825: 
                    826:     return tID;
                    827: }
                    828: 
                    829: 
                    830: static int
1.1.1.5 ! misho     831: yylex(void)
1.1       misho     832: {
                    833:     char               c;
                    834:     char               *p;
                    835:     char               buff[20];
                    836:     int                        Count;
                    837:     int                        sign;
                    838: 
                    839:     for ( ; ; ) {
                    840:        while (isspace((unsigned char)*yyInput))
                    841:            yyInput++;
                    842: 
                    843:        if (isdigit((unsigned char)(c = *yyInput)) || c == '-' || c == '+') {
                    844:            if (c == '-' || c == '+') {
                    845:                sign = c == '-' ? -1 : 1;
                    846:                if (!isdigit((unsigned char)*++yyInput))
                    847:                    /* skip the '-' sign */
                    848:                    continue;
                    849:            }
                    850:            else
                    851:                sign = 0;
                    852:            for (yylval.Number = 0; isdigit((unsigned char)(c = *yyInput++)); )
                    853:                yylval.Number = 10 * yylval.Number + c - '0';
                    854:            yyInput--;
                    855:            if (sign < 0)
                    856:                yylval.Number = -yylval.Number;
                    857:            return sign ? tSNUMBER : tUNUMBER;
                    858:        }
                    859:        if (isalpha((unsigned char)c)) {
                    860:            for (p = buff; isalpha((unsigned char)(c = *yyInput++)) || c == '.'; )
                    861:                if (p < &buff[sizeof buff - 1])
                    862:                    *p++ = c;
                    863:            *p = '\0';
                    864:            yyInput--;
                    865:            return LookupWord(buff);
                    866:        }
                    867:        if (c != '(')
                    868:            return *yyInput++;
                    869:        Count = 0;
                    870:        do {
                    871:            c = *yyInput++;
                    872:            if (c == '\0')
                    873:                return c;
                    874:            if (c == '(')
                    875:                Count++;
                    876:            else if (c == ')')
                    877:                Count--;
                    878:        } while (Count > 0);
                    879:     }
                    880: }
                    881: 
                    882: #define TM_YEAR_ORIGIN 1900
                    883: 
                    884: /* Yield A - B, measured in seconds.  */
                    885: static long
1.1.1.5 ! misho     886: difftm(struct tm *a, struct tm *b)
1.1       misho     887: {
                    888:   int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
                    889:   int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
                    890:   int days = (
                    891:              /* difference in day of year */
                    892:              a->tm_yday - b->tm_yday
                    893:              /* + intervening leap days */
                    894:              +  ((ay >> 2) - (by >> 2))
                    895:              -  (ay/100 - by/100)
                    896:              +  ((ay/100 >> 2) - (by/100 >> 2))
                    897:              /* + difference in years * 365 */
                    898:              +  (long)(ay-by) * 365
                    899:              );
                    900:   return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
                    901:              + (a->tm_min - b->tm_min))
                    902:          + (a->tm_sec - b->tm_sec));
                    903: }
                    904: 
                    905: time_t
1.1.1.5 ! misho     906: get_date(char *p)
1.1       misho     907: {
                    908:     struct tm          *tm, *gmt, gmtbuf;
                    909:     time_t             Start;
                    910:     time_t             tod;
                    911:     time_t             now;
                    912:     time_t             timezone;
                    913: 
                    914:     yyInput = p;
                    915:     (void)time (&now);
                    916: 
                    917:     gmt = gmtime (&now);
                    918:     if (gmt != NULL)
                    919:     {
                    920:        /* Make a copy, in case localtime modifies *tm (I think
                    921:           that comment now applies to *gmt, but I am too
                    922:           lazy to dig into how gmtime and locatime allocate the
                    923:           structures they return pointers to).  */
                    924:        gmtbuf = *gmt;
                    925:        gmt = &gmtbuf;
                    926:     }
                    927: 
                    928:     if (! (tm = localtime (&now)))
                    929:        return -1;
                    930: 
                    931:     if (gmt != NULL)
                    932:        timezone = difftm (gmt, tm) / 60;
                    933:     else
                    934:        /* We are on a system like VMS, where the system clock is
                    935:           in local time and the system has no concept of timezones.
                    936:           Hopefully we can fake this out (for the case in which the
                    937:           user specifies no timezone) by just saying the timezone
                    938:           is zero.  */
                    939:        timezone = 0;
                    940: 
                    941:     if(tm->tm_isdst)
                    942:        timezone += 60;
                    943: 
                    944:     yyYear = tm->tm_year + 1900;
                    945:     yyMonth = tm->tm_mon + 1;
                    946:     yyDay = tm->tm_mday;
                    947:     yyTimezone = timezone;
                    948:     yyDSTmode = DSTmaybe;
                    949:     yyHour = 0;
                    950:     yyMinutes = 0;
                    951:     yySeconds = 0;
                    952:     yyMeridian = MER24;
                    953:     yyRelSeconds = 0;
                    954:     yyRelMonth = 0;
                    955:     yyHaveDate = 0;
                    956:     yyHaveDay = 0;
                    957:     yyHaveRel = 0;
                    958:     yyHaveTime = 0;
                    959:     yyHaveZone = 0;
                    960: 
                    961:     if (yyparse()
                    962:      || yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
                    963:        return -1;
                    964: 
                    965:     if (yyHaveDate || yyHaveTime || yyHaveDay) {
                    966:        Start = Convert(yyMonth, yyDay, yyYear, yyHour, yyMinutes, yySeconds,
                    967:                    yyMeridian, yyDSTmode);
                    968:        if (Start < 0)
                    969:            return -1;
                    970:     }
                    971:     else {
                    972:        Start = now;
                    973:        if (!yyHaveRel)
                    974:            Start -= ((tm->tm_hour * 60L + tm->tm_min) * 60L) + tm->tm_sec;
                    975:     }
                    976: 
                    977:     Start += yyRelSeconds;
                    978:     Start += RelativeMonth(Start, yyRelMonth);
                    979: 
                    980:     if (yyHaveDay && !yyHaveDate) {
                    981:        tod = RelativeDate(Start, yyDayOrdinal, yyDayNumber);
                    982:        Start += tod;
                    983:     }
                    984: 
                    985:     /* Have to do *something* with a legitimate -1 so it's distinguishable
                    986:      * from the error return value.  (Alternately could set errno on error.) */
                    987:     return Start == -1 ? 0 : Start;
                    988: }
                    989: 
                    990: 
1.1.1.5 ! misho     991: #ifdef TEST
1.1       misho     992: 
                    993: /* ARGSUSED */
                    994: int
1.1.1.5 ! misho     995: main(int argc, char *argv[])
1.1       misho     996: {
                    997:     char       buff[128];
                    998:     time_t     d;
                    999: 
                   1000:     (void)printf("Enter date, or blank line to exit.\n\t> ");
                   1001:     (void)fflush(stdout);
1.1.1.5 ! misho    1002:     while (fgets(buff, sizeof(buff), stdin) && buff[0]) {
1.1       misho    1003:        d = get_date(buff);
                   1004:        if (d == -1)
                   1005:            (void)printf("Bad format - couldn't convert.\n");
                   1006:        else
                   1007:            (void)printf("%s", ctime(&d));
                   1008:        (void)printf("\t> ");
                   1009:        (void)fflush(stdout);
                   1010:     }
                   1011:     exit(0);
                   1012:     /* NOTREACHED */
                   1013: }
1.1.1.5 ! misho    1014: #endif /* TEST */
        !          1015: #line 963 "getdate.c"
1.1       misho    1016: /* allocate initial stack or double stack size, up to YYMAXDEPTH */
                   1017: #if defined(__cplusplus) || defined(__STDC__)
                   1018: static int yygrowstack(void)
                   1019: #else
                   1020: static int yygrowstack()
                   1021: #endif
                   1022: {
1.1.1.5 ! misho    1023:     unsigned int newsize;
        !          1024:     long sslen;
1.1       misho    1025:     short *newss;
                   1026:     YYSTYPE *newvs;
                   1027: 
1.1.1.5 ! misho    1028:     if ((newsize = yystacksize) == 0)
        !          1029:         newsize = YYINITSTACKSIZE;
        !          1030:     else if (newsize >= YYMAXDEPTH)
1.1       misho    1031:         return -1;
                   1032:     else if ((newsize *= 2) > YYMAXDEPTH)
                   1033:         newsize = YYMAXDEPTH;
                   1034: #ifdef SIZE_MAX
                   1035: #define YY_SIZE_MAX SIZE_MAX
                   1036: #else
1.1.1.5 ! misho    1037: #ifdef __STDC__
        !          1038: #define YY_SIZE_MAX 0xffffffffU
        !          1039: #else
        !          1040: #define YY_SIZE_MAX (unsigned int)0xffffffff
        !          1041: #endif
1.1       misho    1042: #endif
1.1.1.3   misho    1043:     if (YY_SIZE_MAX / newsize < sizeof *newss)
1.1       misho    1044:         goto bail;
1.1.1.5 ! misho    1045:     sslen = yyssp - yyss;
1.1       misho    1046:     newss = yyss ? (short *)realloc(yyss, newsize * sizeof *newss) :
                   1047:       (short *)malloc(newsize * sizeof *newss); /* overflow check above */
                   1048:     if (newss == NULL)
                   1049:         goto bail;
                   1050:     yyss = newss;
1.1.1.5 ! misho    1051:     yyssp = newss + sslen;
1.1       misho    1052:     newvs = yyvs ? (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs) :
                   1053:       (YYSTYPE *)malloc(newsize * sizeof *newvs); /* overflow check above */
                   1054:     if (newvs == NULL)
                   1055:         goto bail;
                   1056:     yyvs = newvs;
1.1.1.5 ! misho    1057:     yyvsp = newvs + sslen;
1.1       misho    1058:     yystacksize = newsize;
                   1059:     yysslim = yyss + newsize - 1;
                   1060:     return 0;
                   1061: bail:
                   1062:     if (yyss)
                   1063:             free(yyss);
                   1064:     if (yyvs)
                   1065:             free(yyvs);
                   1066:     yyss = yyssp = NULL;
                   1067:     yyvs = yyvsp = NULL;
                   1068:     yystacksize = 0;
                   1069:     return -1;
                   1070: }
                   1071: 
                   1072: #define YYABORT goto yyabort
                   1073: #define YYREJECT goto yyabort
                   1074: #define YYACCEPT goto yyaccept
                   1075: #define YYERROR goto yyerrlab
                   1076: int
                   1077: #if defined(__cplusplus) || defined(__STDC__)
                   1078: yyparse(void)
                   1079: #else
                   1080: yyparse()
                   1081: #endif
                   1082: {
                   1083:     int yym, yyn, yystate;
                   1084: #if YYDEBUG
                   1085: #if defined(__cplusplus) || defined(__STDC__)
                   1086:     const char *yys;
                   1087: #else /* !(defined(__cplusplus) || defined(__STDC__)) */
                   1088:     char *yys;
                   1089: #endif /* !(defined(__cplusplus) || defined(__STDC__)) */
                   1090: 
                   1091:     if ((yys = getenv("YYDEBUG")))
                   1092:     {
                   1093:         yyn = *yys;
                   1094:         if (yyn >= '0' && yyn <= '9')
                   1095:             yydebug = yyn - '0';
                   1096:     }
                   1097: #endif /* YYDEBUG */
                   1098: 
                   1099:     yynerrs = 0;
                   1100:     yyerrflag = 0;
                   1101:     yychar = (-1);
                   1102: 
                   1103:     if (yyss == NULL && yygrowstack()) goto yyoverflow;
                   1104:     yyssp = yyss;
                   1105:     yyvsp = yyvs;
                   1106:     *yyssp = yystate = 0;
                   1107: 
                   1108: yyloop:
                   1109:     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
                   1110:     if (yychar < 0)
                   1111:     {
                   1112:         if ((yychar = yylex()) < 0) yychar = 0;
                   1113: #if YYDEBUG
                   1114:         if (yydebug)
                   1115:         {
                   1116:             yys = 0;
                   1117:             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1118:             if (!yys) yys = "illegal-symbol";
                   1119:             printf("%sdebug: state %d, reading %d (%s)\n",
                   1120:                     YYPREFIX, yystate, yychar, yys);
                   1121:         }
                   1122: #endif
                   1123:     }
                   1124:     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
                   1125:             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
                   1126:     {
                   1127: #if YYDEBUG
                   1128:         if (yydebug)
                   1129:             printf("%sdebug: state %d, shifting to state %d\n",
                   1130:                     YYPREFIX, yystate, yytable[yyn]);
                   1131: #endif
                   1132:         if (yyssp >= yysslim && yygrowstack())
                   1133:         {
                   1134:             goto yyoverflow;
                   1135:         }
                   1136:         *++yyssp = yystate = yytable[yyn];
                   1137:         *++yyvsp = yylval;
                   1138:         yychar = (-1);
                   1139:         if (yyerrflag > 0)  --yyerrflag;
                   1140:         goto yyloop;
                   1141:     }
                   1142:     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
                   1143:             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
                   1144:     {
                   1145:         yyn = yytable[yyn];
                   1146:         goto yyreduce;
                   1147:     }
                   1148:     if (yyerrflag) goto yyinrecovery;
                   1149: #if defined(lint) || defined(__GNUC__)
                   1150:     goto yynewerror;
                   1151: #endif
                   1152: yynewerror:
                   1153:     yyerror("syntax error");
                   1154: #if defined(lint) || defined(__GNUC__)
                   1155:     goto yyerrlab;
                   1156: #endif
                   1157: yyerrlab:
                   1158:     ++yynerrs;
                   1159: yyinrecovery:
                   1160:     if (yyerrflag < 3)
                   1161:     {
                   1162:         yyerrflag = 3;
                   1163:         for (;;)
                   1164:         {
                   1165:             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
                   1166:                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
                   1167:             {
                   1168: #if YYDEBUG
                   1169:                 if (yydebug)
                   1170:                     printf("%sdebug: state %d, error recovery shifting\
                   1171:  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
                   1172: #endif
                   1173:                 if (yyssp >= yysslim && yygrowstack())
                   1174:                 {
                   1175:                     goto yyoverflow;
                   1176:                 }
                   1177:                 *++yyssp = yystate = yytable[yyn];
                   1178:                 *++yyvsp = yylval;
                   1179:                 goto yyloop;
                   1180:             }
                   1181:             else
                   1182:             {
                   1183: #if YYDEBUG
                   1184:                 if (yydebug)
                   1185:                     printf("%sdebug: error recovery discarding state %d\n",
                   1186:                             YYPREFIX, *yyssp);
                   1187: #endif
                   1188:                 if (yyssp <= yyss) goto yyabort;
                   1189:                 --yyssp;
                   1190:                 --yyvsp;
                   1191:             }
                   1192:         }
                   1193:     }
                   1194:     else
                   1195:     {
                   1196:         if (yychar == 0) goto yyabort;
                   1197: #if YYDEBUG
                   1198:         if (yydebug)
                   1199:         {
                   1200:             yys = 0;
                   1201:             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1202:             if (!yys) yys = "illegal-symbol";
                   1203:             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
                   1204:                     YYPREFIX, yystate, yychar, yys);
                   1205:         }
                   1206: #endif
                   1207:         yychar = (-1);
                   1208:         goto yyloop;
                   1209:     }
                   1210: yyreduce:
                   1211: #if YYDEBUG
                   1212:     if (yydebug)
                   1213:         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
                   1214:                 YYPREFIX, yystate, yyn, yyrule[yyn]);
                   1215: #endif
                   1216:     yym = yylen[yyn];
                   1217:     if (yym)
                   1218:         yyval = yyvsp[1-yym];
                   1219:     else
                   1220:         memset(&yyval, 0, sizeof yyval);
                   1221:     switch (yyn)
                   1222:     {
                   1223: case 3:
                   1224: #line 125 "getdate.y"
                   1225: {
                   1226:            yyHaveTime++;
                   1227:        }
                   1228: break;
                   1229: case 4:
                   1230: #line 128 "getdate.y"
                   1231: {
                   1232:            yyHaveZone++;
                   1233:        }
                   1234: break;
                   1235: case 5:
                   1236: #line 131 "getdate.y"
                   1237: {
                   1238:            yyHaveDate++;
                   1239:        }
                   1240: break;
                   1241: case 6:
                   1242: #line 134 "getdate.y"
                   1243: {
                   1244:            yyHaveDay++;
                   1245:        }
                   1246: break;
                   1247: case 7:
                   1248: #line 137 "getdate.y"
                   1249: {
                   1250:            yyHaveRel++;
                   1251:        }
                   1252: break;
                   1253: case 9:
                   1254: #line 143 "getdate.y"
                   1255: {
                   1256:            yyHour = yyvsp[-1].Number;
                   1257:            yyMinutes = 0;
                   1258:            yySeconds = 0;
                   1259:            yyMeridian = yyvsp[0].Meridian;
                   1260:        }
                   1261: break;
                   1262: case 10:
                   1263: #line 149 "getdate.y"
                   1264: {
                   1265:            yyHour = yyvsp[-3].Number;
                   1266:            yyMinutes = yyvsp[-1].Number;
                   1267:            yySeconds = 0;
                   1268:            yyMeridian = yyvsp[0].Meridian;
                   1269:        }
                   1270: break;
                   1271: case 11:
                   1272: #line 155 "getdate.y"
                   1273: {
                   1274:            yyHour = yyvsp[-3].Number;
                   1275:            yyMinutes = yyvsp[-1].Number;
                   1276:            yyMeridian = MER24;
                   1277:            yyDSTmode = DSToff;
                   1278:            yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
                   1279:        }
                   1280: break;
                   1281: case 12:
                   1282: #line 162 "getdate.y"
                   1283: {
                   1284:            yyHour = yyvsp[-5].Number;
                   1285:            yyMinutes = yyvsp[-3].Number;
                   1286:            yySeconds = yyvsp[-1].Number;
                   1287:            yyMeridian = yyvsp[0].Meridian;
                   1288:        }
                   1289: break;
                   1290: case 13:
                   1291: #line 168 "getdate.y"
                   1292: {
                   1293:            yyHour = yyvsp[-5].Number;
                   1294:            yyMinutes = yyvsp[-3].Number;
                   1295:            yySeconds = yyvsp[-1].Number;
                   1296:            yyMeridian = MER24;
                   1297:            yyDSTmode = DSToff;
                   1298:            yyTimezone = - (yyvsp[0].Number % 100 + (yyvsp[0].Number / 100) * 60);
                   1299:        }
                   1300: break;
                   1301: case 14:
                   1302: #line 178 "getdate.y"
                   1303: {
                   1304:            yyTimezone = yyvsp[0].Number;
                   1305:            yyDSTmode = DSToff;
                   1306:        }
                   1307: break;
                   1308: case 15:
                   1309: #line 182 "getdate.y"
                   1310: {
                   1311:            yyTimezone = yyvsp[0].Number;
                   1312:            yyDSTmode = DSTon;
                   1313:        }
                   1314: break;
                   1315: case 16:
                   1316: #line 187 "getdate.y"
                   1317: {
                   1318:            yyTimezone = yyvsp[-1].Number;
                   1319:            yyDSTmode = DSTon;
                   1320:        }
                   1321: break;
                   1322: case 17:
                   1323: #line 193 "getdate.y"
                   1324: {
                   1325:            yyDayOrdinal = 1;
                   1326:            yyDayNumber = yyvsp[0].Number;
                   1327:        }
                   1328: break;
                   1329: case 18:
                   1330: #line 197 "getdate.y"
                   1331: {
                   1332:            yyDayOrdinal = 1;
                   1333:            yyDayNumber = yyvsp[-1].Number;
                   1334:        }
                   1335: break;
                   1336: case 19:
                   1337: #line 201 "getdate.y"
                   1338: {
                   1339:            yyDayOrdinal = yyvsp[-1].Number;
                   1340:            yyDayNumber = yyvsp[0].Number;
                   1341:        }
                   1342: break;
                   1343: case 20:
                   1344: #line 207 "getdate.y"
                   1345: {
                   1346:            yyMonth = yyvsp[-2].Number;
                   1347:            yyDay = yyvsp[0].Number;
                   1348:        }
                   1349: break;
                   1350: case 21:
                   1351: #line 211 "getdate.y"
                   1352: {
                   1353:            if (yyvsp[-4].Number >= 100) {
                   1354:                yyYear = yyvsp[-4].Number;
                   1355:                yyMonth = yyvsp[-2].Number;
                   1356:                yyDay = yyvsp[0].Number;
                   1357:            } else {
                   1358:                yyMonth = yyvsp[-4].Number;
                   1359:                yyDay = yyvsp[-2].Number;
                   1360:                yyYear = yyvsp[0].Number;
                   1361:            }
                   1362:        }
                   1363: break;
                   1364: case 22:
                   1365: #line 222 "getdate.y"
                   1366: {
                   1367:            /* ISO 8601 format.  yyyy-mm-dd.  */
                   1368:            yyYear = yyvsp[-2].Number;
                   1369:            yyMonth = -yyvsp[-1].Number;
                   1370:            yyDay = -yyvsp[0].Number;
                   1371:        }
                   1372: break;
                   1373: case 23:
                   1374: #line 228 "getdate.y"
                   1375: {
                   1376:            /* e.g. 17-JUN-1992.  */
                   1377:            yyDay = yyvsp[-2].Number;
                   1378:            yyMonth = yyvsp[-1].Number;
                   1379:            yyYear = -yyvsp[0].Number;
                   1380:        }
                   1381: break;
                   1382: case 24:
                   1383: #line 234 "getdate.y"
                   1384: {
                   1385:            yyMonth = yyvsp[-1].Number;
                   1386:            yyDay = yyvsp[0].Number;
                   1387:        }
                   1388: break;
                   1389: case 25:
                   1390: #line 238 "getdate.y"
                   1391: {
                   1392:            yyMonth = yyvsp[-3].Number;
                   1393:            yyDay = yyvsp[-2].Number;
                   1394:            yyYear = yyvsp[0].Number;
                   1395:        }
                   1396: break;
                   1397: case 26:
                   1398: #line 243 "getdate.y"
                   1399: {
                   1400:            yyMonth = yyvsp[0].Number;
                   1401:            yyDay = yyvsp[-1].Number;
                   1402:        }
                   1403: break;
                   1404: case 27:
                   1405: #line 247 "getdate.y"
                   1406: {
                   1407:            yyMonth = yyvsp[-1].Number;
                   1408:            yyDay = yyvsp[-2].Number;
                   1409:            yyYear = yyvsp[0].Number;
                   1410:        }
                   1411: break;
                   1412: case 28:
                   1413: #line 254 "getdate.y"
                   1414: {
                   1415:            yyRelSeconds = -yyRelSeconds;
                   1416:            yyRelMonth = -yyRelMonth;
                   1417:        }
                   1418: break;
                   1419: case 30:
                   1420: #line 261 "getdate.y"
                   1421: {
                   1422:            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
                   1423:        }
                   1424: break;
                   1425: case 31:
                   1426: #line 264 "getdate.y"
                   1427: {
                   1428:            yyRelSeconds += yyvsp[-1].Number * yyvsp[0].Number * 60L;
                   1429:        }
                   1430: break;
                   1431: case 32:
                   1432: #line 267 "getdate.y"
                   1433: {
                   1434:            yyRelSeconds += yyvsp[0].Number * 60L;
                   1435:        }
                   1436: break;
                   1437: case 33:
                   1438: #line 270 "getdate.y"
                   1439: {
                   1440:            yyRelSeconds += yyvsp[-1].Number;
                   1441:        }
                   1442: break;
                   1443: case 34:
                   1444: #line 273 "getdate.y"
                   1445: {
                   1446:            yyRelSeconds += yyvsp[-1].Number;
                   1447:        }
                   1448: break;
                   1449: case 35:
                   1450: #line 276 "getdate.y"
                   1451: {
                   1452:            yyRelSeconds++;
                   1453:        }
                   1454: break;
                   1455: case 36:
                   1456: #line 279 "getdate.y"
                   1457: {
                   1458:            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
                   1459:        }
                   1460: break;
                   1461: case 37:
                   1462: #line 282 "getdate.y"
                   1463: {
                   1464:            yyRelMonth += yyvsp[-1].Number * yyvsp[0].Number;
                   1465:        }
                   1466: break;
                   1467: case 38:
                   1468: #line 285 "getdate.y"
                   1469: {
                   1470:            yyRelMonth += yyvsp[0].Number;
                   1471:        }
                   1472: break;
                   1473: case 39:
                   1474: #line 290 "getdate.y"
                   1475: {
                   1476:            if (yyHaveTime && yyHaveDate && !yyHaveRel)
                   1477:                yyYear = yyvsp[0].Number;
                   1478:            else {
                   1479:                if(yyvsp[0].Number>10000) {
                   1480:                    yyHaveDate++;
                   1481:                    yyDay= (yyvsp[0].Number)%100;
                   1482:                    yyMonth= (yyvsp[0].Number/100)%100;
                   1483:                    yyYear = yyvsp[0].Number/10000;
                   1484:                }
                   1485:                else {
                   1486:                    yyHaveTime++;
                   1487:                    if (yyvsp[0].Number < 100) {
                   1488:                        yyHour = yyvsp[0].Number;
                   1489:                        yyMinutes = 0;
                   1490:                    }
                   1491:                    else {
                   1492:                        yyHour = yyvsp[0].Number / 100;
                   1493:                        yyMinutes = yyvsp[0].Number % 100;
                   1494:                    }
                   1495:                    yySeconds = 0;
                   1496:                    yyMeridian = MER24;
                   1497:                }
                   1498:            }
                   1499:        }
                   1500: break;
                   1501: case 40:
                   1502: #line 317 "getdate.y"
                   1503: {
                   1504:            yyval.Meridian = MER24;
                   1505:        }
                   1506: break;
                   1507: case 41:
                   1508: #line 320 "getdate.y"
                   1509: {
                   1510:            yyval.Meridian = yyvsp[0].Meridian;
                   1511:        }
                   1512: break;
1.1.1.5 ! misho    1513: #line 1461 "getdate.c"
1.1       misho    1514:     }
                   1515:     yyssp -= yym;
                   1516:     yystate = *yyssp;
                   1517:     yyvsp -= yym;
                   1518:     yym = yylhs[yyn];
                   1519:     if (yystate == 0 && yym == 0)
                   1520:     {
                   1521: #if YYDEBUG
                   1522:         if (yydebug)
                   1523:             printf("%sdebug: after reduction, shifting from state 0 to\
                   1524:  state %d\n", YYPREFIX, YYFINAL);
                   1525: #endif
                   1526:         yystate = YYFINAL;
                   1527:         *++yyssp = YYFINAL;
                   1528:         *++yyvsp = yyval;
                   1529:         if (yychar < 0)
                   1530:         {
                   1531:             if ((yychar = yylex()) < 0) yychar = 0;
                   1532: #if YYDEBUG
                   1533:             if (yydebug)
                   1534:             {
                   1535:                 yys = 0;
                   1536:                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                   1537:                 if (!yys) yys = "illegal-symbol";
                   1538:                 printf("%sdebug: state %d, reading %d (%s)\n",
                   1539:                         YYPREFIX, YYFINAL, yychar, yys);
                   1540:             }
                   1541: #endif
                   1542:         }
                   1543:         if (yychar == 0) goto yyaccept;
                   1544:         goto yyloop;
                   1545:     }
                   1546:     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
                   1547:             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
                   1548:         yystate = yytable[yyn];
                   1549:     else
                   1550:         yystate = yydgoto[yym];
                   1551: #if YYDEBUG
                   1552:     if (yydebug)
                   1553:         printf("%sdebug: after reduction, shifting from state %d \
                   1554: to state %d\n", YYPREFIX, *yyssp, yystate);
                   1555: #endif
                   1556:     if (yyssp >= yysslim && yygrowstack())
                   1557:     {
                   1558:         goto yyoverflow;
                   1559:     }
                   1560:     *++yyssp = yystate;
                   1561:     *++yyvsp = yyval;
                   1562:     goto yyloop;
                   1563: yyoverflow:
                   1564:     yyerror("yacc stack overflow");
                   1565: yyabort:
                   1566:     if (yyss)
                   1567:             free(yyss);
                   1568:     if (yyvs)
                   1569:             free(yyvs);
                   1570:     yyss = yyssp = NULL;
                   1571:     yyvs = yyvsp = NULL;
                   1572:     yystacksize = 0;
                   1573:     return (1);
                   1574: yyaccept:
                   1575:     if (yyss)
                   1576:             free(yyss);
                   1577:     if (yyvs)
                   1578:             free(yyvs);
                   1579:     yyss = yyssp = NULL;
                   1580:     yyvs = yyvsp = NULL;
                   1581:     yystacksize = 0;
                   1582:     return (0);
                   1583: }

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