|
|
1.1 ! root 1: %token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO ! 2: %{ ! 3: /* Originally from: Steven M. Bellovin (unc!smb) */ ! 4: /* Dept. of Computer Science */ ! 5: /* University of North Carolina at Chapel Hill */ ! 6: /* @(#)getdate.y 2.16 9/24/87 */ ! 7: ! 8: #include "defs.h" ! 9: #include <sys/types.h> ! 10: #ifdef USG ! 11: struct timeb ! 12: { ! 13: time_t time; ! 14: unsigned short millitm; ! 15: short timezone; ! 16: short dstflag; ! 17: }; ! 18: #else ! 19: #include <sys/timeb.h> ! 20: #endif ! 21: #include <ctype.h> ! 22: ! 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; merid = 24; ! 72: daylight = STANDARD; ourzone = -($4%100 + 60*($4/100));} ! 73: | NUMBER ':' NUMBER ':' NUMBER = ! 74: {hh = $1; mm = $3; ss = $5; merid = 24;} ! 75: | NUMBER ':' NUMBER ':' NUMBER MERIDIAN = ! 76: {hh = $1; mm = $3; ss = $5; merid = $6;} ! 77: | NUMBER ':' NUMBER ':' NUMBER NUMBER = ! 78: {hh = $1; mm = $3; ss = $5; merid = 24; ! 79: daylight = STANDARD; ourzone = -($6%100 + 60*($6/100));}; ! 80: ! 81: zone: ZONE = ! 82: {ourzone = $1; daylight = STANDARD;} ! 83: | DAYZONE = ! 84: {ourzone = $1; daylight = DAYLIGHT;}; ! 85: ! 86: dyspec: DAY = ! 87: {dayord = 1; dayreq = $1;} ! 88: | DAY ',' = ! 89: {dayord = 1; dayreq = $1;} ! 90: | NUMBER DAY = ! 91: {dayord = $1; dayreq = $2;}; ! 92: ! 93: dtspec: NUMBER '/' NUMBER = ! 94: {month = $1; day = $3;} ! 95: | NUMBER '/' NUMBER '/' NUMBER = ! 96: {month = $1; day = $3; year = $5;} ! 97: | MONTH NUMBER = ! 98: {month = $1; day = $2;} ! 99: | MONTH NUMBER ',' NUMBER = ! 100: {month = $1; day = $2; year = $4;} ! 101: | NUMBER MONTH = ! 102: {month = $2; day = $1;} ! 103: | NUMBER MONTH NUMBER = ! 104: {month = $2; day = $1; year = $3;}; ! 105: ! 106: ! 107: rspec: NUMBER UNIT = ! 108: {relsec += 60L * $1 * $2;} ! 109: | NUMBER MUNIT = ! 110: {relmonth += $1 * $2;} ! 111: | NUMBER SUNIT = ! 112: {relsec += $1;} ! 113: | UNIT = ! 114: {relsec += 60L * $1;} ! 115: | MUNIT = ! 116: {relmonth += $1;} ! 117: | SUNIT = ! 118: {relsec++;} ! 119: | rspec AGO = ! 120: {relsec = -relsec; relmonth = -relmonth;}; ! 121: %% ! 122: ! 123: static int mdays[12] = ! 124: {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ! 125: #define epoch 1970 ! 126: ! 127: extern struct tm *localtime(); ! 128: ! 129: time_t ! 130: dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) ! 131: int mm, dd, yy, h, m, s, mer, zone, dayflag; ! 132: { ! 133: time_t tod, jdate; ! 134: register int i; ! 135: time_t timeconv(); ! 136: ! 137: if (yy < 0) yy = -yy; ! 138: if (yy < 100) yy += 1900; ! 139: mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); ! 140: if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || ! 141: dd < 1 || dd > mdays[--mm]) return (-1); ! 142: jdate = dd-1; ! 143: for (i=0; i<mm; i++) jdate += mdays[i]; ! 144: for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0); ! 145: jdate *= daysec; ! 146: jdate += zone * 60L; ! 147: if ((tod = timeconv(h, m, s, mer)) < 0) return (-1); ! 148: jdate += tod; ! 149: if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst)) ! 150: jdate += -1*60*60; ! 151: return (jdate); ! 152: } ! 153: ! 154: time_t ! 155: dayconv(ord, day, now) ! 156: int ord, day; time_t now; ! 157: { ! 158: register struct tm *loctime; ! 159: time_t tod; ! 160: time_t daylcorr(); ! 161: ! 162: tod = now; ! 163: loctime = localtime(&tod); ! 164: tod += daysec * ((day - loctime->tm_wday + 7) % 7); ! 165: tod += 7*daysec*(ord<=0?ord:ord-1); ! 166: return daylcorr(tod, now); ! 167: } ! 168: ! 169: time_t ! 170: timeconv(hh, mm, ss, mer) ! 171: register int hh, mm, ss, mer; ! 172: { ! 173: if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); ! 174: switch (mer) { ! 175: case AM: if (hh < 1 || hh > 12) return(-1); ! 176: return (60L * ((hh%12)*60L + mm)+ss); ! 177: case PM: if (hh < 1 || hh > 12) return(-1); ! 178: return (60L * ((hh%12 +12)*60L + mm)+ss); ! 179: case 24: if (hh < 0 || hh > 23) return (-1); ! 180: return (60L * (hh*60L + mm)+ss); ! 181: default: return (-1); ! 182: } ! 183: } ! 184: time_t ! 185: monthadd(sdate, relmonth) ! 186: time_t sdate, relmonth; ! 187: { ! 188: struct tm *ltime; ! 189: time_t dateconv(); ! 190: time_t daylcorr(); ! 191: int mm, yy; ! 192: ! 193: if (relmonth == 0) return 0; ! 194: ltime = localtime(&sdate); ! 195: mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; ! 196: yy = mm/12; ! 197: mm = mm%12 + 1; ! 198: return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, ! 199: ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); ! 200: } ! 201: ! 202: time_t ! 203: daylcorr(future, now) ! 204: time_t future, now; ! 205: { ! 206: int fdayl, nowdayl; ! 207: ! 208: nowdayl = (localtime(&now)->tm_hour+1) % 24; ! 209: fdayl = (localtime(&future)->tm_hour+1) % 24; ! 210: return (future-now) + 60L*60L*(nowdayl-fdayl); ! 211: } ! 212: ! 213: static char *lptr; ! 214: ! 215: yylex() ! 216: { ! 217: extern int yylval; ! 218: int sign; ! 219: register char c; ! 220: register char *p; ! 221: char idbuf[20]; ! 222: int pcnt; ! 223: ! 224: for (;;) { ! 225: while (isspace(*lptr)) ! 226: lptr++; ! 227: ! 228: if (isdigit(c = *lptr) || c == '-' || c == '+') { ! 229: if (c== '-' || c == '+') { ! 230: if (c=='-') sign = -1; ! 231: else sign = 1; ! 232: if (!isdigit(*++lptr)) { ! 233: /* yylval = sign; return (NUMBER); */ ! 234: return yylex(); /* skip the '-' sign */ ! 235: } ! 236: } else sign = 1; ! 237: yylval = 0; ! 238: while (isdigit(c = *lptr++)) ! 239: yylval = 10*yylval + c - '0'; ! 240: yylval *= sign; ! 241: lptr--; ! 242: return (NUMBER); ! 243: ! 244: } else if (isalpha(c)) { ! 245: p = idbuf; ! 246: while (isalpha(c = *lptr++) || c=='.') ! 247: if (p < &idbuf[sizeof(idbuf)-1]) *p++ = c; ! 248: *p = '\0'; ! 249: lptr--; ! 250: return (lookup(idbuf)); ! 251: } ! 252: ! 253: else if (c == '(') { ! 254: pcnt = 0; ! 255: do { ! 256: c = *lptr++; ! 257: if (c == '\0') return(c); ! 258: else if (c == '(') pcnt++; ! 259: else if (c == ')') pcnt--; ! 260: } while (pcnt > 0); ! 261: } ! 262: ! 263: else return (*lptr++); ! 264: } ! 265: } ! 266: ! 267: struct table { ! 268: char *name; ! 269: int type, value; ! 270: }; ! 271: ! 272: struct table mdtab[] = { ! 273: {"january", MONTH, 1}, ! 274: {"february", MONTH, 2}, ! 275: {"march", MONTH, 3}, ! 276: {"april", MONTH, 4}, ! 277: {"may", MONTH, 5}, ! 278: {"june", MONTH, 6}, ! 279: {"july", MONTH, 7}, ! 280: {"august", MONTH, 8}, ! 281: {"september", MONTH, 9}, ! 282: {"sept", MONTH, 9}, ! 283: {"october", MONTH, 10}, ! 284: {"november", MONTH, 11}, ! 285: {"december", MONTH, 12}, ! 286: ! 287: {"sunday", DAY, 0}, ! 288: {"monday", DAY, 1}, ! 289: {"tuesday", DAY, 2}, ! 290: {"tues", DAY, 2}, ! 291: {"wednesday", DAY, 3}, ! 292: {"wednes", DAY, 3}, ! 293: {"thursday", DAY, 4}, ! 294: {"thur", DAY, 4}, ! 295: {"thurs", DAY, 4}, ! 296: {"friday", DAY, 5}, ! 297: {"saturday", DAY, 6}, ! 298: {0, 0, 0}}; ! 299: ! 300: #define HRS *60 ! 301: #define HALFHR 30 ! 302: struct table mztab[] = { ! 303: {"a.m.", MERIDIAN, AM}, ! 304: {"am", MERIDIAN, AM}, ! 305: {"p.m.", MERIDIAN, PM}, ! 306: {"pm", MERIDIAN, PM}, ! 307: {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ ! 308: {"n.s.t.", ZONE, 3 HRS + HALFHR}, ! 309: {"ast", ZONE, 4 HRS}, /* Atlantic */ ! 310: {"a.s.t.", ZONE, 4 HRS}, ! 311: {"adt", DAYZONE, 4 HRS}, ! 312: {"a.d.t.", DAYZONE, 4 HRS}, ! 313: {"est", ZONE, 5 HRS}, /* Eastern */ ! 314: {"e.s.t.", ZONE, 5 HRS}, ! 315: {"edt", DAYZONE, 5 HRS}, ! 316: {"e.d.t.", DAYZONE, 5 HRS}, ! 317: {"cst", ZONE, 6 HRS}, /* Central */ ! 318: {"c.s.t.", ZONE, 6 HRS}, ! 319: {"cdt", DAYZONE, 6 HRS}, ! 320: {"c.d.t.", DAYZONE, 6 HRS}, ! 321: {"mst", ZONE, 7 HRS}, /* Mountain */ ! 322: {"m.s.t.", ZONE, 7 HRS}, ! 323: {"mdt", DAYZONE, 7 HRS}, ! 324: {"m.d.t.", DAYZONE, 7 HRS}, ! 325: {"pst", ZONE, 8 HRS}, /* Pacific */ ! 326: {"p.s.t.", ZONE, 8 HRS}, ! 327: {"pdt", DAYZONE, 8 HRS}, ! 328: {"p.d.t.", DAYZONE, 8 HRS}, ! 329: {"yst", ZONE, 9 HRS}, /* Yukon */ ! 330: {"y.s.t.", ZONE, 9 HRS}, ! 331: {"ydt", DAYZONE, 9 HRS}, ! 332: {"y.d.t.", DAYZONE, 9 HRS}, ! 333: {"hst", ZONE, 10 HRS}, /* Hawaii */ ! 334: {"h.s.t.", ZONE, 10 HRS}, ! 335: {"hdt", DAYZONE, 10 HRS}, ! 336: {"h.d.t.", DAYZONE, 10 HRS}, ! 337: ! 338: {"gmt", ZONE, 0 HRS}, ! 339: {"g.m.t.", ZONE, 0 HRS}, ! 340: {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ ! 341: {"b.s.t.", DAYZONE, 0 HRS}, ! 342: {"eet", ZONE, 0 HRS}, /* European Eastern Time */ ! 343: {"e.e.t.", ZONE, 0 HRS}, ! 344: {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ ! 345: {"e.e.s.t.", DAYZONE, 0 HRS}, ! 346: {"met", ZONE, -1 HRS}, /* Middle European Time */ ! 347: {"m.e.t.", ZONE, -1 HRS}, ! 348: {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ ! 349: {"m.e.s.t.", DAYZONE, -1 HRS}, ! 350: {"wet", ZONE, -2 HRS }, /* Western European Time */ ! 351: {"w.e.t.", ZONE, -2 HRS }, ! 352: {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ ! 353: {"w.e.s.t.", DAYZONE, -2 HRS}, ! 354: ! 355: {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ ! 356: {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ ! 357: /* No daylight savings time */ ! 358: ! 359: {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ ! 360: {"a.e.s.t.", ZONE, -10 HRS}, ! 361: {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ ! 362: {"a.e.s.s.t.", DAYZONE, -10 HRS}, ! 363: {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ ! 364: {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, ! 365: {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ ! 366: {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, ! 367: {"awst", ZONE, -8 HRS}, /* Australian Western Time */ ! 368: {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ ! 369: {0, 0, 0}}; ! 370: ! 371: struct table unittb[] = { ! 372: {"year", MUNIT, 12}, ! 373: {"month", MUNIT, 1}, ! 374: {"fortnight", UNIT, 14*24*60}, ! 375: {"week", UNIT, 7*24*60}, ! 376: {"day", UNIT, 1*24*60}, ! 377: {"hour", UNIT, 60}, ! 378: {"minute", UNIT, 1}, ! 379: {"min", UNIT, 1}, ! 380: {"second", SUNIT, 1}, ! 381: {"sec", SUNIT, 1}, ! 382: {0, 0, 0}}; ! 383: ! 384: struct table othertb[] = { ! 385: {"tomorrow", UNIT, 1*24*60}, ! 386: {"yesterday", UNIT, -1*24*60}, ! 387: {"today", UNIT, 0}, ! 388: {"now", UNIT, 0}, ! 389: {"last", NUMBER, -1}, ! 390: {"this", UNIT, 0}, ! 391: {"next", NUMBER, 2}, ! 392: {"first", NUMBER, 1}, ! 393: /* {"second", NUMBER, 2}, */ ! 394: {"third", NUMBER, 3}, ! 395: {"fourth", NUMBER, 4}, ! 396: {"fifth", NUMBER, 5}, ! 397: {"sixth", NUMBER, 6}, ! 398: {"seventh", NUMBER, 7}, ! 399: {"eigth", NUMBER, 8}, ! 400: {"ninth", NUMBER, 9}, ! 401: {"tenth", NUMBER, 10}, ! 402: {"eleventh", NUMBER, 11}, ! 403: {"twelfth", NUMBER, 12}, ! 404: {"ago", AGO, 1}, ! 405: {0, 0, 0}}; ! 406: ! 407: struct table milzone[] = { ! 408: {"a", ZONE, 1 HRS}, ! 409: {"b", ZONE, 2 HRS}, ! 410: {"c", ZONE, 3 HRS}, ! 411: {"d", ZONE, 4 HRS}, ! 412: {"e", ZONE, 5 HRS}, ! 413: {"f", ZONE, 6 HRS}, ! 414: {"g", ZONE, 7 HRS}, ! 415: {"h", ZONE, 8 HRS}, ! 416: {"i", ZONE, 9 HRS}, ! 417: {"k", ZONE, 10 HRS}, ! 418: {"l", ZONE, 11 HRS}, ! 419: {"m", ZONE, 12 HRS}, ! 420: {"n", ZONE, -1 HRS}, ! 421: {"o", ZONE, -2 HRS}, ! 422: {"p", ZONE, -3 HRS}, ! 423: {"q", ZONE, -4 HRS}, ! 424: {"r", ZONE, -5 HRS}, ! 425: {"s", ZONE, -6 HRS}, ! 426: {"t", ZONE, -7 HRS}, ! 427: {"u", ZONE, -8 HRS}, ! 428: {"v", ZONE, -9 HRS}, ! 429: {"w", ZONE, -10 HRS}, ! 430: {"x", ZONE, -11 HRS}, ! 431: {"y", ZONE, -12 HRS}, ! 432: {"z", ZONE, 0 HRS}, ! 433: {0, 0, 0}}; ! 434: ! 435: lookup(id) ! 436: char *id; ! 437: { ! 438: #define gotit (yylval=i->value, i->type) ! 439: ! 440: char idvar[128]; ! 441: register char *j, *k; ! 442: register struct table *i; ! 443: int abbrev; ! 444: ! 445: (void) strcpy(idvar, id); ! 446: j = idvar; ! 447: k = id - 1; ! 448: while (*++k) ! 449: *j++ = isupper(*k) ? tolower(*k) : *k; ! 450: *j = '\0'; ! 451: ! 452: if (strlen(idvar) == 3) ! 453: abbrev = 1; ! 454: else ! 455: if (strlen(idvar) == 4 && idvar[3] == '.') { ! 456: abbrev = 1; ! 457: idvar[3] = '\0'; ! 458: } ! 459: else ! 460: abbrev = 0; ! 461: ! 462: for (i = mdtab; i->name; i++) { ! 463: k = idvar; ! 464: for (j = i->name; *j++ == *k++;) { ! 465: if (abbrev && j == i->name+3) ! 466: return gotit; ! 467: if (j[-1] == 0) ! 468: return gotit; ! 469: } ! 470: } ! 471: ! 472: for (i = mztab; i->name; i++) ! 473: if (strcmp(i->name, idvar) == 0) ! 474: return gotit; ! 475: ! 476: for (i=mztab; i->name; i++) ! 477: if (strcmp(i->name, idvar) == 0) ! 478: return gotit; ! 479: ! 480: for (i=unittb; i->name; i++) ! 481: if (strcmp(i->name, idvar) == 0) ! 482: return gotit; ! 483: ! 484: if (idvar[strlen(idvar)-1] == 's') ! 485: idvar[strlen(idvar)-1] = '\0'; ! 486: ! 487: for (i=unittb; i->name; i++) ! 488: if (strcmp(i->name, idvar) == 0) ! 489: return gotit; ! 490: ! 491: for (i = othertb; i->name; i++) ! 492: if (strcmp(i->name, idvar) == 0) ! 493: return gotit; ! 494: ! 495: if (strlen(idvar) == 1 && isalpha(*idvar)) { ! 496: for (i = milzone; i->name; i++) ! 497: if (strcmp(i->name, idvar) == 0) ! 498: return gotit; ! 499: } ! 500: ! 501: return ID; ! 502: } ! 503: ! 504: time_t ! 505: getdate(p, now) ! 506: char *p; ! 507: struct timeb *now; ! 508: { ! 509: #define mcheck(f) if (f>1) err++ ! 510: time_t monthadd(); ! 511: int err; ! 512: struct tm *lt; ! 513: struct timeb ftz; ! 514: ! 515: time_t sdate, tod; ! 516: ! 517: lptr = p; ! 518: if (now == ((struct timeb *) NULL)) { ! 519: now = &ftz; ! 520: ftime(&ftz); ! 521: } ! 522: lt = localtime(&now->time); ! 523: year = lt->tm_year; ! 524: month = lt->tm_mon+1; ! 525: day = lt->tm_mday; ! 526: relsec = 0; relmonth = 0; ! 527: timeflag=zoneflag=dateflag=dayflag=relflag=0; ! 528: ourzone = now->timezone; ! 529: daylight = MAYBE; ! 530: hh = mm = ss = 0; ! 531: merid = 24; ! 532: ! 533: if (err = yyparse()) return (-1); ! 534: ! 535: mcheck(timeflag); ! 536: mcheck(zoneflag); ! 537: mcheck(dateflag); ! 538: mcheck(dayflag); ! 539: ! 540: if (err) return (-1); ! 541: if (dateflag || timeflag || dayflag) { ! 542: sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); ! 543: if (sdate < 0) return -1; ! 544: } ! 545: else { ! 546: sdate = now->time; ! 547: if (relflag == 0) ! 548: sdate -= (lt->tm_sec + lt->tm_min*60 + ! 549: lt->tm_hour*(60L*60L)); ! 550: } ! 551: ! 552: sdate += relsec; ! 553: sdate += monthadd(sdate, relmonth); ! 554: ! 555: if (dayflag && !dateflag) { ! 556: tod = dayconv(dayord, dayreq, sdate); ! 557: sdate += tod; ! 558: } ! 559: ! 560: return sdate; ! 561: } ! 562: ! 563: yyerror(s) char *s; ! 564: {}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.