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

unix.superglobalmegacorp.com

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