|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <sys/time.h> ! 3: #include <ctype.h> ! 4: ! 5: /* ! 6: ** promptdate ! 7: ** prompt user for a date specification which can be quite minimal ! 8: ** and print it in a form suitable for parsing by MH ! 9: */ ! 10: ! 11: #define MAXLINE 128 ! 12: ! 13: char *mname[12] ={ ! 14: "Jan","Feb","Mar","Apr","May","Jun", ! 15: "Jul","Aug","Sep","Oct","Nov","Dec"}; ! 16: char *dname[7] ={ ! 17: "Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; ! 18: struct tm now; ! 19: int dayspast = 0; ! 20: int monthlen[2][12] ={ ! 21: 31,28,31,30,31,30,31,31,30,31,30,31, ! 22: 31,29,31,30,31,30,31,31,30,31,30,31}; ! 23: char *defaultformat = "%d %N %y 00:00"; ! 24: ! 25: main(argc, argv) ! 26: int argc; ! 27: char **argv; ! 28: { ! 29: register int c; ! 30: struct tm then; ! 31: extern int optind; /* defined in getopt */ ! 32: extern char *optarg; /* defined in getopt */ ! 33: int getopt(); ! 34: long secsfr70(); ! 35: ! 36: while ((c = getopt (argc, argv, "f:")) != EOF) ! 37: { ! 38: switch (c) ! 39: { ! 40: case 'f': ! 41: defaultformat = optarg; ! 42: break; ! 43: default: ! 44: fprintf(stderr, "usage: %s [-f format] [datespec]\n", argv[0]); ! 45: exit (1); ! 46: } ! 47: } ! 48: argc -= optind; ! 49: argv += optind; ! 50: ! 51: finddate(&now, dayspast = (int)(secsfr70()/86400L)); ! 52: ! 53: if (argc <= 0) /* get from user */ ! 54: { ! 55: if (!promptdate(&then)) ! 56: exit(1); ! 57: printdate(&then, defaultformat); ! 58: } ! 59: else /* get from command line */ ! 60: { ! 61: if (!decodedate(argv[0], &then)) ! 62: exit(1); ! 63: printdate(&then, defaultformat); ! 64: } ! 65: exit(0); ! 66: } ! 67: ! 68: int promptdate(when) ! 69: struct tm *when; ! 70: { ! 71: char line[MAXLINE]; ! 72: int decodedate(); ! 73: char *gets(); ! 74: ! 75: for (;;) ! 76: { ! 77: fprintf(stderr, "When? "); ! 78: if (gets(line) == NULL) ! 79: { ! 80: fprintf(stderr, "\n"); ! 81: return (0); ! 82: } ! 83: if (decodedate(line, when)) ! 84: return (1); ! 85: } ! 86: /*NOTREACHED*/ ! 87: } ! 88: ! 89: int decodedate(line, when) ! 90: char *line; ! 91: struct tm *when; ! 92: /* ! 93: ** accept spec for date in several forms ! 94: ** legal are: sun,mon,tue,wed,thu,fri,sat,today,tomorrow, ! 95: ** <date><month>,+<relative number of days> ! 96: ** <month> should be alpha ! 97: ** upper case accepted too ! 98: */ ! 99: { ! 100: char s[4]; ! 101: register int i,targetdate; ! 102: int tem; ! 103: register char *lptr; ! 104: ! 105: when->tm_year = now.tm_year; ! 106: when->tm_mon = now.tm_mon; ! 107: targetdate = dayspast; ! 108: for (lptr = line; isspace(*lptr); lptr++) ! 109: ; ! 110: if (isdigit(*lptr)) ! 111: { ! 112: i = sscanf(lptr, "%d%3s%d", &when->tm_mday, s, &tem); ! 113: switch(i) ! 114: { ! 115: case 3: ! 116: when->tm_year = tem; ! 117: case 2: ! 118: fold(s); ! 119: when->tm_mon = monthofyear(s); ! 120: if (i == 3) ! 121: break; ! 122: if (when->tm_mday != 0 && when->tm_mon != 0 && daysfr70(when) < dayspast) ! 123: when->tm_year++; ! 124: break; ! 125: case 1: ! 126: if (when->tm_mday != 0 && when->tm_mday < now.tm_mday) ! 127: { ! 128: if (++when->tm_mon > 12) ! 129: { ! 130: when->tm_mon = 1; ! 131: when->tm_year++; ! 132: } ! 133: } ! 134: } ! 135: return (validate(when)); ! 136: } ! 137: if (isalpha(*lptr)) ! 138: { ! 139: sscanf(lptr, "%3s", s); ! 140: fold(s); ! 141: if ((tem = dayofweek(s)) >= 0) ! 142: targetdate += (tem -= now.tm_wday) <= 0 ? tem + 7 : tem; ! 143: else if (strcmp(s, "Tom") == 0) ! 144: targetdate++; ! 145: else if (strcmp(s, "Tod") == 0) ! 146: ; ! 147: else /* mistake */ ! 148: return (0); ! 149: } ! 150: else if (*lptr == '+') ! 151: { ! 152: if (sscanf(++lptr, "%d", &tem) == 0 || tem < 0) /* mistake */ ! 153: return (0); ! 154: targetdate += tem; ! 155: } ! 156: else /* mistake by default */ ! 157: return (0); ! 158: finddate(when, targetdate); ! 159: return (when->tm_mday != 0); ! 160: } ! 161: ! 162: int validate(datetm) ! 163: /* ! 164: ** check that a given date and month combination is legal ! 165: ** datetm->tm_year must hold the year in question ! 166: */ ! 167: register struct tm *datetm; ! 168: { ! 169: ! 170: return (datetm->tm_mday <= monthlen[leapyear(datetm->tm_year)] ! 171: [datetm->tm_mon] && datetm->tm_mday > 0); ! 172: } ! 173: ! 174: finddate(datetm, df70) ! 175: /* ! 176: ** convert days from 1 jan 1970 to a date in struct datetm ! 177: */ ! 178: register int df70; ! 179: register struct tm *datetm; ! 180: { ! 181: register struct tm *tdtm; ! 182: long longtime; ! 183: struct tm *gmtime(); ! 184: ! 185: longtime = df70 * 86400L; ! 186: tdtm = gmtime(&longtime); ! 187: datetm->tm_yday = tdtm->tm_yday; ! 188: datetm->tm_wday = tdtm->tm_wday; ! 189: datetm->tm_year = tdtm->tm_year + 1900; ! 190: datetm->tm_mon = tdtm->tm_mon; ! 191: datetm->tm_mday = tdtm->tm_mday; ! 192: datetm->tm_hour = tdtm->tm_hour; ! 193: datetm->tm_min = tdtm->tm_min; ! 194: datetm->tm_sec = tdtm->tm_sec; ! 195: } ! 196: ! 197: fold(s) ! 198: /* ! 199: ** convert first character to uppercase ! 200: ** convert rest of string from uppercase to lower case ! 201: */ ! 202: register char *s; ! 203: { ! 204: register char c; ! 205: ! 206: if ((c = *s) != '\0') ! 207: *s++ += islower(c) ? 'A' - 'a' : 0; ! 208: while ((c = *s) != '\0') ! 209: *s++ += isupper(c) ? 'a' - 'A' : 0; ! 210: } ! 211: ! 212: int leapyear(y) ! 213: /* ! 214: ** returns 1 if leapyear 0 otherwise ! 215: */ ! 216: register int y; ! 217: { ! 218: ! 219: return (((y % 4) == 0 && (y % 100) != 0) || (y % 400) == 0); ! 220: } ! 221: ! 222: int daysfr70(datetm) ! 223: /* ! 224: ** returns the number of days from 1 Jan 1970 ! 225: ** no checking for illegal date at all ! 226: */ ! 227: register struct tm *datetm; ! 228: { ! 229: register int i, totdays; ! 230: ! 231: ! 232: totdays = 0; ! 233: for (i = 1970; i <= 2050 && i < datetm->tm_year; i++) /* prevent overflow */ ! 234: totdays += 365 + leapyear(i); ! 235: for (i = 0; i < 12 && i < datetm->tm_mon; i++) ! 236: totdays += monthlen[leapyear(datetm->tm_year)][i]; ! 237: totdays += datetm->tm_mday - 1; ! 238: return (totdays); ! 239: } ! 240: ! 241: int monthofyear(s) ! 242: /* ! 243: ** returns month of year in numeric form when given ! 244: ** the first three letters ! 245: */ ! 246: register char *s; ! 247: { ! 248: register int i; ! 249: ! 250: fold(s); ! 251: for (i = 12; i-- && strcmp(s,mname[i]); ) ! 252: ; ! 253: return (i); ! 254: } ! 255: ! 256: int dayofweek(s) ! 257: /* ! 258: ** sunday = 0,...,saturday = 6, nomatch = -1 ! 259: */ ! 260: register char *s; ! 261: { ! 262: register int i; ! 263: ! 264: fold(s); ! 265: for (i = 7; i-- && strcmp(s,dname[i]); ) ! 266: ; ! 267: return (i); ! 268: } ! 269: ! 270: printdate(date, format) ! 271: /* ! 272: ** print date in MH acceptable format ! 273: ** kludge - general formats are not implemented ! 274: */ ! 275: struct tm *date; ! 276: char *format; ! 277: { ! 278: printf("%d %s %d 00:00\n", ! 279: date->tm_mday, mname[date->tm_mon], date->tm_year); ! 280: } ! 281: ! 282: long secsfr70() ! 283: /* ! 284: ** This is system dependent ! 285: */ ! 286: { ! 287: register int dst; ! 288: struct timeval tv; ! 289: struct timezone tz; ! 290: struct tm *localtime(); ! 291: ! 292: gettimeofday(&tv, &tz); ! 293: dst = localtime(&tv.tv_sec)->tm_isdst; ! 294: return (tv.tv_sec - tz.tz_minuteswest * 60 + (dst ? 3600 : 0)); ! 295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.