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

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

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