allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (08/06/89)
Posting-number: Volume 7, Issue 120 Submitted-by: vojta%math.Berkeley.EDU@ucbvax.Berkeley.EDU Archive-name: cal Here's a version of cal(1) which I got from comp.sources.amiga. I've spiffed it up to work under BSD Un*x and Turbo C, and added a man page. Enjoy. --Paul Vojta, vojta@math.berkeley.edu #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: cal.1 cal.c # Wrapped by vojta@maypo on Sat Aug 5 18:02:33 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'cal.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cal.1'\" else echo shar: Extracting \"'cal.1'\" \(491 characters\) sed "s/^X//" >'cal.1' <<'END_OF_FILE' X.TH CAL 1 "5 Aug 1989" COMP.SOURCES.AMIGA X.SH NAME Xcal \- print calendar X.SH SYNOPSIS X.B cal X[[month] year] X.SH DESCRIPTION X.I Cal Xis a program which prints out a calendar either for a given month or for a Xgiven year. By default, it prints a calendar for the current month. It Xcorrectly handles the transition from the Julian to Gregorian calendars Xin September 1752 (at least in England and colonies). X.SH BUGS XNote that `cal 89' refers to 89 A. D., not to 1989. X.SH AUTHOR XGary L. Brant END_OF_FILE if test 491 -ne `wc -c <'cal.1'`; then echo shar: \"'cal.1'\" unpacked with wrong size! fi # end of 'cal.1' fi if test -f 'cal.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'cal.c'\" else echo shar: Extracting \"'cal.c'\" \(5158 characters\) sed "s/^X//" >'cal.c' <<'END_OF_FILE' X/* cal.c - print calendar for one month or one year X * X * cal [[month] year] X * X * cal (C) 1988 by Gary L. Brant X */ X X#include <stdio.h> X#include <time.h> X#include <ctype.h> X#include <string.h> X#include <sys/types.h> X X#define blank(addr, len) (void) memset(addr, ' ', len) X X#define DPY 365L /* days per year */ X#define FUDGE1 1 /* needed to make day of week come out right */ X#define FUDGE2 6 /* for old style (Julian) calendar */ X#define LINEWID 71 /* width of array line[] */ X Xint days[12] = { X 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 X}; Xint mdays[13] = { X 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 X}; Xchar *months[12] = { X "January ", "February ", "March ", "April ", "May ", "June ", X "July " , "August " , "September ", "October ", "November ", "December " X}; Xchar monthline[] = "\t ---\t\t\t---\t\t ---"; Xchar *monthpos[3] = {monthline+2, monthline+8, monthline+20}; Xchar dayline[] = " S M Tu W Th F S"; Xchar line[7][LINEWID]; /* line buffer */ Xint multi = 0; X X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int i, k, m, y; X time_t t; X struct tm *lcl_tim; X X t = time((time_t *) 0); X lcl_tim = localtime(&t); X y = lcl_tim->tm_year + 1900; X m = lcl_tim->tm_mon + 1; X if (argc == 1) { X fixtab (y); X printmonth (m, y); X exit (0); X } X X if ((k = atoi (argv[1])) == 0) { X m = 0; X for (i = 0; i < 12; i++) X if (cmpmonth (argv[1], months[i]) == 0) { X m = i + 1; X break; X } X if (m == 0) { X badarg (argv[1]); X } X } X X if (argc == 2) { X if (k == 0) { X fixtab (y); X printmonth (m, y); X } else { X multi = 1; X fixtab (k); X fputs("\n\n\n\t\t\t\t", stdout); X putd(k); /* put year */ X putchar('\n'); X for (m = 1; m < 13; m++) X printmonth (m, k); X puts("\n\n"); X } X exit (0); X } X X if (k > 0 && k < 13) X m = k; X else if (m == 0 || k != 0) { X badarg (argv[1]); X } X X if (argc == 3) { X if ((y = atoi (argv[2])) == 0) { X badarg (argv[2]); X } X } X fixtab (y); X printmonth (m, y); X} X X X/* printmonth () - either prints an entire month at a time or multiplexes X * a month into a buffer, dumping the buffer after the third call. X */ Xprintmonth (m, y) Xregister int m; Xint y; X{ X register int first, last; X register int index, p = 0; X register char *ll; X static int q = 0; X int l; X X --m; X if (multi) { X q++; X if (q > 3) X q = 1; X p = 23 * (q - 1); /* character position of line in buffer */ X (void) memcpy(monthpos[q-1], months[m], 3); /* copy month name */ X if (q == 3) { X puts(monthline); X for (index = 0; index < 2; ++index) { X fputs(dayline, stdout); X fputs(" ", stdout); X } X puts(dayline); X } X else X blank(line[0]+p+12, 11); X } else { X q = 1; X fputs(" ", stdout); X fputs(months[m], stdout); /* put month name */ X putd(y); /* put year */ X puts(dayline); X } X X l = 1; X if (p == 0) blank(line[1], 6*LINEWID); X X if (y == 1752 && m == 8) { /* special case Sep. 1752 */ X line[1][p + 7] = '1'; X line[1][p + 10] = '2'; X first = 14; X last = 16; X index = 12; X } X else { X int dow; /* day of week for first day of month */ X X first = 1; X dow = weekday (m, y); X last = 7 - dow; X index = 3 * dow; X } X X for (; l < 7; ++l) { /* loop thru month one week per line */ X ll = line[l] + p; X while (first <= last) { /* for each day in week encode day of month */ X if (first >= 10) X ll[index] = '0' + first / 10; X ll[index+1] = '0' + first % 10; X index += 3; X ++first; X } X if (!multi || q == 3) { X index += p - 2; X if (index < 0) index = 0; X ll -= p; X while (index >= 0 && ll[index] == ' ') X --index; X ll[index+1] = '\0'; X puts(ll); X } X last = (last + 7) > days[m] ? days[m] : last + 7; X index = 0; X } X X} X X X/* putd - put year to standard output. X */ Xputd (n) Xregister int n; X{ X char str[5]; X register char *p = str+4; X X *p = '\0'; X do { X --p; X *p = '0' + n % 10; X n = n / 10; X } X while (n); X puts(p); X} X X X/* fixtab - correct for leapyears. X */ Xfixtab (y) Xregister int y; X{ X register int i; X X if ((y % 4) == 0) { X if (((y % 100) != 0) || ((y % 400) == 0) || (y < 1753)) { X days[1] = 29; X for (i = 2; i < 13; i++) X mdays[i]++; X } X } X} X X X/* weekday - return day-of-week for first day of month. X */ Xweekday (m, y) Xregister int m, y; X{ X --y; X if (y > 1752-1 || (y == 1752-1 && m > 8)) X return (mdays[m] + y + y / 4 - y / 100 + y / 400 + FUDGE1) % 7; X else X return (mdays[m] + y + y / 4 + FUDGE2) % 7; X} X X X Xbadarg (string) Xchar string[]; X{ X fputs(string, stderr); X fputs(" bad argument\n", stderr); X exit (10); X} X X X/* cmpmonth () - compare month argument entered by user with month name. X * The comparison will be made case insensitive. X */ Xcmpmonth (str1, str2) Xregister char str1[], str2[]; X{ X register int j; X X if ((j = (toupper(str1[0])-str2[0])) != 0) X return (j); X else if ((j = tolower(str1[1])-str2[1]) != 0) X return (j); X else X return (tolower(str1[2])-str2[2]); X} END_OF_FILE if test 5158 -ne `wc -c <'cal.c'`; then echo shar: \"'cal.c'\" unpacked with wrong size! fi # end of 'cal.c' fi echo shar: End of shell archive. exit 0