v07i120: cal(1) - print calendar
Brandon S. Allbery - comp.sources.misc
allbery at uunet.UU.NET
Sun Aug 6 12:20:51 AEST 1989
Posting-number: Volume 7, Issue 120
Submitted-by: vojta%math.Berkeley.EDU at 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 at 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 at 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
More information about the Comp.sources.misc
mailing list