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

unix.superglobalmegacorp.com

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