[net.sources] CALFORM -- print a calendar

silvert@dalcs.UUCP (03/13/87)

Here is a program that prints a calendar starting on any day of the week
for an arbitrary number of weeks.  No manual page, but if you print
"calform" without any arguments you get a help menu.  Great for printing
calendars for trip planning.

I haven't checked for portability, but with relatively minor changes
this compiles with C/80 on a CP/M system.  This version runs on Sys V
Ver. 2 Unix, and portability depends on having a complete implementation
of the K&R printf formats.

/* program to create calendar forms of various widths -- W. Silvert */
static char SCCSID[] = "@(#)calform.c	Ver. 1.8, 87/03/12 15:19:54";
struct months {
	char *name;
	int length;
} m[] = {	/* months mod 12 */
	"December",31,
	"January",31,
	"February",28,
	"March",31,
	"April",30,
	"May ",31,	/* note blank to expand to 4 bytes */
	"June",30,
	"July",31,
	"August",31,
	"September",30,
	"October",31,
	"November",30
};
char *week[] = {"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
/* Formatting information */
#define WEEK	" %-9s%s"
#define BAR	"|_________%s"
#define SPACE	"|         %s"
#define DLINE	"| %.3s%c %2d %s"
#define ENDLIN	"|\n"
char *fill[]={""," ","  ","   ","    ","     ","      ","       ","        "};
char *rill[]={"","_","__","___","____","_____","______","_______","________"};
int argint[3], month, nlines; /* argint={month, day, nweeks} */
int length=62, width=1; /* default length and width */
int day0=1;		/* starting weekday is taken to be Monday */
char *progname;
main(argc,argv)
	int argc;
	char *argv[];
{
	int index=2 ;
	char c;
	progname = argv[0];
	if(argc < 4)	/* error processing */
		help();
	/* process arguments for -l and -w here */
	while(--argc > 0) {
		switch(c = argv[argc][0]) {
		case '-':	/* flag */
			switch(c = argv[argc][1]) {
			case 'l':	/* next part of argument is length */
				length=atoi(argv[argc]+2);
				break;
			case 'w':	/* next part of argument is width */
				width=atoi(argv[argc]+2);
				width=(width - 71)/7;
				if(width < 0 || width >8) {
					printf("Illegal width\n");
					exit(1);
				}
				break;
			case 'L':	/* leap year correction */
				m[2].length=29;
				break;
			case 'd':	/* starting day */
				day0=atoi(argv[argc]+2);
				break;
			default:
				printf("Unknown flag %s\n",argv[argc]);
				help();
			}
			break;
		default:	/* should test for digits here */
			argint[index]=atoi(argv[argc]);
			if(index-- < 0) {
				printf("Too many arguments\n");
				help();
			}
			break;
		}
	}
	month = argint[0] % 12 ;
	nlines = (length - 2) / argint[2] ;
	do_top(); /* print header and first bar */
	while(argint[2]-- > 0) { /* main loop */
		do_date();
		do_fill(nlines);
		do_bar();
	}
}
do_top() /* printer header with days of week */
{
	int i;
	for(i=day0;i<day0+7;printf(WEEK,week[i++%7],fill[width]));
	printf("\n");
	do_bar();
	return;
}
do_date() /* enter row of dates */
{
	int i;
	for (i=0;i++ <7;) { /* print "Jan." or "June", etc. */
		printf(DLINE,	m[month].name,
				m[month].name[4]?'.':m[month].name[3],
				argint[1]++,fill[width]);
		if(argint[1] > m[month].length) {
			argint[1]=1;
			month= ++month % 12;
		}
	}
	printf(ENDLIN);
	return;
}
do_fill(n) /* print n-2 blank lines */
	int n;
{
	int i;
	while(n-- > 2) {
		for(i=0;i++<7;printf(SPACE,fill[width]));
		printf(ENDLIN);
	}
	return;
}
do_bar() /* draw a bar across */
{
	int i;
	for(i=0;i++<7;printf(BAR,rill[width]));
	printf(ENDLIN);
	return;
}
help()
{
	printf("\nUsage: %s [-lnn] [-wnn] [-L] [-dn] month day #weeks\n",
				progname);
	printf("\t-l sets lines, -w sets width, -L for leap year\n");
	printf("\t-d sets starting day (0=Sun., 6=Sat., default=Mon.)\n");
	printf("Example: %s -l24 -w90 -L -d0 12 25 10\n", progname);
	printf("\tprints a 10-week calendar starting on Christmas, a Sunday,\n");
	printf("\tbefore a leap year with 24 lines and 90 columns maximum.\n\n");
	exit();
}
-- 
Bill Silvert
Marine Ecology Laboratory, Dartmouth, NS, Canada
CDN or BITNET: silvert@cs.dal.cdn	-- UUCP: ..!{seismo|utai}!dalcs!silvert
ARPA: silvert%dalcs.uucp@seismo.CSS.GOV	-- CSNET: silvert%cs.dal.cdn@ubc.csnet