Annotation of 43BSDReno/usr.bin/cal/cal.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * This code is derived from software contributed to Berkeley by
        !             6:  * Kim Letkeman.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms are permitted
        !             9:  * provided that: (1) source distributions retain this entire copyright
        !            10:  * notice and comment, and (2) distributions including binaries display
        !            11:  * the following acknowledgement:  ``This product includes software
        !            12:  * developed by the University of California, Berkeley and its contributors''
        !            13:  * in the documentation or other materials provided with the distribution
        !            14:  * and in all advertising materials mentioning features or use of this
        !            15:  * software. Neither the name of the University nor the names of its
        !            16:  * contributors may be used to endorse or promote products derived
        !            17:  * from this software without specific prior written permission.
        !            18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            21:  */
        !            22: 
        !            23: #ifndef lint
        !            24: char copyright[] =
        !            25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
        !            26:  All rights reserved.\n";
        !            27: #endif /* not lint */
        !            28: 
        !            29: #ifndef lint
        !            30: static char sccsid[] = "@(#)cal.c      4.8 (Berkeley) 6/1/90";
        !            31: #endif /* not lint */
        !            32: 
        !            33: #include <sys/types.h>
        !            34: #include <sys/time.h>
        !            35: #include <stdio.h>
        !            36: #include <ctype.h>
        !            37: 
        !            38: #define        THURSDAY                4               /* for reformation */
        !            39: #define        SATURDAY                6               /* 1 Jan 1 was a Saturday */
        !            40: #define        FIRST_MISSING_DAY       639787          /* 3 Sep 1752 */
        !            41: #define        NUMBER_MISSING_DAYS     11              /* 11 day correction */
        !            42: #define        SPACE                   -1              /* used in day array */
        !            43: 
        !            44: static int days_in_month[2][13] = {
        !            45:        {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        !            46:        {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
        !            47: };
        !            48: 
        !            49: static int sep1752[42] = {
        !            50:        SPACE,  SPACE,  1,      2,      14,     15,     16,
        !            51:        17,     18,     19,     20,     21,     22,     23,
        !            52:        24,     25,     26,     27,     28,     29,     30,
        !            53:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            54:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            55:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            56: }, j_sep1752[42] = {
        !            57:        SPACE,  SPACE,  245,    246,    258,    259,    260,
        !            58:        261,    262,    263,    264,    265,    266,    267,
        !            59:        268,    269,    270,    271,    272,    273,    274,
        !            60:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            61:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            62:        SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,  SPACE,
        !            63: };
        !            64: 
        !            65: static char *month_names[12] = {
        !            66:        "January", "February", "March", "April", "May", "June",
        !            67:        "July", "August", "September", "October", "November", "December",
        !            68: };
        !            69: 
        !            70: static char *day_headings = " S  M  Tu W  Th F  S";
        !            71: static char *j_day_headings = " S   M   Tu  W   Th  F   S";
        !            72: 
        !            73: /* leap year -- account for gregorian reformation in 1752 */
        !            74: #define        leap_year(yr) \
        !            75:        ((yr) <= 1752 ? !((yr) % 4) : \
        !            76:        !((yr) % 4) && ((yr) % 100) || !((yr) % 400))
        !            77: 
        !            78: /* number of centuries since 1700, not inclusive */
        !            79: #define        centuries_since_1700(yr) \
        !            80:        ((yr) > 1700 ? (yr) / 100 - 17 : 0)
        !            81: 
        !            82: /* number of centuries since 1700 whose modulo of 400 is 0 */
        !            83: #define        quad_centuries_since_1700(yr) \
        !            84:        ((yr) > 1600 ? ((yr) - 1600) / 400 : 0)
        !            85: 
        !            86: /* number of leap years between year 1 and this year, not inclusive */
        !            87: #define        leap_years_since_year_1(yr) \
        !            88:        ((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
        !            89: 
        !            90: int julian;
        !            91: 
        !            92: main(argc, argv)
        !            93:        int argc;
        !            94:        char **argv;
        !            95: {
        !            96:        extern char *optarg;
        !            97:        extern int optind;
        !            98:        struct tm *local_time;
        !            99:        time_t now, time();
        !           100:        int ch, month, year, yflag;
        !           101: 
        !           102:        yflag = 0;
        !           103:        while ((ch = getopt(argc, argv, "jy")) != EOF)
        !           104:                switch(ch) {
        !           105:                case 'j':
        !           106:                        julian = 1;
        !           107:                        break;
        !           108:                case 'y':
        !           109:                        yflag = 1;
        !           110:                        break;
        !           111:                case '?':
        !           112:                default:
        !           113:                        usage();
        !           114:                }
        !           115:        argc -= optind;
        !           116:        argv += optind;
        !           117: 
        !           118:        switch(argc) {
        !           119:        case 2:
        !           120:                if ((month = atoi(*argv++)) <= 0 || month > 12) {
        !           121:                        (void)fprintf(stderr, "cal: illegal month value.\n");
        !           122:                        exit(1);
        !           123:                }
        !           124:                /* FALLTHROUGH */
        !           125:        case 1:
        !           126:                if ((year = atoi(*argv)) <= 0 || year > 9999) {
        !           127:                        (void)fprintf(stderr, "cal: illegal year value.\n");
        !           128:                        exit(1);
        !           129:                }
        !           130:                break;
        !           131:        case 0:
        !           132:                (void)time(&now);
        !           133:                local_time = localtime(&now);
        !           134:                year = local_time->tm_year + 1900;
        !           135:                if (!yflag)
        !           136:                        month = local_time->tm_mon + 1;
        !           137:                break;
        !           138:        default:
        !           139:                usage();
        !           140:        }
        !           141:        if (month)
        !           142:                monthly(month, year);
        !           143:        else if (julian)
        !           144:                j_yearly(year);
        !           145:        else
        !           146:                yearly(year);
        !           147:        exit(0);
        !           148: }
        !           149: 
        !           150: #define        DAY_LEN         3               /* 3 spaces per day */
        !           151: #define        J_DAY_LEN       4               /* 4 spaces per day */
        !           152: #define        WEEK_LEN        20              /* 7 * 3 - one space at the end */
        !           153: #define        J_WEEK_LEN      27              /* 7 * 4 - one space at the end */
        !           154: #define        HEAD_SEP        2               /* spaces between day headings */
        !           155: #define        J_HEAD_SEP      3
        !           156: 
        !           157: monthly(month, year)
        !           158:        int month, year;
        !           159: {
        !           160:        register int col, row;
        !           161:        register char *p;
        !           162:        int len, days[42];
        !           163:        char lineout[30];
        !           164: 
        !           165:        day_array(month, year, days);
        !           166:        len = sprintf(lineout, "%s %d", month_names[month - 1], year);
        !           167:        (void)printf("%*s%s\n%s\n",
        !           168:            ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "",
        !           169:            lineout, julian ? j_day_headings : day_headings);
        !           170:        for (row = 0; row < 6; row++) {
        !           171:                for (col = 0, p = lineout; col < 7; col++,
        !           172:                    p += julian ? J_DAY_LEN : DAY_LEN)
        !           173:                        ascii_day(p, days[row * 7 + col]);
        !           174:                trim_trailing_spaces(lineout);
        !           175:                (void)printf("%s\n", lineout);
        !           176:        }
        !           177: }
        !           178: 
        !           179: j_yearly(year)
        !           180:        int year;
        !           181: {
        !           182:        register int col, *dp, i, month, row, which_cal;
        !           183:        register char *p;
        !           184:        int days[12][42];
        !           185:        char lineout[80];
        !           186: 
        !           187:        (void)sprintf(lineout, "%d", year);
        !           188:        center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0);
        !           189:        (void)printf("\n\n");
        !           190:        for (i = 0; i < 12; i++)
        !           191:                day_array(i + 1, year, &days[i][0]);
        !           192:        (void)memset(lineout, ' ', sizeof(lineout) - 1);
        !           193:        lineout[sizeof(lineout) - 1] = '\0';
        !           194:        for (month = 0; month < 12; month += 2) {
        !           195:                center(month_names[month], J_WEEK_LEN, J_HEAD_SEP);
        !           196:                center(month_names[month + 1], J_WEEK_LEN, 0);
        !           197:                (void)printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "",
        !           198:                    j_day_headings);
        !           199:                for (row = 0; row < 6; row++) {
        !           200:                        for (which_cal = 0; which_cal < 2; which_cal++) {
        !           201:                                p = lineout + which_cal * (J_WEEK_LEN + 2);
        !           202:                                dp = &days[month + which_cal][row * 7];
        !           203:                                for (col = 0; col < 7; col++, p += J_DAY_LEN)
        !           204:                                        ascii_day(p, *dp++);
        !           205:                        }
        !           206:                        trim_trailing_spaces(lineout);
        !           207:                        (void)printf("%s\n", lineout);
        !           208:                }
        !           209:        }
        !           210:        (void)printf("\n");
        !           211: }
        !           212: 
        !           213: yearly(year)
        !           214:        int year;
        !           215: {
        !           216:        register int col, *dp, i, month, row, which_cal;
        !           217:        register char *p;
        !           218:        int days[12][42];
        !           219:        char lineout[80];
        !           220: 
        !           221:        (void)sprintf(lineout, "%d", year);
        !           222:        center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0);
        !           223:        (void)printf("\n\n");
        !           224:        for (i = 0; i < 12; i++)
        !           225:                day_array(i + 1, year, &days[i][0]);
        !           226:        (void)memset(lineout, ' ', sizeof(lineout) - 1);
        !           227:        lineout[sizeof(lineout) - 1] = '\0';
        !           228:        for (month = 0; month < 12; month += 3) {
        !           229:                center(month_names[month], WEEK_LEN, HEAD_SEP);
        !           230:                center(month_names[month + 1], WEEK_LEN, HEAD_SEP);
        !           231:                center(month_names[month + 2], WEEK_LEN, 0);
        !           232:                (void)printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP,
        !           233:                    "", day_headings, HEAD_SEP, "", day_headings);
        !           234:                for (row = 0; row < 6; row++) {
        !           235:                        for (which_cal = 0; which_cal < 3; which_cal++) {
        !           236:                                p = lineout + which_cal * (WEEK_LEN + 2);
        !           237:                                dp = &days[month + which_cal][row * 7];
        !           238:                                for (col = 0; col < 7; col++, p += DAY_LEN)
        !           239:                                        ascii_day(p, *dp++);
        !           240:                        }
        !           241:                        trim_trailing_spaces(lineout);
        !           242:                        (void)printf("%s\n", lineout);
        !           243:                }
        !           244:        }
        !           245:        (void)printf("\n");
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * day_array --
        !           250:  *     Fill in an array of 42 integers with a calendar.  Assume for a moment
        !           251:  *     that you took the (maximum) 6 rows in a calendar and stretched them
        !           252:  *     out end to end.  You would have 42 numbers or spaces.  This routine
        !           253:  *     builds that array for any month from Jan. 1 through Dec. 9999.
        !           254:  */
        !           255: day_array(month, year, days)
        !           256:        register int *days;
        !           257:        int month, year;
        !           258: {
        !           259:        register int i, day, dw, dm, *p;
        !           260: 
        !           261:        dm = days_in_month[leap_year(year)][month];
        !           262:        dw = day_in_week(1, month, year);
        !           263:        if (month == 9 && year == 1752) {
        !           264:                p = julian ? j_sep1752 : sep1752;
        !           265:                for (i = 0; i < 42; i++)
        !           266:                        *days++ = *p++;
        !           267:                return;
        !           268:        }
        !           269:        for (i = 42, p = days; i--;)
        !           270:                *p++ = SPACE;
        !           271:        day = julian ? day_in_year(1, month, year) : 1;
        !           272:        while (dm--)
        !           273:                days[dw++] = day++;
        !           274: }
        !           275: 
        !           276: /*
        !           277:  * day_in_year --
        !           278:  *     return the 1 based day number within the year
        !           279:  */
        !           280: day_in_year(day, month, year)
        !           281:        register int day, month;
        !           282:        int year;
        !           283: {
        !           284:        register int i, leap;
        !           285: 
        !           286:        leap = leap_year(year);
        !           287:        for (i = 1; i < month; i++)
        !           288:                day += days_in_month[leap][i];
        !           289:        return(day);
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * day_in_week
        !           294:  *     return the 0 based day number for any date from 1 Jan. 1 to
        !           295:  *     31 Dec. 9999.  Assumes the Gregorian reformation eliminates
        !           296:  *     3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all
        !           297:  *     missing days.
        !           298:  */
        !           299: day_in_week(day, month, year)
        !           300:        int day, month, year;
        !           301: {
        !           302:        long temp;
        !           303: 
        !           304:        temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
        !           305:            + day_in_year(day, month, year);
        !           306:        if (temp < FIRST_MISSING_DAY)
        !           307:                return((temp - 1 + SATURDAY) % 7);
        !           308:        if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS))
        !           309:                return(((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
        !           310:        return(THURSDAY);
        !           311: }
        !           312: 
        !           313: ascii_day(p, day)
        !           314:        register char *p;
        !           315:        register int day;
        !           316: {
        !           317:        register int display, val;
        !           318: 
        !           319:        if (day == SPACE) {
        !           320:                memset(p, ' ', julian ? 4 : 3);
        !           321:                return;
        !           322:        }
        !           323:        display = 0;
        !           324:        if (julian) {
        !           325:                if (val = day / 100) {
        !           326:                        day %= 100;
        !           327:                        *p++ = val + '0';
        !           328:                        display = 1;
        !           329:                } else
        !           330:                        *p++ = ' ';
        !           331:        }
        !           332:        val = day / 10;
        !           333:        if (val || display)
        !           334:                *p++ = val + '0';
        !           335:        else
        !           336:                *p++ = ' ';
        !           337:        *p++ = day % 10 + '0';
        !           338:        *p = ' ';
        !           339: }
        !           340: 
        !           341: trim_trailing_spaces(s)
        !           342:        register char *s;
        !           343: {
        !           344:        register char *p;
        !           345: 
        !           346:        for (p = s; *p; ++p);
        !           347:        while (p > s && isspace(*--p));
        !           348:        if (p > s)
        !           349:                ++p;
        !           350:        *p = '\0';
        !           351: }
        !           352: 
        !           353: center(str, len, separate)
        !           354:        char *str;
        !           355:        register int len;
        !           356:        int separate;
        !           357: {
        !           358:        len -= strlen(str);
        !           359:        (void)printf("%*s%s%*s", len / 2, "", str, len / 2 + len % 2, "");
        !           360:        if (separate)
        !           361:                (void)printf("%*s", separate, "");
        !           362: }
        !           363: 
        !           364: usage()
        !           365: {
        !           366:        (void)fprintf(stderr, "usage: cal [-jy] [[month] year]\n");
        !           367:        exit(1);
        !           368: }

unix.superglobalmegacorp.com

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