|
|
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: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.