home *** CD-ROM | disk | FTP | other *** search
- /* cal.c - print calendar for one month or one year
- *
- * cal [[month] year]
- *
- * cal (C) 1988 by Gary L. Brant
- */
-
- #include <stdio.h>
- #include <time.h>
- #include <ctype.h>
- #include <string.h>
- #include <sys/types.h>
-
- #define blank(addr, len) (void) memset(addr, ' ', len)
-
- #define DPY 365L /* days per year */
- #define FUDGE1 1 /* needed to make day of week come out right */
- #define FUDGE2 6 /* for old style (Julian) calendar */
- #define LINEWID 71 /* width of array line[] */
-
- int days[12] = {
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- };
- int mdays[13] = {
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- };
- char *months[12] = {
- "January ", "February ", "March ", "April ", "May ", "June ",
- "July " , "August " , "September ", "October ", "November ", "December "
- };
- char monthline[] = "\t ---\t\t\t---\t\t ---";
- char *monthpos[3] = {monthline+2, monthline+8, monthline+20};
- char dayline[] = " S M Tu W Th F S";
- char line[7][LINEWID]; /* line buffer */
- int multi = 0;
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i, k, m, y;
- time_t t;
- struct tm *lcl_tim;
-
- t = time((time_t *) 0);
- lcl_tim = localtime(&t);
- y = lcl_tim->tm_year + 1900;
- m = lcl_tim->tm_mon + 1;
- if (argc == 1) {
- fixtab (y);
- printmonth (m, y);
- exit (0);
- }
-
- if ((k = atoi (argv[1])) == 0) {
- m = 0;
- for (i = 0; i < 12; i++)
- if (cmpmonth (argv[1], months[i]) == 0) {
- m = i + 1;
- break;
- }
- if (m == 0) {
- badarg (argv[1]);
- }
- }
-
- if (argc == 2) {
- if (k == 0) {
- fixtab (y);
- printmonth (m, y);
- } else {
- multi = 1;
- fixtab (k);
- fputs("\n\n\n\t\t\t\t", stdout);
- putd(k); /* put year */
- putchar('\n');
- for (m = 1; m < 13; m++)
- printmonth (m, k);
- puts("\n\n");
- }
- exit (0);
- }
-
- if (k > 0 && k < 13)
- m = k;
- else if (m == 0 || k != 0) {
- badarg (argv[1]);
- }
-
- if (argc == 3) {
- if ((y = atoi (argv[2])) == 0) {
- badarg (argv[2]);
- }
- }
- fixtab (y);
- printmonth (m, y);
- }
-
-
- /* printmonth () - either prints an entire month at a time or multiplexes
- * a month into a buffer, dumping the buffer after the third call.
- */
- printmonth (m, y)
- register int m;
- int y;
- {
- register int first, last;
- register int index, p = 0;
- register char *ll;
- static int q = 0;
- int l;
-
- --m;
- if (multi) {
- q++;
- if (q > 3)
- q = 1;
- p = 23 * (q - 1); /* character position of line in buffer */
- (void) memcpy(monthpos[q-1], months[m], 3); /* copy month name */
- if (q == 3) {
- puts(monthline);
- for (index = 0; index < 2; ++index) {
- fputs(dayline, stdout);
- fputs(" ", stdout);
- }
- puts(dayline);
- }
- else
- blank(line[0]+p+12, 11);
- } else {
- q = 1;
- fputs(" ", stdout);
- fputs(months[m], stdout); /* put month name */
- putd(y); /* put year */
- puts(dayline);
- }
-
- l = 1;
- if (p == 0) blank(line[1], 6*LINEWID);
-
- if (y == 1752 && m == 8) { /* special case Sep. 1752 */
- line[1][p + 7] = '1';
- line[1][p + 10] = '2';
- first = 14;
- last = 16;
- index = 12;
- }
- else {
- int dow; /* day of week for first day of month */
-
- first = 1;
- dow = weekday (m, y);
- last = 7 - dow;
- index = 3 * dow;
- }
-
- for (; l < 7; ++l) { /* loop thru month one week per line */
- ll = line[l] + p;
- while (first <= last) { /* for each day in week encode day of month */
- if (first >= 10)
- ll[index] = '0' + first / 10;
- ll[index+1] = '0' + first % 10;
- index += 3;
- ++first;
- }
- if (!multi || q == 3) {
- index += p - 2;
- if (index < 0) index = 0;
- ll -= p;
- while (index >= 0 && ll[index] == ' ')
- --index;
- ll[index+1] = '\0';
- puts(ll);
- }
- last = (last + 7) > days[m] ? days[m] : last + 7;
- index = 0;
- }
-
- }
-
-
- /* putd - put year to standard output.
- */
- putd (n)
- register int n;
- {
- char str[5];
- register char *p = str+4;
-
- *p = '\0';
- do {
- --p;
- *p = '0' + n % 10;
- n = n / 10;
- }
- while (n);
- puts(p);
- }
-
-
- /* fixtab - correct for leapyears.
- */
- fixtab (y)
- register int y;
- {
- register int i;
-
- if ((y % 4) == 0) {
- if (((y % 100) != 0) || ((y % 400) == 0) || (y < 1753)) {
- days[1] = 29;
- for (i = 2; i < 13; i++)
- mdays[i]++;
- }
- }
- }
-
-
- /* weekday - return day-of-week for first day of month.
- */
- weekday (m, y)
- register int m, y;
- {
- --y;
- if (y > 1752-1 || (y == 1752-1 && m > 8))
- return (mdays[m] + y + y / 4 - y / 100 + y / 400 + FUDGE1) % 7;
- else
- return (mdays[m] + y + y / 4 + FUDGE2) % 7;
- }
-
-
-
- badarg (string)
- char string[];
- {
- fputs(string, stderr);
- fputs(" bad argument\n", stderr);
- exit (10);
- }
-
-
- /* cmpmonth () - compare month argument entered by user with month name.
- * The comparison will be made case insensitive.
- */
- cmpmonth (str1, str2)
- register char str1[], str2[];
- {
- register int j;
-
- if ((j = (toupper(str1[0])-str2[0])) != 0)
- return (j);
- else if ((j = tolower(str1[1])-str2[1]) != 0)
- return (j);
- else
- return (tolower(str1[2])-str2[2]);
- }
-