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: {}

Defined functions

_dateconv defined in line 126; used 3 times
_dayconv defined in line 150; used 1 times
_daylcorr defined in line 192; used 4 times
_getdate defined in line 465; used 1 times
_lookup defined in line 407; used 1 times
_monthadd defined in line 176; used 2 times
_timeconv defined in line 163; used 2 times
_yyerror defined in line 522; never used
_yylex defined in line 203; used 1 times

Defined variables

_lptr defined in line 201; used 11 times
_mdays defined in line 121; used 3 times
_mdtab defined in line 258; used 1 times
_milzone defined in line 379; used 1 times
_mztab defined in line 288; used 2 times
_othertb defined in line 356; used 1 times
_unittb defined in line 343; used 2 times

Defined struct's

table defined in line 253; used 12 times
timeb defined in line 16; used 6 times

Defined macros

AM defined in line 41; used 2 times
DAYLIGHT defined in line 43; used 2 times
HALFHR defined in line 287; used 6 times
HRS defined in line 286; used 71 times
MAYBE defined in line 45; used 3 times
NULL defined in line 33; used 1 times
PM defined in line 42; used 2 times
STANDARD defined in line 44; used 1 times
  • in line 80
daysec defined in line 34; used 3 times
epoch defined in line 123; used 2 times
getid defined in line 410; used 5 times
gotit defined in line 409; used 8 times
mcheck defined in line 467; used 4 times
Last modified: 1985-10-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1561
Valid CSS Valid XHTML 1.0 Strict