[alt.sources] Pcal

jmasters@pcocd2.intel.com (Justin Masters ~) (01/31/90)

Is there any idea why pcal does not seem to work properly on a Sun386i?

-----------------------------------------------------------------------------
 "Beatings will continue until morale     |     Justin Masters
   improves."                             |
                 - management             | jmasters@fmdgr1.intel.com

covertr@force.UUCP (Richard E. Covert) (01/31/90)

In article <1546@mipos3.intel.com>, jmasters@pcocd2.intel.com (Justin Masters ~) writes:
> 
> 
> Is there any idea why pcal does not seem to work properly on a Sun386i?
> 
> -----------------------------------------------------------------------------
>  "Beatings will continue until morale     |     Justin Masters
>    improves."                             |
>                  - management             | jmasters@fmdgr1.intel.com

 
Well, pcal seems to work OK on our Apollo workstations but when I ported it
to my home computer (an Atari Mega ST4 running MarkWilliams C) it wouldn't
read the calendar file. It seems that the UNIX strtok() function operates
differently than the MWC strtok() does.

I found that the MWC strtok() needed an extra NULL terminator at the end of
the original string, otherwise MWC's strtok() would continue past the
end of the original string under certain situations. What I found was that if
I tokenized a very long string and then tried to tokenize a short string that
MWC's strtok() was continuing past the end of the short string and was tokenizing
parts of the previous longer string. But, by placing an extra NULL terminator,
MWC's strtok() was detecting the end of the short string proplerly.

I don't know if this helps you any but it is what I found when porting
strok() to my home computer. Good luck with your problem!!

-- 
 Richard E. Covert, Lead Engineer of Software Tools Group
 AG Communications Systems, Phoenix AZ   (602) - 581-4652
 TCP/IP: covertr@gtephx
 UUCP: {ncar!noao!asuvax | uunet!zardoz!hrc | att}!gtephx!covertr

rogers@sud509.ed.ray.com (Andrew Rogers) (08/13/90)

This is still another new and improved release of Pcal.  The changes this
time are:

	1) -r flag replaced by -l and -p to draw landscape and portrait mode
	   calendars respectively.

	2) -s and -S flags replaced by clearer and more flexible mechanism:
	   specify "-b DAY" to print all dates falling on weekday DAY in black,
	   "-g DAY" to print them in gray.  "-[b|g] all" prints all dates in
	   the selected color.  These options are cumulative: "-b all -g tue"
	   prints Tuesdays in gray and all other days in black.  Holidays are
	   printed in whichever color contrasts with the majority of days.

	3) Command-line flags (except -e and -f) may be specified in the
	   date file by including one or more lines of the form

		opt <options>

	   where <options> is one or more valid command-line flags.  Any
	   flags specified in this manner override the defaults, but in
	   turn are overridden themselves by flags specified explicitly on
	   the command line (which is why both -l and -p are supported).
	   Specifying a flag without an argument on the command line resets
	   its value to the program default.

	4) The source code has been revised and redocumented (again) for
	   clarity.

The accompanying file called "ReadMe.orig" came with the original distribution
as README and states this program is copyrighted but with permission to modify
and redistribute.  Please include this file in any further distribution.

Andrew W. Rogers

-------------------------------- cut here --------------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	 Makefile
#	 ReadMe
#	 ReadMe.orig
#	 calendar
#	 pcal.c
#	 pcal.hlp
#	 pcal.man
#	 pcalinit.h
# This archive created: Mon Aug 13 10:56:41 EDT 1990
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'Makefile'
then
	echo shar: will not over-write existing file 'Makefile'
else
cat << \SHAR_EOF > 'Makefile'
#
MANDIR=/usr1/jad/man			# must change this

pcal:	pcal.c pcalinit.h
	$(CC) $(CFLAGS) $(LDFLAGS) $(COPTS) -o pcal pcal.c

man:	pcal.man
	nroff -man pcal.man > pcal.1
	pack pcal.1
#	mv pcal.1.z $(MANDIR)
SHAR_EOF
fi
if test -f 'ReadMe'
then
	echo shar: will not over-write existing file 'ReadMe'
else
cat << \SHAR_EOF > 'ReadMe'
This is still another new and improved release of pcal.  The changes this
time are:

	1) -r flag replaced by -l and -p to draw landscape and portrait mode
	   calendars respectively.

	2) -s and -S flags replaced by clearer and more flexible mechanism:
	   specify "-b DAY" to print all dates falling on weekday DAY in black,
	   "-g DAY" to print them in gray.  "-[b|g] all" prints all dates in
	   the selected color.  These options are cumulative: "-b all -g tue"
	   prints Tuesdays in gray and all other days in black.  Holidays are
	   printed in whichever color contrasts with the majority of days.

	3) Command-line flags (except -e and -f) may be specified in the
	   date file by including one or more lines of the form

		opt <options>

	   where <options> is one or more valid command-line flags.  Any
	   flags specified in this manner override the defaults, but in
	   turn are overridden themselves by flags specified explicitly on
	   the command line (which is why both -l and -p are supported).
	   Specifying a flag without an argument on the command line resets
	   its value to the program default.

	4) The month and day names are in pcal.c, not in pcalinit.h - so
	   anyone attempting to change pcal to use a language other than
	   English need only change them in one place (for both printing
	   and date/flag parsing).

	5) The usage() message fits in a 24x80 screen (thanks to Jim
	   Prescott for suggesting this.)

The accompanying file called "ReadMe.orig" came with the original distribution
as README and states this program is copyrighted but with permission to modify
and redistribute.

Andrew W. Rogers

Additional note: This distribution includes a VMS HELP file written by
Richard Dyson.  Countless other people worked on pcal long before me; see
the ReadMe.orig file and topline comments in pcal.c.

SHAR_EOF
fi
if test -f 'ReadMe.orig'
then
	echo shar: will not over-write existing file 'ReadMe.orig'
else
cat << \SHAR_EOF > 'ReadMe.orig'
"Pcal" is a program to print PostScript calendars for any month and year.
By default, it looks for a file in the home directory named "calendar"
for entries with leading dates matching dates on the calendar, and prints
any following text under the appropriate day.

The program may be a little System V flavored (getopt, time routines)
but should be easily portable to other vintages of UNIX.

Pcal is the combined effort of several people, most notably Patrick Wood
of Pipeline Associates, Inc. for the original PostScript code and Bill
Vogel of AT&T for the calendar file mechanism.  My part was simple
translation to a "C" program, the addition of a couple options and a more
generalized date searching routine (oh yes, and a manual page :-).

The original calendar PostScript was Copyright (c) 1987 by Patrick Wood
and Pipeline Associates, Inc. with permission to modify and redistribute.
Please retain this README file with the package.


Ken Keirnan
Pacific Bell
San Ramon, CA.
SHAR_EOF
fi
if test -f 'calendar'
then
	echo shar: will not over-write existing file 'calendar'
else
cat << \SHAR_EOF > 'calendar'
# Sample calendar file for pcal
#
# This should be ~/calendar on Unix, SYS$LOGIN:CALENDAR.DAT on VMS
#
# Valid entries are of the following forms:
#
#	opt <options>
#	year <year>
#	<month_name> <day>{*} {<text>}
#	<month><sep><day>{<sep><year>}{*} {<text>}
#
# where:
#	<options> := one or more valid command-line options (except -e and -f)
#	<month_name> := first 3+ characters of name of month (in English)
#	<sep> := one or more non-numeric, non-space, non-'*' characters
#	<text> is the text to be printed in the calendar box
#	<day>, <month>, and <year> are appropriate integers
#
#	whitespace is to be used/avoided as implied by the above productions
#	'*' flags the date as a holiday (to be printed in gray)
#	comments run from '#' through end-of-line

# A sample "opt" line to change the fonts and output file names and to print
# only Sundays in gray:
#
#opt -d Helvetica-Bold -t Helvetica-Bold -o myfile.ps -b all -g sun

year 1990				# set year explicitly

5/28* Memorial Day (observed)		# '*' prints holiday in gray
5/31 Memorial Day

7/4/90* Independence Day		# full date format

Sep 3* Labor Day			# month written out

10/8* Columbus Day (observed)
10/12 Columbus Day

11/22* Thanksgiving
11/23*					# holiday without text

12/24* Christmas
12/25*

1/1/91* New Year's Day			# set new year implicitly
SHAR_EOF
fi
if test -f 'pcal.c'
then
	echo shar: will not over-write existing file 'pcal.c'
else
cat << \SHAR_EOF > 'pcal.c'
/*
 * pcal.c - generate PostScript file to print calendar for any month and year
 *
 * The original PostScript code to generate the calendars was written by
 * Patrick Wood (Copywrite (c) 1987 by Patrick Wood of Pipeline Associates,
 * Inc.), and authorized for modification and redistribution.  The calendar
 * file inclusion code was originally written in "bs(1)" by Bill Vogel of
 * AT&T.  Patrick's original PostScript was modified and enhanced several
 * times by others whose names have regrettably been lost.  This C version
 * was originally created by Ken Keirnan of Pacific Bell; additional
 * enhancements by Joseph P. Larson, Ed Hand, and Andrew Rogers (who also
 * did the VMS port).
 *
 * Revision history:
 *
 *	2.00	AWR	08/08/90	included revision history; replaced -r
 *					flag with -l and -p; replaced -s and -S
 *					flags with -b and -g; recognize flags
 *					set in date file; translate ( and ) in
 *					text to octal escape sequence; usage()
 *					message condensed to fit 24x80 screen
 *
 *	Parameters:
 *
 *		pcal [opts]		generate calendar for current month/year
 *
 *		pcal [opts] yy		generate calendar for entire year yy
 *
 *		pcal [opts] mm yy	generate calendar for month mm
 *					(Jan = 1), year yy (19yy if yy < 100)
 *
 *		pcal [opts] mm yy n	as above, for n consecutive months
 *
 *	Output:
 *
 *		PostScript file to print calendars for all selected months.
 *
 *	Options:
 *
 *		-b <DAY>	print specified weekday in black
 *		-g <DAY>	print specified weekday in gray
 *				(default: print Saturdays and Sundays in gray)
 *		
 *		-d <FONT>	specify alternate font for day names
 *				(default: Times-Bold)
 *
 *		-e		generate empty calendar (ignore date file)
 *
 *		-f <FILE>	specify alternate date file (default:
 *				~/calendar on Un*x, SYS$LOGIN:CALENDAR.DAT
 *				on VMS)
 *
 *		-o <FILE>	specify alternate output file (default:
 *				stdout on Un*x, CALENDAR.PS on VMS)
 *
 *		-l		generate landscape-mode calendars
 *		-p		generate portrait-mode calendars
 *				(default: landscape-mode)
 *
 *		-t <FONT>	specify alternate font for titles
 *				(default: Times-Bold)
 *
 *		Parameters and flags may be mixed on the command line.
 *
 *	All but the -e and -f options may be specified in the date file by
 *	the inclusion of one or more lines of the form "opt <options>".  Any
 *	such options override the defaults, but are themselves overridden
 *	by options specified explicitly on the command line.  (The -b, -d,
 *	-g, -o, and -t flags may be specified without arguments to reset
 *	the corresponding options to the defaults.)
 */


#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <string.h>

#ifdef VMS		/* VMS oddities isolated here */

#define DATEFILE  "calendar.dat"
#define OUTFILE   "calendar.ps"
#define END_PATH ']'
#define EXIT_SUCCESS 1
#define EXIT_FAILURE 3

#else			/* non-VMS - assume Un*x of some sort */

#define DATEFILE  "calendar"
#define OUTFILE   ""
#define END_PATH '/'
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
extern char *getenv();	/* to translate "HOME" to path name */

#endif

#define IS_LEAP(y)	((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
#define INIT_COLORS	memcpy(color, default_color, sizeof(color))

#define PRT		(void)printf
#define FPR		(void)fprintf

#define FALSE	0
#define TRUE	1

#define DATEFILE_FLAGS	"ef"		/* flags relating to date file name */
#define OTHER_FLAGS	"bdglopt"	/* all other flags */

#define DAYFONT   "Times-Bold"		/* default font names */
#define TITLEFONT "Times-Bold"

#define LANDSCAPE  90		/* degrees to rotate for landscape/portrait */
#define PORTRAIT    0
#define ROTATE	   LANDSCAPE	/* default */

#define BLACK	0		/* colors for dates */
#define GRAY	1

#define NO_DATEFILE 	0	/* date file (if any) to use */
#define USER_DATEFILE	1
#define SYS_DATEFILE	2

#define MIN_YR	1900		/* significant years (calendar limits) */
#define MAX_YR	9999

#define JAN	 1		/* significant months */
#define FEB	 2
#define DEC	12

#define STRSIZ	100		/* size of misc. strings */

#define MAXARGS 3		/* numeric command-line args */

#define HOLIDAY	(1 << 6)	/* bit set to flag day as holiday */

#define WHITESPACE " \t"	/* token delimiters in date file */

/*
 * Global variables:
 */

FILE *dfp = NULL;		/* date file pointer */
int init_month;			/* initial month, year, number of months */
int init_year;
int nmonths;
int curr_year;			/* current default year for date file entries */
char *words[100];		/* maximum number of words per date file line */
char lbuf[512];			/* maximum date file line size */
char progname[STRSIZ];		/* program name (for error messages) */
char color[7];			/* colors of weekdays - cf. default_color[] */

/*
 * Default values for command-line options:
 */

char default_color[7] = {		/* -b, -g */
	GRAY, BLACK, BLACK, BLACK, BLACK, BLACK, GRAY	/* cf. COLOR_MSG */
	};

int datefile_type = SYS_DATEFILE;	/* -e, -f */
char datefile[STRSIZ] = "";

int rotate = ROTATE;			/* -l, -p */

char dayfont[STRSIZ] = DAYFONT;		/* -d, -t */
char titlefont[STRSIZ] = TITLEFONT;

char outfile[STRSIZ] = OUTFILE;		/* -o */

/*
 * Language-dependent strings (month and day names, option file keywords):
 */

static char *months[12] = {
	"January", "February", "March", "April", "May", "June",
	"July", "August", "September", "October", "November", "December"
	};

static char *days[7] = {
	"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
	"Saturday"
	};

#define MIN_DAY_LEN   2		/* minimum size of day/month abbreviations  */
#define MIN_MONTH_LEN 3

#define ALL	"All"		/* command-line or date file keywords */
#define OPT	"Opt"
#define YEAR	"Year"

#define COLOR_MSG	"Sat/Sun in gray, others in black"    /* cf. usage() */

/*
 * PostScript boilerplate
 */

#include "pcalinit.h"


/*
 * Main program - parse and validate command-line arguments, open files,
 * generate PostScript boilerplate and code to generate calendars.
 *
 * Program structure:
 *
 * main() calls get_args() once just to get the date file name and any numeric
 * arguments (month, year, number of months), and calls find_options() to make
 * a preliminary pass through the date file looking for "opt" lines (which
 * override the defaults for the command-line flags).  It then calls get_args()
 * again to process the other command-line flags, which in turn override any
 * specified in the date file.
 *
 * main() then generates the common PostScript code and then calls pmonth() to
 * print the calendars.
 *
 * find_options() calls getline() to read the date file.  Upon encountering
 * an "opt" line, it calls loadwords() to tokenize the line and get_args()
 * to parse it.
 *
 * pmonth() calls find_holidays() to make a first pass through the date file
 * to generate the list of holidays to be printed in gray; it then calls
 * find_daytext() to make a second pass to generate the text to be printed
 * inside the calendar boxes.
 *
 * find_holidays() and find_daytext() both call getday() to retrieve the next
 * day of interest from the date file.
 *
 * getday() calls getline() to read successive lines from the date file and
 * calls parse() to interpret them, stopping when parse() determines that the
 * line contains a usable date or when EOF is reached.
 *
 * getline() reads one or more lines from the date file, stripping comments
 * (# through end-of-line) and ignoring blank lines.
 *
 * parse() parses a line from the date file, determining whether or not it
 * contains a date in the current month and year.  It calls utility routines
 * is_valid() to validate the date found and loadwords() to split any
 * accompanying text into individual tokens for PostScript to print.
 * 
 */
main(argc, argv)
	int argc;
	char **argv;
{
	char *p, **ap;
	int i, month, year, ngray;

#define DO_HEADER(phdr)	for (ap = phdr; *ap; ap++) PRT("%s\n", *ap)

	INIT_COLORS;		/* set up default colors */

	/* isolate root program name (for use in error messages) */

	strcpy(progname, **argv ? *argv : "pcal");

	if ((p = strrchr(progname, END_PATH)) != NULL)
		strcpy(progname, ++p);
	if ((p = strchr(progname, '.')) != NULL)
		*p = '\0';

	/*
	 * Get the arguments from a) "opt" lines in the date file, and b)
	 * the command line, in that order
	 */

	/* parse command-line arguments once to find name of date file */

	if (!get_args(argv, DATEFILE_FLAGS, TRUE)) {
		usage();
		exit(EXIT_FAILURE);
	}

	/* Attempt to open the date file as specified by the [-e | -f] flags */

	switch (datefile_type) {
	case NO_DATEFILE:
		dfp = NULL;
		break;

	case USER_DATEFILE:	
		/* Attempt to open user-specified calendar file */
		if ((dfp = fopen(datefile, "r")) == NULL) {
			FPR(stderr, "%s: can't open file %s\n", progname, 
				datefile);
			exit(EXIT_FAILURE);
		}
		break;

	case SYS_DATEFILE:
		/* Look for the system (default) calendar file */
#ifdef VMS
		strcpy(datefile, "SYS$LOGIN:");	/* get home directory (VMS) */
#else
		*datefile = '\0';		/* translate "HOME" to path (Un*x) */
		if ((p = getenv("HOME")) != NULL) {
			strcat(datefile, p);
			strcat(datefile, "/");
		}
#endif
		strcat(datefile, DATEFILE);
		dfp = fopen(datefile, "r");	/* no error if nonexistent */
		break;
	}

	find_options();		/* read date file looking for option lines */

	/* reparse command line - flags there supersede those in date file */

	get_args(argv, OTHER_FLAGS, FALSE);

	/* done with the arguments and flags - try to open the output file */

	if (*outfile && freopen(outfile, "w", stdout) == (FILE *) NULL) {
		FPR(stderr, "%s: can't open file %s\n", progname, outfile);
		exit(EXIT_FAILURE);
	}

	/*
	 * Write out PostScript prolog
	 */

	/* font names */

 	PRT("%%!\n");
 	PRT("/titlefont /%s def\n/dayfont /%s def\n", titlefont, dayfont);

	/* month names */

	PRT("/month_names [");
	for (i = 0; i < 12; i++)
		PRT("%s(%s) ", i % 6 == 0 ? "\n\t" : "", months[i]);
	PRT("] def\n");

	/* day names */

	PRT("/day_names [");
	for (i = 0; i < 7; i++)
		PRT("%s(%s) ", i % 6 == 0 ? "\n\t" : "", days[i]);
	PRT("] def\n");

	/* colors (black/gray) to print weekdays and holidays */

	PRT("/day_gray [");
	for (ngray = i = 0; i < 7; ngray += color[i++] == GRAY)
		PRT(" %s", color[i] == GRAY ? "true" : "false");
	PRT(" ] def\n");
	PRT("/holiday_gray %s def\n", ngray <= 3 ? "true" : "false");

	/* PostScript boilerplate (part 1) */

	DO_HEADER(header_1);

	/* landscape or portrait mode */

 	PRT("\t%d rotate\n", rotate);
 	if (rotate == LANDSCAPE)
 		PRT("\t50 -120 translate\n");
 	else
 		PRT("\t0.75 0.75 scale\n\t50 460 translate\n");

	/* PostScript boilerplate (part 2) */

	DO_HEADER(header_2);

	/*
	 * Write out PostScript code to print calendars
	 */

	month = init_month;
	year = init_year;

	while (nmonths--) {
		pmonth(month, year);
		if (++month > DEC) {
			month = JAN;
			year++;
		}
	}

	if (dfp)		/* close date file */
		fclose(dfp);

#ifdef VMS
	FPR(stderr, "Output is in file %s\n", outfile);
#endif
	exit(EXIT_SUCCESS);
}

/*
 * get_args - walk the argument list, parsing all arguments but processing only
 * those specified in "flags".  If "do_numargs" is TRUE, processes numeric
 * arguments (month, year, number of months) as well.
 */
int get_args(argv, flags, do_numargs)
	char **argv;		/* argument list */
	char *flags;		/* which flags to process */
	int do_numargs;		/* process numeric arguments? */
{
	char *p, *opt;
	int i, do_flag;
	long tmp;			/* for getting current month/year */
	struct tm *p_tm;
	int badopt = FALSE;		/* flag set if bad param   */
	int nargs = 0;			/* count of non-flag args  */
	int numargs[MAXARGS];		/* non-flag (numeric) args */

/* Look for the argument following flag - may be separated by spaces or
 * not (bumps argv in former case).  If no non-flag argument appears, set
 * "arg" to NULL (-b, -d, -g, -o, and -t without an argument reset the
 * corresponding option to its default value).
 */
#define GETARG(arg) arg = *(*argv + 2) ? *argv + 2 : \
			(*(argv+1) && **(argv+1) != '-' ? *++argv : NULL)

	/* Walk argument list, ignoring first element (program name) */

 	while (*++argv) {

		/* Assume that any non-flag argument is a numeric argument */
		if (**argv != '-') {
		    	if (do_numargs && nargs < MAXARGS)
				numargs[nargs++] = atoi(*argv);
			continue;
		}

		/* Is this flag among those to be processed beyond parsing? */

		do_flag = strchr(flags, *(opt = *argv + 1)) != NULL;

		switch (*opt) {

		case 'b':		/* print day in black or gray */
		case 'g':
			GETARG(p);
			if (do_flag)
				if (p)
					set_color(p, *opt == 'b' ? BLACK : GRAY);
				else
					INIT_COLORS;	/* reset to defaults */
			break;

 		case 'd':		/* specify alternate day font */
 			GETARG(p);
			if (do_flag)
				strcpy(dayfont, p ? p : DAYFONT);
 			break;

		case 'e':		/* generate empty calendar */
			if (do_flag) {
				datefile_type = NO_DATEFILE;
				datefile[0] = '\0';
			}
			break;

		case 'f':		/* specify alternate date file */
			GETARG(p);
			if (p && do_flag) {
				datefile_type = USER_DATEFILE;
				strcpy(datefile, p);
			}
			break;

 		case 'l':		/* generate landscape calendar */
			if (do_flag)
	 			rotate = LANDSCAPE;
 			break;
 
		case 'o':		/* specify alternate output file */
			GETARG(p);
			if (do_flag)
				strcpy(outfile, p ? p : OUTFILE);
			break;

 		case 'p':		/* generate portrait calendar */
			if (do_flag)
	 			rotate = PORTRAIT;
 			break;
 
 		case 't':		/* specify alternate title font */
 			GETARG(p);
			if (do_flag)
				strcpy(titlefont, p ? p : TITLEFONT);
 			break;

		default:		/* unrecognized flag */
			FPR(stderr, "%s: illegal option -%s\n", progname, opt);
			badopt = TRUE;
			break;
		}
        }

	if (!do_numargs)
		return (!badopt);	/* return TRUE if OK, FALSE if error */

	/* Validate non-flag (numeric) parameters */

	switch (nargs) {
	case 0:		/* no arguments - print current month/year */
		time(&tmp);
		p_tm = localtime(&tmp);
		init_month = p_tm->tm_mon + 1;
		init_year = p_tm->tm_year;
		nmonths = 1;
		break;			
	case 1:		/* one argument - print entire year */
		init_month = JAN;
		init_year = numargs[0];
		nmonths = 12;
		break;
	default:	/* two or three arguments - print one or more months */
		init_month = numargs[0];
		init_year = numargs[1];
		nmonths = nargs > 2 ? numargs[2] : 1;
		break;
	}

	if (nmonths < 1)		/* ensure at least one month */
		nmonths = 1;

	/* check range of month and year */

	if (init_month < JAN || init_month > DEC) {
		FPR(stderr, "%s: month %d not in range 1 .. 12\n", progname,
			init_month);
		badopt = TRUE;
	}
	
	if (init_year > 0 && init_year < 100)	/* treat nn as 19nn */
		init_year += 1900;
	
	if (init_year < MIN_YR || init_year > MAX_YR) {
		FPR(stderr, "%s year %d not in range %d .. %d\n", progname,
			init_year, MIN_YR, MAX_YR);
		badopt = TRUE;
	}

	return (!badopt);	/* return TRUE if OK, FALSE if error */
}



/*
 *	usage - print message explaining correct usage of the command-line
 *	arguments and flags
 */
usage()
{
	FPR(stderr, "\nUsage:\t%s [-b DAY]* [-d FONT] [-e | -f FILE] [-g DAY]* [-o FILE]\n", progname);
	FPR(stderr, "\t\t[-l|-p] [-t FONT] [ [ [mm] yy ] | [mm yy n] ]\n");
	FPR(stderr, "\n");
	FPR(stderr, "\t-b DAY\t\tprint weekday DAY in black\n");
	FPR(stderr, "\t-g DAY\t\tprint weekday DAY in gray\n");
	FPR(stderr, "\t\t\t(default: %s)\n", COLOR_MSG);
	FPR(stderr, "\n");
	FPR(stderr, "\t-d FONT\t\tspecify alternate day name font (default: %s)\n",
		DAYFONT);
	FPR(stderr, "\t-t FONT\t\tspecify alternate title font (default: %s)\n",
		TITLEFONT);
	FPR(stderr, "\n");
	FPR(stderr, "\t-e\t\tgenerate empty calendar (ignore date file)\n");
	FPR(stderr, "\t-f FILE\t\tspecify alternate date file (default: %s)\n",
		DATEFILE);
	FPR(stderr, "\t-o FILE\t\tspecify alternate output file (default: %s)\n",
		OUTFILE[0] ? OUTFILE : "stdout");
	FPR(stderr, "\n");
	FPR(stderr, "\t-l\t\tgenerate landscape-style calendars");
#if (ROTATE == LANDSCAPE)
	FPR(stderr, " (default)");
#endif
	FPR(stderr, "\n\t-p\t\tgenerate portrait-style calendars");
#if (ROTATE == PORTRAIT)
	FPR(stderr, " (default)");
#endif
	FPR(stderr, "\n\n");
	FPR(stderr, "\tyy\t\tgenerate calendar for year yy (19yy if yy < 100)\n");
	FPR(stderr, "\tmm yy\t\tgenerate calendar for month mm (Jan = 1), year yy\n");
	FPR(stderr, "\tmm yy n\t\tgenerate calendars for n months, starting at mm/yy\n");
	FPR(stderr, "\t(default)\tgenerate calendar for current month/year\n");
}


/*
 * is_valid - return TRUE if d is a valid date in m/y (assumed valid)
 */
int is_valid(m, d, y)
	register int m, d, y;
{
	static char len[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

	return (d >= 1 && d <= (len[m] + (m == FEB && IS_LEAP(y))) );
}


/*
 * loadwords - tokenize line buffer into word array, return word count
 * (assumes strtok() has already been called with non-null first arg)
 */
int loadwords()
{
	register char **ap = words;
	register i;

	for (i = 0; *ap = strtok(NULL, WHITESPACE) ; ap++, i++) ;
	return(i);
}


/*
 * strcap - convert first character of string to uppercase, rest to lowercase
 */
char *strcap(s)
	char *s;
{
	char *p = s;

	if (*p) {
		if (islower(*p))
			*p = toupper(*p);
		while (*++p)
			if (isupper(*p))
				*p = tolower(*p);
	}
	return(s);
}


/*
 * set_color - set one or all weekdays to print in black or gray
 */
set_color(day, col)
	char *day;		/* weekday name (or "all") */
	int  col;		/* select black or gray */
{
	int i, do_all;

	do_all = strncmp(strcap(day), ALL, strlen(ALL)) == 0;	/* set all days? */

	for (i = 0; i < 7; i++)
		if (do_all || strncmp(day, days[i], MIN_DAY_LEN) == 0)
			color[i] = col;
}


/*
 * prt_word - print word as PostScript string, converting '(' and ')' to octal
 */
prt_word(p)
	char *p;
{
	PRT("(");
	for ( ; *p ; p++)
		if (*p == '(' || *p == ')')
			PRT("\\%03o", *p);
		else
			PRT("%c", *p);
	PRT(")\n");
}

/*
 * parse - check date file entry for (in lbuf[]) for desired month/year
 *
 * Looks for an entry of one of the following forms:
 *
 *	year <year>
 *	<month_name> <day>{*} {<text>}
 *	<month><sep><day>{<sep><year>}{*} {<text>}
 *
 * where
 *	<month_name> := first 3+ characters of name of month (in English)
 *	<sep> := one or more non-numeric, non-space, non-'*' characters
 *
 * Returns day (with holiday flag set if specified) if date file entry
 * is applicable to current month/year; 0 if not.  If applicable, parses
 * any following text into global array words[].
 *
 * Also see find_options(), which is used during an initial pass to identify
 * and parse only lines of the form
 *
 *	opt <options>
 *
 * which override defaults for command-line options.
 */
int parse(month, year)
	register int month, year;
{
	register char *cp;
	int mm, dd, yy;
	int is_holiday;

/* macro to skip numeric field */

#define SKIP_FIELD(p) \
	if (1) {while (isdigit(*p)) p++; while (*p && !isdigit(*p)) p++;} else

	/*
	 * Get first field - can be either "year", "opt" (ignored), a month
	 * name, or a (complete) numeric date spec
         */

	cp = strtok(lbuf, WHITESPACE);	/* set up strtok() to parse line */

	/*
	 * If field begins with alpha, look for "year" or month name
	 */
	if (isalpha(*cp)) {
		strcap(cp);

		/* Check for "year" line */

		if (strcmp(cp, YEAR) == 0) {
			cp = strtok(NULL, WHITESPACE);
			if ((yy = atoi(cp)) > 0) {
				if (yy < 100)
					yy += 1900;
				curr_year = yy;
			}
			return(0);
		}

		/* Check month and year.  "opt" falls out here */

		if (year != curr_year || 
		    strncmp(cp, months[month-1], MIN_MONTH_LEN) != 0)
			return(0);

		/* month found, get and validate day */

		if ((cp = strtok(NULL, WHITESPACE)) == NULL || 
		    !is_valid(month, dd = atoi(cp), year))
			return(0);

		is_holiday = cp[strlen(cp) - 1] == '*';	/* look for holiday flag */

		if (loadwords() || is_holiday)
			return(dd | is_holiday * HOLIDAY);
		return(0);
	}

	/*
	 * Not alpha month, try numeric date (parse completely in case year
	 * has changed)
	 */

	is_holiday = cp[strlen(cp) - 1] == '*';	/* look for holiday flag */
 
	/* extract month and day fields */

	mm = atoi(cp);
	SKIP_FIELD(cp);

	dd = atoi(cp);
	SKIP_FIELD(cp);

	/* Numeric dates may (or may not) have a year */

	if ((yy = atoi(cp)) > 0) {
		if (yy < 100)
			yy += 1900;
		curr_year = yy;
	}

	/* if date is valid and significant (text or holiday flag), return it */

	if (mm == month && curr_year == year && is_valid(month, dd, year) &&
	    (loadwords() || is_holiday))
		return(dd | is_holiday * HOLIDAY);
	return(0);
}


/*
 * getline - read next non-null line of input file into lbuf; return 0 on EOF
 */
int getline()
{
	register char *cp;
	register int c;
	int in_comment;		/* comments: from '#' to end-of-line */

	cp = lbuf;
	do {
		in_comment = FALSE;
		while ((c = getc(dfp)) != '\n' && c != EOF) {
			if (c == '#')
				in_comment = TRUE;

			/* ignore comments and leading white space */
			if (in_comment ||
			    (cp == lbuf && (c == ' ' || c == '\t')))
				continue;
			*cp++ = c;
		}
		if (c == EOF)
			return(0);

	} while (cp == lbuf);	/* ignore empty lines */

	*cp = '\0';
	return(1);
}


/*
 * getday - find next day entry for specified month and year in the date file
 */
int getday(month, year, reset)
	register int month, year;
	int reset;		/* TRUE: rewind date file */
{
	static int eof = FALSE;
	int day;

	if (dfp == NULL)	/* whoops, no date file */
		return(0);

	if (reset) {		/* rewind file, reset default year, clear eof */
		rewind(dfp);
		curr_year = init_year;
		eof = FALSE;
	}

	if (eof)
		return(0);

	/* read lines until we find a line we want or until EOF */

	do {
	   	if (!getline())	{
			eof = TRUE;
			return(0);
		}
	} while ( (day = parse(month, year)) == 0);

	return(day);
}

/*
 * Browse through the date file looking for day text in specified month/year
 */
find_daytext(month, year)
	int month, year;
{
	register char **s;
	register int oldday = -1;
	register int day;

	for (day = getday(month, year, TRUE);
	     day != 0;
	     day = getday(month, year, FALSE))
		if (*words) {
			day &= ~HOLIDAY;
			if (day != oldday) {
				if (oldday != -1)
					PRT("] daytext\n");
				PRT("%d [ \n", day);
				oldday = day;
			} else
				PRT("(.p)\n");
			for (s = words; *s; s++)
				prt_word(*s);
		}

	if (oldday != -1)	/* terminate last call to daytext (if any) */
		PRT("] daytext\n");
}


/*
 * Browse through the date file looking for holidays in specified month/year
 */
find_holidays(month, year)
	int month, year;
{
	register int day;
	unsigned long holidays = 0;

	/* get unique, sorted list of holidays by setting bits in flag word */

	for (day = getday(month, year, TRUE);
	     day != 0;
	     day = getday(month, year, FALSE))
		if (day & HOLIDAY)
			holidays |= 1 << (day & ~HOLIDAY);

	PRT("/holidays [");	/* start definition of list */
	for (day = 1; day <= 31; day++)
		if (holidays & (1 << day))
			PRT(" %d", day);
	PRT(" 99 ] def\n");	/* terminate with dummy entry */
}

/*
 * Browse through the date file looking for "opt" lines; parse any found
 */
find_options()
{
	char *cp, **argv;

	if (!dfp)
		return;

	rewind(dfp);

	/* read all lines in date file; if "opt" found, tokenize and parse it */

	while (getline()) {

		cp = strtok(lbuf, WHITESPACE);	/* initialize strtok() */

		if (isalpha(*cp) && strncmp(strcap(cp), OPT, strlen(OPT)) == 0) {
			loadwords();		/* tokenize the option line */
			argv = &words[-1];	/* argv[1] points to words[0] */

		 	if (!get_args(argv, OTHER_FLAGS, FALSE)) {
				usage();
				exit(EXIT_FAILURE);
			}
		}
	}
}


/*
 * pmonth - generate calendar for specified month/year
 */
pmonth(month, year)
	int month, year;
{

	PRT("/year %d def\n", year);	/* set up year and month */
	PRT("/month %d def\n", month);
	find_holidays(month, year);	/* first pass - make list of holidays */
	PRT("printmonth\n");
	find_daytext(month, year);	/* second pass - add text to boxes */
	PRT("showpage\n");
}
SHAR_EOF
fi
if test -f 'pcal.hlp'
then
	echo shar: will not over-write existing file 'pcal.hlp'
else
cat << \SHAR_EOF > 'pcal.hlp'
1 PCAL
        Pcal  generates  PostScript  to produce landscape or  portrait
    orientated calendars for  any  month  and  year.  The defaults for
    month and year are the current month and year.

        VMS Version
        Execution format:
    
            pcal [options] [mm yy] [n]

        If a file named calendar.dat  resides  in  the  caller's  home
    directory, it  will  be  searched  for  lines  with  leading dates
    matching the requested  month  and year (current by default).  Any
    text following the date  will be printed on the calendar under the
    appropriate day of the month.   Dates in the calendar.dat file may
    consist  of  a  numeric or alpha  month  (at  least  the  first  3
    characters  for  month  names)  followed  by  a  numeric  day  and
    optionally  followed  by  a year.  Any non-numeric  character  may
    separate numeric dates.  Holidays may be flagged by  following the
    date immediately with '*';  this will cause the date to be printed
    in gray.  Lines in the calendar.dat file consisting of "year xxxx"
    (where  xxxx  is a numeric year) can be used to set the  year  for
    following entries.  This assumes that the following entries do not
    contain a year;  any date entries containing year information will
    set  the  remembered  year  to  that  year.  Lines  consisting  of
    "opt <options>" can be used to  override defaults for all command-
    line flags  except  -e and -f; any  flags set  in this  manner are
    themselves overridden by flags specified explicitly on the command
    line.  Comments ('#' through end-of-line) are permitted.

2 parameters
  mm yy n
        "mm" and "yy"  are numeric values of the month (1-12) and year
    (0-99) (i.e., July 1990  would  be 7 90).  If you just include the
    "yy" option, an entire 12  months  of calendars will be generated.
    A specific month can be produced  by including the "mm" parameter.
    The  "n"  parameter will produce the "n"  consectutive  months  of
    calendars starting with the requested month.

2 -e
        Print an  empty  calendar.    Do  not  print  entries  from  a
    calendar.dat file.

2 -f <FILE>
        Directs pcal to use the  file name <FILE> as the input file in
    place  of the  default  calendar.dat  file  in  the  callers  home
    directory.
2 -o <FILE>
        Directs pcal to write the PostScript calendar into FILE.
2 -l
        This will cause the  output  to  come  out  in  landscape mode
    (default).
2 -p
        This will cause  the  output  to  come  out  in  portrait mode
    instead of landscape mode.
2 -b <DAY> | all
        This  will cause  all dates  on weekday  DAY to be  printed in 
    black;  "-b all" causes  all dates  to be printed  in black unless
    explicitly flagged as a holiday.
2 -g <DAY> | all
        This  will cause  all dates  on weekday  DAY to be  printed in 
    gray; "-g all" causes all dates to be printed in gray.  Default is
    to print Saturdays  and Sundays in gray and  other dates in black.
2 -t <FONT>
        This option can be used  to  change  the  font  the  title  is
    printed in  (ie. pcal -tTimes-Roman).  The default  is Times-Bold.
2 -d <FONT>
        This option is the same as  -t  except  that  the font used to
    print the day numbers is changed.
2 CAVEATS
        The original PostScript code  to  generate  the  calendars was
    written by Patrick Wood (Copywrite  (c)  1987  by  Patrick Wood of
    Pipeline  Associates, Inc.), and authorized for  modification  and
    redistribution.    The  calendar.dat  file  inclusion  code    was
    originally written in "bs(1)" by Bill Vogel of  AT&T.    Patrick's
    original  PostScript  was  modified  and enhanced several times by
    others  whose names  have  regrettably been lost.  Ken Keirnan  of
    Pacific Bell assembled the original "C" version upon which this is
    based;  additional modifications and enhancements were the work of
    Joseph P. Larson, Ed Hand,  and Andrew W. Rogers.  This  VMS  HELP
    file was written by Richard Dyson.
SHAR_EOF
fi
if test -f 'pcal.man'
then
	echo shar: will not over-write existing file 'pcal.man'
else
cat << \SHAR_EOF > 'pcal.man'
.TH PCAL 1
.SH NAME
pcal \- generate PostScript calendars
.SH SYNOPSIS
.B pcal
[
.BR \-e
|
.BR \-f
<cal>
]
[
.BR \-o
<file>
]
[
.BR \-l
|
.BR \-p
]
[
.BR \-b
<day>
|
all
]*
[
.BR \-g
<day>
|
all
]*
[
.B -t
<titlefont name>
]
[
.B -d
<dayfont name>
]
[
.B month
] [
.B year
] [
.B nmonths
]
.SH DESCRIPTION
.I Pcal
generates PostScript to produce landscape or portrait calendars for any 
month and year.  The arguments
.BR month ,
.BR year ,
and
.BR nmonths ,
if provided, should be numeric.  The month should be in the range 1 - 12,
and year should be specified as 1 or 2 digits or as the full 4 digit year.
.P
If no numeric arguments are provided, the current month and year will be
generated.
.P
If one numeric argument is provided, it is interpreted as the year; the
entire year will be generated.  Otherwise, 
.I nmonth
months, starting with
.I month
and
.I year,
will be generated.
.PP
If a file named
.I calendar
resides in the caller's home directory, it will be searched for lines with
leading dates matching the requested month and year (current by default).
Any text following the date will be printed on the calendar under the
appropriate day of the month.  Dates in the
.I calendar
file may consist of a numeric or alpha month (at least the first 3 characters
for month names) followed by a numeric day and optionally followed by a
year.  Any non-numeric character may separate numeric dates.  Holidays may
be flagged by following the date immediately with '*'; this will cause the
date to be printed in gray.
.PP
Lines in the
.I calendar
file consisting of "year xxxx" (where xxxx is a numeric year) can be used
to set the year for following entries.  This assumes that the following
entries do not contain a year; any date entries containing year information
will set the remembered year to that year.
.PP
LInes in the
.I calendar
file consisting of "opt <options>" can be used to override the defaults for
any command-line flags except -e and -f.  Any flags specified in this manner
are, in turn, overridden by those specified explicitly on the command line.
.PP
Comments ('#' through end-of-line) are supported.
.PP
.I Pcal
has many options:
.P
.TP
.B \-e
Print an empty calendar.  Do not print entries from a calendar file.
.TP
.B \-f <cal>
Directs
.I pcal
to use the file name <cal> as the input file in place of the default
calendar file in the callers home directory.
.TP
.B \-o <file>
Directs
.I pcal
to write the output to <file> instead of to stdout.
.TP
.B \-l
This will cause the output to come out in landscape mode (default).
.TP
.B \-p
This will cause the output to come out in portrait mode.
.TP
.B \-b <day> | all
This will cause all dates falling on weekday <day> to be printed in black;
"-b all" causes all weekdays to be printed in black.
.TP
.B \-g <day> | all
This will cause all dates falling on weekday <day> to be printed in gray;
"-g all" causes all weekdays to be printed in gray.
.IP
(The default for the -b and -g flags is to print Saturdays and Sundays in
gray and other days - unless flagged as holidays - in black.)
.TP
.B \-t <titlefont name>
This option can be used to change the font the title
is printed in. (ie. pcal -t Times-Roman).
.TP
.B \-d <dayfont name>
This option is the same as -t except that the font used
to print the day numbers is changed.
.SH SEE ALSO
cal(1)
.SH CAVEATS
The original PostScript code to generate the calendars was written by
Patrick Wood (Copywrite (c) 1987 by Patrick Wood of Pipeline Associates,
Inc.), and authorized for modification and redistribution.  The calendar
file inclusion code was originally written in "bs(1)" by Bill Vogel of
AT&T.  Patrick's original PostScript was modified and enhanced several
times by others whos names have regrettably been lost.  Ken Keirnan of
Pacific Bell assembled the original "C" version upon which this is based;
additional modifications and enhancements were the work of Joseph P.
Larson, Ed Hand, and Andrew W. Rogers.

SHAR_EOF
fi
if test -f 'pcalinit.h'
then
	echo shar: will not over-write existing file 'pcalinit.h'
else
cat << \SHAR_EOF > 'pcalinit.h'
/*
 * pcalinit.h - provides the PostScript routines for v2.00 of pcal.c
 *
 * modified by AWR as follows:
 *
 *	skip printing days of week on small calendars
 *	center month and year at top of calendar
 *	use correct algorithm for leap year calculation
 *	get month and day names from main program
 *	use table to determine color (black/gray) of weekdays and holidays
 *      use hanging indent to print continued text lines
 *
 */

char *header_1[] = {
  "/prtnum { 3 string cvs show} def",
  "/drawgrid {\t\t% draw calendar boxes",
  "\tdayfont findfont 10 scalefont setfont",
  "\t0 1 6 {",
  "\t\t/i exch def",
  "\t\tsubmonth 0 eq {",
  "\t\t\ti 100 mul 40 moveto",
  "\t\t\tday_names i get",
  "\t\t\t100 center",
  "\t\t} if",
  "\t\ti 100 mul 35 moveto",
  "\t\t1.0 setlinewidth",
  "\t\t0 1 5 {",
  "\t\t\tgsave",
  "\t\t\t100 0 rlineto ",
  "\t\t\t0 -80 rlineto",
  "\t\t\t-100 0 rlineto",
  "\t\t\tclosepath stroke",
  "\t\t\tgrestore",
  "\t\t\t0 -80 rmoveto",
  "\t\t pop } for",
  "\t} for",
  "} def",
  "/drawnums {\t\t% place day numbers on calendar",
  "\tdayfont findfont 30 scalefont setfont",
  "\t/start startday def",
  "\t/days ndays def",
  "\t/n 0 def",
  "\tstart 100 mul 5 add 10 rmoveto",
  "\t1 1 days {",
  "\t\t/day exch def",
  "\t\tgsave",
  "\t\tsubmonth 0 eq {",
  "\t\t\t/gray day_gray day start add 1 sub 7 mod get def",
  "\t\t\tday holidays n get eq {",
  "\t\t\t\t/gray holiday_gray def",
  "\t\t\t\t/n n 1 add def",
  "\t\t\t} if",
  "\t\t\tgray {",
  "\t\t\t\t0.8 setgray",
  "\t\t\t} if",
  "\t\t} if",
  "\t\tday prtnum",
  "\t\tgrestore",
  "\t\tday start add 7 mod 0 eq",
  "\t\t{",
  "\t\t\tcurrentpoint exch pop 80 sub 5 exch moveto",
  "\t\t}",
  "\t\t{",
  "\t\t\t100 0 rmoveto",
  "\t\t} ifelse",
  "\t} for",
  "} def",
  "/drawfill {\t\t% place fill squares on calendar",
  "\t/start startday def",
  "\t/days ndays def",
  "\t0 35 rmoveto",
  "\t1.0 setlinewidth",
  "\t0 1 start 1 sub {",
  "\t\tgsave",
  "\t\t.9 setgray",
  "\t\t100 0 rlineto ",
  "\t\t0 -80 rlineto",
  "\t\t-100 0 rlineto",
  "\t\tclosepath fill",
  "\t\tgrestore",
  "\t\t100 0 rmoveto",
  "\tpop } for",
  "\tsubmonth 1 eq",
  "\t{",
  "\t\t/lastday 42 def",
  "\t\t600 -365 moveto",
  "\t}",
  "\t{",
  "\t\t/lastday 40 def",
  "\t\t400 -365 moveto",
  "\t} ifelse",
  "\tlastday -1 ndays start 1 add add",
  "\t{",
  "\t\t/day exch def",
  "\t\tgsave",
  "\t\t.9 setgray",
  "\t\t100 0 rlineto ",
  "\t\t0 -80 rlineto",
  "\t\t-100 0 rlineto",
  "\t\tclosepath fill",
  "\t\tgrestore",
  "\t\tday 7 mod 1 eq",
  "\t\t{",
  "\t\t\t600 -365 80 add moveto",
  "\t\t}",
  "\t\t{",
  "\t\t\t-100 0 rmoveto",
  "\t\t} ifelse",
  "\t} for",
  "} def",
  "/isleap {\t\t% is this a leap year?",
  "\tyear 4 mod 0 eq\t\t% multiple of 4",
  "\tyear 100 mod 0 ne \t% not century",
  "\tyear 400 mod 0 eq or and\t% or divisible by 400",
  "} def",
  "/days_month [ 31 28 31 30 31 30 31 31 30 31 30 31 ] def",
  "/ndays {\t\t% number of days in this month",
  "\tdays_month month 1 sub get",
  "\tmonth 2 eq\t% Feb",
  "\tisleap and",
  "\t{",
  "\t\t1 add",
  "\t} if",
  "} def",
  "/startday {\t\t% starting day-of-week for this month",
  "\t/off year 2000 sub def\t% offset from start of epoch",
  "\toff",
  "\toff 4 idiv add\t\t% number of leap years",
  "\toff 100 idiv sub\t% number of centuries",
  "\toff 400 idiv add\t% number of years divisible by 400",
  "\t6 add 7 mod 7 add \t% offset from Jan 1 2000",
  "\t/off exch def",
  "\t1 1 month 1 sub {",
  "\t\t/idx exch def",
  "\t\tdays_month idx 1 sub get",
  "\t\tidx 2 eq",
  "\t\tisleap and",
  "\t\t{",
  "\t\t\t1 add",
  "\t\t} if",
  "\t\t/off exch off add def",
  "\t} for",
  "\toff 7 mod\t\t% 0--Sunday, 1--monday, etc.",
  "} def",
  "/center {\t\t% center string in given width",
  "\t/width exch def",
  "\t/str exch def width str ",
  "\tstringwidth pop sub 2 div 0 rmoveto str show",
  "} def",
  "/strcat {\t\t% concatenate two strings",
  "\t2 copy",
  "\tlength exch length",
  "\tdup 3 -1 roll add",
  "\tstring",
  "\tdup 0 6 -1 roll putinterval",
  "\tdup 3 -1 roll 4 -1 roll putinterval",
  "} def",
  "/calendar",
  "{",
  "\ttitlefont findfont 48 scalefont setfont",
  "\t/month_name month_names month 1 sub get def",
  "\t/yearstring year 10 string cvs def",
  "\t0 60 moveto",
  "\tmonth_name (  ) strcat yearstring strcat 700 center",
  "\t0 0 moveto",
  "\tdrawnums",
  "\t0 0 moveto",
  "\tdrawfill",
  "\t0 0 moveto",
  "\tdrawgrid",
  "} def",
  "/daytext {",
  "\t/Helvetica-Narrow findfont 6 scalefont setfont",
  "\t/mytext\texch def /myday exch def",
  "\tstartday myday 1 sub add dup 7 mod 100 mul 5 add % gives column",
  "\texch 7 idiv -80 mul % gives row",
  "\tdup /ypos exch def moveto",
  "\t/LM currentpoint pop def /RM LM 95 add def",
  "        mytext { dup (.p) eq { crlf pop} {prstr ( ) show} ifelse } forall",
  "} def",
  "/crlf {",
  "    ypos 8 sub /ypos exch def LM ypos moveto",
  "} def",
  "/prstr {",
  "    dup stringwidth pop currentpoint pop",
  "    add RM gt {crlf (   ) show} if show",
  "} def",
  "/printmonth {",
   (char *)0,
 };
 
 char *header_2[] = {
  "\t/submonth 0 def",
  "\tcalendar",
  "\tmonth 1 sub 0 eq",
  "\t{",
  "\t\t/lmonth 12 def",
  "\t\t/lyear year 1 sub def",
  "\t}",
  "\t{",
  "\t\t/lmonth month 1 sub def",
  "\t\t/lyear year def",
  "\t} ifelse",
  "\tmonth 1 add 13 eq",
  "\t{",
  "\t\t/nmonth 1 def",
  "\t\t/nyear year 1 add def",
  "\t} ",
  "\t{",
  "\t\t/nmonth month 1 add def",
  "\t\t/nyear year def",
  "\t} ifelse",
  "\t/savemonth month def",
  "\t/saveyear year def",
  "\t/submonth 1 def",
  "\t/year lyear def",
  "\t/month lmonth def",
  "\tgsave",
  "\t500 -365 translate",
  "\tgsave",
  "\t.138 .138 scale",
  "\t10 -120 translate",
  "\tcalendar",
  "\tgrestore",
  "\t/submonth 1 def",
  "\t/year nyear def",
  "\t/month nmonth def",
  "\t100 0 translate",
  "\tgsave",
  "\t.138 .138 scale",
  "\t10 -120 translate",
  "\tcalendar",
  "\tgrestore",
  "\t/month savemonth def",
  "\t/year saveyear def",
  "\t/submonth 0 def",
  "\tgrestore",
  "} def",
  (char *)0,
};

SHAR_EOF
fi
exit 0
#	End of shell archive