Annotation of 43BSD/contrib/mh/miscellany/mem/promptdate.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.