Annotation of 43BSD/contrib/news/src/getdate.y, revision 1.1.1.1

1.1       root        1: %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
                      2: %{
                      3:        /*      Steven M. Bellovin (unc!smb)                    */
                      4:        /*      Dept. of Computer Science                       */
                      5:        /*      University of North Carolina at Chapel Hill     */
                      6:        /*      @(#)getdate.y   2.12    4/16/85 */
                      7: 
                      8: #include <sys/types.h>
                      9: #ifdef USG
                     10: struct timeb
                     11: {
                     12:        time_t  time;
                     13:        unsigned short millitm;
                     14:        short   timezone;
                     15:        short   dstflag;
                     16: };
                     17: #else
                     18: #include <sys/timeb.h>
                     19: #endif
                     20: #include <ctype.h>
                     21: 
                     22: #include "defs.h"
                     23: #if defined(BSD4_2) || defined (BSD4_1C)
                     24: #include <sys/time.h>
                     25: #else sane
                     26: #include <time.h>
                     27: #endif sane
                     28: 
                     29: #define        NULL    0
                     30: #define daysec (24L*60L*60L)
                     31:        static int timeflag, zoneflag, dateflag, dayflag, relflag;
                     32:        static time_t relsec, relmonth;
                     33:        static int hh, mm, ss, merid, daylight;
                     34:        static int dayord, dayreq;
                     35:        static int month, day, year;
                     36:        static int ourzone;
                     37: #define AM 1
                     38: #define PM 2
                     39: #define DAYLIGHT 1
                     40: #define STANDARD 2
                     41: #define MAYBE    3
                     42: %}
                     43: 
                     44: %%
                     45: timedate:              /* empty */
                     46:        | timedate item;
                     47: 
                     48: item:  tspec =
                     49:                {timeflag++;}
                     50:        | zone =
                     51:                {zoneflag++;}
                     52:        | dtspec =
                     53:                {dateflag++;}
                     54:        | dyspec =
                     55:                {dayflag++;}
                     56:        | rspec =
                     57:                {relflag++;}
                     58:        | nspec;
                     59: 
                     60: nspec: NUMBER =
                     61:                {if (timeflag && dateflag && !relflag) year = $1;
                     62:                else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
                     63: 
                     64: tspec: NUMBER MERIDIAN =
                     65:                {hh = $1; mm = 0; ss = 0; merid = $2;}
                     66:        | NUMBER ':' NUMBER =
                     67:                {hh = $1; mm = $3; merid = 24;}
                     68:        | NUMBER ':' NUMBER MERIDIAN =
                     69:                {hh = $1; mm = $3; merid = $4;}
                     70:        | NUMBER ':' NUMBER ':' NUMBER =
                     71:                {hh = $1; mm = $3; ss = $5; merid = 24;}
                     72:        | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
                     73:                {hh = $1; mm = $3; ss = $5; merid = $6;};
                     74: 
                     75: zone:  ZONE =
                     76:                {ourzone = $1; daylight = STANDARD;}
                     77:        | DAYZONE =
                     78:                {ourzone = $1; daylight = DAYLIGHT;};
                     79: 
                     80: dyspec:        DAY =
                     81:                {dayord = 1; dayreq = $1;}
                     82:        | DAY ',' =
                     83:                {dayord = 1; dayreq = $1;}
                     84:        | NUMBER DAY =
                     85:                {dayord = $1; dayreq = $2;};
                     86: 
                     87: dtspec:        NUMBER '/' NUMBER =
                     88:                {month = $1; day = $3;}
                     89:        | NUMBER '/' NUMBER '/' NUMBER =
                     90:                {month = $1; day = $3; year = $5;}
                     91:        | MONTH NUMBER =
                     92:                {month = $1; day = $2;}
                     93:        | MONTH NUMBER ',' NUMBER =
                     94:                {month = $1; day = $2; year = $4;}
                     95:        | NUMBER MONTH =
                     96:                {month = $2; day = $1;}
                     97:        | NUMBER MONTH NUMBER =
                     98:                {month = $2; day = $1; year = $3;};
                     99: 
                    100: 
                    101: rspec: NUMBER UNIT =
                    102:                {relsec +=  60L * $1 * $2;}
                    103:        | NUMBER MUNIT =
                    104:                {relmonth += $1 * $2;}
                    105:        | NUMBER SUNIT =
                    106:                {relsec += $1;}
                    107:        | UNIT =
                    108:                {relsec +=  60L * $1;}
                    109:        | MUNIT =
                    110:                {relmonth += $1;}
                    111:        | SUNIT =
                    112:                {relsec++;}
                    113:        | rspec AGO =
                    114:                {relsec = -relsec; relmonth = -relmonth;};
                    115: %%
                    116: 
                    117: static int mdays[12] =
                    118:        {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
                    119: #define epoch 1970
                    120: 
                    121: extern struct tm *localtime();
                    122: time_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
                    123: int mm, dd, yy, h, m, s, mer, zone, dayflag;
                    124: {
                    125:        time_t tod, jdate;
                    126:        register int i;
                    127:        time_t timeconv();
                    128: 
                    129:        if (yy < 0) yy = -yy;
                    130:        if (yy < 100) yy += 1900;
                    131:        mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
                    132:        if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
                    133:                dd < 1 || dd > mdays[--mm]) return (-1);
                    134:        jdate = dd-1;
                    135:         for (i=0; i<mm; i++) jdate += mdays[i];
                    136:        for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
                    137:        jdate *= daysec;
                    138:        jdate += zone * 60L;
                    139:        if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
                    140:        jdate += tod;
                    141:        if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
                    142:                jdate += -1*60*60;
                    143:        return (jdate);
                    144: }
                    145: 
                    146: time_t dayconv(ord, day, now) int ord, day; time_t now;
                    147: {
                    148:        register struct tm *loctime;
                    149:        time_t tod;
                    150:        time_t daylcorr();
                    151: 
                    152:        tod = now;
                    153:        loctime = localtime(&tod);
                    154:        tod += daysec * ((day - loctime->tm_wday + 7) % 7);
                    155:        tod += 7*daysec*(ord<=0?ord:ord-1);
                    156:        return daylcorr(tod, now);
                    157: }
                    158: 
                    159: time_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
                    160: {
                    161:        if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
                    162:        switch (mer) {
                    163:                case AM: if (hh < 1 || hh > 12) return(-1);
                    164:                         return (60L * ((hh%12)*60L + mm)+ss);
                    165:                case PM: if (hh < 1 || hh > 12) return(-1);
                    166:                         return (60L * ((hh%12 +12)*60L + mm)+ss);
                    167:                case 24: if (hh < 0 || hh > 23) return (-1);
                    168:                         return (60L * (hh*60L + mm)+ss);
                    169:                default: return (-1);
                    170:        }
                    171: }
                    172: time_t monthadd(sdate, relmonth) time_t sdate, relmonth;
                    173: {
                    174:        struct tm *ltime;
                    175:        time_t dateconv();
                    176:        time_t daylcorr();
                    177:        int mm, yy;
                    178: 
                    179:        if (relmonth == 0) return 0;
                    180:        ltime = localtime(&sdate);
                    181:        mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
                    182:        yy = mm/12;
                    183:        mm = mm%12 + 1;
                    184:        return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
                    185:                ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
                    186: }
                    187: 
                    188: time_t daylcorr(future, now) time_t future, now;
                    189: {
                    190:        int fdayl, nowdayl;
                    191: 
                    192:        nowdayl = (localtime(&now)->tm_hour+1) % 24;
                    193:        fdayl = (localtime(&future)->tm_hour+1) % 24;
                    194:        return (future-now) + 60L*60L*(nowdayl-fdayl);
                    195: }
                    196: 
                    197: static char *lptr;
                    198: 
                    199: yylex()
                    200: {
                    201:        extern int yylval;
                    202:        int sign;
                    203:        register char c;
                    204:        register char *p;
                    205:        char idbuf[20];
                    206:        int pcnt;
                    207: 
                    208:        for (;;) {
                    209:                while (isspace(*lptr)) lptr++;
                    210: 
                    211:                if (isdigit(c = *lptr) || c == '-' || c == '+') {
                    212:                        if (c== '-' || c == '+') {
                    213:                                if (c=='-') sign = -1;
                    214:                                else sign = 1;
                    215:                                if (!isdigit(*++lptr)) {
                    216:                                        /* yylval = sign; return (NUMBER); */
                    217:                                        return yylex(); /* skip the '-' sign */
                    218:                                }
                    219:                        } else sign = 1;
                    220:                        yylval = 0;
                    221:                        while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
                    222:                        yylval *= sign;
                    223:                        lptr--;
                    224:                        return (NUMBER);
                    225: 
                    226:                } else if (isalpha(c)) {
                    227:                        p = idbuf;
                    228:                        while (isalpha(c = *lptr++) || c=='.')
                    229:                                *p++ = c;
                    230:                        *p = '\0';
                    231:                        lptr--;
                    232:                        return (lookup(idbuf));
                    233:                }
                    234: 
                    235:                else if (c == '(') {
                    236:                        pcnt = 0;
                    237:                        do {
                    238:                                c = *lptr++;
                    239:                                if (c == '\0') return(c);
                    240:                                else if (c == '(') pcnt++;
                    241:                                else if (c == ')') pcnt--;
                    242:                        } while (pcnt > 0);
                    243:                }
                    244: 
                    245:                else return (*lptr++);
                    246:        }
                    247: }
                    248: 
                    249: struct table {
                    250:        char *name;
                    251:        int type, value;
                    252: };
                    253: 
                    254: struct table mdtab[] = {
                    255:        {"January", MONTH, 1},
                    256:        {"February", MONTH, 2},
                    257:        {"March", MONTH, 3},
                    258:        {"April", MONTH, 4},
                    259:        {"May", MONTH, 5},
                    260:        {"June", MONTH, 6},
                    261:        {"July", MONTH, 7},
                    262:        {"August", MONTH, 8},
                    263:        {"September", MONTH, 9},
                    264:        {"Sept", MONTH, 9},
                    265:        {"October", MONTH, 10},
                    266:        {"November", MONTH, 11},
                    267:        {"December", MONTH, 12},
                    268: 
                    269:        {"Sunday", DAY, 0},
                    270:        {"Monday", DAY, 1},
                    271:        {"Tuesday", DAY, 2},
                    272:        {"Tues", DAY, 2},
                    273:        {"Wednesday", DAY, 3},
                    274:        {"Wednes", DAY, 3},
                    275:        {"Thursday", DAY, 4},
                    276:        {"Thur", DAY, 4},
                    277:        {"Thurs", DAY, 4},
                    278:        {"Friday", DAY, 5},
                    279:        {"Saturday", DAY, 6},
                    280:        {0, 0, 0}};
                    281: 
                    282: #define HRS *60
                    283: #define HALFHR 30
                    284: struct table mztab[] = {
                    285:        {"a.m.", MERIDIAN, AM},
                    286:        {"am", MERIDIAN, AM},
                    287:        {"p.m.", MERIDIAN, PM},
                    288:        {"pm", MERIDIAN, PM},
                    289:        {"nst", ZONE, 3 HRS + HALFHR},          /* Newfoundland */
                    290:        {"n.s.t.", ZONE, 3 HRS + HALFHR},
                    291:        {"ast", ZONE, 4 HRS},           /* Atlantic */
                    292:        {"a.s.t.", ZONE, 4 HRS},
                    293:        {"adt", DAYZONE, 4 HRS},
                    294:        {"a.d.t.", DAYZONE, 4 HRS},
                    295:        {"est", ZONE, 5 HRS},           /* Eastern */
                    296:        {"e.s.t.", ZONE, 5 HRS},
                    297:        {"edt", DAYZONE, 5 HRS},
                    298:        {"e.d.t.", DAYZONE, 5 HRS},
                    299:        {"cst", ZONE, 6 HRS},           /* Central */
                    300:        {"c.s.t.", ZONE, 6 HRS},
                    301:        {"cdt", DAYZONE, 6 HRS},
                    302:        {"c.d.t.", DAYZONE, 6 HRS},
                    303:        {"mst", ZONE, 7 HRS},           /* Mountain */
                    304:        {"m.s.t.", ZONE, 7 HRS},
                    305:        {"mdt", DAYZONE, 7 HRS},
                    306:        {"m.d.t.", DAYZONE, 7 HRS},
                    307:        {"pst", ZONE, 8 HRS},           /* Pacific */
                    308:        {"p.s.t.", ZONE, 8 HRS},
                    309:        {"pdt", DAYZONE, 8 HRS},
                    310:        {"p.d.t.", DAYZONE, 8 HRS},
                    311:        {"yst", ZONE, 9 HRS},           /* Yukon */
                    312:        {"y.s.t.", ZONE, 9 HRS},
                    313:        {"ydt", DAYZONE, 9 HRS},
                    314:        {"y.d.t.", DAYZONE, 9 HRS},
                    315:        {"hst", ZONE, 10 HRS},          /* Hawaii */
                    316:        {"h.s.t.", ZONE, 10 HRS},
                    317:        {"hdt", DAYZONE, 10 HRS},
                    318:        {"h.d.t.", DAYZONE, 10 HRS},
                    319: 
                    320:        {"gmt", ZONE, 0 HRS},
                    321:        {"g.m.t.", ZONE, 0 HRS},
                    322:        {"bst", DAYZONE, 0 HRS},                /* British Summer Time */
                    323:        {"b.s.t.", DAYZONE, 0 HRS},
                    324:        {"eet", ZONE, 0 HRS},           /* European Eastern Time */
                    325:        {"e.e.t.", ZONE, 0 HRS},
                    326:        {"eest", DAYZONE, 0 HRS},       /* European Eastern Summer Time */
                    327:        {"e.e.s.t.", DAYZONE, 0 HRS},
                    328:        {"met", ZONE, -1 HRS},          /* Middle European Time */
                    329:        {"m.e.t.", ZONE, -1 HRS},
                    330:        {"mest", DAYZONE, -1 HRS},      /* Middle European Summer Time */
                    331:        {"m.e.s.t.", DAYZONE, -1 HRS},
                    332:        {"wet", ZONE, -2 HRS },         /* Western European Time */
                    333:        {"w.e.t.", ZONE, -2 HRS },
                    334:        {"west", DAYZONE, -2 HRS},      /* Western European Summer Time */
                    335:        {"w.e.s.t.", DAYZONE, -2 HRS},
                    336: 
                    337:        {"jst", ZONE, -9 HRS},          /* Japan Standard Time */
                    338:        {"j.s.t.", ZONE, -9 HRS},       /* Japan Standard Time */
                    339:                                        /* No daylight savings time */
                    340: 
                    341:        {"aest", ZONE, -10 HRS},        /* Australian Eastern Time */
                    342:        {"a.e.s.t.", ZONE, -10 HRS},
                    343:        {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
                    344:        {"a.e.s.s.t.", DAYZONE, -10 HRS},
                    345:        {"acst", ZONE, -(9 HRS + HALFHR)},      /* Australian Central Time */
                    346:        {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
                    347:        {"acsst", DAYZONE, -(9 HRS + HALFHR)},  /* Australian Central Summer */
                    348:        {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
                    349:        {"awst", ZONE, -8 HRS},         /* Australian Western Time */
                    350:        {"a.w.s.t.", ZONE, -8 HRS},     /* (no daylight time there, I'm told */
                    351:        {0, 0, 0}};
                    352: 
                    353: struct table unittb[] = {
                    354:        {"year", MUNIT, 12},
                    355:        {"month", MUNIT, 1},
                    356:        {"fortnight", UNIT, 14*24*60},
                    357:        {"week", UNIT, 7*24*60},
                    358:        {"day", UNIT, 1*24*60},
                    359:        {"hour", UNIT, 60},
                    360:        {"minute", UNIT, 1},
                    361:        {"min", UNIT, 1},
                    362:        {"second", SUNIT, 1},
                    363:        {"sec", SUNIT, 1},
                    364:        {0, 0, 0}};
                    365: 
                    366: struct table othertb[] = {
                    367:        {"tomorrow", UNIT, 1*24*60},
                    368:        {"yesterday", UNIT, -1*24*60},
                    369:        {"today", UNIT, 0},
                    370:        {"now", UNIT, 0},
                    371:        {"last", NUMBER, -1},
                    372:        {"this", UNIT, 0},
                    373:        {"next", NUMBER, 2},
                    374:        {"first", NUMBER, 1},
                    375:        /* {"second", NUMBER, 2}, */
                    376:        {"third", NUMBER, 3},
                    377:        {"fourth", NUMBER, 4},
                    378:        {"fifth", NUMBER, 5},
                    379:        {"sixth", NUMBER, 6},
                    380:        {"seventh", NUMBER, 7},
                    381:        {"eigth", NUMBER, 8},
                    382:        {"ninth", NUMBER, 9},
                    383:        {"tenth", NUMBER, 10},
                    384:        {"eleventh", NUMBER, 11},
                    385:        {"twelfth", NUMBER, 12},
                    386:        {"ago", AGO, 1},
                    387:        {0, 0, 0}};
                    388: 
                    389: struct table milzone[] = {
                    390:        {"a", ZONE, 1 HRS},
                    391:        {"b", ZONE, 2 HRS},
                    392:        {"c", ZONE, 3 HRS},
                    393:        {"d", ZONE, 4 HRS},
                    394:        {"e", ZONE, 5 HRS},
                    395:        {"f", ZONE, 6 HRS},
                    396:        {"g", ZONE, 7 HRS},
                    397:        {"h", ZONE, 8 HRS},
                    398:        {"i", ZONE, 9 HRS},
                    399:        {"k", ZONE, 10 HRS},
                    400:        {"l", ZONE, 11 HRS},
                    401:        {"m", ZONE, 12 HRS},
                    402:        {"n", ZONE, -1 HRS},
                    403:        {"o", ZONE, -2 HRS},
                    404:        {"p", ZONE, -3 HRS},
                    405:        {"q", ZONE, -4 HRS},
                    406:        {"r", ZONE, -5 HRS},
                    407:        {"s", ZONE, -6 HRS},
                    408:        {"t", ZONE, -7 HRS},
                    409:        {"u", ZONE, -8 HRS},
                    410:        {"v", ZONE, -9 HRS},
                    411:        {"w", ZONE, -10 HRS},
                    412:        {"x", ZONE, -11 HRS},
                    413:        {"y", ZONE, -12 HRS},
                    414:        {"z", ZONE, 0 HRS},
                    415:        {0, 0, 0}};
                    416: 
                    417: lookup(id) char *id;
                    418: {
                    419: #define gotit (yylval=i->value,  i->type)
                    420: #define getid for(j=idvar, k=id; *j++ = *k++; )
                    421: 
                    422:        char idvar[20];
                    423:        register char *j, *k;
                    424:        register struct table *i;
                    425:        int abbrev;
                    426: 
                    427:        getid;
                    428:        if (strlen(idvar) == 3) abbrev = 1;
                    429:        else if (strlen(idvar) == 4 && idvar[3] == '.') {
                    430:                abbrev = 1;
                    431:                idvar[3] = '\0';
                    432:        }
                    433:        else abbrev = 0;
                    434: 
                    435:        if (islower(*idvar)) *idvar = toupper(*idvar);
                    436: 
                    437:        for (i = mdtab; i->name; i++) {
                    438:                k = idvar;
                    439:                for (j = i->name; *j++ == *k++;) {
                    440:                        if (abbrev && j==i->name+3) return gotit;
                    441:                        if (j[-1] == 0) return gotit;
                    442:                }
                    443:        }
                    444: 
                    445:        getid;
                    446:        for (i = mztab; i->name; i++)
                    447:                if (strcmp(i->name, idvar) == 0) return gotit;
                    448: 
                    449:        for (j = idvar; *j; j++) if (isupper(*j)) *j = tolower(*j);
                    450:        for (i=mztab; i->name; i++)
                    451:                if (strcmp(i->name, idvar) == 0) return gotit;
                    452: 
                    453:        getid;
                    454:        for (i=unittb; i->name; i++)
                    455:                if (strcmp(i->name, idvar) == 0) return gotit;
                    456: 
                    457:        if (idvar[strlen(idvar)-1] == 's') idvar[strlen(idvar)-1] = '\0';
                    458:        for (i=unittb; i->name; i++)
                    459:                if (strcmp(i->name, idvar) == 0) return gotit;
                    460: 
                    461:        getid;
                    462:        for (i = othertb; i->name; i++)
                    463:                if (strcmp(i->name, idvar) == 0) return gotit;
                    464: 
                    465:        getid;
                    466:        if (strlen(idvar) == 1 && isalpha(*idvar)) {
                    467:                if (isupper(*idvar)) *idvar = tolower(*idvar);
                    468:                for (i = milzone; i->name; i++)
                    469:                        if (strcmp(i->name, idvar) == 0) return gotit;
                    470:        }
                    471: 
                    472:        return(ID);
                    473: }
                    474: 
                    475: time_t getdate(p, now) char *p; struct timeb *now;
                    476: {
                    477: #define mcheck(f)      if (f>1) err++
                    478:        time_t monthadd();
                    479:        int err;
                    480:        struct tm *lt;
                    481:        struct timeb ftz;
                    482: 
                    483:        time_t sdate, tod;
                    484: 
                    485:        lptr = p;
                    486:        if (now == ((struct timeb *) NULL)) {
                    487:                now = &ftz;
                    488:                ftime(&ftz);
                    489:        }
                    490:        lt = localtime(&now->time);
                    491:        year = lt->tm_year;
                    492:        month = lt->tm_mon+1;
                    493:        day = lt->tm_mday;
                    494:        relsec = 0; relmonth = 0;
                    495:        timeflag=zoneflag=dateflag=dayflag=relflag=0;
                    496:        ourzone = now->timezone;
                    497:        daylight = MAYBE;
                    498:        hh = mm = ss = 0;
                    499:        merid = 24;
                    500: 
                    501:        if (err = yyparse()) return (-1);
                    502: 
                    503:        mcheck(timeflag);
                    504:        mcheck(zoneflag);
                    505:        mcheck(dateflag);
                    506:        mcheck(dayflag);
                    507: 
                    508:        if (err) return (-1);
                    509:        if (dateflag || timeflag || dayflag) {
                    510:                sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
                    511:                if (sdate < 0) return -1;
                    512:        }
                    513:        else {
                    514:                sdate = now->time;
                    515:                if (relflag == 0)
                    516:                        sdate -= (lt->tm_sec + lt->tm_min*60 +
                    517:                                lt->tm_hour*(60L*60L));
                    518:        }
                    519: 
                    520:        sdate += relsec;
                    521:        sdate += monthadd(sdate, relmonth);
                    522: 
                    523:        if (dayflag && !dateflag) {
                    524:                tod = dayconv(dayord, dayreq, sdate);
                    525:                sdate += tod;
                    526:        }
                    527: 
                    528:        return sdate;
                    529: }
                    530: 
                    531: yyerror(s) char *s;
                    532: {}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.