home *** CD-ROM | disk | FTP | other *** search
- From: jbr0@cbnews.att.com (joseph.a.brownlee)
- Newsgroups: alt.sources
- Subject: Pcal v4.0, part 4 of 5
- Message-ID: <1991Mar14.125134.9708@cbnews.att.com>
- Date: 14 Mar 91 12:51:34 GMT
-
- #!/bin/sh
- # This is part 04 of a multipart archive
- # ============= pcalinit.c ==============
- if test -f 'pcalinit.c' -a X"$1" != X"-c"; then
- echo 'x - skipping pcalinit.c (File already exists)'
- else
- echo 'x - extracting pcalinit.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'pcalinit.c' &&
- /*
- X * Create a .h file from a .ps file. Strips out leading and trailing
- X * whitespace, blank lines, and lines consisting solely of comments,
- X * except for the very first block of comments/blanklines, which are
- X * turned into C comments at the top of the file.
- X *
- X * 14-sep-90 Jamie Zawinski created.
- X *
- X * Revision history:
- X *
- X * 4.0 AWR 02/25/91 added optional third argument for
- X * name of array
- X *
- X * AWR 02/19/91 added function prototypes; documented
- X *
- X * AWR 01/16/91 Escape " and \ in quoted strings;
- X * strip trailing comments; skip FF
- X *
- X * 2.6 JAB 10/18/90 Add exit(0).
- X *
- X * 2.3 JWZ 09/14/90 Author
- X */
- X
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- X
- #if defined(__STDC__) || defined(AMIGA)
- #define PROTOS
- #endif
- X
- #define FALSE 0
- #define TRUE 1
- X
- #define ARRAY_NAME "header" /* default name of array in .h file */
- X
- #define IS_WHITESPACE(c) \
- X ((c) == ' ' || (c) == '\t' || (c) == '\n' || c == '\f')
- X
- #define IS_POSTSCRIPT(s) ((s)[0] != '%' && (s)[0] != '\0')
- X
- X
- /*
- X * strip_white: strip leading and trailing whitespace from 'string'; return
- X * pointer to first non-whitespace character
- X */
- #ifdef PROTOS
- char *strip_white (char *string)
- #else
- char *strip_white (string)
- X char *string;
- #endif
- {
- X int n;
- X for (; IS_WHITESPACE(*string); string++)
- X ;
- X n = strlen(string)-1;
- X for (; IS_WHITESPACE(string[n]); n--)
- X string[n] = '\0';
- X return string;
- }
- X
- X
- /*
- X * strip_comment: strip comment and any preceding whitespace from 'string';
- X * return pointer to 'string'
- X */
- #ifdef PROTOS
- char *strip_comment (char *string)
- #else
- char *strip_comment (string)
- X char *string;
- #endif
- {
- X char *p;
- X if ((p = strchr(string, '%')) != NULL) {
- X *p = '\0';
- X string = strip_white(string);
- X }
- X return string;
- }
- X
- X
- /*
- X * escape: copy string 'in' to string 'out', escaping the characters \ and ";
- X * return pointer to 'out'
- X */
- #ifdef PROTOS
- char *escape(char *out, char *in)
- #else
- char *escape(out, in)
- X char *out, *in;
- #endif
- {
- X char c, *sv_out = out;
- X
- X for (; c = *in; *out++ = *in++)
- X if (c == '\\' || c == '"')
- X *out++ = '\\';
- X
- X *out = '\0';
- X return sv_out;
- }
- X
- X
- #ifdef PROTOS
- int main(int argc, char *argv[])
- #else
- int main (argc, argv)
- X int argc; char *argv[];
- #endif
- {
- X FILE *in, *out;
- X char line[256], line2[512], *L, *array;
- X int in_initial_comments = TRUE;
- X
- X /* retrieve arguments and attempt to open input and output files */
- X
- X if (argc < 3 || argc > 4) {
- X fprintf(stderr, "usage: %s <infile>.ps <outfile>.h [<arrayname>]\n",
- X argv[0]);
- X exit(-1); }
- X
- X in = fopen(argv[1], "r");
- X if (NULL == in) {
- X fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[1]);
- X exit(-1); }
- X
- X out = fopen(argv[2], "w");
- X if (NULL == out) {
- X fprintf(stderr, "%s: couldn't open %s\n", argv[0], argv[2]);
- X exit(-1); }
- X
- X array = argc == 4 ? argv[3] : ARRAY_NAME;
- X
- X /* print topline comment on output file */
- X
- X fprintf (out, "/*\n * %s: automatically generated by %s from %s\n",
- X argv[2], argv[0], argv[1]);
- X fprintf (out, " *\n *\tDO NOT EDIT THIS FILE!\n *\n");
- X
- X /* main loop - copy lines from input file, to output file, preserving
- X * only initial block of comments and blank lines
- X */
- X
- X while ( fgets(line, 255, in) != NULL ) {
- X L = strip_white(line); /* strip whitespace */
- X
- X if ( IS_POSTSCRIPT(L) ) { /* PostScript source? */
- X if ( in_initial_comments ) { /* first PS line? */
- X in_initial_comments = FALSE;
- X fprintf(out, " */\n\nchar *%s[] = {\n", array);
- X }
- X L = strip_comment(L); /* copy string to output */
- X L = escape(line2, L);
- X fprintf(out, " \"%s\",\n", L);
- X } else /* blank or comment line */
- X if ( in_initial_comments ) /* copy only initial block */
- X fprintf(out, " * %s\n", L);
- X }
- X
- X fprintf(out, " (char *)0,\n};\n"); /* terminate array decl */
- X
- X fclose(out); /* close files and exit */
- X fclose(in);
- X exit (0);
- }
- SHAR_EOF
- chmod 0644 pcalinit.c ||
- echo 'restore of pcalinit.c failed'
- Wc_c="`wc -c < 'pcalinit.c'`"
- test 3975 -eq "$Wc_c" ||
- echo 'pcalinit.c: original size 3975, current size' "$Wc_c"
- fi
- # ============= pcalinit.ps ==============
- if test -f 'pcalinit.ps' -a X"$1" != X"-c"; then
- echo 'x - skipping pcalinit.ps (File already exists)'
- else
- echo 'x - extracting pcalinit.ps (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'pcalinit.ps' &&
- % pcalinit.ps - provides the PostScript routines for pcal.c
- %
- % 4.0 modified by Andrew Rogers:
- %
- % support -w ("whole year") option - cf. printmonth_[pl], startpage
- % moved all the calendar calculations to pcal.c and moonphas.c (q.v.)
- %
- % support -B option (leave unused boxes blank)
- %
- % support -O option (print "gray" numbers as outlines)
- %
- % revised several of the basic routines and added some others; dates,
- % moons, text, Julian days are now relative to upper-left corner of box
- %
- % enlarged title and dates in small calendars
- %
- % 3.0 modified by Andrew Rogers:
- %
- % added xsval, ysval, xtval, ytval for scaling and translation
- % as per Ed Hand
- %
- % added day-of-year support (-j, -J flags)
- %
- % 2.6 * no modifications *
- %
- % 2.5 modified by Joe Brownlee:
- %
- % made day numbers smaller, providing more room for event text
- % repositioned event text and moons accordingly
- % added support for variable first day of week
- %
- % 2.4 * no modifications *
- %
- % 2.3 modified by Jamie Zawinski <jwz@lucid.com>:
- %
- % merged in moon routines (originally by Mark Hanson)
- %
- % 2.2 modified by Joe Brownlee:
- %
- % add "notetext" to print notes in unused calendar box
- %
- % 2.1 modified by Mark Kantrowitz:
- %
- % use symbolic names instead of magic numbers throughout
- % support -L, -C, -R, -n options (all new)
- % print holiday text in otherwise-wasted space next to date
- % use larger text for dates in large calendars
- %
- % 2.0 modified by Andrew W. Rogers:
- %
- % 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
- X
- /SM 0 def % definitions for calendar sizes
- /MED 1 def
- /LG 2 def
- X
- /titlefontsize [ 60 48 48 ] def % font sizes for SM/MED/LG calendars
- /datefontsize [ 54 40 25 ] def
- /weekdayfontsize [ 0 24 12 ] def
- /footfontsize 12 def
- /notesfontsize 6 def
- X
- /titlepos [ 19 40 25 ] def % Y-offset (SM/MED/LG) of month/year title
- /Y0 35 def % Y-coordinate of calendar grid origin
- X
- /daywidth 100 def % dimensions of grid boxes
- /dayheight 80 def
- /gridwidth daywidth 7 mul def
- /gridheight dayheight 6 mul def
- /negdaywidth daywidth neg def
- /negdayheight dayheight neg def
- /neggridwidth gridwidth neg def
- /neggridheight gridheight neg def
- X
- /gridlinewidth 1.0 def % width of grid lines
- /charlinewidth 0.1 def % width of outline characters
- /moonlinewidth 0.1 def % width of moon icon line
- /dategray 0.8 def % density of gray for dates
- /fillgray 0.9 def % density of gray for fill squares
- X
- /hangingindent ( ) def % for indenting continued text lines
- X
- X
- %
- % Utility functions:
- %
- X
- X
- /center { % print string centered in given width
- X /width exch def
- X /str exch def
- X width str stringwidth pop sub 2 div 0 rmoveto str show
- } def
- X
- X
- /strcat { % concatenate two strings
- X 2 copy
- X length exch length
- X dup 3 -1 roll add
- X string
- X dup 0 6 -1 roll putinterval
- X dup 3 -1 roll 4 -1 roll putinterval
- } def
- X
- X
- /prtday { % print the date in black, gray, or outline
- X day 3 string cvs % convert to string
- X color (outline) eq {
- X true charpath stroke % print as outline
- X }
- X {
- X color (gray) eq { dategray setgray } if % print in gray
- X show
- X } ifelse
- } def
- X
- X
- /nextbox { % go to next column or start of next row
- X day startday add 7 mod 0 eq % end of week?
- X { neggridwidth daywidth add negdayheight rmoveto } % next row
- X { daywidth 0 rmoveto } % next col
- X ifelse
- } def
- X
- X
- /datepos { % push coords of upper-left corner of box for day <arg>
- X startday add 1 sub dup 7 mod daywidth mul % x-coord
- X exch 7 idiv negdayheight mul Y0 add % y-coord
- } def
- X
- X
- %
- % Functions for drawing parts of calendar:
- %
- X
- X
- /drawtitle { % draw month and year title
- X titlefont findfont titlefontsize calsize get scalefont setfont
- X /month_name month_names month 1 sub get def
- X /yearstring year 10 string cvs def
- X 0 Y0 titlepos calsize get add moveto
- X month_name ( ) strcat yearstring strcat gridwidth center
- } def
- X
- X
- /drawdaynames { % draw day names above respective columns
- X dayfont findfont weekdayfontsize calsize get scalefont setfont
- X 0 1 6 {
- X /i exch def
- X i daywidth mul Y0 5 add moveto
- X day_names i get
- X daywidth center
- X } for
- } def
- X
- X
- /drawgrid { % draw the grid for the calendar
- X gridlinewidth setlinewidth
- X 0 daywidth gridwidth { % vertical lines
- X Y0 moveto
- X 0 neggridheight rlineto
- X stroke
- X } for
- X 0 negdayheight neggridheight { % horizontal lines
- X 0 exch Y0 add moveto
- X gridwidth 0 rlineto
- X stroke
- X } for
- } def
- X
- X
- /drawnums { % place day numbers on calendar
- X dayfont findfont datefontsize calsize get scalefont setfont
- X /fontdiff datefontsize calsize get datefontsize LG get sub def
- X charlinewidth setlinewidth
- X 1 datepos 20 fontdiff add sub exch 5 add exch moveto
- X
- X 1 1 ndays {
- X /day exch def
- X /color (black) def
- X calsize SM ne { % select alternate color
- X /gray day_gray day startday add 1 sub 7 mod get def
- X holidays { day eq { /gray holiday_gray def } if } forall
- X gray {
- X /color outline {(outline)} {(gray)} ifelse def
- X } if
- X } if
- X gsave
- X prtday
- X grestore
- X nextbox
- X } for
- } def
- X
- X
- /drawjnums { % place day-of-year numbers on calendar
- X notesfont findfont notesfontsize scalefont setfont
- X 1 datepos dayheight 3 sub sub exch daywidth 3 sub add exch moveto
- X
- X 1 1 ndays {
- X /day exch def
- X /jday jdstart day add 1 sub def
- X /str jday 3 string cvs def
- X julian-dates true eq { % print days left in year?
- X /str str ( \050) strcat yearlen jday sub 3 string cvs
- X strcat (\051) strcat def
- X } if
- X gsave
- X str dup stringwidth pop 0 exch sub 0 rmoveto show
- X grestore
- X nextbox
- X } for
- } def
- X
- X
- /fillboxes { % used by drawfill to generate row of fill squares
- X /last exch def % last box to fill (0 = Sun)
- X /first exch def % first box to fill (0 = Sun)
- X /width last first sub 1 add daywidth mul def
- X
- X width 0 gt {
- X gsave
- X first daywidth mul 0 rmoveto
- X fillgray setgray
- X width 0 rlineto
- X 0 negdayheight rlineto
- X width neg 0 rlineto
- X closepath fill
- X grestore
- X } if
- } def
- X
- X
- /drawfill { % generate fill squares where necessary
- X /firstbox startday ndays add def
- X /lastbox calsize LG ne {41} { note_block {38} {39} ifelse } ifelse def
- X
- X 0 Y0 moveto % boxes (if any) at start of first row
- X 0 startday 1 sub fillboxes
- X
- X 0 4 negdayheight mul rmoveto % boxes (if any) at end of fifth row
- X firstbox 35 lt {
- X firstbox 7 mod 6 fillboxes
- X /firstbox 35 def
- X } if
- X
- X 0 negdayheight rmoveto % boxes at end of bottom row
- X firstbox 7 mod lastbox 7 mod fillboxes
- } def
- X
- X
- /footstrings { % print foot strings at bottom of page
- X titlefont findfont footfontsize scalefont setfont
- X /bottomrow { neggridheight 20 add } def
- X 0 bottomrow moveto
- X Lfootstring show
- X gridwidth Rfootstring stringwidth pop sub bottomrow moveto
- X Rfootstring show
- X 0 bottomrow moveto
- X Cfootstring gridwidth center
- } def
- X
- X
- %
- % Functions for printing text inside boxes:
- %
- X
- X
- /daytext {
- X notesfont findfont notesfontsize scalefont setfont
- X /mytext exch def /day exch def
- X day datepos 29 sub dup /ypos exch def exch 2 add exch moveto
- X currentpoint pop /LM exch def /RM LM 95 add def
- X showtext
- } def
- X
- X
- /holidaytext { % print text for holiday (next to date)
- X notesfont findfont notesfontsize scalefont setfont
- X /mytext exch def /day exch def
- X /dwidth day 10 lt {20} {33} ifelse def % width of date
- X /mwidth do-moon-p {16} {0} ifelse def % width of moon icon
- X day datepos 8 sub dup /ypos exch def exch dwidth add exch moveto
- X currentpoint pop /LM exch def /RM LM 97 dwidth mwidth add sub add def
- X showtext
- } def
- X
- X
- /notetext { % print text in notes box
- X dayfont findfont 12 scalefont setfont
- X /day 40 startday sub def % "date" of notes box
- X day datepos 11 sub exch 4 add exch moveto
- X notesheading show
- X
- X notesfont findfont notesfontsize scalefont setfont
- X /mytext exch def
- X day datepos 19 sub dup /ypos exch def exch 4 add exch moveto
- X /LM currentpoint pop def /RM LM 93 add def
- X showtext
- } def
- X
- X
- /crlf { % simulate CR/LF sequence
- X ypos notesfontsize sub /ypos exch def LM ypos moveto
- } def
- X
- X
- /prstr { % print string on current or next line
- X dup stringwidth pop currentpoint pop
- X add RM gt { crlf hangingindent show } if show
- } def
- X
- X
- /showtext { % print words in "mytext", splitting into lines
- X mytext {
- X dup linesep eq % force new line?
- X { crlf pop } % yes - discard text
- X { prstr ( ) show } % no - print string + space
- X ifelse
- X } forall
- } def
- X
- X
- %
- % Functions for printing months of various sizes and orientations:
- %
- X
- X
- /startpage { % initialize new physical page
- X rval rotate
- X xsval ysval scale
- X xtval ytval translate
- } def
- X
- X
- /calendar % draw calendar for month/year
- {
- X drawtitle % month/year heading
- X
- X calsize SM ne { % day names
- X drawdaynames
- X } if
- X
- X calsize LG eq { % foot strings
- X footstrings
- X } if
- X
- X drawnums % calendar dates
- X
- X julian-dates false ne calsize LG eq and { % julian dates
- X drawjnums
- X } if
- X
- X fill-boxes { % fill unused boxes
- X drawfill
- X } if
- X
- X drawgrid % calendar grid
- X
- X draw-moons false ne calsize LG eq and { % moon icons
- X drawmoons
- X } if
- X
- X 0 0 moveto % return to origin
- } def
- X
- X
- /printmonth_l { % print month on landscape page ("posn" = 0..11)
- X /calsize MED def
- X
- X posn 0 eq { % assume first month printed on page is posn 0
- X startpage
- X footstrings
- X } if
- X
- X gsave % draw medium calendar at selected position
- X .226 .25 scale % landscape mode - 3 rows, 4 cols
- X posn 4 mod 800 mul
- X posn 4 idiv -700 mul 150 add
- X translate
- X calendar
- X grestore
- } def
- X
- X
- /printmonth_p { % print month on portrait page ("posn" = 0..11)
- X /calsize MED def
- X /footfontsize 15 def % compensate for scaling
- X
- X posn 0 eq { % assume first month printed on page is posn 0
- X gsave % print foot strings at original scale
- X startpage
- X 0 20 translate % move foot strings up slightly
- X footstrings
- X grestore % re-scale Y axis for portrait mode
- X /sv_ysval ysval def
- X /ysval ysval 1.675 mul def
- X startpage
- X /ysval sv_ysval def
- X } if
- X
- X gsave % draw medium calendar at selected position
- X .304 .194 scale % portrait mode - 4 rows, 3 cols
- X posn 3 mod 800 mul
- X posn 3 idiv -700 mul 300 add
- X translate
- X calendar
- X grestore
- } def
- X
- X
- /printmonth { % print single month on page
- X startpage
- X
- X /calsize LG def % main (large) calendar
- X calendar
- X
- X gsave % small calendars
- X /calsize SM def
- X /sv_startday startday def
- X
- X % calculate previous and next month, year, and starting day
- X
- X /lmonth month 1 eq { 12 } { month 1 sub } ifelse def
- X /lyear month 1 eq { year 1 sub } { year } ifelse def
- X /lstartday startday 35 add lndays sub 7 mod def
- X /nmonth month 12 eq { 1 } { month 1 add } ifelse def
- X /nyear month 12 eq { year 1 add } { year } ifelse def
- X /nstartday startday ndays add 7 mod def
- X
- X /year lyear def % prev month/year
- X /month lmonth def
- X /startday lstartday def
- X /ndays lndays def
- X 5 daywidth mul 5 negdayheight mul Y0 add translate
- X gsave
- X .138 .138 scale
- X 12 -120 translate
- X calendar
- X grestore
- X
- X /year nyear def % next month/year
- X /month nmonth def
- X /startday nstartday def
- X /ndays nndays def
- X daywidth 0 translate
- X gsave
- X .138 .138 scale
- X 12 -120 translate
- X calendar
- X grestore
- X
- X /startday sv_startday def % restore starting day (for text boxes)
- X grestore
- } def
- X
- X
- %
- % Moon drawing functions:
- %
- X
- X
- /domoon { % draw moon at phase (0 = new; .25 = 1q; .5 = full; .75 = 3q)
- X /phase exch def
- X
- X gsave
- X currentpoint translate
- X newpath
- X
- X % if moon is full, just draw unfilled circle
- X
- X phase halfperiod .01 sub ge phase halfperiod .01 add le and {
- X 0 0 radius
- X 0 360 arc stroke
- X }
- X {
- X % draw the line arc now; prepare (but don't draw) the fill arc
- X
- X 0 0 radius % for line and fill arcs
- X 0 0 radius
- X phase halfperiod lt { % phase between new and full
- X 270 90 arc stroke % (line on right, fill on left)
- X 0 radius neg moveto
- X 270 90 arcn
- X }
- X { % phase between full and new
- X 90 270 arc stroke % (line on left, fill on right)
- X 0 radius neg moveto
- X 270 90 arc
- X /phase phase halfperiod sub def
- X } ifelse
- X
- X % curveto uses (x0,y0) (current point), (x1,y1), (x2,y2),
- X % and (x3,y3) as the control points for drawing a Bezier
- X % cubic section, used here as the curve dividing the moon
- X % icon into dark and light sections. x1 is in the range
- X % -R*sqrt(2) <= x1 <= R*sqrt(2) and y1 is in the range
- X % 0 <= y1 <= R; note that except in the degenerate case
- X % where x1 = y1 = x2 = y2 = 0, the curve does not actually
- X % pass through (x1,y1) or (x2,y2).
- X
- X /x1 quartperiod phase sub rect mul def
- X /y1 x1 abs 2 sqrt div def
- X
- X % push control points for curveto
- X
- X % x0 = 0 (current
- X % y0 = R point)
- X x1 % x1
- X y1 % y1
- X x1 % x2 = x1
- X y1 neg % y2 = -y1
- X 0 % x3 = 0
- X radius neg % y3 = -R
- X
- X % draw Bezier curve; fill area between curve and fill arc
- X
- X curveto
- X fill
- X } ifelse
- X
- X grestore
- } def
- X
- X
- /do-moon-p { % draw a moon on "day"?
- X draw-moons (some) eq { % printing quarter moons? look up day
- X /p false def
- X quarter_moons { day eq { /p true def } if } forall
- X p
- X }
- X {
- X draw-moons % all moons or no moons
- X } ifelse
- } def
- X
- X
- /drawmoons { % main routine to draw moons on calendar
- X /halfperiod 0.5 def
- X /quartperiod 0.25 def
- X /radius 6 def
- X /offset radius 3 add def
- X /rect radius 2 sqrt mul quartperiod div def % domoon{} scale factor
- X /n 0 def
- X
- X gsave
- X moonlinewidth setlinewidth
- X 1 datepos offset sub exch daywidth add offset sub exch moveto
- X 1 1 ndays {
- X /day exch def
- X do-moon-p { % draw a moon today?
- X moon_phases n get domoon
- X /n n 1 add def
- X } if
- X nextbox
- X } for
- X grestore
- } def
- SHAR_EOF
- chmod 0666 pcalinit.ps ||
- echo 'restore of pcalinit.ps failed'
- Wc_c="`wc -c < 'pcalinit.ps'`"
- test 13415 -eq "$Wc_c" ||
- echo 'pcalinit.ps: original size 13415, current size' "$Wc_c"
- fi
- # ============= 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 * 4.0 AWR 03/01/91 expand parameter message to explain
- X * parameter meaning when -w specified
- X *
- X * AWR 02/19/91 revise ordinal definitions for
- X * support of negative ordinals
- X *
- X * AWR 02/06/91 add text describing expression syntax
- X *
- X * AWR 02/04/91 support "odd" and "even" ordinals
- X *
- X * AWR 01/28/91 support -B (blank fill squares) flag
- X * and -O (outline "gray" dates) flag
- X *
- X * 01/16/91 added moon file support (tokens, help
- X * file text, error messages); define
- X * note block heading here
- X *
- X * 01/07/91 added support for -w (whole year) flag
- 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
- #define ALL "all" /* command-line or date file keyword */
- X
- #ifdef MAIN_MODULE
- X
- 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 */
- 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: token name, token code, dispatch routine */
- 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, NULL, /* 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": ordinal name,
- X * ordinal code, ordinal value; note that "all" is parsed as a keyword
- X * and (depending on context) may be subsequently treated as an ordinal
- X */
- X
- KWD_O ordinals[] = {
- X "first", ORD_POSNUM, 1,
- X "second", ORD_POSNUM, 2,
- X "third", ORD_POSNUM, 3,
- X "fourth", ORD_POSNUM, 4,
- X "fifth", ORD_POSNUM, 5,
- X "last", ORD_NEGNUM, -1,
- X "odd", ORD_ODD, 0,
- X "even", ORD_EVEN, 0,
- X NULL, ORD_OTHER, 0 }; /* must be last */
- X
- /* allowable suffixes for ordinal numbers */
- X
- char *ord_suffix[] = { "st", "nd", "rd", "th", NULL };
- 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
- 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
- /* moon phases (for moon file) */
- X
- KWD phases[] = {
- X "NM", MOON_NM, /* new moon */
- X "1Q", MOON_1Q, /* first quarter */
- X "FQ", MOON_1Q,
- X "FM", MOON_FM, /* full moon */
- X "3Q", MOON_3Q, /* third (last) quarter */
- X "LQ", MOON_3Q,
- X NULL, MOON_OTHER }; /* must be last */
- X
- #else
- extern char *months[];
- extern char days[14][12];
- extern KWD_F pp_info[];
- extern KWD preps[];
- extern KWD_O ordinals[];
- extern char *ord_suffix[];
- extern KWD keywds[];
- extern KWD phases[];
- #endif
- 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
- #define F_WHOLE_YEAR 'w' /* print whole year per page */
- X /* (cf. W_WYFLAG below) */
- X
- #define F_BLANK_BOXES 'B' /* don't fill unused boxes */
- X
- #define F_OUTLINE 'O' /* draw "gray" dates as outlines */
- 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], -M|-m [moons], -w
- X * [whole year], or -O [outline "gray" dates] once selected is to use -I
- X * 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
- #ifdef MAIN_MODULE
- 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 F_WHOLE_YEAR, FALSE, P_ENV | P_CMD1 | P_OPT ,
- X
- X F_BLANK_BOXES, FALSE, P_ENV | P_OPT | P_CMD2 ,
- X
- X F_OUTLINE, 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
- #else
- extern FLAG_USAGE flag_tbl[];
- #endif
- 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_WYFLAG "-w" /* must conform to F_WHOLE_YEAR */
- 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 */
- #ifdef MAIN_MODULE
- 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 (see below)", NULL,
- X END_GROUP,
- X
- X F_OUTLINE, NULL, "print \"gray\" dates as outlined characters", NULL,
- X
- 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 DEFAULT_OUTFILE
- X F_OUT_FILE, W_FILE, "specify alternate output file", DEFAULT_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,
- X
- X F_WHOLE_YEAR, NULL, "print whole year (12 consecutive months) per page", NULL,
- X END_GROUP,
- X
- X F_BLANK_BOXES, NULL, "leave unused boxes blank", NULL,
- X
- X END_GROUP, /* must precede END_LIST */
- X
- X END_LIST /* must be last */
- };
- X
- #else
- extern FLAG_MSG flag_msg[];
- #endif
- X
- /* Numeric parameter descriptions and text */
- X
- #ifdef MAIN_MODULE
- 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 and/or year",
- X "", "",
- X "if " W_WYFLAG " specified:", "",
- X "", "",
- X W_YY, "generate calendar for year " W_YY " (19" W_YY " if " W_YY " < 100)",
- X W_MM " " W_YY, "generate calendars for 12 months, starting at " W_MM "/" W_YY,
- X W_MM " " W_YY " N", "generate calendars for N months, starting at " W_MM "/" W_YY,
- X "", " (N rounded up to next multiple of 12)",
- X "(" W_DEFAULT ")", "generate calendar for current 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 and year",
- X "", "",
- X "if -w specified:", "",
- X "", "",
- X "YY", "generate calendar for year YY (19YY if YY < 100)",
- X "MM YY", "generate calendar for 12 months, starting at MM/YY",
- X "MM YY N", "generate calendars for N months, starting at MM/YY",
- X "", " (N rounded up to next multiple of 12)",
- X "(default)", "generate calendar for current year",
- X NULL, NULL /* must be last */
- };
- #endif
- X
- #else
- extern PARAM_MSG param_msg[];
- #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
- #ifdef MAIN_MODULE
- X
- char *date_msg[] = {
- X "",
- X "Date file syntax:",
- X "",
- 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_name> <day>{*} {<text>}",
- X " <month><sep><day>{<sep><year>}{*} {<text>}",
- X "",
- X " if -E flag (European date formats) specified:",
- X " <day> <month_name>{*} {<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 " {x} means x is optional",
- X "",
- X " <date_spec> := any of the above date specs (not year, note, or opt)",
- X " <month_name> := first 3+ characters of name of month, or \"all\"",
- X " <month_spec> := <month_name>, or \"year\"",
- X " <day_name> := first 3+ characters of name of weekday, \"day\",",
- X " \"weekday\", \"workday\", \"holiday\", \"nonweekday\",",
- X " \"nonworkday\", or \"nonholiday\"",
- X " <ordinal> := ordinal number (\"1st\", \"2nd\", etc.), \"first\" .. \"fifth\",",
- X " \"last\", \"even\", \"odd\", 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\". Negative ordinals are",
- X "allowed; \"-2nd\" means \"next to last\".",
- 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 "\"Odd\" and \"even\" do not refer to the actual date; instead, \"odd\"",
- X "means \"alternate, starting with the first\"; \"even\" means \"alternate,",
- X "starting with the second\". Thus, \"odd Fridays in March\" refers to",
- X "the first, third, and (if present) fifth Fridays in March - not to",
- X "those Fridays falling on odd dates.",
- X "",
- X "\"All\" refers to each individual month; \"year\" refers to the year",
- X "as an entity. Thus \"odd Fridays in all\" refers to the first/third/",
- X "fifth Friday of each month, while \"odd Fridays in year\" refers to",
- X "the first Friday of January and every other Friday thereafter.",
- 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 <expr>",
- 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 "<sym> is a symbol name consisting of a letter followed by zero or",
- X "more letters, digits, or underscores ('_'). Symbol names are always",
- X "treated in a case-insensitive manner.",
- X "",
- X "<expr> is an expression consisting of symbol names joined by the logical",
- X "operators (in order of precedence, high to low) '!' (unary negate), '&'",
- X "(and), '^' (exclusive or), and '|' (inclusive or). '&&' and '||' are",
- X "accepted as synonyms for '&' and '|' respectively; the order of",
- X "evaluation may be altered by the use of parentheses. A symbol whose",
- X "name is currently defined evaluates to TRUE; one whose name is not",
- X "currently defined evaluates to FALSE. Thus \"ifdef A | B | C\" is TRUE",
- X "if any of the symbols A, B, and C is currently defined, and",
- X "\"ifdef A & B & C\" is TRUE if all of them are.",
- X "",
- X "\"ifndef A | B | C\" is equivalent to \"ifdef !(A | B | C)\" (or, using",
- X "DeMorgan's Law, \"ifdef !A & !B & !C\") - in other words, TRUE if none of",
- X "the symbols A, B, and C is currently defined.",
- X "",
- X "\"define\" alone deletes all the current definitions; \"ifdef\" alone is",
- X "always false; \"ifndef\" alone is always true.",
- 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 "",
- X "",
- X "Moon file syntax:",
- X "",
- X "Pcal normally calculates the approximate phase of the moon using",
- X "a simple algorithm which assumes (among other things) that the",
- X "length of the lunar month is constant and that the quarter moons",
- X "will occur on the same day worldwide. For most users, that is",
- X "adequate; however, moon-phase freaks may enter the dates and",
- X "(optionally) times of quarter moons (from a reliable source such",
- X "as an almanac or astronomical table) into a file called .moonXX ",
- X "(moonXX.dat on VMS), where XX is the last two digits of the year.",
- X "If such a file exists (in the same directory as the date file),",
- X "pcal will interpolate the phase of the moon from the information",
- X "in this file instead of using the default algorithm.",
- X "",
- X "Entries in the moon file must conform to the following syntax:",
- X "",
- X " if -A flag (American date formats) specified:",
- X " <quarter> <month><sep><day> {<hour><sep><min>}",
- X "",
- X " if -E flag (European date formats) specified:",
- X " <quarter> <day><sep><month> {<hour><sep><min>}",
- X "",
- X "where",
- X "",
- X " <quarter> := \"nm\", \"fq\" or \"1q\", \"fm\", \"3q\" or \"lq\" (new",
- X " moon, first quarter, full moon, last quarter)",
- X " <hour> := number 0-23 (24-hour clock)",
- X " <min> := number 0-59",
- X "",
- X "This file must contain entries for all quarter moons in the year,",
- X "in chronological order; if any errors are encountered, pcal will",
- X "revert to using its default algorithm.",
- X "",
- X "As in the date file, comments start with '#' and run through",
- X "end-of-line. ",
- X NULL
- X };
- #else
- extern char *date_msg[];
- #endif
- 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
- /* format strings for comment in PostScript output file */
- #define VERSION_MSG "Generated by %s %s"
- #define DATEFILE_MSG " from %s"
- X
- #define NOTES_HDR "Notes" /* title of "notes" box */
- #define LINE_SEP ".p" /* text line separator */
- X
- /* strings used in error messages */
- #define ENV_VAR "environment variable "
- #define DATE_FILE "date file "
- 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 flag %s"
- #define E_ILL_OPT2 " (%s\"%s\")"
- #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"
- #define E_FLAG_IGNORED "%s: -%c flag ignored (%s\"%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 (or no match for wildcard)"
- #define E_INV_LINE "unrecognized line"
- #define E_NESTING "maximum file nesting level exceeded"
- #define E_EXPR_SYNTAX "syntax error in expression"
- X
- /* moon file error strings */
- #define E_DATE_SEQ "date or phase out of sequence"
- #define E_PREM_EOF "premature EOF"
- X
- /* information message (VMS, Amiga 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 23965 -eq "$Wc_c" ||
- echo 'pcallang.h: original size 23965, current size' "$Wc_c"
- fi
- # ============= pcalutil.c ==============
- if test -f 'pcalutil.c' -a X"$1" != X"-c"; then
- echo 'x - skipping pcalutil.c (File already exists)'
- else
- echo 'x - extracting pcalutil.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'pcalutil.c' &&
- /*
- X * pcalutil.c - utility routines for Pcal
- X *
- X * Contents:
- X *
- X * alloc
- X * calc_day
- X * calc_weekday
- X * calc_year_day
- X * ci_strcmp
- X * ci_strncmp
- X * copy_text
- X * getline
- X * is_valid
- X * loadwords
- X * mk_filespec
- X * mk_path
- X * normalize
- X * split_date
- X * trnlog
- X *
- X * Revision history:
- X *
- X * 4.0 AWR 02/24/91 Revised getline() and copy_text() to
- X * handle C-style escapes of characters
- X * and octal/hex numbers
- X *
- X * AWR 02/19/91 Added support for negative ordinals
- X * in calc_day(), calc_year_day()
- X *
- X * AWR 02/04/91 Added calc_year_day()
- X *
- X * AWR 01/15/91 Extracted from pcal.c
- X *
- X */
- X
- X
- /*
- X * Standard headers:
- X */
- X
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- X
- /*
- X * Pcal-specific definitions:
- X */
- X
- #include "pcaldefs.h"
- #include "pcalglob.h"
- #include "pcallang.h"
- X
- /*
- X * Macros:
- X */
- X
- /* skip over numeric field and subsequent non-numeric characters */
- #define SKIP_FIELD(p) \
- X do { while (*p && isdigit(*p)) p++; \
- X while (*p && !isdigit(*p)) p++; } while (0)
- X
- X
- /*
- X * General-purpose utility routines
- X */
- X
- X
- /*
- X * alloc - interface to calloc(); terminates if unsuccessful
- X */
- #ifdef PROTOS
- char *alloc(int size)
- #else
- char *alloc(size)
- X int size;
- #endif
- {
- X char *p;
- X
- X if (size == 0) /* not all calloc()s like null requests */
- X size = 1;
- X
- X if ((p = calloc(1, size)) == NULL) {
- X FPR(stderr, E_ALLOC_ERR, progname);
- X exit(EXIT_FAILURE);
- X }
- X
- X return p;
- }
- X
- X
- /*
- X * ci_str{n}cmp - case-insensitive flavors of strcmp(), strncmp()
- X */
- #ifdef PROTOS
- int ci_strcmp(register char *s1,
- X register char *s2)
- #else
- int ci_strcmp(s1, s2)
- register char *s1, *s2;
- #endif
- {
- X register char c1, c2;
- X
- X for ( ; (c1 = TOLOWER(*s1)) == (c2 = TOLOWER(*s2)); s1++, s2++)
- X if (c1 == '\0')
- X return 0;
- X
- X return c1 - c2;
- }
- X
- X
- #ifdef PROTOS
- int ci_strncmp(register char *s1,
- X register char *s2,
- X int n)
- #else
- int ci_strncmp(s1, s2, n)
- register char *s1, *s2;
- int n;
- #endif
- {
- X register char c1, c2;
- X
- X for ( ; --n >= 0 && (c1 = TOLOWER(*s1)) == (c2 = TOLOWER(*s2)); s1++, s2++)
- X if (c1 == '\0')
- X return 0;
- X
- X return n < 0 ? 0 : c1 - c2;
- }
- X
- X
- /*
- X * Date calculation routines (see also macros in pcaldefs.h)
- X */
- X
- X
- /*
- X * normalize - adjust day in case it has crossed month (or year) bounds
- X */
- #ifdef PROTOS
- void normalize(DATE *pd)
- #else
- void normalize(pd)
- X DATE *pd; /* pointer to date */
- #endif
- {
- X int len;
- X
- X /* adjust if day is in previous or following month */
- X
- X while (pd->dd < 1) {
- X pd->yy = PREV_YEAR(pd->mm, pd->yy);
- X pd->mm = PREV_MONTH(pd->mm, pd->yy);
- X pd->dd += LENGTH_OF(pd->mm, pd->yy);
- X }
- X
- X while (pd->dd > (len = LENGTH_OF(pd->mm, pd->yy))) {
- X pd->dd -= len;
- X pd->yy = NEXT_YEAR(pd->mm, pd->yy);
- X pd->mm = NEXT_MONTH(pd->mm, pd->yy);
- X }
- }
- X
- X
- /*
- X * calc_day - calculate calendar date from ordinal date (e.g., "first Friday
- X * in November", "last day in October"); return calendar date if it exists,
- X * 0 if it does not
- X */
- #ifdef PROTOS
- int calc_day(int ord,
- X int wkd,
- X int mm)
- #else
- int calc_day(ord, wkd, mm)
- X int ord;
- X int wkd;
- X int mm;
- #endif
- {
- #ifdef PROTOS
- X int first, last, day, (*pfcn)(int, int, int);
- #else
- X int first, last, day, (*pfcn)();
- #endif
- X
- X if (IS_WILD(wkd)) { /* "day", "weekday", "workday", or "holiday" */
- X pfcn = pdatefcn[wkd - WILD_FIRST];
- X last = LENGTH_OF(mm, curr_year);
- X
- X if (ord < 0) { /* search backwards */
- X for (day = last;
- X day >= 1 &&
- X !((*pfcn)(mm, day, curr_year) && ++ord == 0);
- X day--)
- X ;
- X } else { /* search forwards */
- X for (day = 1;
- X day <= last &&
- X !((*pfcn)(mm, day, curr_year) && --ord == 0);
- X day++)
- X ;
- X }
- X return is_valid(mm, day, curr_year) ? day : 0;
- X
- X } else { /* fixed weekday - calculate it */
- X first = (wkd - FIRST_OF(mm, curr_year) + 7) % 7 + 1;
- X if (ord < 0) { /* get last (try 5th, then 4th) */
- X if (!is_valid(mm, last = first + 28, curr_year))
- X last -= 7;
- X if (!is_valid(mm, day = last + 7 * (ord + 1),
- X curr_year))
- X day = 0;
- X }
- X else
- X if (!is_valid(mm, day = first + 7 * (ord - 1),
- X curr_year))
- X day = 0;
- X
- X return day;
- X }
- X
- }
- X
- X
- /*
- X * calc_year_day - calculate calendar date from ordinal date within year
- X * (e.g., "last Friday in year", "10th holiday in year"); if date exists,
- X * fill in pdate and return TRUE; else return FALSE
- X */
- #ifdef PROTOS
- int calc_year_day(int ord,
- X int wkd,
- X DATE *pdate)
- #else
- int calc_year_day(ord, wkd, pdate)
- X int ord;
- X int wkd;
- X DATE *pdate;
- #endif
- {
- #ifdef PROTOS
- X int incr, (*pfcn)(int, int, int);
- #else
- X int incr, (*pfcn)();
- #endif
- X DATE date;
- X
- X if (IS_WILD(wkd)) { /* "day", "weekday", "workday", or "holiday" */
- X pfcn = pdatefcn[wkd - WILD_FIRST];
- X
- X if (ord < 0) { /* nth occurrence backwards */
- X MAKE_DATE(date, DEC, 31, curr_year);
- X ord = -ord;
- X incr = -1;
- X } else { /* nth occurrence forwards */
- X MAKE_DATE(date, JAN, 1, curr_year);
- X incr = 1;
- X }
- X
- X /* search for selected occurrence of specified wildcard */
- X
- X while (date.yy == curr_year &&
- X !((*pfcn)(date.mm, date.dd, date.yy) && --ord == 0)) {
- X date.dd += incr;
- X normalize(&date);
- X }
- X
- X } else { /* fixed weekday - calculate it */
- X if (ord < 0)
- X MAKE_DATE(date, DEC,
- X calc_day(-1, wkd, DEC) + 7 * (ord + 1),
- X curr_year);
- X else
- X MAKE_DATE(date, JAN,
- X calc_day(1, wkd, JAN) + 7 * (ord - 1),
- X curr_year);
- X normalize(&date);
- X }
- X
- X return date.yy == curr_year ? (*pdate = date, TRUE) : FALSE;
- }
- X
- X
- /*
- X * calc_weekday - return the weekday (0-6) of mm/dd/yy (mm: 1-12)
- X */
- #ifdef PROTOS
- int calc_weekday(int mm,
- X int dd,
- X int yy)
- #else
- int calc_weekday(mm, dd, yy)
- X int mm;
- X int dd;
- X int yy;
- #endif
- {
- X return (yy + (yy-1)/4 - (yy-1)/100 + (yy-1)/400 + OFFSET_OF(mm, yy) +
- X (dd-1)) % 7;
- }
- X
- X
- /*
- X * is_valid - return TRUE if m/d/y is a valid date
- X */
- #ifdef PROTOS
- int is_valid(register int m,
- X register int d,
- X register int y)
- #else
- int is_valid(m, d, y)
- X register int m, d, y;
- #endif
- {
- X return m >= JAN && m <= DEC &&
- X d >= 1 && d <= LENGTH_OF(m, y);
- }
- X
- X
- X
- /*
- X * Token parsing/remerging routines:
- X */
- X
- X
- /*
- X * loadwords - tokenize line buffer into word array, return word count.
- X * differs from old loadwords() in that it handles quoted (" or ') strings
- X * and removes escaped quotes
- X */
- #ifdef PROTOS
- int loadwords(void)
- #else
- int loadwords()
- #endif
- {
- X register char *ptok;
- X char *delim, **ap, *p1, *p2, c;
- X int nwords;
- X
- X for (ptok = lbuf, ap = words; TRUE; ap++) {
- X
- X ptok += strspn(ptok, WHITESPACE); /* find next token */
- X
- X if (! *ptok) { /* end of lbuf? */
- X *ap = NULL; /* add null ptr at end */
- X nwords = ap - words; /* number of non-null ptrs */
- X break; /* exit loop */
- X }
- X
- X delim = *ptok == '"' ? "\"" : /* set closing delimiter */
- X *ptok == '\'' ? "'" :
- X WHITESPACE;
- X
- X if (*ptok == *delim) /* skip opening quote */
- X ptok++;
- X
- X *ap = ptok; /* save token ptr */
- X
- X do { /* find unescaped delimiter */
- X ptok += strcspn(ptok, delim);
- X if ((c = ptok[-1]) == '\\')
- X ptok++;
- X } while (c == '\\');
- X
- X if (*ptok) /* terminate token */
- X *ptok++ = '\0';
- X }
- X
- X /* now reprocess the word list, removing escapes from quotes */
- X
- X for (ap = words; *ap; *ap++)
- X for (p1 = p2 = *ap; c = *p2 = *p1++; *p2++)
- X if (c == '\\')
- X *p2 = *p1++;
- X
- X return nwords; /* return word count */
- X
- }
- X
- X
- /*
- X * copy_text - retrieve remaining text in lbuf and copy to output string,
- X * separating tokens by a single blank and condensing runs of blanks (all
- X * other whitespace has been converted to blanks by now) to one blank
- X */
- #ifdef PROTOS
- void copy_text(char *pbuf,
- X char **ptext)
- #else
- void copy_text(pbuf, ptext)
- X char *pbuf; /* output buffer - can be lbuf itself */
- X char **ptext; /* pointer to first text word in "words" */
- #endif
- {
- X char *p, *pb;
- X
- X /* copy words to pbuf, separating by one blank */
- X
- X for (*(pb = pbuf) = '\0'; p = *ptext; *pb++ = *++ptext ? ' ' : '\0') {
- X for ( ; *p; *p++)
- X if (! (*p == ' ' && (pb == pbuf || pb[-1] == ' ')))
- X *pb++ = *p;
- X if (pb > pbuf && pb[-1] == ' ')
- X pb--;
- X }
- }
- X
- X
- /*
- X * split_date - extract 1-3 numeric fields (separated by one or more
- X * non-numeric characters) from date string; return number of fields
- X */
- #ifdef PROTOS
- int split_date(char *pstr,
- X int *pn1,
- X int *pn2,
- X int *pn3)
- #else
- int split_date(pstr, pn1, pn2, pn3)
- X char *pstr; /* input string */
- X int *pn1, *pn2, *pn3; /* output numbers */
- #endif
- {
- X int i, n, *pn;
- X
- X /* attempt to extract up to three numeric fields */
- X for (n = 0, i = 1; i <= 3; i++) {
- X pn = i == 1 ? pn1 : i == 2 ? pn2 : pn3; /* crude but portable */
- X if (pn)
- X *pn = *pstr ? (n++, atoi(pstr)) : 0;
- X SKIP_FIELD(pstr); /* go to next field */
- X }
- X
- X return n;
- }
- X
- X
- X
- /*
- X * File input routines:
- X */
- X
- X
- /*
- X * octal_esc - read up to 3 octal digits from file; return value of octal
- X * constant and leave file pointer at last character
- X */
- #ifdef PROTOS
- static int octal_esc(FILE *fp)
- #else
- static int octal_esc(fp)
- X FILE *fp;
- #endif
- {
- X int i, n, c;
- X
- X for (n = 0, i = 0; i < 3; i++) {
- X c = getc(fp);
- X if (c == EOF)
- X return EOF;
- X if (!isodigit(c)) {
- X ungetc(c, fp);
- X break;
- X }
- X n = n * 8 + (c - '0');
- X }
- X
- X return n & 0377; /* truncate to 8 bits */
- }
- X
- X
- /*
- X * hex_esc - read 'x' or 'X' followed by 1 or 2 hex digits from file; return
- X * value of hexadecimal constant (or letter if no hex digits follow) and
- X * leave file pointer at last character
- X */
- #ifdef PROTOS
- static int hex_esc(FILE *fp)
- #else
- static int hex_esc(fp)
- X FILE *fp;
- #endif
- {
- X int i, n, c, sv_c;
- X
- X sv_c = c = getc(fp); /* read leading 'x' or 'X' */
- X if (TOLOWER(c) != 'x')
- X return c; /* something else - just return it */
- X
- X for (n = 0, i = 0; i < 2; i++) {
- X c = getc(fp);
- X if (c == EOF)
- X return EOF;
- X if (!isxdigit(c)) {
- X ungetc(c, fp);
- X break;
- X }
- X n = n * 16 + (isupper(c) ? c - 'A' + 10 :
- X islower(c) ? c - 'a' + 10 :
- X c - '0');
- X }
- X
- X return i > 0 ? n & 0377 : sv_c; /* truncate to 8 bits */
- }
- X
- X
- /*
- X * getline - read next non-null line of input file into lbuf; return 0 on EOF
- X * strip leading whitespace, translate other whitespace to blanks, and handle
- X * all escapes except \' and \", (cf. loadwords())
- X */
- #ifdef PROTOS
- int getline(FILE *fp,
- X int *pline)
- #else
- int getline(fp, pline)
- X FILE *fp;
- X int *pline;
- #endif
- {
- X register char *cp;
- X register int c, c2;
- X static char escape[] = "abfnrtv"; /* cf. ANSI spec, 2.2.2 */
- X int in_comment; /* comments: from '#' to end-of-line */
- X
- X cp = lbuf;
- X do {
- X in_comment = FALSE;
- X while ((c = getc(fp)) != '\n' && c != EOF) {
- X if (c == '#')
- X in_comment = TRUE;
- X
- X if (isspace(c)) /* whitespace => blank */
- X c = ' ';
- X
- X /* ignore comments and leading white space */
- X if (in_comment || (cp == lbuf && c == ' '))
- X continue;
- X
- X /* handle escape sequences here: escaped whitespace
- X * and ANSI escapes are all converted to a space;
- X * octal and hex constants are converted in place
- X */
- X if (c == '\\') {
- X if ((c2 = getc(fp)) == EOF)
- X return FALSE;
- X
- X if (isspace(c2) || strchr(escape, c2)) {
- X c = ' ';
- X if (c2 == '\n')
- X (*pline)++;
- X }
- X else if (isodigit(c2)) { /* octal */
- X ungetc(c2, fp);
- X if((c = octal_esc(fp)) == EOF)
- X return FALSE;
- X }
- X else if (TOLOWER(c2) == 'x') { /* hex */
- X ungetc(c2, fp);
- X if((c = hex_esc(fp)) == EOF)
- X return FALSE;
- X }
- X else if (c2 == '\'' || c2 == '"')
- X ungetc(c2, fp);
- X else
- X c = c2;
- X
- X }
- X *cp++ = c;
- X }
- X
- X if (c == EOF) /* no more input lines */
- X return FALSE;
- X
- X (*pline)++; /* bump line number */
- X
- X } while (cp == lbuf); /* ignore empty lines */
- X
- X *cp = '\0';
- X return TRUE;
- }
- X
- X
- /*
- X * Routines dealing with translation of file specifications (VMS, Un*x)
- X */
- X
- #ifdef VMS
- /*
- X * mk_path - extract the path component from VMS file spec
- X */
- #ifdef PROTOS
- char *mk_path(char *path,
- X char *filespec)
- #else
- char *mk_path(path, filespec)
- X char *path; /* output path */
- X char *filespec; /* input filespec */
- #endif
- {
- X char *p;
- X
- X strcpy(path, filespec);
- X if (!(p = strchr(path, ']')) && !(p = strchr(path, ':')))
- X p = path - 1; /* return null string if no path */
- X *++p = '\0';
- X
- X return path;
- }
- X
- X
- /*
- X * mk_filespec - merge VMS path and file names, where latter can be relative
- X */
- #ifdef PROTOS
- char *mk_filespec(char *filespec,
- X char *path,
- X char *name)
- #else
- char *mk_filespec(filespec, path, name)
- X char *filespec; /* output filespec */
- X char *path; /* input path */
- X char *name; /* input file name */
- #endif
- {
- X char *p;
- X
- X *filespec = '\0';
- X
- X /* copy name intact if absolute; else merge path and relative name */
- X if (!strchr(name, ':')) {
- X strcpy(filespec, path);
- X if ((p = P_LASTCHAR(filespec)) && *p == END_PATH &&
- X name[0] == START_PATH && strchr(".-", name[1]))
- X *p = *++name == '-' ? '.' : '\0';
- X }
- X
- X return strcat(filespec, name);
- }
- X
- X
- /*
- X * trnlog - return translation of VMS logical name (null if missing)
- X */
- #ifdef PROTOS
- char *trnlog(char *logname)
- #else
- char *trnlog(logname) /* look up logical name */
- X char *logname;
- #endif
- {
- X static char trnbuf[STRSIZ];
- X
- X $DESCRIPTOR(src, logname);
- X $DESCRIPTOR(dst, trnbuf);
- X short len;
- X int ret;
- X
- X src.dsc$w_length = strlen(logname);
- X ret = LIB$SYS_TRNLOG(&src, &len, &dst);
- X return ret == SS$_NORMAL ? (trnbuf[len] = '\0', trnbuf) : NULL;
- }
- X
- #else /* apparently DOS and Amiga can use the Un*x flavors */
- X
- /*
- X * mk_path - extract the path component from a Un*x file spec
- X */
- #ifdef PROTOS
- char *mk_path(char *path,
- X char *filespec)
- #else
- char *mk_path(path, filespec)
- X char *path; /* output path */
- X char *filespec; /* input filespec */
- #endif
- {
- X char *p;
- X
- X strcpy(path, filespec);
- X if (! (p = strrchr(path, END_PATH)) )
- X p = path - 1; /* return null string if no path */
- X
- X *++p = '\0';
- X return path;
- }
- X
- X
- /*
- X * mk_filespec - merge Un*x path and file names, where latter can be relative
- X */
- #ifdef PROTOS
- char *mk_filespec(char *filespec,
- X char *path,
- X char *name)
- #else
- char *mk_filespec(filespec, path, name)
- X char *filespec; /* output filespec */
- X char *path; /* input path */
- X char *name; /* input file name */
- #endif
- {
- X char *p;
- X
- X *filespec = '\0';
- X
- X /* copy name intact if absolute; else merge path and relative name */
- X
- X /* if path starts with "~/", translate it for user */
- X if (strncmp(name, "~/", 2) == 0 && (p = trnlog(HOME_DIR)) != NULL) {
- X strcpy(filespec, p);
- X if ((p = P_LASTCHAR(filespec)) && *p != END_PATH)
- X *++p = END_PATH, *++p = '\0';
- X name += 2; /* skip "~/" */
- X }
- X else if (*name != START_PATH) { /* relative path */
- X strcpy(filespec, path);
- X if ((p = P_LASTCHAR(filespec)) && *p != END_PATH)
- X *++p = END_PATH, *++p = '\0';
- X }
- X
- X return strcat(filespec, name);
- }
- X
- X
- /*
- X * trnlog - return translation of Un*x environment variable
- X */
- #ifdef PROTOS
- char *trnlog(char *logname)
- #else
- char *trnlog(logname) /* look up logical name */
- X char *logname;
- #endif
- {
- X return getenv(logname);
- }
- X
- #endif
- SHAR_EOF
- chmod 0644 pcalutil.c ||
- echo 'restore of pcalutil.c failed'
- Wc_c="`wc -c < 'pcalutil.c'`"
- test 14737 -eq "$Wc_c" ||
- echo 'pcalutil.c: original size 14737, current size' "$Wc_c"
- fi
- true || echo 'restore of protos.h failed'
- echo End of part 4, continue with part 5
- exit 0
-