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