home *** CD-ROM | disk | FTP | other *** search
- From: jbr0@cbnews.att.com (joseph.a.brownlee)
- Newsgroups: alt.sources
- Subject: Pcal v4.0, part 5 of 5
- Message-ID: <1991Mar14.125242.9791@cbnews.att.com>
- Date: 14 Mar 91 12:52:42 GMT
-
- #!/bin/sh
- # This is part 05 of a multipart archive
- # ============= protos.h ==============
- if test -f 'protos.h' -a X"$1" != X"-c"; then
- echo 'x - skipping protos.h (File already exists)'
- else
- echo 'x - extracting protos.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'protos.h' &&
- /*
- X * protos.h - ANSI-style function prototypes for Pcal sources
- X *
- X * Revision history:
- X *
- X * 4.0 AWR 03/01/91 use <stdlib.h> where possible
- X *
- X * AWR 02/19/91 adapted from Bill Hogsett's source
- X *
- X */
- X
- X
- /*
- X * Prototypes for functions defined in exprpars.c:
- X */
- int parse_expr(char *pbuf);
- X
- X
- /*
- X * Prototypes for functions defined in moonphas.c:
- X */
- double calc_phase(int month, int day, int year);
- double find_phase(int month, int day, int year, int *pquarter);
- char *find_moonfile(int year);
- int read_moonfile(int year);
- X
- X
- /*
- X * Prototypes for functions defined in pcal.c:
- X */
- FILE *alt_fopen(char *fullpath, char *name, char *pathlist[], char *access);
- char *color_msg(void);
- int get_args(char **argv, int curr_pass, char *where);
- FLAG_USAGE *get_flag(char flag);
- int main(int argc, char **argv);
- void set_color(char *day, int col);
- void usage(FILE *fp, int fullmsg);
- X
- X
- /*
- X * Prototypes for functions defined in pcalutil.c:
- X */
- char *alloc(int size);
- int calc_day(int ord, int wkd, int mm);
- int calc_weekday(int mm, int dd, int yy);
- int calc_year_day(int ord, int wkd, DATE *pdate);
- int ci_strcmp(register char *s1, register char *s2);
- int ci_strncmp(register char *s1, register char *s2, int n);
- void copy_text(char *pbuf, char **ptext);
- int getline(FILE *fp, int *pline);
- int is_valid(register int m, register int d, register int y);
- int loadwords(void);
- char *mk_filespec(char *filespec, char *path, char *name);
- char *mk_path(char *path, char *filespec);
- void normalize(DATE *pd);
- int split_date(char *pstr, int *pn1, int *pn2, int *pn3);
- char *trnlog(char *logname);
- X
- X
- /*
- X * Prototypes for functions defined in readfile.c:
- X */
- void cleanup(void);
- void clear_syms(void);
- int date_type(char *cp, int *pn, int *pv);
- int do_define(char *sym);
- int do_ifdef(char *expr);
- int do_ifndef(char *expr);
- int do_include(char *path, char *name);
- int do_undef(char *sym);
- int enter_day_info(int m, int d, int y, int text_type, char **pword);
- int find_sym(char *sym);
- year_info *find_year(int year, int insert);
- int get_keywd(char *cp);
- int get_month(char *cp, int numeric_ok, int year_ok);
- int get_ordinal(char *cp, int *pval);
- int get_prep(char *cp);
- int get_token(char *token);
- int get_weekday(char *cp, int wild_ok);
- int is_anyday(int mm, int dd, int yy);
- int is_holiday(int mm, int dd, int yy);
- int is_weekday(int mm, int dd, int yy);
- int is_workday(int mm, int dd, int yy);
- int not_holiday(int mm, int dd, int yy);
- int not_weekday(int mm, int dd, int yy);
- int not_workday(int mm, int dd, int yy);
- int parse(char **pword, char *filename);
- int parse_date(char **pword, int *ptype, char ***pptext);
- int parse_ord(int ord, int val, char **pword);
- int parse_rel(int wkd, char **pword, int *ptype, char ***pptext);
- void read_datefile(FILE *fp, char *filename);
- X
- X
- /*
- X * Prototypes for functions defined in writefil.c:
- X */
- void def_footstring(char *p, char c);
- void find_daytext(int month, int year, int is_holiday);
- void find_holidays(int month, int year);
- void print_julian_info(int month, int year);
- void print_month(int month, int year);
- void print_moon_info(int month, int year);
- void print_text(char *p);
- char *print_word(char *p);
- void write_psfile(int month, int year, int nmonths);
- X
- X
- /*
- X * Prototypes for miscellaneous library routines (if not already included
- X * via <stdlib.h> - cf. pcaldefs.h):
- X */
- #ifndef STDLIB
- extern int atoi(char *);
- extern char *calloc(unsigned int, unsigned int);
- extern char *getenv(char *);
- #endif
- SHAR_EOF
- chmod 0666 protos.h ||
- echo 'restore of protos.h failed'
- Wc_c="`wc -c < 'protos.h'`"
- test 3428 -eq "$Wc_c" ||
- echo 'protos.h: original size 3428, current size' "$Wc_c"
- fi
- # ============= readfile.c ==============
- if test -f 'readfile.c' -a X"$1" != X"-c"; then
- echo 'x - skipping readfile.c (File already exists)'
- else
- echo 'x - extracting readfile.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'readfile.c' &&
- /*
- X * readfile.c - Pcal routines concerned with reading and parsing the datefile
- X *
- X * Contents:
- X *
- X * cleanup
- X * clear_syms
- X * date_type
- X * do_define
- X * do_ifdef
- X * do_ifndef
- X * do_include
- X * do_undef
- X * enter_day_info
- X * find_sym
- X * find_year
- X * get_keywd
- X * get_month
- X * get_ordinal
- X * get_prep
- X * get_token
- X * get_weekday
- X * is_anyday
- X * is_holiday
- X * is_weekday
- X * is_workday
- X * not_holiday
- X * not_weekday
- X * not_workday
- X * parse
- X * parse_date
- X * parse_ord
- X * parse_rel
- X * read_datefile
- X *
- X * Revision history:
- X *
- X * 4.0 AWR 02/19/91 Support negative ordinals
- X *
- X * AWR 02/06/91 Support expressions in "if{n}def"
- X *
- X * AWR 02/04/91 Support "even" and "odd" ordinals
- X * and ordinals > 5th; support "year"
- X *
- X * AWR 01/15/91 Extracted from pcal.c
- X *
- X */
- X
- /*
- X * Standard headers:
- X */
- X
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- X
- /*
- X * Pcal-specific definitions:
- X */
- X
- #include "pcaldefs.h"
- #include "pcalglob.h"
- #include "pcallang.h"
- X
- /*
- X * Macros:
- X */
- X
- /* status codes returned by parse(), enter_day_info() */
- #define PARSE_OK 0 /* successful date parse */
- #define PARSE_INVDATE 1 /* nonexistent date */
- #define PARSE_INVLINE 2 /* syntax error */
- X
- /* append date to list; terminate list */
- #define ADD_DATE(m, d, y) pdate->mm = m, pdate->dd = d, pdate++->yy = y
- #define TERM_DATES pdate->mm = pdate->dd = pdate->yy = 0
- X
- /*
- X * Globals:
- X */
- X
- static DATE dates[MAX_DATES+1]; /* array of date structures */
- static char *pp_sym[MAX_PP_SYMS]; /* preprocessor defined symbols */
- X
- X
- /*
- X * read_datefile - read and parse date file, handling preprocessor lines
- X *
- X * This is the main routine of this module. It calls getline() to read each
- X * non-null line (stripped of leading blanks and trailing comments), loadwords()
- X * to "tokenize" it, and get_token() to classify it as a preprocessor directive
- X * or "other". A switch{} statement takes the appropriate action for each
- X * token type; "other" lines are further classified by parse() (q.v.) which
- X * calls parse_date() (q.v.) to parse date entries and enter them in the data
- X * structure (as described in pcaldefs.h).
- X *
- X */
- #ifdef PROTOS
- void read_datefile(FILE *fp,
- X char *filename)
- #else
- void read_datefile(fp, filename)
- X FILE *fp; /* file pointer (assumed open) */
- X char *filename; /* file name (for error messages) */
- #endif
- {
- X static int file_level = 0;
- X int if_level = 0;
- X int restart_level = 0;
- X int line = 0;
- X int processing = TRUE;
- X
- X int pptype, extra, ntokens, save_year, expr;
- X int (*pfcn)();
- X char *ptok;
- X char **pword;
- X char msg[STRSIZ], incpath[STRSIZ];
- X
- X if (fp == NULL) /* whoops, no date file */
- X return;
- X
- X if (++file_level > MAX_NESTING) { /* nesting too deep? */
- X ERR(E_NESTING);
- X exit(EXIT_FAILURE);
- X }
- X
- X save_year = curr_year; /* save default year */
- X
- X /* read lines until EOF */
- X
- X while (getline(fp, &line)) {
- X
- X ntokens = loadwords(); /* split line into tokens */
- X pword = words; /* point to the first */
- X
- X /* get token type and pointers to function and name */
- X
- X pptype = get_token(*pword++);
- X pfcn = pp_info[pptype].pfcn;
- X ptok = pp_info[pptype].name;
- X
- X switch (pptype) {
- X
- X case PP_DEFINE:
- X case PP_UNDEF:
- X if (processing)
- X (void) (*pfcn)(*pword);
- X extra = ntokens > 2;
- X break;
- X
- X case PP_ELSE:
- X if (if_level < 1) {
- X ERR(E_ELSE_ERR);
- X break;
- X }
- X
- X if (processing) {
- X processing = FALSE; /* disable processing */
- X restart_level = if_level;
- X }
- X else
- X if (if_level == restart_level) {
- X processing = TRUE; /* re-enable processing */
- X restart_level = 0;
- X }
- X extra = ntokens > 1;
- X break;
- X
- X case PP_ENDIF:
- X if (if_level < 1) {
- X ERR(E_END_ERR);
- X break;
- X }
- X
- X if (! processing && if_level == restart_level) {
- X processing = TRUE; /* re-enable processing */
- X restart_level = 0;
- X }
- X if_level--;
- X extra = ntokens > 1;
- X break;
- X
- X case PP_IFDEF:
- X case PP_IFNDEF:
- X if_level++;
- X if (processing) {
- X copy_text(lbuf, pword); /* reconstruct string */
- X if ((expr = (*pfcn)(lbuf)) == EXPR_ERR) {
- X ERR(E_EXPR_SYNTAX);
- X expr = FALSE;
- X }
- X if (! expr) { /* disable processing */
- X processing = FALSE;
- X restart_level = if_level;
- X }
- X }
- X extra = FALSE;
- X break;
- X
- X case PP_INCLUDE:
- X if (processing)
- X do_include(mk_path(incpath, filename), *pword);
- X extra = ntokens > 2;
- X break;
- X
- X case PP_OTHER: /* none of the above - parse as date */
- X if (processing) {
- X switch (parse(words, filename)) {
- X
- X case PARSE_INVDATE:
- X ERR(E_INV_DATE);
- X break;
- X
- X case PARSE_INVLINE:
- X ERR(E_INV_LINE);
- X break;
- X
- X }
- X }
- X extra = FALSE;
- X break;
- X
- X } /* end switch */
- X
- X if (extra) { /* extraneous data? */
- X sprintf(msg, E_GARBAGE, ptok);
- X ERR(msg);
- X }
- X
- X } /* end while */
- X
- X if (if_level > 0)
- X FPR(stderr, E_UNT_IFDEF, progname, filename);
- X
- X file_level--;
- X curr_year = save_year; /* restore default year */
- }
- X
- X
- /*
- X * Routines to free allocated data (symbol table and data structure)
- X */
- X
- X
- /*
- X * clear_syms - clear and deallocate the symbol table
- X */
- #ifdef PROTOS
- void clear_syms(void)
- #else
- void clear_syms()
- #endif
- {
- X int i;
- X
- X for (i = 0; i < MAX_PP_SYMS; i++)
- X if (pp_sym[i]) {
- X free(pp_sym[i]);
- X pp_sym[i] = NULL;
- X }
- }
- X
- X
- /*
- X * cleanup - free all allocated data
- X */
- #ifdef PROTOS
- void cleanup(void)
- #else
- void cleanup()
- #endif
- {
- X int i, j;
- X year_info *py, *pny;
- X month_info *pm;
- X day_info *pd, *pnd;
- X
- X for (py = head; py; py = pny) { /* main data structure */
- X pny = py->next;
- X for (i = 0; i < 12; i++) {
- X if ((pm = py->month[i]) == NULL)
- X continue;
- X for (j = 0; j < NOTE_DAY; j++)
- X for (pd = pm->day[j]; pd; pd = pnd) {
- X pnd = pd->next;
- X free(pd->text);
- X free(pd);
- X }
- X free(pm);
- X }
- X free(py);
- X }
- X
- X clear_syms(); /* symbol table */
- X
- }
- X
- X
- /*
- X * Preprocessor token and symbol table routines
- X */
- X
- X
- /*
- X * find_sym - look up symbol; return symbol table index if found, PP_SYM_UNDEF
- X * if not found
- X */
- #ifdef PROTOS
- int find_sym(char *sym)
- #else
- int find_sym(sym)
- X char *sym;
- #endif
- {
- X int i;
- X
- X if (!sym)
- X return PP_SYM_UNDEF;
- X
- X for (i = 0; i < MAX_PP_SYMS; i++)
- X if (pp_sym[i] && ci_strcmp(pp_sym[i], sym) == 0)
- X return i;
- X
- X return PP_SYM_UNDEF;
- }
- X
- X
- /*
- X * do_ifdef - return TRUE if 'expr' is true; FALSE if not; EXPR_ERR if invalid
- X */
- #ifdef PROTOS
- int do_ifdef(char *expr)
- #else
- int do_ifdef(expr)
- X char *expr;
- #endif
- {
- X return parse_expr(expr);
- }
- X
- X
- /*
- X * do_ifndef - return FALSE if 'expr' is true; TRUE if not; EXPR_ERR if invalid
- X */
- #ifdef PROTOS
- int do_ifndef(char *expr)
- #else
- int do_ifndef(expr)
- X char *expr;
- #endif
- {
- X int val;
- X
- X return (val = parse_expr(expr)) == EXPR_ERR ? EXPR_ERR : ! val;
- }
- X
- X
- /*
- X * do_define - enter 'sym' into symbol table; if 'sym' NULL, clear symbol table.
- X * Always returns 0 (for compatibility with other dispatch functions).
- X */
- #ifdef PROTOS
- int do_define(char *sym)
- #else
- int do_define(sym)
- X char *sym;
- #endif
- {
- X int i;
- X
- X if (! sym) { /* null argument - clear all definitions */
- X clear_syms();
- X return 0;
- X }
- X
- X if (do_ifdef(sym)) /* already defined? */
- X return 0;
- X
- X for (i = 0; i < MAX_PP_SYMS; i++) /* find room for it */
- X if (! pp_sym[i]) {
- X strcpy(pp_sym[i] = alloc(strlen(sym)+1), sym);
- X return 0;
- X }
- X
- X FPR(stderr, E_SYMFULL, progname, sym);
- X return 0;
- }
- X
- X
- /*
- X * do_undef - undefine 'sym' and free its space; no error if not defined.
- X * Always return 0 (for compatibility with other dispatch fcns).
- X */
- #ifdef PROTOS
- int do_undef(char *sym)
- #else
- int do_undef(sym)
- X char *sym;
- #endif
- {
- X int i;
- X
- X if (! sym)
- X return 0;
- X
- X if ((i = find_sym(sym)) != PP_SYM_UNDEF) {
- X free(pp_sym[i]);
- X pp_sym[i] = NULL;
- X }
- X
- X return 0;
- }
- X
- X
- /*
- X * do_include - include specified file (optionally in "" or <>); always
- X * returns 0 (for compatibility with related functions returning int)
- X */
- #ifdef PROTOS
- int do_include(char *path,
- X char *name)
- #else
- int do_include(path, name)
- X char *path; /* path to file */
- X char *name; /* file name */
- #endif
- {
- X FILE *fp;
- X char *p, incfile[STRSIZ], tmpnam[STRSIZ];
- X
- X if (! name) /* whoops, no date file */
- X return 0;
- X
- X /* copy name, stripping "" or <> */
- X strcpy(tmpnam, name + (*name == '"' || *name == '<'));
- X if ((p = P_LASTCHAR(tmpnam)) && *p == '"' || *p == '>')
- X *p = '\0';
- X
- X if ((fp = fopen(mk_filespec(incfile, path, tmpnam), "r")) == NULL) {
- X FPR(stderr, E_FOPEN_ERR, progname, incfile);
- X exit(EXIT_FAILURE);
- X }
- X
- X read_datefile(fp, incfile); /* recursive call */
- X fclose(fp);
- X
- X return 0;
- }
- X
- X
- X
- /*
- X * Dispatch functions for wildcard matching
- X */
- X
- X
- /*
- X * is_anyday - dummy function which always returns TRUE
- X */
- #ifdef PROTOS
- int is_anyday(int mm,
- X int dd,
- X int yy)
- #else
- int is_anyday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return TRUE;
- }
- X
- X
- /*
- X * is_weekday - determine whether or not mm/dd/yy is a weekday (i.e., the
- X * day of the week normally prints in black)
- X */
- #ifdef PROTOS
- int is_weekday(int mm,
- X int dd,
- X int yy)
- #else
- int is_weekday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return day_color[calc_weekday(mm, dd, yy)] == BLACK;
- }
- X
- X
- /*
- X * is_workday - determine whether or not mm/dd/yy is a workday (i.e., the
- X * day of the week normally prints in black and the date is not a holiday)
- X */
- #ifdef PROTOS
- int is_workday(int mm,
- X int dd,
- X int yy)
- #else
- int is_workday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return is_weekday(mm, dd, yy) && ! is_holiday(mm, dd, yy);
- }
- X
- X
- /*
- X * is_holiday - determine whether or not mm/dd/yy is a holiday
- X */
- #ifdef PROTOS
- int is_holiday(int mm,
- X int dd,
- X int yy)
- #else
- int is_holiday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X year_info *py;
- X month_info *pm;
- X
- X pm = (py = find_year(yy, FALSE)) ? py->month[mm-1] : NULL;
- X return pm ? (pm->holidays & (1L << (dd-1))) != 0 : FALSE;
- }
- X
- X
- /*
- X * not_XXXXX - converses of is_XXXXX above
- X */
- #ifdef PROTOS
- int not_weekday(int mm,
- X int dd,
- X int yy)
- #else
- int not_weekday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return !is_weekday(mm, dd, yy);
- }
- X
- X
- #ifdef PROTOS
- int not_workday(int mm,
- X int dd,
- X int yy)
- #else
- int not_workday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return !is_workday(mm, dd, yy);
- }
- X
- X
- #ifdef PROTOS
- int not_holiday(int mm,
- X int dd,
- X int yy)
- #else
- int not_holiday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return !is_holiday(mm, dd, yy);
- }
- X
- X
- X
- /*
- X * Keyword classification routines
- X */
- X
- /*
- X * get_month - convert alpha (or, optionally, numeric) string to month; return
- X * 1..12 if valid, NOT_MONTH if not, ALL_MONTHS if "all", ENTIRE_YEAR if "year"
- X */
- #ifdef PROTOS
- int get_month(char *cp,
- X int numeric_ok,
- X int year_ok)
- #else
- int get_month(cp, numeric_ok, year_ok)
- X char *cp; /* string to convert */
- X int numeric_ok; /* accept numeric string ? */
- X int year_ok; /* accept "year"? */
- #endif
- {
- X int mm;
- X
- X if (! cp)
- X return NOT_MONTH;
- X
- X if (get_keywd(cp) == DT_ALL)
- X return ALL_MONTHS;
- X
- X if (year_ok && get_keywd(cp) == DT_YEAR)
- X return ENTIRE_YEAR;
- X
- X if (numeric_ok && isdigit(*cp))
- X mm = atoi(cp);
- X else
- X for (mm = JAN;
- X mm <= DEC && ci_strncmp(cp, months[mm-1], MIN_MONTH_LEN);
- X mm++)
- X ;
- X
- X return mm >= JAN && mm <= DEC ? mm : NOT_MONTH;
- }
- X
- X
- /*
- X * get_weekday - look up string in weekday list; return 0-6 if valid,
- X * NOT_WEEKDAY if not. If wild_ok flag is set, accept "day", "weekday",
- X * "workday", or "holiday" and return appropriate value.
- X */
- #ifdef PROTOS
- int get_weekday(char *cp,
- X int wild_ok)
- #else
- int get_weekday(cp, wild_ok)
- X char *cp;
- X int wild_ok;
- #endif
- {
- X int w;
- X
- X if (!cp)
- X return NOT_WEEKDAY;
- X
- X if (wild_ok) { /* try wildcards first */
- X for (w = WILD_FIRST; w <= WILD_LAST; w++)
- X if (ci_strncmp(cp, days[w], strlen(days[w])) == 0)
- X return w;
- X }
- X
- X for (w = SUN; w <= SAT; w++)
- X if (ci_strncmp(cp, days[w], MIN_DAY_LEN) == 0)
- X return w;
- X
- X return NOT_WEEKDAY;
- }
- X
- X
- /*
- X * get_keywd - look up string in misc. keyword list; return keyword code
- X * if valid, DT_OTHER if not
- X */
- #ifdef PROTOS
- int get_keywd(char *cp)
- #else
- int get_keywd(cp)
- X char *cp;
- #endif
- {
- X KWD *k;
- X
- X if (!cp)
- X return DT_OTHER;
- X
- X for (k = keywds;
- X k->name && ci_strncmp(cp, k->name, strlen(k->name));
- X k++)
- X ;
- X
- X return k->code;
- }
- X
- X
- /*
- X * get_ordinal - look up string in ordinal list; return ordinal code (and
- X * fill in ordinal value) if valid, return ORD_OTHER if not
- X */
- #ifdef PROTOS
- int get_ordinal(char *cp,
- X int *pval)
- #else
- int get_ordinal(cp, pval)
- X char *cp;
- X int *pval;
- #endif
- {
- X KWD_O *o;
- X int val;
- X char **psuf;
- X
- X if (!cp)
- X return ORD_OTHER;
- X
- X if (isdigit(*cp) || *cp == '-') { /* numeric? */
- X if ((val = atoi(cp)) == 0)
- X return ORD_OTHER;
- X
- X if (*cp == '-') /* skip over number */
- X cp++;
- X cp += strspn(cp, DIGITS);
- X
- X for (psuf = ord_suffix; *psuf; psuf++) /* find suffix */
- X if (ci_strcmp(cp, *psuf) == 0) {
- X *pval = val;
- X return val < 0 ? ORD_NEGNUM : ORD_POSNUM;
- X }
- X
- X return ORD_OTHER;
- X }
- X
- X /* look for word in ordinals list */
- X
- X for (o = ordinals; o->name && ci_strncmp(cp, o->name, MIN_ORD_LEN); o++)
- X ;
- X
- X *pval = o->value;
- X return o->code;
- }
- X
- X
- /*
- X * get_prep - look up string in preposition list; return preposition code if
- X * valid, PR_OTHER if not
- X */
- #ifdef PROTOS
- int get_prep(char *cp)
- #else
- int get_prep(cp)
- X char *cp;
- #endif
- {
- X KWD *p;
- X
- X if (!cp)
- X return PR_OTHER;
- X
- X for (p = preps; p->name && ci_strncmp(cp, p->name, MIN_PREP_LEN); p++)
- X ;
- X
- X return p->code;
- }
- X
- X
- /*
- X * get_token - look up 'token' in list of preprocessor tokens; return its
- X * index if found, PP_OTHER if not
- X */
- #ifdef PROTOS
- int get_token(char *token)
- #else
- int get_token(token)
- X char *token;
- #endif
- {
- X KWD_F *p;
- X
- X for (p = pp_info;
- X p->name && ci_strncmp(token, p->name, MIN_PPTOK_LEN);
- X p++)
- X ;
- X
- X return p->code;
- }
- X
- X
- /*
- X * date_type - examine token and return date type code; if DT_MONTH, DT_ORDINAL,
- X * or DT_WEEKDAY, fill in appropriate code (and value if DT_ORDINAL)
- X */
- #ifdef PROTOS
- int date_type(char *cp,
- X int *pn,
- X int *pv)
- #else
- int date_type(cp, pn, pv)
- X char *cp; /* pointer to start of token */
- X int *pn; /* token type code (returned) */
- X int *pv; /* ordinal value (returned) */
- #endif
- {
- X int n, v;
- X
- X if ((n = get_ordinal(cp, &v)) != ORD_OTHER) /* ordinal? */
- X return (*pn = n, *pv = v, DT_ORDINAL);
- X
- X if (isdigit(*cp)) /* other digit? */
- X return IS_NUMERIC(cp) ? DT_EURDATE : DT_DATE;
- X
- X if ((n = get_weekday(cp, TRUE)) != NOT_WEEKDAY) /* weekday name? */
- X return (*pn = n, DT_WEEKDAY);
- X
- X /* "all" can be either a keyword or a month wildcard - look for
- X the former usage first */
- X
- X if ((n = get_keywd(cp)) != DT_OTHER)
- X return n;
- X
- X if ((n = get_month(cp, FALSE, FALSE)) != NOT_MONTH) /* month name? */
- X return (*pn = n, DT_MONTH);
- X
- X return DT_OTHER; /* unrecognized keyword - give up */
- X
- }
- X
- X
- X
- /*
- X * Routines for entering data in the data structure (described in pcaldefs.h)
- X */
- X
- X
- /*
- X * find_year - find record in year list; optionally create if not present
- X */
- #ifdef PROTOS
- year_info *find_year(int year,
- X int insert)
- #else
- year_info *find_year(year, insert) /* find record in year list */
- X int year;
- X int insert; /* insert if missing */
- #endif
- {
- X year_info *pyear, *plast, *p;
- X
- X for (plast = NULL, pyear = head; /* search linked list */
- X pyear && pyear->year < year;
- X plast = pyear, pyear = pyear->next)
- X ;
- X
- X if (pyear && pyear->year == year) /* found - return it */
- X return pyear;
- X
- X if (insert) { /* not found - insert it if requested */
- X p = (year_info *) alloc((int) sizeof(year_info)); /* create new record */
- X p->year = year;
- X
- X p->next = pyear; /* link it in */
- X return *(plast ? &plast->next : &head) = p;
- X }
- X else
- X return NULL;
- }
- X
- X
- /*
- X * enter_day_info - enter text for specified day; avoid entering duplicates.
- X * Returns PARSE_INVDATE if date invalid, PARSE_OK if OK; if symbol FEB_29_OK
- X * is non-zero (cf. pcaldefs.h), will silently ignore Feb 29 of common year.
- X */
- #ifdef PROTOS
- int enter_day_info(int m,
- X int d,
- X int y,
- X int text_type,
- X char **pword)
- #else
- int enter_day_info(m, d, y, text_type, pword) /* fill in information for given day */
- X int m, d, y;
- X int text_type;
- X char **pword;
- #endif
- {
- X static year_info *pyear;
- X static int prev_year = 0;
- X month_info *pmonth;
- X day_info *pday, *plast;
- X int is_holiday = text_type == HOLIDAY_TEXT;
- X char text[LINSIZ];
- X
- X if (! is_valid(m, d == NOTE_DAY && text_type == NOTE_TEXT ? 1 : d, y))
- X return (m == FEB && d == 29 && FEB_29_OK) ? PARSE_OK : PARSE_INVDATE;
- X
- X if (y != prev_year) /* avoid unnecessary year lookup */
- X pyear = find_year(y, 1);
- X
- X --m, --d; /* adjust for use as subscripts */
- X
- X if ((pmonth = pyear->month[m]) == NULL) /* find/create month record */
- X pyear->month[m] = pmonth = (month_info *) alloc((int) sizeof(month_info));
- X
- X if (is_holiday)
- X pmonth->holidays |= (1L << d);
- X
- X /* insert text for day at end of list (preserving the order of entry
- X * for multiple lines on same day); eliminate those differing only
- X * in spacing and capitalization from existing entries
- X */
- X
- X copy_text(text, pword); /* consolidate text from lbuf into text */
- X
- #ifdef DATE_DEBUG
- X {
- X char *p;
- X fprintf(stderr, "%02d/%02d/%d%c '", m+1, d+1, y, is_holiday ? '*' : ' ');
- X for (p = text; *p; p++)
- X fprintf(stderr, isprint(*p) ? "%c" : "\\%03o", *p & 0377);
- X fprintf(stderr, "'\n");
- X }
- #endif
- X
- X if (*text) {
- X for (plast = NULL, pday = pmonth->day[d];
- X pday;
- X plast = pday, pday = pday->next)
- X if (ci_strcmp(pday->text, text) == 0) {
- X pday->is_holiday |= is_holiday;
- X return PARSE_OK;
- X }
- X
- X /* unique - add to end of list */
- X
- X pday = (day_info *) alloc(sizeof(day_info));
- X pday->is_holiday = is_holiday;
- X strcpy(pday->text = (char *) alloc(strlen(text)+1), text);
- X pday->next = NULL;
- X *(plast ? &plast->next : &pmonth->day[d]) = pday;
- X }
- X
- X return PARSE_OK;
- }
- X
- X
- X
- /*
- X * Date parsing routines:
- X */
- X
- X
- /*
- X * parse_ord - parse an ordinal date spec (e.g. "first Monday in September",
- X * "every Sunday in October", "last workday in all"); return PARSE_OK if line
- X * syntax valid, PARSE_INVLINE if not. Write all matching dates (if any) to
- X * global array dates[]; terminate date list with null entry.
- X */
- #ifdef PROTOS
- int parse_ord(int ord,
- X int val,
- X char **pword)
- #else
- int parse_ord(ord, val, pword)
- X int ord; /* valid ordinal code - from get_ordinal() */
- X int val; /* ordinal value - also from get_ordinal() */
- X char **pword; /* pointer to word after ordinal */
- #endif
- {
- X int wkd, mon, mm, dd, len, (*pfcn)(), doit;
- X int val_first, val_last, val_incr, mon_first, mon_last;
- X DATE *pdate, date;
- X
- X if ((wkd = get_weekday(*pword, TRUE)) == NOT_WEEKDAY || /* weekday */
- X *++pword == NULL || /* any word */
- X (mon = get_month(*++pword, FALSE, TRUE)) == NOT_MONTH) /* month */
- X return PARSE_INVLINE;
- X
- X /* set up loop boundaries for month loop */
- X
- X mon_first = mon == ALL_MONTHS || mon == ENTIRE_YEAR ? JAN : mon;
- X mon_last = mon == ALL_MONTHS || mon == ENTIRE_YEAR ? DEC : mon;
- X
- X pdate = dates; /* start of date array */
- X
- X /* special case of "all|odd|even <wildcard> in <month>|all|year" */
- X
- X if ((ord == ORD_ALL || ord == ORD_EVEN || ord == ORD_ODD) &&
- X IS_WILD(wkd)) {
- X pfcn = pdatefcn[wkd - ANY_DAY];
- X doit = ord != ORD_EVEN;
- X for (mm = mon_first; mm <= mon_last; mm++) {
- X len = LENGTH_OF(mm, curr_year);
- X if (mon != ENTIRE_YEAR)
- X doit = ord != ORD_EVEN;
- X for (dd = 1; dd <= len; dd++)
- X if ((*pfcn)(mm, dd, curr_year)) {
- X if (doit)
- X ADD_DATE(mm, dd, curr_year);
- X if (ord != ORD_ALL)
- X doit = ! doit;
- X }
- X }
- X }
- X
- X /* special case of "odd|even <weekday> in year" */
- X
- X else if ((ord == ORD_EVEN || ord == ORD_ODD) && mon == ENTIRE_YEAR) {
- X date.mm = JAN; /* starting date */
- X date.dd = calc_day(ord == ORD_EVEN ? 2 : 1, wkd, JAN);
- X date.yy = curr_year;
- X do { /* alternates throughout year */
- X ADD_DATE(date.mm, date.dd, date.yy);
- X date.dd += 14;
- X normalize(&date);
- X } while (date.yy == curr_year);
- X }
- X
- X /* special case of "<ordinal>|last <weekday>|<wildcard> in year" */
- X
- X else if ((ord == ORD_NEGNUM || ord == ORD_POSNUM) &&
- X mon == ENTIRE_YEAR) {
- X if (calc_year_day(val, wkd, &date))
- X ADD_DATE(date.mm, date.dd, date.yy);
- X }
- X
- X /* all other combinations of ordinal and day */
- X
- X else {
- X /* set up loop boundaries for "wildcard" ordinals */
- X
- X val_first = ord == ORD_ALL || ord == ORD_ODD ? 1 :
- X ord == ORD_EVEN ? 2 : val;
- X val_last = ord == ORD_ALL || ord == ORD_ODD ? 5 :
- X ord == ORD_EVEN ? 4 : val;
- X val_incr = ord == ORD_ODD || ord == ORD_EVEN ? 2 : 1;
- X
- X for (mm = mon_first; mm <= mon_last; mm++)
- X for (val = val_first; val <= val_last; val += val_incr)
- X if ((dd = calc_day(val, wkd, mm)) != 0)
- X ADD_DATE(mm, dd, curr_year);
- X }
- X
- X TERM_DATES; /* terminate array with null entry */
- X return PARSE_OK;
- X
- }
- X
- X
- /*
- X * parse_rel - parse a relative date spec (e.g. "Friday after fourth Thursday
- X * in November", "Saturday after first Friday in all"; return PARSE_OK if
- X * line syntax valid, PARSE_INVLINE if not. Transform all dates that match
- X * the base date to the appropriate day, month, and year.
- X *
- X * This calls parse_date() recursively in order to handle cases such as
- X * "Friday after Tuesday before last day in all".
- X */
- #ifdef PROTOS
- int parse_rel(int wkd,
- X char **pword,
- X int *ptype,
- X char ***pptext)
- #else
- int parse_rel(wkd, pword, ptype, pptext)
- X int wkd; /* valid weekday code - from get_weekday() */
- X char **pword; /* pointer to word after weekday */
- X int *ptype; /* return text type (holiday/non-holiday) */
- X char ***pptext; /* return pointer to first word of text */
- #endif
- {
- X int prep, rtn, base_wkd, incr, (*pfcn)();
- X DATE *pd;
- X
- X /* we have the weekday - now look for the preposition */
- X if ((prep = get_prep(*pword++)) == PR_OTHER)
- X return PARSE_INVLINE;
- X
- X /* get the base date */
- X if ((rtn = parse_date(pword, ptype, pptext)) != PARSE_OK)
- X return rtn;
- X
- X /* transform date array in place - note that the relative date may
- X not be in the same month or even year */
- X
- X if (IS_WILD(wkd)) { /* wildcard for weekday name? */
- X pfcn = pdatefcn[wkd - ANY_DAY];
- X incr = prep == PR_BEFORE || prep == PR_ON_BEFORE ? -1 : 1;
- X
- X for (pd = dates; pd->mm; pd++) {
- X /* search for nearest matching date */
- X
- X if (prep == PR_BEFORE || prep == PR_AFTER) {
- X pd->dd += incr;
- X normalize(pd);
- X }
- X while (!(*pfcn)(pd->mm, pd->dd, pd->yy)) {
- X pd->dd += incr;
- X normalize(pd);
- X }
- X }
- X
- X } else { /* explicit weekday name */
- X for (pd = dates; pd->mm; pd++) {
- X /* calculate nearest matching date */
- X
- X base_wkd = calc_weekday(pd->mm, pd->dd, pd->yy);
- X
- X if (prep == PR_BEFORE ||
- X (prep == PR_ON_BEFORE && wkd != base_wkd))
- X pd->dd -= 7 - (wkd - base_wkd + 7) % 7;
- X
- X if (prep == PR_AFTER ||
- X (prep == PR_ON_AFTER && wkd != base_wkd))
- X pd->dd += (wkd - base_wkd + 6) % 7 + 1;
- X
- X normalize(pd); /* adjust for month/year crossing */
- X }
- X }
- X
- X return PARSE_OK;
- }
- X
- X
- /*
- X * parse_date - parse a date specification in any of its myriad forms; upon
- X * return, array dates[] will contain a list of all the dates that matched,
- X * terminated by a null entry. Also fill in the date type (holiday/non-
- X * holiday) code and the pointer to the first word of text.
- X */
- #ifdef PROTOS
- int parse_date(char **pword,
- X int *ptype,
- X char ***pptext)
- #else
- int parse_date(pword, ptype, pptext)
- X char **pword; /* first word to parse */
- X int *ptype; /* return date type (holiday/non-holiday) */
- X char ***pptext; /* return pointer to first word of text */
- #endif
- {
- X int mm, dd, yy;
- X int token, n, v, ord, val, wkd, rtn;
- X DATE *pdate;
- X char *cp;
- X
- X pdate = dates;
- X
- X switch (token = date_type(*pword, &n, &v)) {
- X
- X case DT_MONTH: /* <month> dd */
- X if (date_style != USA_DATES)
- X return PARSE_INVLINE;
- X
- X if ((cp = *++pword) == NULL)
- X return PARSE_INVLINE;
- X
- X ADD_DATE(n, atoi(cp), curr_year);
- X TERM_DATES;
- X
- X break;
- X
- X case DT_DATE: /* mm/dd{/yy} | dd/mm{/yy} */
- X n = split_date(*pword,
- X date_style == USA_DATES ? &mm : &dd,
- X date_style == USA_DATES ? &dd : &mm,
- X &yy);
- X
- X if (n > 2) { /* year present? */
- X if (yy < 100)
- X yy += CENTURY;
- X curr_year = yy; /* reset current year */
- X }
- X
- X ADD_DATE(mm, dd, curr_year);
- X TERM_DATES;
- X
- X break;
- X
- X case DT_EURDATE: /* dd [ <month> | "all" ] */
- X if (date_style != EUR_DATES)
- X return PARSE_INVLINE;
- X
- X dd = atoi(*pword);
- X
- X if (get_keywd(*++pword) == DT_ALL) {
- X for (mm = JAN; mm <= DEC; mm++) /* wildcard */
- X ADD_DATE(mm, dd, curr_year);
- X }
- X else { /* one month */
- X if ((mm = get_month(*pword, FALSE, FALSE)) == NOT_MONTH)
- X return PARSE_INVLINE;
- X
- X ADD_DATE(mm, dd, curr_year);
- X }
- X
- X TERM_DATES;
- X break;
- X
- X case DT_ALL: /* "all" <weekday> "in" [ <month> | "all" ] */
- X /* or "all" <day>" */
- X
- X if ((cp = *(pword+1)) && (*(cp += strspn(cp, DIGITS)) == '\0' ||
- X *cp == '*')) {
- X dd = atoi(*++pword); /* "all" <day> */
- X for (mm = JAN; mm <= DEC; mm++)
- X ADD_DATE(mm, dd, curr_year);
- X TERM_DATES;
- X break; /* leave switch */
- X }
- X
- X n = ORD_ALL; /* "all" <weekday> ... */
- X v = 0;
- X /* fall through */
- X
- X case DT_ORDINAL: /* <ordinal> <weekday> in [ <month> | "all" ] */
- X ord = n;
- X val = v;
- X if ((rtn = parse_ord(ord, val, pword + 1)) != PARSE_OK)
- X return rtn;
- X
- X pword += 3; /* last word of date */
- X break;
- X
- X case DT_WEEKDAY: /* <weekday> <prep> <date> */
- X wkd = n;
- X
- X /* parse_rel() calls parse_date() recursively */
- X return parse_rel(wkd, ++pword, ptype, pptext);
- X break;
- X
- X default:
- X return PARSE_INVLINE;
- X break;
- X }
- X
- X /* at this point, pword points to the last component of the date;
- X * fill in type code and pointer to following word (start of text)
- X */
- X *ptype = LASTCHAR(*pword) == '*' ? HOLIDAY_TEXT : DAY_TEXT;
- X *pptext = ++pword;
- X
- X return PARSE_OK;
- }
- X
- /*
- X * parse - parse non-preprocessor lines in date file
- X *
- X * This routine parses "year", "opt", "note", and date entries in the date
- X * file. It calls parse_date() to parse date entries (and enter the date(s)
- X * matched in global array "dates"), and then calls enter_day_info() to
- X * enter each date found (and its associated text) in the date file.
- X *
- X * N.B.: "inc" and other cpp-like lines are handled in read_datefile().
- X *
- X */
- #ifdef PROTOS
- int parse(char **pword,
- X char *filename)
- #else
- int parse(pword, filename)
- X char **pword; /* pointer to first word to parse */
- X char *filename; /* name of file (for error messages) */
- #endif
- {
- X register char *cp;
- X char **ptext;
- X int mm, yy;
- X int text_type, n, v, rtn, match;
- X int token;
- X DATE *pd;
- X
- X /*
- X * Get first field and call date_type() to decode it
- X */
- X cp = *pword;
- X
- X switch (token = date_type(cp, &n, &v)) {
- X
- X case DT_YEAR:
- X if ((cp = *++pword) != NULL && (yy = atoi(cp)) > 0) {
- X if (yy < 100)
- X yy += CENTURY;
- X curr_year = yy;
- X return PARSE_OK;
- X }
- X return PARSE_INVLINE; /* year missing or non-numeric */
- X break;
- X
- X case DT_OPT:
- X if (!get_args(pword, P_OPT, filename)) {
- X usage(stderr, FALSE);
- X exit(EXIT_FAILURE);
- X }
- X return PARSE_OK;
- X break;
- X
- X case DT_NOTE:
- X if ((mm = get_month(*++pword, TRUE, TRUE)) == NOT_MONTH)
- X return PARSE_INVLINE;
- X
- X if (mm == ALL_MONTHS || mm == ENTIRE_YEAR) /* "note all"? */
- X for (mm = JAN; mm <= DEC; mm++)
- X enter_day_info(mm, NOTE_DAY, curr_year,
- X NOTE_TEXT, pword+1);
- X else
- X enter_day_info(mm, NOTE_DAY, curr_year, NOTE_TEXT,
- X pword+1);
- X
- X return PARSE_OK;
- X break;
- X
- X case DT_OTHER: /* unrecognized token */
- X return PARSE_INVLINE;
- X break;
- X
- X /* assume anything else is a date */
- X
- X default:
- X if ((rtn = parse_date(pword, &text_type, &ptext)) == PARSE_OK) {
- X match = FALSE; /* is at least one date valid? */
- X for (pd = dates; pd->mm; pd++)
- X match |= enter_day_info(pd->mm, pd->dd, pd->yy,
- X text_type, ptext) == PARSE_OK;
- X rtn = match ? PARSE_OK : PARSE_INVDATE;
- X }
- X return rtn;
- X break;
- X
- X }
- }
- SHAR_EOF
- chmod 0644 readfile.c ||
- echo 'restore of readfile.c failed'
- Wc_c="`wc -c < 'readfile.c'`"
- test 27599 -eq "$Wc_c" ||
- echo 'readfile.c: original size 27599, current size' "$Wc_c"
- fi
- # ============= writefil.c ==============
- if test -f 'writefil.c' -a X"$1" != X"-c"; then
- echo 'x - skipping writefil.c (File already exists)'
- else
- echo 'x - extracting writefil.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'writefil.c' &&
- /*
- X * writefil.c - Pcal routines concerned with writing the PostScript output
- X *
- X * Contents:
- X *
- X * def_footstring
- X * find_daytext
- X * find_holidays
- X * print_julian_info
- X * print_month
- X * print_moon_info
- X * print_text
- X * print_word
- X * write_psfile
- X *
- X * Revision history:
- X *
- X * 4.0 AWR 01/28/91 Support -B, -w flags and moon file
- X *
- X * 01/15/91 Extracted from pcal.c
- X *
- X */
- X
- /*
- X * Standard headers:
- X */
- X
- #include <stdio.h>
- #include <ctype.h>
- X
- /*
- X * Pcal-specific definitions:
- X */
- X
- #include "pcaldefs.h"
- #include "pcalglob.h"
- #include "pcallang.h"
- #include "pcalinit.h" /* PostScript boilerplate */
- X
- /*
- X * Macros:
- X */
- X
- /* convert "ph" (approximate quarter moon) to exact quarter moon */
- #define EXACT_QUARTER(ph) ((((int) (((ph) + .05) * 4.0)) % 4) / 4.0)
- X
- /* make sure printf() doesn't round "ph" up to 1.0 when printing it */
- #define PRT_TWEAK(ph) ((ph) >= 0.9995 ? 0.0 : (ph))
- X
- /*
- X * Globals:
- X */
- X
- static char *cond[3] = {"false", "true", "(some)"};
- X
- X
- /*
- X * write_psfile - write PostScript code to stdout
- X *
- X * The actual output of the PostScript code is straightforward. This routine
- X * writes a PostScript header followed by declarations of all the PostScript
- X * variables affected by command-line flags and/or language dependencies. It
- X * the generates the PostScript boilerplate generated from pcalinit.ps, and
- X * finally calls print_month() to generate the PostScript code for each
- X * requested month.
- X */
- #ifdef PROTOS
- void write_psfile(int month,
- X int year,
- X int nmonths)
- #else
- void write_psfile(month, year, nmonths)
- X int month; /* starting month */
- X int year; /* starting year */
- X int nmonths; /* number of months */
- #endif
- {
- X int i, ngray;
- X char **ap, tmp[20];
- X
- X /*
- X * Write out PostScript prolog
- X */
- X
- X PRT("%%!\n%%\t");
- X PRT(VERSION_MSG, progname, version);
- X if (*datefile)
- X PRT(DATEFILE_MSG, datefile);
- X PRT("\n%%\n");
- X
- X /* font names */
- X
- X PRT("/titlefont /%s def\n/dayfont /%s def\n/notesfont /%s def\n",
- X titlefont, dayfont, notesfont);
- X
- X /* foot strings */
- X
- X def_footstring(lfoot, 'L');
- X def_footstring(cfoot, 'C');
- X def_footstring(rfoot, 'R');
- X
- X /* month names */
- X
- X PRT("/month_names [");
- X for (i = JAN; i <= DEC; i++) {
- X PRT(i % 6 == 1 ? "\n\t" : " ");
- X (void) print_word(months[i-1]);
- X }
- X PRT(" ] def\n");
- X
- X /* day names - abbreviate if printing entire year on page */
- X
- X PRT("/day_names [");
- X for (i = SUN; i <= SAT; i++) {
- X PRT(i % 6 == 0 && ! do_whole_year ? "\n\t" : " ");
- X strcpy(tmp, days[(i + first_day_of_week) % 7]);
- X if (do_whole_year)
- X tmp[MIN_DAY_LEN] = '\0';
- X (void) print_word(tmp);
- X }
- X PRT(" ] def\n");
- X
- X /* title for "notes" box */
- X
- X PRT("/notesheading (");
- X PUTSTR(NOTES_HDR);
- X PRT(") def\n");
- X
- X /* line separator */
- X
- X PRT("/linesep ");
- X print_word(LINE_SEP);
- X PRT(" def\n");
- X
- X /* colors (black/gray) to print weekdays and holidays */
- X
- X PRT("/day_gray [");
- X for (ngray = 0, i = SUN; i <= SAT; ngray += day_color[i++] == GRAY)
- X PRT(" %s", cond[day_color[(i + first_day_of_week) % 7]]);
- X PRT(" ] def\n");
- X PRT("/holiday_gray %s def\n", cond[ngray <= 3]);
- X
- X /* rotation, scale, and translate values. */
- X
- X PRT("/rval %d def\n", rotate);
- X PRT("/xsval %s def\n/ysval %s def\n", xsval, ysval);
- X PRT("/xtval %s def\n/ytval %s def\n", xtval, ytval);
- X
- X /* moon, Julian date, box fill, and outline flags */
- X
- X PRT("/draw-moons %s def\n", cond[draw_moons]);
- X PRT("/julian-dates %s def\n", cond[julian_dates]);
- X PRT("/fill-boxes %s def\n", cond[! blank_boxes]);
- X PRT("/outline %s def\n", cond[outline_nums]);
- X
- X /* PostScript boilerplate (part 1 of 1) */
- X
- X for (ap = header; *ap; ap++)
- X PRT("%s\n", *ap);
- X PRT("\n");
- X
- X /*
- X * Write out PostScript code to print calendars
- X */
- X
- X if (do_whole_year) /* round up to multiple of 12 months */
- X nmonths = ((nmonths + 11) / 12) * 12;
- X
- X while (nmonths--) {
- X print_month(month, year);
- X year = NEXT_YEAR(month, year);
- X month = NEXT_MONTH(month, year);
- X }
- X
- }
- X
- X
- /*
- X * low-level utilities for PostScript generation
- X */
- X
- X
- /*
- X * print_word - print a single word, representing parentheses and non-ASCII
- X * characters as octal literals; return pointer to character following word
- X * (NULL if no word follows)
- X */
- #ifdef PROTOS
- char *print_word(char *p)
- #else
- char *print_word(p)
- X char *p;
- #endif
- {
- X char c;
- X
- X if (*p == '\0' || *(p += strspn(p, WHITESPACE)) == '\0')
- X return NULL;
- X
- X PRT("(");
- X for ( ; (c = *p) && !isspace(c); p++)
- X PUTCHAR(c);
- X PRT(")");
- X
- X return p;
- }
- X
- X
- /*
- X * print_text - print tokens in text (assumed separated by single blank)
- X * in PostScript format
- X */
- #ifdef PROTOS
- void print_text(char *p)
- #else
- void print_text(p)
- X char *p;
- #endif
- {
- X
- X while (p = print_word(p))
- X PRT(" ");
- }
- X
- X
- /*
- X * def_footstring - print definition for foot string, again converting
- X * all characters other than letters, digits, or space to octal escape
- X */
- #ifdef PROTOS
- void def_footstring(char *p,
- X char c)
- #else
- void def_footstring(p, c)
- X char *p; /* definition */
- X char c; /* L, C, or R */
- #endif
- {
- X
- X PRT("/%cfootstring (", c);
- X PUTSTR(p);
- X PRT(") def\n");
- }
- X
- X
- /*
- X * Routines to extract and print data
- X */
- X
- X
- /*
- X * find_daytext - find and print the day (including notes) or holiday text
- X * for the specified month/year
- X */
- #ifdef PROTOS
- void find_daytext(int month,
- X int year,
- X int is_holiday)
- #else
- void find_daytext(month, year, is_holiday)
- X int month, year;
- X int is_holiday; /* TRUE: print holiday text */
- #endif
- {
- X register int day;
- X year_info *py;
- X month_info *pm;
- X register day_info *pd;
- X int first;
- X char *fcn = is_holiday ? "holidaytext" : "daytext";
- X
- X /* if no text for this year and month, return */
- X
- X if ((py = find_year(year, FALSE)) == NULL ||
- X (pm = py->month[month-1]) == NULL)
- X return;
- X
- X /* walk array of day text pointers and linked lists of text */
- X
- X for (day = 1; day <= NOTE_DAY; day++) {
- X for (pd = pm->day[day-1], first = TRUE;
- X pd;
- X pd = pd->next) {
- X if (pd->is_holiday != is_holiday)
- X continue;
- X if (first) {
- X if (day != NOTE_DAY) /* set up call */
- X PRT("%d ", day);
- X printf("[ \n");
- X }
- X else {
- X PRT("\n");
- X print_word(LINE_SEP); /* separate lines */
- X PRT("\n");
- X }
- X print_text(pd->text);
- X first = FALSE;
- X }
- X if (! first) /* wrap up call (if one made) */
- X PRT("\n] %s\n", day == NOTE_DAY ? "notetext" : fcn);
- X }
- }
- X
- X
- /*
- X * find_holidays - find and print the note block flag and holidays for
- X * specified month/year
- X */
- #ifdef PROTOS
- void find_holidays(int month,
- X int year)
- #else
- void find_holidays(month, year)
- X int month, year;
- #endif
- {
- X register int day;
- X register unsigned long holidays;
- X year_info *py;
- X month_info *pm;
- X
- X pm = (py = find_year(year, FALSE)) ? py->month[month-1] : NULL;
- X
- X if (! do_whole_year)
- X PRT("/note_block %s def\n", cond[pm && pm->day[NOTE_DAY-1]]);
- X
- X PRT("/holidays ["); /* start definition of list */
- X
- X for (holidays = pm ? pm->holidays : 0, day = 1;
- X holidays;
- X holidays >>= 1, day++)
- X if (holidays & 01)
- X PRT(" %d", day);
- X
- X PRT(" ] def\n");
- X
- }
- X
- X
- /*
- X * print_moon_info - print the information necessary to draw moons. If
- X * printing moons on all days, print the phase for each day; if printing
- X * only quarter moons, tweak the phase to an exact quarter (so the icon
- X * is printed correctly) and generate a list of the quarter-moon dates
- X */
- #ifdef PROTOS
- void print_moon_info(int month,
- X int year)
- #else
- void print_moon_info(month, year)
- X int month, year;
- #endif
- {
- X int n, ndays, day, is_q;
- X char *p;
- X unsigned long qdays;
- X double phase;
- X
- X if (draw_moons == NO_MOONS)
- X return;
- X
- X /* print the phase of the moon for each day of the month */
- X
- X PRT("/moon_phases [\t\t%% from %s\n\t",
- X (p = find_moonfile(year)) ? p : "algorithm");
- X
- X for (n = 0, qdays = 0L, day = 1, ndays = LENGTH_OF(month, year);
- X day <= ndays;
- X day++) {
- X phase = find_phase(month, day, year, &is_q);
- X if (draw_moons == SOME_MOONS && is_q)
- X phase = EXACT_QUARTER(phase);
- X if (draw_moons == ALL_MOONS || is_q)
- X PRT("%.3f%s", PRT_TWEAK(phase), ++n % 10 == 0 ?
- X "\n\t" : " ");
- X if (is_q)
- X qdays |= 1L << (day - 1);
- X }
- X PRT("] def\n");
- X
- X /* if drawing only quarter moons, print days when they occur */
- X
- X if (draw_moons == SOME_MOONS) {
- X PRT("/quarter_moons [ ");
- X for (day = 1; qdays; day++, qdays >>= 1)
- X if (qdays & 01)
- X PRT("%d ", day);
- X PRT("] def\n");
- X }
- }
- X
- X
- /*
- X * print_julian_info - print the information necessary to print Julian dates
- X */
- #ifdef PROTOS
- void print_julian_info(int month,
- X int year)
- #else
- void print_julian_info(month, year)
- X int month, year;
- #endif
- {
- X
- X if (julian_dates != NO_JULIANS)
- X PRT("/jdstart %d def\n", DAY_OF_YEAR(month, 1, year));
- X if (julian_dates == ALL_JULIANS)
- X PRT("/yearlen %d def\n", YEAR_LEN(year));
- }
- X
- X
- /*
- X * print_month - generate calendar for specified month/year
- X */
- #ifdef PROTOS
- void print_month(int month,
- X int year)
- #else
- void print_month(month, year)
- X int month, year;
- #endif
- {
- X static int nmonths = 0;
- X
- X PRT("/year %d def\n", year); /* set up year and month */
- X PRT("/month %d def\n", month);
- X PRT("/startday %d def\n",
- X (FIRST_OF(month, year) - first_day_of_week + 7) % 7);
- X PRT("/ndays %d def\n", LENGTH_OF(month, year));
- X
- X find_holidays(month, year); /* make list of holidays */
- X
- X /* are we printing 12 months per page or only one? */
- X
- X if (do_whole_year) {
- X PRT("/posn %d def\n", nmonths % 12); /* location on page */
- X PRT("printmonth_%c\n", rotate == LANDSCAPE ? 'l' : 'p');
- X if (++nmonths % 12 == 0)
- X PRT("showpage\n");
- X }
- X else {
- X /* generate lengths of previous and next months */
- X PRT("/lndays %d def\n", LENGTH_OF(PREV_MONTH(month, year),
- X PREV_YEAR(month, year)));
- X PRT("/nndays %d def\n", LENGTH_OF(NEXT_MONTH(month, year),
- X NEXT_YEAR(month, year)));
- X
- X print_julian_info(month, year); /* Julian date info */
- X print_moon_info(month, year); /* moon info */
- X
- X PRT("printmonth\n");
- X find_daytext(month, year, TRUE); /* holiday text */
- X find_daytext(month, year, FALSE); /* day and note text */
- X PRT("showpage\n");
- X }
- }
- SHAR_EOF
- chmod 0644 writefil.c ||
- echo 'restore of writefil.c failed'
- Wc_c="`wc -c < 'writefil.c'`"
- test 9889 -eq "$Wc_c" ||
- echo 'writefil.c: original size 9889, current size' "$Wc_c"
- fi
- exit 0
-