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

Defined functions

dayofweek defined in line 256; used 1 times
daysfr70 defined in line 222; used 1 times
decodedate defined in line 89; used 3 times
finddate defined in line 174; used 2 times
fold defined in line 197; used 4 times
leapyear defined in line 212; used 3 times
main defined in line 25; never used
monthofyear defined in line 241; used 1 times
printdate defined in line 270; used 2 times
promptdate defined in line 68; used 1 times
  • in line 55
secsfr70 defined in line 282; used 2 times
validate defined in line 162; used 1 times

Defined variables

dayspast defined in line 19; used 3 times
defaultformat defined in line 23; used 3 times
dname defined in line 16; used 1 times
mname defined in line 13; used 2 times
monthlen defined in line 20; used 2 times
now defined in line 18; used 5 times

Defined macros

MAXLINE defined in line 11; used 1 times
  • in line 71
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1365
Valid CSS Valid XHTML 1.0 Strict