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