[alt.sources] Pcal v3.0, part 2 of 3

jbr0@cbnews.att.com (joseph.a.brownlee) (01/02/91)

#!/bin/sh
# This is part 02 of a multipart archive
# ============= pcallang.h ==============
if test -f 'pcallang.h' -a X"$1" != X"-c"; then
	echo 'x - skipping pcallang.h (File already exists)'
else
echo 'x - extracting pcallang.h (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'pcallang.h' &&
/*
X * pcallang.h - language-dependent strings (month and day names, option file 
X * keywords, preprocessor tokens, prepositions, etc.):
X *
X * Revision history:
X *
X *	3.0	AWR	12/10/90	added support for "workday", "weekday",
X *					"holiday", et. al.
X *
X *		AWR	11/15/90	extracted from pcal.c; revised
X *					to contain all language-dependent
X *					strings
X */
X
static char *months[12] = {
X	"January", "February", "March", "April", "May", "June",
X	"July", "August", "September", "October", "November", "December"
X	};
X
/* Must be a 2-D array so address within may be used as an initializer;
X * wildcard names must be in same order as symbolic names in pcaldefs.h
X */
static char days[14][12] = {
X        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
X        "Saturday", 		/* weekday names */
X	"day", "weekday", "workday", "holiday", "nonweekday", "nonworkday",
X	"nonholiday"		/* wildcards */
X	};
X
/* preprocessor tokens */
X
KWD_F pp_info[] = {
X	"define",	PP_DEFINE,	do_define,
X	"else",		PP_ELSE,	NULL,
X	"endif",	PP_ENDIF,	NULL,
X	"ifdef",	PP_IFDEF,	do_ifdef,
X	"ifndef",	PP_IFNDEF,	do_ifndef,
X	"include",	PP_INCLUDE,	do_include,
X	"undef",	PP_UNDEF,	do_undef,
X	NULL,		PP_OTHER,	NULL };		/* must be last */
X
/* ordinal numbers - e.g. "first Monday in September" */
X
KWD ordinals[] = {
X	"1st",		ORD_FIRST,
X	"first",	ORD_FIRST,
X	"2nd",		ORD_SECOND,
X	"second",	ORD_SECOND,
X	"3rd",		ORD_THIRD,
X	"third",	ORD_THIRD,
X	"4th",		ORD_FOURTH,
X	"fourth",	ORD_FOURTH,
X	"5th",		ORD_FIFTH,
X	"fifth",	ORD_FIFTH,
X	"last",		ORD_LAST,
X	NULL,		ORD_OTHER };		/* must be last */
X
/* prepositions - e.g., "Friday after fourth Thursday in November" */
X
KWD preps[] = {
X	"before",	PR_BEFORE,
X	"preceding",	PR_BEFORE,
X	"on_or_before",	PR_ON_BEFORE,
X	"oob",		PR_ON_BEFORE,
X	"after",	PR_AFTER,
X	"following",	PR_AFTER,
X	"on_or_after",	PR_ON_AFTER,
X	"ooa",		PR_ON_AFTER,
X	NULL,		PR_OTHER };	/* must be last */
X
/* other keywords */
X
#define ALL	"all"		/* command-line or date file keyword */
X
KWD keywds[] = {
X	ALL,	 	DT_ALL,
X	"each",		DT_ALL,
X	"every",	DT_ALL,
X	"note",		DT_NOTE,
X	"opt",		DT_OPT,
X	"year",		DT_YEAR,
X	NULL,		DT_OTHER };	/* must be last */
X
/* minimum size of abbreviations  */
X
#define MIN_DAY_LEN	3
#define MIN_MONTH_LEN	3
#define MIN_PPTOK_LEN	3
#define MIN_PREP_LEN	7	/* distinguish "on_or_before", "on_or_after" */
#define MIN_ORD_LEN	3	/* distinguish "Thursday" from "third" */
X
X
/*
X * Symbolic names for command-line flags.  These may be changed
X * as desired in order to be meaningful in languages other than
X * English.
X */
X
#define F_INITIALIZE	'I'		/* re-initialize program defaults */
#define	F_BLACK_DAY	'b'		/* print day in black */
#define F_GRAY_DAY	'g'		/* print day in gray */
X
#define F_DAY_FONT	'd'		/* select alternate day font */
#define F_NOTES_FONT	'n'		/* select alternate notes font */
#define F_TITLE_FONT	't'		/* select alternate title font */
X
#define F_EMPTY_CAL	'e'		/* print empty calendar */
#define F_DATE_FILE	'f'		/* select alternate date file */
#define F_OUT_FILE	'o'		/* select alternate output file */
X
#define F_LANDSCAPE	'l'		/* landscape mode */
#define F_PORTRAIT	'p'		/* portrait mode */
X
#define F_HELP		'h'		/* generate help message */
X
#define F_MOON_4	'm'		/* print new/half/full moons */
#define F_MOON_ALL	'M'		/* print all moons */
X
#define F_DEFINE	'D'		/* define preprocessor symbol */
#define F_UNDEF		'U'		/* undefine preprocessor symbol */
X
#define F_L_FOOT	'L'		/* define left foot string */
#define F_C_FOOT	'C'		/* define center foot string */
#define F_R_FOOT	'R'		/* define right foot string */
X
#define F_FIRST_DAY	'F'		/* define alternate starting day */
X
#define F_USA_DATES	'A'		/* parse American date format */
#define F_EUR_DATES	'E'		/* parse European date format */
X
#define F_X_TRANS	'X'		/* X-axis transformation */
#define F_Y_TRANS	'Y'		/* Y-axis transformation */
#define F_X_SCALE	'x'		/* X-axis scale factor */
#define F_Y_SCALE	'y'		/* Y-axis scale factor */
X
#define F_JULIAN	'j'		/* print Julian day (day of year) */
#define F_JULIAN_ALL	'J'		/* print Julian day and days left */
X
X
/*
X * Flag usage information - not strictly language-dependent, but here anyway
X * (N.B.: all flags must be represented by an entry in this table!)
X *
X * Flags may appear in any of three places: in environment variable
X * PCAL_OPTS, on the command line, or in "opt" lines in the date file.
X * The command line is actually parsed twice: once before reading the date
X * file to get the flags needed in processing it (-e, -f, -b, -g, -D, -U, -A,
X * -E), and again after reading the date file to give the user one last
X * chance to override any of the other flags set earlier.  (Note, however,
X * that the only way to turn off -J|-j [Julian dates] or -M|-m [moons]
X * once selected is to use -I to reinitialize all program defaults.)
X *
X * The table below supplies the following information about each flag:
X *
X *	- Its name (cf. symbolic definitions above)
X *
X *	- Whether or not it can take an (optional) argument
X *
X *	- Which passes parse it: P_ENV (environment variable), P_CMD1
X *	  (first command line pass), P_OPT ("opt" lines in date file), 
X *	  and P_CMD2 (second command line pass)
X *
X */
X
FLAG_USAGE flag_tbl[] = {
X
/*	flag name	arg?	passes where parsed		*/
X
X	F_INITIALIZE,	FALSE,	P_ENV | P_CMD1 | P_OPT | P_CMD2 ,
X
X	F_BLACK_DAY,	TRUE,	P_ENV | P_CMD1 | P_OPT          ,
X	F_GRAY_DAY,	TRUE,	P_ENV | P_CMD1 | P_OPT          ,
X
X	F_DAY_FONT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_NOTES_FONT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_TITLE_FONT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_EMPTY_CAL,	FALSE,	P_ENV | P_CMD1                  ,
X	F_DATE_FILE,	TRUE,	P_ENV | P_CMD1                  ,
X	F_OUT_FILE,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_LANDSCAPE,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_PORTRAIT,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_HELP,		FALSE,	        P_CMD1                  ,
X
X	F_MOON_4,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_MOON_ALL,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_DEFINE,	TRUE,	P_ENV | P_CMD1                  ,
X	F_UNDEF,	TRUE,	P_ENV | P_CMD1                  ,
X
X	F_L_FOOT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_C_FOOT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_R_FOOT,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_FIRST_DAY,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_USA_DATES,	FALSE,	P_ENV | P_CMD1 | P_OPT          ,
X	F_EUR_DATES,	FALSE,	P_ENV | P_CMD1 | P_OPT          ,
X
X	F_X_TRANS,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_Y_TRANS,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_X_SCALE,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_Y_SCALE,	TRUE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	F_JULIAN,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X	F_JULIAN_ALL,	FALSE,	P_ENV          | P_OPT | P_CMD2 ,
X
X	'-',		FALSE,	P_ENV | P_CMD1 | P_OPT | P_CMD2 ,
X	'\0',		FALSE,	P_ENV | P_CMD1 | P_OPT | P_CMD2		/* must be last */
X	};
X
/*
X * Words used in usage() message - translate as necessary
X */
X
#define W_DEFAULT	"default"		/* translate as required */
#define W_USAGE		"Usage"
X
#define W_FONT		"FONT"			/* names of metavariables */
#define W_DAY		"DAY"
#define W_STRING	"STRING"
#define W_FILE		"FILE"
#define W_SYMBOL	"SYMBOL"
#define W_VALUE		"VALUE"
X
#define W_MM		"MM"			/* abbrev. for month, year */
#define W_YY		"YY"
X
#define W_BLACK		"black"			/* cf. color_msg() */
#define W_GRAY		"gray"
X
X
/* special flag_msg[] entries for end of option group, etc. */
X
#define END_GROUP	'\n', NULL, NULL, NULL		/* end of option group */
#define END_LIST	'\0', NULL, NULL, NULL		/* end of list */
#define GROUP_DEFAULT	' ', NULL, " "			/* group default */
X
/*
X * Message strings to be printed by usage() - translate as necessary
X */
X
FLAG_MSG flag_msg[] = {
X
/*	flag name	metasyntax	description						default */
X
X	F_INITIALIZE,	NULL,		"initialize all parameters to program defaults",	NULL,
X	END_GROUP,
X
X	F_BLACK_DAY,	W_DAY,		"print weekday in black",				NULL,
X	F_GRAY_DAY,	W_DAY,		"print weekday in gray",				NULL,
X	END_GROUP,
X
X	F_DAY_FONT,	W_FONT,		"specify alternate day name font",			DAYFONT,
X	F_NOTES_FONT,	W_FONT,		"specify alternate notes font",				NOTESFONT,
X	F_TITLE_FONT,	W_FONT,		"specify alternate title font",				TITLEFONT,
X	END_GROUP,
X
X	F_EMPTY_CAL,	NULL,		"generate empty calendar (ignore date file)",		NULL,
X	END_GROUP,
X
X	F_DATE_FILE,	W_FILE,		"specify alternate date file",				DATEFILE,
X	END_GROUP,
X
#ifdef VMS
X	F_OUT_FILE,	W_FILE,		"specify alternate output file",			OUTFILE,
#else
X	F_OUT_FILE,	W_FILE,		"specify alternate output file",			"stdout",
#endif
X	END_GROUP,
X
X	F_LANDSCAPE,	NULL,		"generate landscape-style calendar",			NULL,
X	F_PORTRAIT,	NULL,		"generate portrait-style calendar",			NULL,
#if ROTATE == LANDSCAPE
X	GROUP_DEFAULT,										"landscape",
#else	
X	GROUP_DEFAULT,										"portrait",
#endif
X	END_GROUP,
X
X	F_HELP,		NULL,		"print this help message",				NULL,
X	END_GROUP,
X
X	F_MOON_4,	NULL,		"draw a \"moon\" icon at full/new/half moons",		NULL,
X	F_MOON_ALL,	NULL,		"draw a \"moon\" icon every day",			NULL,
#if DRAW_MOONS == NO_MOONS
X	GROUP_DEFAULT,										"no moons",
#else
#if DRAW_MOONS == SOME_MOONS
X	GROUP_DEFAULT,										"full/new/half moons",
#else
X	GROUP_DEFAULT,										"every day",
#endif
#endif
X	END_GROUP,
X
X	F_DEFINE,	W_SYMBOL,	"define preprocessor symbol",				NULL,
X	F_UNDEF,	W_SYMBOL,	"undefine preprocessor symbol",				NULL,
X	END_GROUP,
X
X	F_L_FOOT,	W_STRING,	"specify left foot string",				LFOOT,
X	F_C_FOOT,	W_STRING,	"specify center foot string",				CFOOT,
X	F_R_FOOT,	W_STRING,	"specify right foot string",				RFOOT,
X	END_GROUP,
X
X	F_FIRST_DAY,	W_DAY,		"specify starting day of week",				days[FIRST_DAY],
X	END_GROUP,
X
X	F_USA_DATES,	NULL,		"parse American dates (\"mm/dd{/yy}\" and \"month dd\")", NULL,
X	F_EUR_DATES,	NULL,		"parse European dates (\"dd/mm{/yy}\" and \"dd month\")", NULL,
#if DATE_STYLE == USA_DATES
X	GROUP_DEFAULT,										"American",
#else
X	GROUP_DEFAULT,										"European",
#endif
X	END_GROUP,
X
X	F_X_TRANS,	W_VALUE,	"specify x-axis translation",				XTVAL,
X	F_Y_TRANS,	W_VALUE,	"specify y-axis translation",				YTVAL,
X	F_X_SCALE,	W_VALUE,	"specify x-axis scale factor",				XSVAL,
X	F_Y_SCALE,	W_VALUE,	"specify y-axis scale factor",				YSVAL,
X	END_GROUP,
X
X	F_JULIAN,	NULL,		"print Julian day (day of year)",			NULL,
X	F_JULIAN_ALL,	NULL,		"print Julian day and days left in year",		NULL,
#if JULIAN_DATES == NO_JULIANS
X	GROUP_DEFAULT,										"neither",
#else
#if JULIAN_DATES == SOME_JULIANS
X	GROUP_DEFAULT,										"Julian day",
#else
X	GROUP_DEFAULT,										"both",
#endif
#endif
X	END_GROUP,			/* must precede END_LIST */
X
X	END_LIST			/* must be last */
};
X
/* Numeric parameter descriptions and text */
X
#if __STDC__
PARAM_MSG param_msg[] = {
X	W_YY,			"generate calendar for year " W_YY " (19" W_YY " if " W_YY " < 100)",
X	W_MM " " W_YY,		"generate calendar for month " W_MM " (Jan = 1), year " W_YY,
X	W_MM " " W_YY " N",	"generate calendars for N months, starting at " W_MM "/" W_YY,
X	"(" W_DEFAULT ")",	"generate calendar for current month/year",
X	NULL,		NULL		/* must be last */
};
#else
PARAM_MSG param_msg[] = {
X	"YY",		"generate calendar for year YY (19YY if YY < 100)",
X	"MM YY",	"generate calendar for month MM (Jan = 1), year YY",
X	"MM YY N",	"generate calendars for N months, starting at MM/YY",
X	"(default)",	"generate calendar for current month/year",
X	NULL,		NULL		/* must be last */
};
#endif
X
#define PARAM_MSGS	3	/* number of above to print in command-line syntax message */
X
/* Date file syntax message - lines are copied intact */
X
char *date_msg[] = {
X	"The following rules describe the syntax of date file entries:",
X	"",
X	"  year <year>",
X	"",
X	"  opt <options>",
X	"",
X	"  note <month_spec> <text>",
X	"  note <month> <text>",
X	"",
X	"  if -A flag (American date formats) specified:",
X	"    <month_spec> <day>{*} {<text>}",
X	"    <month><sep><day>{<sep><year>}{*} {<text>}",
X	"",
X	"  if -E flag (European date formats) specified:",
X	"    <day> <month_spec>{*} {<text>}",
X	"    <day><sep><month>{<sep><year>}{*} {<text>}",
X	"",
X	"  <ordinal> <day_spec> in <month_spec>{*} {<text>}",
X	"  <day_spec> <prep> <date_spec>",
X	"",
X	"where",
X	"  {x}	  means x is optional",
X	"",
X	"  <date_spec> := any of the above date specs (not year, note, or opt)",
X	"  <month_spec> := first 3+ characters of name of month, or \"all\"",
X	"  <day_name> := first 3+ characters of name of weekday, \"day\",",
X	"		\"weekday\", \"workday\", \"holiday\", \"nonweekday\",",
X	"		\"nonworkday\", or \"nonholiday\"",
X	"  <ordinal> := \"first\", \"1st\", ... \"fifth\", \"5th\", \"last\", or \"all\"",
X	"  <prep> := \"before\", \"preceding\", \"after\", \"following\", \"on_or_before\",",
X	"		or \"on_or_after\"",
X	"  <sep> := one or more non-numeric, non-space, non-'*' characters",
X	"  <month>, <day>, <year> are the numeric forms",
X	"",
X	"  <options> := any command-line option except -e, -f, -h, -D, -U",
X	"",
X	"Comments start with '#' and run through end-of-line.",
X	"",
X	"Holidays may be flagged by specifying '*' as the last character of",
X	"the date field(s), e.g. \"10/12* Columbus Day\", \"July 4* Independence",
X	"Day\", etc.  Any dates flagged as holidays will be printed in gray, and",
X	"any associated text will appear adjacent to the date.",
X	"",
X	"Note that the numeric date formats (mm/dd{/yy}, dd.mm{.yy}) support",
X	"an optional year, which will become the subsequent default year.  The",
X	"alphabetic date formats (month dd, dd month) do not support a year",
X	"field; the \"year yy\" command is provided to reset the default year.",
X	"",
X	"\"Floating\" days may be specified in the date file as \"first Mon in ",
X	"Sep\", \"last Mon in May\", \"4th Thu in Nov\", etc.; any word may be",
X	"used in place of \"in\".  \"Relative floating\" days (e.g. \"Fri after 4th ",
X	"Thu in Nov\") are also accepted; they may span month/year bounds.",
X	"Pcal also accepts date specs such as \"all Friday{s} in October\", \"last",
X	"Thursday in all\", etc., and produces the expected results; \"each\" and",
X	"\"every\" are accepted as synonyms for \"all\".",
X	"",
X	"The words \"day\", \"weekday\", \"workday\", and \"holiday\" may be used as",
X	"wildcards: \"day\" matches any day, \"weekday\" matches any day normally",
X	"printed in black, \"workday\" matches any day normally printed in black",
X	"and not explicitly flagged as a holiday, and \"holiday\" matches any",
X	"day explicitly flagged as a holiday.  \"Nonweekday\", \"nonworkday\",",
X	"and \"nonholiday\" are also supported and have the obvious meanings.",
X	"",
X	"Additional notes may be propagated to an empty calendar box by the",
X	"inclusion of one or more lines of the form \"note <month> <text>\",",
X	"where <month> may be numeric or alphabetic; \"note all <text>\"",
X	"propagates <text> to each month in the current year.",
X	"",
X	"Simple cpp-like functionality is provided.  The date file may include",
X	"the following commands, which work like their cpp counterparts:",
X	"",
X	"        define <sym>",
X	"        undef <sym>",
X	"",
X	"        if{n}def <sym>",
X	"           ...",
X	"        { else",
X	"           ... }",
X	"        endif",
X	"",
X	"        include <file>",
X	"",
X	"Note that these do not start with '#', which is reserved as a comment",
X	"character.",
X	"",
X	"\"define\" alone deletes all the current definitions; \"ifdef\" alone is",
X	"always false; \"ifndef\" alone is always true.  All defined symbols are",
X	"treated in a case-insensitive manner.",
X	"",
X	"The file name in the \"include\" directive may optionally be surrounded",
X	"by \"\" or <>.  In any case, path names are taken to be relative to",
X	"the location of the file containing the \"include\" directive.",
X	NULL
X	};
X
/* format strings for color_msg() - translate as necessary */
#define COLOR_MSG_1	"all days in %s"
#define COLOR_MSG_2	"in %s; others in %s"
X
/* format string for short usage() message */
#define USAGE_MSG	"enter \"%s -%c\" for full description of parameters\n"
X
/* Error and information messages - translate as necessary */
X
/* program error messages */
#define	E_ALLOC_ERR	"%s: calloc() failed - out of memory\n"
#define	E_FOPEN_ERR	"%s: can't open file %s\n"
#define	E_ILL_LINE	"%s: %s in file %s, line %d\n"
#define	E_ILL_MONTH	"%s: month %d not in range %d .. %d\n"
#define	E_ILL_OPT	"%s: unrecognized parameter %s\n"
#define	E_ILL_YEAR	"%s: year %d not in range %d .. %d\n"
#define	E_SYMFULL	"%s: symbol table full - can't define %s\n"
#define	E_UNT_IFDEF	"%s: unterminated if{n}def..{else..}endif in file %s\n"
X
/* preprocessor error strings */
#define E_ELSE_ERR	"unmatched \"else\""
#define E_END_ERR	"unmatched \"endif\""
#define E_GARBAGE	"extraneous data on \"%s\" line"
#define E_INV_DATE	"invalid date"
#define E_INV_LINE	"unrecognized line"
#define E_NESTING	"maximum file nesting level exceeded"
X
/* information message (VMS only) */
#define	I_OUT_NAME	"%s: output is in file %s\n"
X
SHAR_EOF
chmod 0666 pcallang.h ||
echo 'restore of pcallang.h failed'
Wc_c="`wc -c < 'pcallang.h'`"
test 16742 -eq "$Wc_c" ||
	echo 'pcallang.h: original size 16742, current size' "$Wc_c"
fi
true || echo 'restore of pcal.c failed'
echo End of part 2, continue with part 3
exit 0