Annotation of 43BSD/contrib/mh/miscellany/mem/promptdate.c, revision 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.