home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 3 / 3862 < prev    next >
Internet Message Format  |  1991-08-22  |  49KB

  1. Path: wupost!cs.utexas.edu!uwm.edu!linac!att!cbnews!jbr0
  2. From: jbr0@cbnews.cb.att.com (joseph.a.brownlee)
  3. Newsgroups: alt.sources
  4. Subject: Pcal v4.1, part 2 of 6
  5. Keywords: pcal calendar postscript
  6. Message-ID: <1991Aug19.121327.445@cbnews.cb.att.com>
  7. Date: 19 Aug 91 12:13:27 GMT
  8. Followup-To: alt.sources.d
  9. Organization: AT&T Bell Laboratories
  10. Lines: 1387
  11.  
  12. #!/bin/sh
  13. # This is part 02 of a multipart archive
  14. # ============= Pcal.hlp ==============
  15. if test -f 'Pcal.hlp' -a X"$1" != X"-c"; then
  16.     echo 'x - skipping Pcal.hlp (File already exists)'
  17. else
  18. echo 'x - extracting Pcal.hlp (Text)'
  19. sed 's/^X//' << 'SHAR_EOF' > 'Pcal.hlp' &&
  20. 1 PCAL
  21. X        Pcal generates PostScript  to  produce  landscape  or portrait
  22. X    calendars for any month  and  year.  The arguments month,year, and
  23. X    nmonths, if provided, should be  numeric.   The month value should
  24. X    be in the range 1 -  12, and the year value should be specified as
  25. X    1  or 2 digits or as the  full  4  digit  year.    If  no  numeric
  26. X    arguments  are  provided, the calendar for the current  month  and
  27. X    year will be generated.
  28. X
  29. X        If one numeric argument is provided, it is interpreted  as the
  30. X    year  value, and calendars for the entire year will be  generated.
  31. X    Otherwise,  nmonth  months,  starting with month and year, will be
  32. X    generated.
  33. X
  34. X        For whole-year calendars (i.e.  the  -w  option is given), the
  35. X    command line arguments are interpreted somewhat differently.    By
  36. X    default, all months in the current year are printed, starting with
  37. X    January.  If the month argument alone is given,  it is expected to
  38. X    be the desired year to print, and prints all of  the months in the
  39. X    given year.  If both month and year are given, then 12 consecutive
  40. X    months  are printed starting at the given month and year.  If  the
  41. X    month,  year, and nmonths  arguments  are  all  present,  printing
  42. X    begins  with the given month  and  year  and  nmonths  months  are
  43. X    printed, rounded up to the nearest multiple of 12.
  44. X    
  45. X        VMS Version
  46. X        Execution format:
  47. X
  48. X            pcal [options] [mm yy] [n]
  49. X
  50. 2 Parameters
  51. X  mm yy n
  52. X        "mm" and "yy"  are numeric values of the month (1-12) and year
  53. X    (0-99) (i.e., July 1990  would  be 7 90).  If you just include the
  54. X    "yy" option, an entire 12  months  of calendars will be generated.
  55. X    A specific month can be produced  by including the "mm" parameter.
  56. X    The  "n"  parameter will  produce the "n"  consecutive  months  of
  57. X    calendars starting with the requested month.
  58. X
  59. X        The following  flags  may be specified (in increasing order of
  60. X    precedence) in global symbol PCAL_OPTS, in "opt" lines in the date
  61. X    file (all but -e, -f, -h, -v, -"D", -"U"), or on the command line.
  62. X    Any flag which normally takes an argument may be specified without
  63. X    the  argument;  this resets its  value  to  the  program  default.
  64. X    (-"D" alone thus clears all defined symbols;    -"U"  alone has no
  65. X    effect.)
  66. X
  67. X        The "-" flag has  been added to  disambiguate  cases  where an
  68. X    argument-less flag has been specified immediately before a numeric
  69. X    parameter:
  70. X
  71. X        pcal -t - 9 90
  72. X
  73. 2 Options
  74. X        Pcal  accepts  several  command  line  options  (or  from  the
  75. X    CALENDAR.DAT file).  The uppercase options  should  be enclosed in
  76. X    quotes as pcal is case-sensitive and the  VMS  command line parser
  77. X    will  convert  the  string to upper case otherwise.    The  quoted
  78. X    strings  are  not  needed if the options are included  within  the
  79. X    CALENDAR.DAT file.
  80. X
  81. 3 -e
  82. X        Print an  empty  calendar (i.e., do not  print entries  from a
  83. X    CALENDAR.DAT file.)
  84. X
  85. 3 -f <FILE>
  86. X        Directs pcal to use the  file name <FILE> as the input file in
  87. X    place  of the  default  CALENDAR.DAT  file  in  the  callers  home
  88. X    directory or in the  directory specified by logical name PCAL_DIR.
  89. X
  90. 3 -o <FILE>
  91. X        Directs  pcal to  write  the  PostScript  calendar  into  FILE
  92. X    (default: CALENDAR.PS in the current directory.)
  93. X
  94. 3 -j
  95. X        Directs pcal to print  the  Julian  (Day Of Year, DOY) in each
  96. X    calendar box.
  97. X
  98. 3 -"J"
  99. X        Directs pcal to print the Julian  (Day  Of  Year, DOY) and the
  100. X    number of days remaining in the year in each calendar box.
  101. X
  102. 3 -l
  103. X        This will cause the  output  to  come  out  in  landscape mode
  104. X    (This is the default).
  105. X
  106. 3 -p
  107. X        This will cause  the  output  to  come  out  in  portrait mode
  108. X    instead of landscape mode.
  109. X
  110. 3 -m
  111. X        This option causes a  moon to be printed on days corresponding
  112. X    to a full, half, or new moon (default: no moons).
  113. X
  114. 3 -"M"
  115. X        This option causes a fractional moon to be printed on all days
  116. X    (default:  no moons).
  117. X
  118. 3 -b <DAY> | all
  119. X        This  will cause  all dates  on weekday  DAY to be  printed in
  120. X    black;  "-b all" causes  all dates  to be printed  in black unless
  121. X    explicitly flagged as a holiday.
  122. X
  123. 3 -g <DAY> | all
  124. X        This  will cause  all dates  on weekday  DAY to be  printed in
  125. X    gray; "-g all" causes all dates to be printed in gray.  Default is
  126. X    to print Saturdays  and Sundays in gray and  other dates in black.
  127. X
  128. 3 -"O"
  129. X        Causes  pcal to  print  "gray"  dates  as outlined characters.
  130. X
  131. 3 -"G"
  132. X        Causes  pcal  to  print  "gray"  dates  as outlined characters
  133. X    filled with gray.
  134. X
  135. 3 -"F" <DAY>
  136. X        This will cause  the weekday  DAY  to be the first day of each
  137. X    week;  weekday  DAY  will appear in  the left-most  column of each
  138. X    calendar.
  139. X
  140. 3 -"A" | -"E"
  141. X        Directs  pcal    to  use  either  American  or  European  date
  142. X    conventions.  Use  one  of these options to select the date format
  143. X    for the calendar file.    The  -"A"  option  (the default) selects
  144. X    American-style dates like "10/19/90" or  "Sep  19 1990", while the
  145. X    -"E" option selects European-style dates like  "17/10/90"  or  "19
  146. X    Sep 1990".
  147. X
  148. 3 -t <FONT>
  149. X        This option can be used  to  change  the  font  the  title  is
  150. X    printed in  (ie. pcal -t Times-Roman).  The default is Times-Bold.
  151. X
  152. 3 -d <FONT>
  153. X        This option is the same as  -t  except  that  the font used to
  154. X    print the  day  numbers is  changed.  The  default is  Times-Bold.
  155. X
  156. 3 -n <FONT>
  157. X        This option is the same as  -n  except  that  the font used to
  158. X    print the notes in the calendar boxes is  changed.  The default is
  159. X    Helvetica-Narrow.
  160. X
  161. 3 -"L" <STRING>
  162. X        This will cause STRING to be printed as a left footer.
  163. X
  164. 3 -"C" <STRING>
  165. X        This will cause STRING to be printed as a center footer.
  166. X
  167. 3 -"R" <STRING>
  168. X        This will cause STRING to be printed as a right footer.
  169. X
  170. 3 -"D" <SYM>
  171. X        This will define symbol SYM prior to  reading  the  date file;
  172. X    -"D" alone clears all defined symbols.
  173. X
  174. 3 -"U" <SYM>
  175. X        This will undefine symbol  SYM prior to reading the date file.
  176. X
  177. 3 -x xscale
  178. X        Specifies the x-axis scaling factor for the calendar size.
  179. X
  180. 3 -y yscale
  181. X        Specifies the y-axis scaling factor for the calendar size.
  182. X
  183. 3 -"X" xtrans
  184. X        Specifies  the  x-axis  translation  value for positioning the
  185. X    output on the page.
  186. X
  187. 3 -"Y" ytrans
  188. X        Specifies  the  y-axis  translation  value for positioning the
  189. X    output on the page.
  190. X
  191. 3 -"I"
  192. X        Resets all parameters to the program defaults.
  193. X
  194. 3 -"B"
  195. X        Causes pcal to leave  unused  calendar boxes blank (default is
  196. X    gray).
  197. X
  198. 3 -w
  199. X        Causes pcal  to print a calendar for 12 consecutive months:  3
  200. X    rows / 4 columns in landscape mode, 4 rows / 3 columns in portrait
  201. X    mode.  This option  effectively  disables  the  -"M"|m (moons) and
  202. X    -"J"|j (Julian dates) flags, and  also  suppresses the text in the
  203. X    calendar boxes.  The numeric parameters work slightly differently:
  204. X
  205. X            yy              print Jan/yy .. Dec/yy
  206. X            mm yy           print 12 months starting with mm/yy
  207. X            mm yy n         print n months (rounded up to multiple of 12)
  208. X                                starting with mm/yy
  209. X            (default)       print Jan .. Dec of current year
  210. X
  211. X        Note that "-w" in conjunction with "-p" overrides any  Y-scale
  212. X    factor  (default  or  set  with  "-y")  in order to use  the  full
  213. X    portrait page.
  214. X
  215. 3 -h
  216. X        This prints version AND usage information only. (LONG)
  217. X
  218. 3 -v
  219. X        This prints version information only.
  220. X
  221. 2 Calendar_File
  222. X        By default,  pcal  simply  prints an empty calendar.  Its real
  223. X    power is in  its  ability to place "events" in appropriate days on
  224. X    the  calendar,  thus allowing  the  user  to  create  personalized
  225. X    calendars.  This is achieved through the use of the "date file".
  226. X
  227. X        The date file is named  CALENDAR.DAT Pcal will look in several
  228. X    places for such a file.   First,  if  a  file  called CALENDAR.DAT
  229. X    exists in the caller's home directory, it  is used.  Next, if such
  230. X    a  file  exists  in the directory indicated by  the  logical  name
  231. X    PCAL_DIR  (or  the  current  directory  if  no  such  variable  is
  232. X    defined),  it  is  used.    Finally, the directory where the  pcal
  233. X    executable resides will be checked.  If no date file is  found, an
  234. X    empty calendar is printed.
  235. X
  236. X        If  a  date file is found, it will be searched for lines  with
  237. X    leading dates matching  the  requested  month  and year.  Any text
  238. X    following the dates found  will  be  printed on the calendar under
  239. X    the appropriate day of the  month.  Dates in the CALENDAR.DAT file
  240. X    may be expressed in any of several formats:
  241. X
  242. X          <ordinal> <day_spec> in <month_spec>{*} {<text>}
  243. X          <day_spec> <prep> <date_spec>{*} {<text>}
  244. X          <date_spec>{*} {<text>}
  245. X
  246. X    Where:
  247. X
  248. X      <month_spec>  := first 3+ characters of name of month or "all"
  249. X      <day_spec>    := first 3+ characters of name of weekday, "day",
  250. X                       "weekday", "workday", "holiday",
  251. X                       "nonweekday", "nonworkday", or "nonholiday"
  252. X      <ordinal>     := "first", "1st", ... "fifth", "5th",
  253. X                       "last", "odd", "even", or "all"
  254. X      <prep>        := "before", "preceding", "after", "following",
  255. X                       "on_or_before" ("oob"), or
  256. X                       "on_or_after" ("ooa")
  257. X      <sep>         := 1 or more non-numeric, non-space, non-"*" characters
  258. X      <month>       := day of month (1-31)
  259. X      <day>         := a numeric month (1-12)
  260. X      <year>        := a numeric year
  261. X
  262. X     If the -"A" option (American date formats, the default) is given:
  263. X
  264. X      <date_spec>   := [<month_spec><day> | <month><sep><day>{<sep><year>}]
  265. X
  266. X     If the -"E" option (European date formats) is given:
  267. X
  268. X      <date_spec>   := [<day><month_spec> | <day><sep><month>{<sep><year>}]
  269. X
  270. 3 Text_Format_Description
  271. X        Pcal also allows format  specifiers  in both the text and foot
  272. X    strings (see the -L, -C,  and  -R  options  below);   each will be
  273. X    replaced by a corresponding string as outlined in the table below.
  274. X    Most of these are derived from the  strftime()  function;   the %l
  275. X    and %[o0+--] format specifiers are specific to pcal:
  276. X
  277. X                %a     abbreviated weekday
  278. X                %A     full weekday
  279. X                %b     abbreviated month name
  280. X                %B     full month name
  281. X                %d     day of month (1-31)
  282. X                %j     day of year (1-366)
  283. X                %l     days left in year (0-365)
  284. X                %m     month (1-12)
  285. X                %U     week number (0-53)
  286. X                %W     week number (0-53)
  287. X                %y     year w/o century (00-99)
  288. X                %Y     year w/century
  289. X                %%     % character
  290. X
  291. X                %o     print number as ordinal
  292. X                %0     print number with leading zeroes
  293. X                %+     use following month or year
  294. X                %-     use previous month or year
  295. X
  296. X        The %U  format  specifier  considers  the first logical Sunday
  297. X    (the first day  of  the week as printed;  see the -F option below)
  298. X    of the year as  the  first day of week number 1;  the %W specifier
  299. X    uses the first logical Monday  instead.    This is an extension of
  300. X    the behavior of the strftime() function.
  301. X
  302. X        The %o format specifier prints a  number  as  an ordinal, with
  303. X    the  appropriate  suffix ("st", "nd", "rd", or  "th"  in  English)
  304. X    appended;  for example, %od prints the day  of the month as "1st",
  305. X    "2nd", "3rd", etc.
  306. X
  307. X        Unlike  strftime(), pcal's default is to print numbers (except
  308. X    %y)  without  leading zeroes.  If leading zeroes are desired,  the
  309. X    "0" prefix may be used;  for example, %0j prints the  day  of year
  310. X    as 001-365.
  311. X
  312. X        The  %+ and %- format specifiers direct pcal to substitute the
  313. X    following or  previous  month  or  year  for the following [bBmyY]
  314. X    specifier;  for  example,  %+B  prints  the  name of the following
  315. X    month.
  316. X
  317. 3 Date_Syntax_Description
  318. X        Any  non-numeric  character  may  separate    numeric   dates.
  319. X    Holidays may be flagged by following the date immediately with "*"
  320. X    as in the examples above;   this will cause the date to be printed
  321. X    in gray.  "Each" and "every" are  accepted  as synonyms for "all",
  322. X    and any word may be used in place  of  "in".    The  abbreviations
  323. X    "oob"  and  "ooa"  may  be  used  in  place  of    the    keywords
  324. X    "on_or_before" and "on_or_after", respectively.
  325. X
  326. X        Wildcard  day  names are also provided.  The keyword "weekday"
  327. X    applies to  any  days  which  are normally printed in black on the
  328. X    calendar.  The keyword "workday" is the same, but does not include
  329. X    any holidays.  The  keyword  "holiday"  includes  only  those days
  330. X    flagged as holidays.  The keywords "nonweekday", "nonworkday", and
  331. X    "nonholiday" are also recognized as negations  of  the above.  See
  332. X    the Caveats below for important notes on using these keywords.
  333. X
  334. X        Ordinal  day  numbers may be used  to  specify  dates,  either
  335. X    relative to the month or to the  year.    Either  words or numeric
  336. X    abbreviations  may  be used for "first" through "fifth";    higher
  337. X    numbers must be given using the numeric equivalent (e.g.   100th).
  338. X    Negative  ordinal numbers may even be used.  For example,  "-2nd"
  339. X    means "next to last".
  340. X
  341. X        "Odd" and "even" do not refer  to  the  actual date;  instead,
  342. X    "odd" means "alternate, starting with the first", and "even" means
  343. X    "alternate,  starting  with  the second".  Thus, "odd  Fridays  in
  344. X    March" refers to the first, third, and (if present)  fifth Fridays
  345. X    in March - not to those Fridays falling on odd dates.
  346. X
  347. X        "All" refers to each individual month;    "year" refers to the
  348. X    year as an entity.  Thus "odd Fridays in all" refers to the first,
  349. X    third, and fifth Friday of each month, while "odd Fridays in year"
  350. X    refers  to  the  first  Friday of January and every  other  Friday
  351. X    thereafter.
  352. X
  353. X        Text in the date file may use C-like escape sequences (i.e.  a
  354. X    "\" followed by a character, 1--3 octal digits, or "x" followed by
  355. X    1--2 hexadecimal digits).  Escaped  whitespace (including newline)
  356. X    and the standard ANSI character escapes  ("\a",  "\b", "\f", "\n",
  357. X    "\r", "\t", "\v") are all replaced by a single blank.
  358. X
  359. X        Lines in the CALENDAR.DAT file consisting  of year #### (where
  360. X    #### is a numeric year) can be  used to set the year for following
  361. X    entries.  This assumes that the following entries do not contain a
  362. X    year;  any date entries containing year information will  set  the
  363. X    remembered year to that year.
  364. X
  365. X        Lines in the CALENDAR.DAT file consisting of opt <options> can
  366. X    be used to override the  defaults  for  any  command-line  options
  367. X    except -e, -f, -h, -"D", and  -"U".  Any options specified in this
  368. X    manner are, in turn, overridden by those  specified  explicitly on
  369. X    the command line.  Note that the upper  case letter options do NOT
  370. X    need to be enclosed in quotes if they are  put in the CALENDAR.DAT
  371. X    file.  Enclose the upper case letters in quotes only when they are
  372. X    used on the DCL.
  373. X
  374. X        Lines in the CALENDAR.DAT file consisting of note  <month> can
  375. X    be used to place notes regarding the entire month  is  one  of the
  376. X    unused  blocks  of  the  calendar.   The <month> indicator may  be
  377. X    either  a  number  1  through  12  or an alphabetic month name  as
  378. X    described above;  "note all" will place the associated text in the
  379. X    notes block for each month in the current year.
  380. X
  381. X        Comments  are   supported  in  the  CALENDAR.DAT  file.    Any
  382. X    characters following a  "#"  character through the end of the line
  383. X    are ignored.
  384. X
  385. X        Pcal  supports rudimentary cpp-like functionality in the  date
  386. X    file, allowing the following constructs:  define | undef, if{n}def
  387. X    ...  {else ...} endif,  and  include.    Note  that  these are not
  388. X    preceded  by  "#" as they are in C.  Symbol  names  defined  using
  389. X    these  keywords (or via the -"D" option) are case-insensitive.  It
  390. X    is not  an  error  to  undef  an undefined symbol, nor to define a
  391. X    previously-defined one.   An  ifdef  alone  is  always  false;  an
  392. X    ifndef alone is always true.
  393. X
  394. X        The  name  of the file in the include directive may optionally
  395. X    be surrounded by either "" or <>, both of which are ignored.    If
  396. X    the  name  is not an absolute path, it is taken to be relative  to
  397. X    the directory where the file containing the directive is located.
  398. X
  399. X        In  addition  to  pre-processing keywords, pcal  also  accepts
  400. X    boolean  expressions in if{n}def directives.    These  expressions
  401. X    consist of symbol names joined by  the  boolean operators !, &, ^,
  402. X    and |, in order of precedence, high to low.   Parentheses  may  be
  403. X    used to alter the precedence.  The synonyms && and || are accepted
  404. X    for  &  and  |.    A  symbol  name evaluates to true if  currently
  405. X    defined, false if not;  thus:
  406. X
  407. X                              ifdef A | B | C
  408. X
  409. X    ...is true if any of the symbols A, B, and C is defined, and:
  410. X
  411. X                              ifdef A & B & C
  412. X
  413. X    ...is true if they all are.  Note that ifndef <expr> is equivalent
  414. X    to ifdef !( <expr> ).
  415. X
  416. 3 Example
  417. X    Date File Example:
  418. X
  419. X    # A sample "opt" line to change the fonts and output file names,
  420. X    # to print only Sundays in gray, and to print moons on all days:
  421. X    #
  422. X    opt -d Helvetica-Bold -t Helvetica-Bold -o myfile.ps -b all -g sun -M
  423. X
  424. X    year 1990               # set year explicitly
  425. X    1/1*                    New Year's Day
  426. X    ifndef Arizona
  427. X        3rd Mon in Jan*     Martin Luther King's Birthday
  428. X    endif
  429. X    2/2                     Groundhog Day
  430. X    Feb 14                  Valentine's Day
  431. X    3rd Monday in Feb*      Presidents' Day
  432. X    3/17                    St. Patrick's Day
  433. X    last Monday in May*     Memorial Day
  434. X    7/4*                    Independence Day
  435. X    1st Monday in Sep*      Labor Day
  436. X    second Monday in Oct*   Columbus Day (observed)
  437. X    first workday in all    %-B progress report due
  438. X    all Fridays in Oct      Status Meeting, 11 AM
  439. X    all Fri in all          Time card due, 3 PM
  440. X    all Monday in all       Fiscal week %0W
  441. X    -2nd workday in all     Schedule for %+B due
  442. X    Fri on_or_before all 15 Pay Day
  443. X    even Fridays in year    Pay Day
  444. X    183rd day of year       mid-year (%l days left)
  445. X    10/12                   Columbus Day (traditional)
  446. X    10/31                   Halloween
  447. X    Tue after first Mon in Nov      Election Day
  448. X    second Monday in Nov*           Veterans' Day (observed)
  449. X    11/11*                          Veterans' Day (traditional)
  450. X    fourth Thu in Nov*              Thanksgiving
  451. X    Fri after 4th Thu in Nov*       Day after Thanksgiving
  452. X    day after fourth Thu in Nov*
  453. X    12/24*                  Christmas Eve
  454. X    12/25*                  Christmas
  455. X    last day in Dec*        New Year's Eve
  456. X    last workday in all     Status reports due
  457. X    note Dec                Office closed throughout week of Christmas
  458. X    1/1/91*                 New Year's Day      # set new year implicitly
  459. X
  460. 2 Moon_File
  461. X        If  a  file  of the name MOON##.DAT (where ## is the last  two
  462. X    digits  of  the calendar year) exists in the same directory as the
  463. X    date file, pcal uses the information contained within to calculate
  464. X    the phase of  the  moon.    If  no  such file exists, pcal uses an
  465. X    extreamly reliable algorithm.  This is the prefered method of use.
  466. X
  467. X        Entries in the moon file must conform to the following syntax:
  468. X
  469. X        If the -"A" option  (American  date  formats,  the default) is
  470. X    given:
  471. X
  472. X              <quarter> <month><sep><day> {<hour><sep><min>}
  473. X
  474. X        If the -"E" option (European date formats) is given:
  475. X
  476. X              <quarter> <day><sep><month> {<hour><sep><min>}
  477. X
  478. X        Where:
  479. X
  480. X            <quarter>   := "nm", "fq" or "1q", "fm", "3q" or "lq"
  481. X                           (new moon,first quarter,full moon,last quarter)
  482. X            <hour>      := number 0-23 (24-hour clock)
  483. X            <min>       := number 0-59
  484. X
  485. X        This file must contain entries for  all  quarter  moons in the
  486. X    year, in chronological order;  if any errors are encountered, pcal
  487. X    will revert to using its default algorithm.
  488. X
  489. X        As in the date file, comments start with  "#"  and run through
  490. X    end-of-line.
  491. X
  492. 3 Example
  493. X        The following  is  a  short example of an European style (-"E)
  494. X    moon data file.    It  is  taken from the MOON91.DAT file supplied
  495. X    with pcal.
  496. X
  497. X        3q 01/07 13:37        # third quarter
  498. X        nm 01/15 18:51        # new moon
  499. X        1q 01/23 09:23        # first quarter
  500. X        fm 01/30 01:10        # full moon
  501. X
  502. 2 Logical_Names
  503. X        Pcal optionally uses two (2)  logical  names during execution.
  504. X    A user may define them or let the administrator set them up.
  505. X
  506. 3 Pcal_Dir
  507. X        Pcal logical name for the location  of the directory for input
  508. X    and output files.  In this way,  a  user can over-ride the current
  509. X    default location for the source  of  the  CALENDAR.DAT input file
  510. X    and the CALENDAR.PS output file.
  511. X
  512. 3 Pcal_Opts
  513. X        Pcal  also  looks for a logical name "Pcal_Opts;  if  defined,
  514. X    its contents  are  parsed  as command-line flags.  These over-ride
  515. X    the program defaults,  but  are  over-ridden  by any specified via
  516. X    "opt" lines in the date file or on the command line.  Example:
  517. X
  518. X        Define Pcal_Opts "-n Helvetica -D meetings"     ! login.com
  519. X        pcal -"U" meetings 9 90       ! un-define symbol at runtime
  520. X
  521. 2 Caveats
  522. X        The "workday" and "holiday" keywords are aware  of  only those
  523. X    holidays which have already been flagged at the  point  where they
  524. X    appear.  For example, consider January 1990:
  525. X
  526. X                        January 1990
  527. X                     S  M Tu  W Th  F  S
  528. X                        1  2  3  4  5  6
  529. X                     7  8  9 10 11 12 13
  530. X                    14 15 16 17 18 19 20
  531. X                    21 22 23 24 25 26 27
  532. X                    28 29 30 31
  533. X
  534. X        If the CALENDAR.DAT file looked like this:
  535. X
  536. X            workday on_or_before all 15         payday
  537. X            3rd Mon in Jan*                     MLK day
  538. X
  539. X    then Pcal would mark the 15th as "payday" since  at  that point in
  540. X    the CALENDAR.DAT file it has no way of knowing that  January  15th
  541. X    will  later  be  flagged  as  a  holiday.  If the two  lines  were
  542. X    reversed, such that  the  holiday preceded the "workday" wildcard,
  543. X    then Pcal would work  as  intended,  marking  instead  the 12th as
  544. X    "payday".    Also, beware of  year  boundaries  which  affect  the
  545. X    handling of all of the day  wildcard  keywords.  In general, it is
  546. X    best to place monthly wildcards such as  the  example above at the
  547. X    end of each year to acheive the desired effect.
  548. X
  549. X        When the -w and -p options are used together, pcal revises the
  550. X    y-scale   factor  in  order  to  use  the  entire  portrait  page;
  551. X    therefore, the user should avoid using use  the  -y using both the
  552. X    -w and -p options.  Use of the  -w  option in any case effectively
  553. X    disables the -m, -"M", -j, and -"J" options.
  554. X
  555. 2 Authors
  556. X        The original  PostScript  code  to  generate the calendars was
  557. X    written by Patrick  Wood  (Copyright  (c)  1987 by Patrick Wood of
  558. X    Pipeline Associates, Inc.), and  authorized  for  modification and
  559. X    redistribution.    The  CALENDAR.DAT  file    inclusion  code  was
  560. X    originally written in "bs(1)" by Bill  Vogel  of  AT&T.  Patrick's
  561. X    original  PostScript  was modified and enhanced several  times  by
  562. X    others  whose names have regrettably been lost.   Ken  Keirnan  of
  563. X    Pacific Bell assembled the original "C" version upon which this is
  564. X    based;  additional modifications and enhancements were the work of
  565. X    Joseph P.    Larson,  Ed Hand, Andrew W.  Rogers, Mark Kantrowitz,
  566. X    Joe Brownlee, Jamie  Zawinski and Floyd Miller.  The moon routines
  567. X    were  originally  written  by   Mark  Hanson,  were  improved  and
  568. X    incorporated  into  this  version  by  Jamie  Zawinski,  and  were
  569. X    translated from PostScript to C by  Andrew  Rogers.    VMS and TeX
  570. X    support was provided by Richard Dyson and  updated  by  Andrew  W.
  571. X    Rogers and Joe Brownlee.  The Amiga support  was  supplied by Bill
  572. X    Hogsett.
  573. X
  574. 2 Version
  575. X        This help file  currently reflects pcal v4.1 dated 15-AUG-1991
  576. X    and was updated by Richard Dyson on 15-AUG-1991.
  577. SHAR_EOF
  578. chmod 0644 Pcal.hlp ||
  579. echo 'restore of Pcal.hlp failed'
  580. Wc_c="`wc -c < 'Pcal.hlp'`"
  581. test 24613 -eq "$Wc_c" ||
  582.     echo 'Pcal.hlp: original size 24613, current size' "$Wc_c"
  583. fi
  584. # ============= SetUp.com ==============
  585. if test -f 'SetUp.com' -a X"$1" != X"-c"; then
  586.     echo 'x - skipping SetUp.com (File already exists)'
  587. else
  588. echo 'x - extracting SetUp.com (Text)'
  589. sed 's/^X//' << 'SHAR_EOF' > 'SetUp.com' &&
  590. $ Write Sys$Output "SETting UP Pcal (v4.1)..."
  591. $ THIS_PATH = F$Element (0, "]", F$Environment ("PROCEDURE")) + "]"
  592. $ PCAL :== $ 'THIS_PATH'PCAL.EXE
  593. $ Define Pcal_Dir 'THIS_PATH'
  594. $!
  595. $!  Put the help library into the next available help library slot
  596. $!
  597. $ LIB = "Hlp$Library"
  598. $ X = F$Trnlnm (LIB, "Lnm$Process")
  599. $ If X .eqs. "" Then GoTo INSERT
  600. $ If X .eqs. "''THIS_PATH'PCAL.HLB" Then GoTo EXIT
  601. $ BASE = LIB + "_"
  602. $ N = 1
  603. $NEXTLIB:
  604. $   LIB := 'BASE''N'
  605. $   X = F$Trnlnm (LIB, "Lnm$Process")
  606. $   If X .eqs. "" Then GoTo INSERT
  607. $   If X .eqs. "''THIS_PATH'PCAL.HLB" Then GoTo EXIT
  608. $   N = N + 1
  609. $   GoTo NEXTLIB
  610. $INSERT:
  611. $   Define 'LIB' 'THIS_PATH'PCAL.HLB
  612. $EXIT:
  613. $   Exit
  614. SHAR_EOF
  615. chmod 0644 SetUp.com ||
  616. echo 'restore of SetUp.com failed'
  617. Wc_c="`wc -c < 'SetUp.com'`"
  618. test 670 -eq "$Wc_c" ||
  619.     echo 'SetUp.com: original size 670, current size' "$Wc_c"
  620. fi
  621. # ============= VaxCrtl.opt ==============
  622. if test -f 'VaxCrtl.opt' -a X"$1" != X"-c"; then
  623.     echo 'x - skipping VaxCrtl.opt (File already exists)'
  624. else
  625. echo 'x - extracting VaxCrtl.opt (Text)'
  626. sed 's/^X//' << 'SHAR_EOF' > 'VaxCrtl.opt' &&
  627. Sys$Library:VAXCRTL.EXE /Share
  628. SHAR_EOF
  629. chmod 0644 VaxCrtl.opt ||
  630. echo 'restore of VaxCrtl.opt failed'
  631. Wc_c="`wc -c < 'VaxCrtl.opt'`"
  632. test 31 -eq "$Wc_c" ||
  633.     echo 'VaxCrtl.opt: original size 31, current size' "$Wc_c"
  634. fi
  635. # ============= calendar ==============
  636. if test -f 'calendar' -a X"$1" != X"-c"; then
  637.     echo 'x - skipping calendar (File already exists)'
  638. else
  639. echo 'x - extracting calendar (Text)'
  640. sed 's/^X//' << 'SHAR_EOF' > 'calendar' &&
  641. # Sample date file for Pcal: this should be called .calendar for Un*x,
  642. # CALENDAR.DAT for VMS, and should live in the user's home directory.
  643. #
  644. # Date file syntax:
  645. #    
  646. #    The following rules describe the syntax of date file entries:
  647. #    
  648. #      year <year>
  649. #    
  650. #      opt <options>
  651. #    
  652. #      note <month_spec> <text>
  653. #      note <month> <text>
  654. #    
  655. #      if -A flag (American date formats) specified:
  656. #        <month_name> <day>{*} {<text>}
  657. #        <month><sep><day>{<sep><year>}{*} {<text>}
  658. #    
  659. #      if -E flag (European date formats) specified:
  660. #        <day> <month_name>{*} {<text>}
  661. #        <day><sep><month>{<sep><year>}{*} {<text>}
  662. #    
  663. #      <ordinal> <day_name> in <month_spec>{*} {<text>}
  664. #      <day_name> <prep> <date_spec>
  665. #    
  666. #    where
  667. #    
  668. #      {x}          means x is optional
  669. #    
  670. #      <date_spec> := any of the above date specs (not year, note, or opt)
  671. #      <month_name> := first 3+ characters of name of month, or "all"
  672. #      <month_spec> := <month_name>, or "year"
  673. #      <day_name> := first 3+ characters of name of weekday, "day",
  674. #                    "weekday", "workday", "holiday", "nonweekday",
  675. #                    "nonworkday", or "nonholiday"
  676. #      <ordinal> := ordinal number ("1st", "2nd", etc.), "first" .. "fifth",
  677. #                    "last", "even", "odd", or "all"
  678. #      <prep> := "before", "preceding", "after", "following", "on_or_before",
  679. #                    or "on_or_after"
  680. #      <sep> := one or more non-numeric, non-space, non-'*' characters
  681. #      <month>, <day>, <year> are the numeric forms
  682. #    
  683. #      <options> := any command-line option except -e, -f, -h, -D, -U
  684. #    
  685. #    Comments start with '#' and run through end-of-line.
  686. #    
  687. #    Holidays may be flagged by specifying '*' as the last character of
  688. #    the date field(s), e.g. "10/12* Columbus Day", "July 4* Independence
  689. #    Day", etc.  Any dates flagged as holidays will be printed in gray, and
  690. #    any associated text will appear adjacent to the date.
  691. #    
  692. #    Note that the numeric date formats (mm/dd{/yy}, dd.mm{.yy}) support
  693. #    an optional year, which will become the subsequent default year.  The
  694. #    alphabetic date formats (month dd, dd month) do not support a year
  695. #    field; the "year yy" command is provided to reset the default year.
  696. #    
  697. #    "Floating" days may be specified in the date file as "first Mon in 
  698. #    Sep", "last Mon in May", "4th Thu in Nov", etc.; any word may be
  699. #    used in place of "in".  "Relative floating" days (e.g. "Fri after 4th 
  700. #    Thu in Nov") are also accepted; they may span month/year bounds.
  701. #    Pcal also accepts date specs such as "all Friday{s} in October", "last
  702. #    Thursday in all", etc., and produces the expected results; "each" and
  703. #    "every" are accepted as synonyms for "all".  Negative ordinals are
  704. #    allowed; "-2nd" means "next to last".
  705. #    
  706. #    The words "day", "weekday", "workday", and "holiday" may be used as
  707. #    wildcards: "day" matches any day, "weekday" matches any day normally
  708. #    printed in black, "workday" matches any day normally printed in black
  709. #    and not explicitly flagged as a holiday, and "holiday" matches any
  710. #    day explicitly flagged as a holiday.  "Nonweekday", "nonworkday",
  711. #    and "nonholiday" are also supported and have the obvious meanings.
  712. #    
  713. #    "Odd" and "even" do not refer to the actual date; instead, "odd"
  714. #    means "alternate, starting with the first"; "even" means "alternate,
  715. #    starting with the second".  Thus, "odd Fridays in March" refers to
  716. #    the first, third, and (if present) fifth Fridays in March - not to
  717. #    those Fridays falling on odd dates.
  718. #    
  719. #    "All" refers to each individual month; "year" refers to the year
  720. #    as an entity.  Thus "odd Fridays in all" refers to the first/third/
  721. #    fifth Friday of each month, while "odd Fridays in year" refers to
  722. #    the first Friday of January and every other Friday thereafter.
  723. #    
  724. #    Additional notes may be propagated to an empty calendar box by the
  725. #    inclusion of one or more lines of the form "note <month> <text>",
  726. #    where <month> may be numeric or alphabetic; "note all <text>"
  727. #    propagates <text> to each month in the current year.
  728. #    
  729. #    Pcal also allows format specifiers in the text (and foot strings -
  730. #    cf. the -L, -C, and -R options); each will be replaced by its
  731. #    equivalent string as outlined in the table below.  (Most of these are
  732. #    derived from the strftime() function; %[lo0+-] are Pcal-specific.)
  733. #
  734. #        %a : abbreviated weekday
  735. #        %A : full weekday
  736. #        %b : abbreviated month name
  737. #        %B : full month name
  738. #        %d : day of month (1-31)
  739. #        %j : day of year (1-366)
  740. #        %l : days left in year (0-365)
  741. #        %m : month (1-12)
  742. #        %U : week number (0-53)
  743. #        %W : week number (0-53)
  744. #        %y : year w/o century (00-99)
  745. #        %Y : year w/century
  746. #        %% : '%' character
  747. #
  748. #        %o : print number as ordinal
  749. #        %0 : print number with leading zeroes
  750. #        %+ : use following month or year
  751. #        %- : use previous month or year
  752. #
  753. #    %U considers the first logical Sunday (the first day of the week as
  754. #    printed; cf. the -F flag) of the year as the first day of week 1;
  755. #    %W uses the first logical Monday instead.  This is an extension of
  756. #    strftime()'s behavior.
  757. #
  758. #    %o prints a number as an ordinal, with the appropriate suffix ("st",
  759. #    "nd", "rd", or "th" in English) appended; for example, "%od" prints
  760. #    the day of the month as "1st", "2nd", "3rd", etc.
  761. #
  762. #    Unlike strftime(), Pcal's default is to print numbers (except %y)
  763. #    without leading zeroes.  If leading zeroes are desired, the '0'
  764. #    prefix may be used; for example, "%0j" prints the day of year as
  765. #    001-365.
  766. #
  767. #    %+ and %- direct Pcal to substitute the following/previous month/year
  768. #    in the following [bBmyY] specifier; for example, %+B prints the name
  769. #    of the next month.
  770. #
  771. #    Simple cpp-like functionality is provided.  The date file may include
  772. #    the following commands, which work like their cpp counterparts:
  773. #    
  774. #            define <sym>
  775. #            undef <sym>
  776. #    
  777. #            if{n}def <expr>
  778. #               ...
  779. #            { else
  780. #               ... }
  781. #            endif
  782. #    
  783. #            include <file>
  784. #    
  785. #    Note that these do not start with '#', which is reserved as a comment
  786. #    character.
  787. #    
  788. #    <sym> is a symbol name consisting of a letter followed by zero or
  789. #    more letters, digits, or underscores ('_').  Symbol names are always
  790. #    treated in a case-insensitive manner.
  791. #    
  792. #    <expr> is an expression consisting of symbol names joined by the logical
  793. #    operators (in order of precedence, high to low) '!' (unary negate), '&'
  794. #    (and), '^' (exclusive or), and '|' (inclusive or).  '&&' and '||' are
  795. #    accepted as synonyms for '&' and '|' respectively; the order of
  796. #    evaluation may be altered by the use of parentheses.  A symbol whose
  797. #    name is currently defined evaluates to TRUE; one whose name is not
  798. #    currently defined evaluates to FALSE.  Thus "ifdef A | B | C" is TRUE
  799. #    if any of the symbols A, B, and C is currently defined, and
  800. #    "ifdef A & B & C" is TRUE if all of them are.
  801. #    
  802. #    "ifndef A | B | C" is equivalent to "ifdef !(A | B | C)" (or, using
  803. #    DeMorgan's Law, "ifdef !A & !B & !C") - in other words, TRUE if none of
  804. #    the symbols A, B, and C is currently defined.
  805. #    
  806. #    "define" alone deletes all the current definitions; "ifdef" alone is
  807. #    always false; "ifndef" alone is always true.
  808. #    
  809. #    The file name in the "include" directive may optionally be surrounded
  810. #    by "" or <>.  In any case, path names are taken to be relative to
  811. #    the location of the file containing the "include" directive.
  812. X
  813. X
  814. # "opt" lines to override program defaults
  815. X
  816. opt -d Helvetica-Bold -t Helvetica-Bold -n Helvetica    # override default fonts
  817. opt -M                             # moon icons on all days
  818. opt -O                            # print outlined characters
  819. X
  820. year 1991            # set year explicitly
  821. X
  822. # note to be propagated to "Notes" box for all months
  823. X
  824. note all            Engineering staff meeting every Tuesday, 1:30 PM
  825. X
  826. # examples of format specifiers
  827. X
  828. all Monday in all        Fiscal week %W.%y    # e.g. 26.91
  829. last workday in all        %B status meeting    # substitute month name
  830. 2nd workday in all        %-B status report due    # use previous month
  831. X
  832. # some sample holidays (flagged by '*') and other days of note
  833. X
  834. 1/1*                New Year's Day
  835. X
  836. # if "AZ" or "MT" defined, holiday definition will be skipped
  837. ifndef AZ || NH || MT
  838. 3rd Monday in Jan*        Martin Luther King Day (except AZ, NH, MT)
  839. endif
  840. X
  841. 3rd Monday in Feb        Presidents' Day
  842. Feb 14                Valentine's Day
  843. X
  844. # any Pcal users in Alaska?
  845. ifdef AK
  846. first Sat in March        Iditarod starts
  847. endif
  848. X
  849. 3/17                St. Patrick's Day
  850. X
  851. # another local holiday - included only if "MA" or "ME" defined
  852. ifdef MA || ME
  853. 3rd Monday in Apr        Patriots' Day (MA, ME)
  854. endif
  855. X
  856. last Monday in May*        Memorial Day
  857. X
  858. 6/14                Flag Day
  859. X
  860. 7/4*                Independence Day
  861. X
  862. 1st Monday in Sep*        Labor Day
  863. X
  864. second Monday in Oct        Columbus Day (observed)
  865. 10/31                Halloween
  866. X
  867. Tue after first Mon in Nov    Election Day
  868. second Mon in Nov        Veterans' Day # (observed)
  869. fourth Thu in Nov*        Thanksgiving
  870. day after fourth Thu in Nov*
  871. X
  872. 12/24*                Christmas Eve
  873. 12/25*                Christmas
  874. last day in Dec*        New Year's Eve
  875. X
  876. # if the symbol "paydays" has been defined, print text on alternate
  877. # Fridays (starting with the first Friday of the year)
  878. ifdef paydays
  879. odd Fridays in year        Pay Day
  880. endif
  881. X
  882. # if the symbol "meetings" has been defined, print text on the next-to-last
  883. # Monday of each month
  884. ifdef meetings
  885. -2nd Monday in all        Monthly staff meeting
  886. endif
  887. X
  888. 1/1/92*                New Year's Day        # reset year implicitly
  889. SHAR_EOF
  890. chmod 0666 calendar ||
  891. echo 'restore of calendar failed'
  892. Wc_c="`wc -c < 'calendar'`"
  893. test 9144 -eq "$Wc_c" ||
  894.     echo 'calendar: original size 9144, current size' "$Wc_c"
  895. fi
  896. # ============= exprpars.c ==============
  897. if test -f 'exprpars.c' -a X"$1" != X"-c"; then
  898.     echo 'x - skipping exprpars.c (File already exists)'
  899. else
  900. echo 'x - extracting exprpars.c (Text)'
  901. sed 's/^X//' << 'SHAR_EOF' > 'exprpars.c' &&
  902. /*
  903. X * exprpars.c - Pcal routines concerned with parsing if{n}def expressions
  904. X *
  905. X * Contents:
  906. X *
  907. X *        do_xxx
  908. X *        lookup_token
  909. X *        next_token
  910. X *        parse_expr
  911. X *
  912. X * Revision history:
  913. X *
  914. X *    4.0    AWR    02/06/91    Author
  915. X *
  916. X */
  917. X
  918. /*
  919. X * Standard headers:
  920. X */
  921. X
  922. #include <ctype.h>
  923. #include <string.h>
  924. #include <stdio.h>
  925. X
  926. /*
  927. X * Pcal-specific definitions:
  928. X */
  929. X
  930. #include "pcaldefs.h"
  931. #include "pcalglob.h"
  932. X
  933. /*
  934. X * Macros:
  935. X */
  936. X
  937. /*
  938. X * token type code definitions:
  939. X */
  940. X
  941. #define TK_UNKNOWN     0        /* codes returned by next_token() */
  942. #define TK_IDENT     1
  943. #define TK_LPAREN     2
  944. #define TK_RPAREN     3
  945. #define TK_UNARYOP     4
  946. #define TK_BINARYOP     5
  947. #define TK_ENDINPUT     6
  948. #define TK_STARTINPUT     7        /* special code for start symbol */
  949. X
  950. /* bit position for token type codes (cf. where_ok[] below) */
  951. #define ID_OK        (1 << TK_IDENT)
  952. #define LP_OK        (1 << TK_LPAREN)
  953. #define RP_OK        (1 << TK_RPAREN)
  954. #define UO_OK        (1 << TK_UNARYOP)
  955. #define BO_OK        (1 << TK_BINARYOP)
  956. #define ST_OK        (1 << TK_STARTINPUT)
  957. #define NEVER_OK    0
  958. X
  959. /* is token "curr" legal after "prev"? (cf. where_ok[] below) */
  960. #define IS_LEGAL(curr, prev)    (where_ok[curr] & (1 << (prev)))
  961. X
  962. /*
  963. X * operator-related definitions:
  964. X */
  965. X
  966. #define OP_AND        0    /* operator subcodes */
  967. #define OP_OR        1
  968. #define OP_XOR        2
  969. #define OP_NEGATE    3
  970. X
  971. #define ENDINPUT_PREC    -1    /* arbitrary number < lowest op. prec  */
  972. #define OR_PREC         1    /* operator precedence levels */
  973. #define XOR_PREC     2
  974. #define AND_PREC     3
  975. #define NEGATE_PREC     4
  976. #define PAREN_PREC     8    /* arbitrary number > highest op. prec */
  977. X
  978. /* lower bits of operator stack entry are code; higher are precedence */
  979. #define OPR_BITS    4
  980. #define OPR_MASK    ((1 << OPR_BITS) - 1)
  981. #define PREC(op)    ((op) >> OPR_BITS)
  982. #define OPCODE(op)    ((op) & OPR_MASK)
  983. #define MAKE_OPR(p, o)    (((p) << OPR_BITS) | (o))
  984. X
  985. #define MAX_OP        20    /* size of operand and operator stacks */
  986. X
  987. /*
  988. X * Globals:
  989. X */
  990. X
  991. typedef short OPERAND;        /* types for operand and operator stacks */
  992. typedef short OPERATOR;
  993. X
  994. X
  995. typedef struct {
  996. X    char    *name;        /* token spelling */
  997. X    short    type;        /* token type code */
  998. X    short    value;        /* associated value */
  999. X    } TOKEN;
  1000. X
  1001. /* token table - note that substrings must follow longer strings */
  1002. X
  1003. TOKEN token_tbl[] = {
  1004. X    "&&",    TK_BINARYOP,    OP_AND,        /* synonym for "&" */
  1005. X    "&",    TK_BINARYOP,    OP_AND,
  1006. X    "||",    TK_BINARYOP,    OP_OR,        /* synonym for "|" */
  1007. X    "|",    TK_BINARYOP,    OP_OR,
  1008. X    "!",    TK_UNARYOP,    OP_NEGATE,
  1009. X    "^",    TK_BINARYOP,    OP_XOR,
  1010. X    "(",    TK_LPAREN,    0,
  1011. X    ")",    TK_RPAREN,    0,
  1012. X    NULL,    TK_UNKNOWN,    0        /* must be last entry */
  1013. X    };
  1014. X
  1015. X
  1016. typedef struct {
  1017. X    short prec;        /* precedence */
  1018. X    short type;        /* token type (TK_UNARYOP or TK_BINARYOP) */
  1019. #ifdef PROTOS
  1020. X    OPERAND (*pfcn)(OPERAND *);    /* dispatch function */
  1021. #else
  1022. X    OPERAND (*pfcn)();        /* dispatch function */
  1023. #endif
  1024. X    } OPR;
  1025. X
  1026. /* operator table - entries must be in same order as OP_XXX */
  1027. X
  1028. #ifdef PROTOS
  1029. static OPERAND do_and(OPERAND *);
  1030. static OPERAND do_or(OPERAND *);
  1031. static OPERAND do_xor(OPERAND *);
  1032. static OPERAND do_negate(OPERAND *);
  1033. #else
  1034. static OPERAND do_and(), do_or(), do_xor(), do_negate();   /* dispatch fcns */
  1035. #endif
  1036. X
  1037. OPR opr_tbl[] = {
  1038. X    AND_PREC,    TK_BINARYOP,    do_and,        /* OP_AND    */
  1039. X    OR_PREC,    TK_BINARYOP,    do_or,        /* OP_OR    */
  1040. X    XOR_PREC,    TK_BINARYOP,    do_xor,        /* OP_XOR    */
  1041. X    NEGATE_PREC,    TK_UNARYOP,    do_negate    /* OP_NEGATE    */
  1042. X    };
  1043. X
  1044. X
  1045. /* set of tokens which each token may legally follow (in TK_XXX order) */
  1046. X
  1047. int where_ok[] = {
  1048. X    NEVER_OK                                      ,     /* TK_UNKNOWN    */
  1049. X    ST_OK         | LP_OK         | UO_OK | BO_OK ,     /* TK_IDENT    */
  1050. X    ST_OK         | LP_OK         | UO_OK | BO_OK ,     /* TK_LPAREN    */
  1051. X            ID_OK | LP_OK | RP_OK                 ,     /* TK_RPAREN    */
  1052. X    ST_OK         | LP_OK                 | BO_OK ,     /* TK_UNARYOP    */
  1053. X            ID_OK         | RP_OK                 ,     /* TK_BINARYOP    */
  1054. X    ST_OK | ID_OK         | RP_OK                    /* TK_ENDINPUT    */
  1055. X    };
  1056. X
  1057. X
  1058. /*
  1059. X * do_xxx - dispatch functions for operators
  1060. X */
  1061. X
  1062. #ifdef PROTOS
  1063. static OPERAND do_and(OPERAND *ptop)
  1064. #else
  1065. static OPERAND do_and(ptop)
  1066. X    OPERAND *ptop;
  1067. #endif
  1068. {
  1069. X    return ptop[0] & ptop[-1];
  1070. }
  1071. X
  1072. X
  1073. #ifdef PROTOS
  1074. static OPERAND do_or(OPERAND *ptop)
  1075. #else
  1076. static OPERAND do_or(ptop)
  1077. X    OPERAND *ptop;
  1078. #endif
  1079. {
  1080. X    return ptop[0] | ptop[-1];
  1081. }
  1082. X
  1083. X
  1084. #ifdef PROTOS
  1085. static OPERAND do_xor(OPERAND *ptop)
  1086. #else
  1087. static OPERAND do_xor(ptop)
  1088. X    OPERAND *ptop;
  1089. #endif
  1090. {
  1091. X    return ptop[0] ^ ptop[-1];
  1092. }
  1093. X
  1094. X
  1095. #ifdef PROTOS
  1096. static OPERAND do_negate(OPERAND *ptop)
  1097. #else
  1098. static OPERAND do_negate(ptop)
  1099. X    OPERAND *ptop;
  1100. #endif
  1101. {
  1102. X    return ! ptop[0];
  1103. }
  1104. X
  1105. X
  1106. /*
  1107. X * lookup_token - look up token in table; return pointer to table entry
  1108. X */
  1109. #ifdef PROTOS
  1110. static TOKEN *lookup_token(char *p)
  1111. #else
  1112. static TOKEN *lookup_token(p)
  1113. X    char *p;
  1114. #endif
  1115. {
  1116. X    TOKEN *ptok;
  1117. X
  1118. X    for (ptok = token_tbl;
  1119. X         ptok->name && strncmp(p, ptok->name, strlen(ptok->name));
  1120. X         ptok++)
  1121. X        ;
  1122. X
  1123. X    return ptok;
  1124. }
  1125. X
  1126. X
  1127. /*
  1128. X * next_token - fetch next token from input string; fill in its type and value
  1129. X * and return pointer to following character
  1130. X */
  1131. #ifdef PROTOS
  1132. static char *next_token(char *p,
  1133. X            int *ptype,
  1134. X            int *pvalue)
  1135. #else
  1136. static char *next_token(p, ptype, pvalue)
  1137. X    char *p;
  1138. X    int *ptype;
  1139. X    int *pvalue;
  1140. #endif
  1141. {
  1142. X    TOKEN *ptok;
  1143. X    char tokbuf[STRSIZ], *pb;
  1144. X
  1145. #define NT_RETURN(p, t, v) \
  1146. X    if (1) { *ptype = t; *pvalue = v; return p; } else
  1147. X
  1148. X    while (*p && isspace(*p))    /* skip whitespace */
  1149. X        p++;
  1150. X
  1151. X    if (*p == '\0')            /* end of input? */
  1152. X        NT_RETURN(p, TK_ENDINPUT, 0);
  1153. X
  1154. X    if (isalpha(*p)) {        /* identifier? */
  1155. X
  1156. X        pb = tokbuf;        /* make local copy and look up */
  1157. X        while (*p && (isalpha(*p) || isdigit(*p) || *p == '_'))
  1158. X            *pb++ = *p++;
  1159. X        *pb = '\0';
  1160. X
  1161. X        NT_RETURN(p, TK_IDENT, find_sym(tokbuf));
  1162. X    }
  1163. X
  1164. X    ptok = lookup_token(p);        /* other token */
  1165. X    NT_RETURN(p + (ptok->name ? strlen(ptok->name) : 1), ptok->type,
  1166. X        ptok->value);
  1167. }
  1168. X
  1169. X
  1170. /*
  1171. X * parse_expr - parses expression consisting of identifiers and logical
  1172. X * operators; return TRUE if expression is true (identifier defined => true);
  1173. X * FALSE if false; EXPR_ERR if syntax error in expression
  1174. X */
  1175. #ifdef PROTOS
  1176. int parse_expr(char *pbuf)
  1177. #else
  1178. int parse_expr(pbuf)
  1179. X    char *pbuf;
  1180. #endif
  1181. {
  1182. X    OPERAND opd_stack[MAX_OP];    /* operand stack - TRUE/FALSE values */
  1183. X    OPERATOR opr_stack[MAX_OP];    /* operator stack - precedence | op */
  1184. X    int value, token, plevel, prec, result, npop, opr, opd, prev_token, op;
  1185. X
  1186. X    plevel = 0;            /* paren nesting level */
  1187. X    opd = opr = -1;            /* indices of stack tops */
  1188. X    prev_token = TK_STARTINPUT;    /* to detect null expressions */
  1189. X
  1190. X    do {
  1191. X        pbuf = next_token(pbuf, &token, &value);
  1192. X
  1193. X        /* check that the current token may follow the previous one */
  1194. X        if (! IS_LEGAL(token, prev_token))
  1195. X            return EXPR_ERR;
  1196. X
  1197. X        switch(token) {
  1198. X
  1199. X        case TK_IDENT:        /* identifier => 1 if def, 0 if not */
  1200. X            opd_stack[++opd] = value != PP_SYM_UNDEF;
  1201. X            break;
  1202. X
  1203. X        case TK_LPAREN:        /* left paren - bump nesting level */
  1204. X            ++plevel;
  1205. X            break;
  1206. X
  1207. X        case TK_RPAREN:        /* right paren - decrement nesting */
  1208. X            if (--plevel < 0)
  1209. X                return EXPR_ERR;
  1210. X            break;
  1211. X
  1212. X        case TK_ENDINPUT:    /* end-of-input - treat as operator */
  1213. X            if (prev_token == TK_STARTINPUT)
  1214. X                return FALSE;    /* null expr => FALSE */
  1215. X            /* fall through */
  1216. X
  1217. X        case TK_UNARYOP:
  1218. X        case TK_BINARYOP:
  1219. X
  1220. X            /* get precedence of operator, adjusting for paren
  1221. X             * nesting (TK_ENDINPUT has the lowest precedence
  1222. X             * of all, to unwind operand/operator stacks at end)
  1223. X             */
  1224. X
  1225. X            prec = token == TK_ENDINPUT ? ENDINPUT_PREC :
  1226. X                (plevel * PAREN_PREC) + opr_tbl[value].prec;
  1227. X
  1228. X            /* pop (and perform) any equal- or higher-precedence
  1229. X             * operators on operator stack: extract operator,
  1230. X             * check for operand stack underflow, execute
  1231. X             * operator, adjust operand stack height and place
  1232. X             * result of operator on top
  1233. X             */
  1234. X
  1235. X            for ( ;
  1236. X                 opr >= 0 && PREC(opr_stack[opr]) >= prec;
  1237. X                 opr--) {
  1238. X                op = OPCODE(opr_stack[opr]);
  1239. X                npop = opr_tbl[op].type == TK_UNARYOP ? 0 : 1;
  1240. X                if (opd < npop)
  1241. X                    return EXPR_ERR;
  1242. X                result = (*opr_tbl[op].pfcn)(opd_stack + opd);
  1243. X                opd_stack[opd -= npop] = result;
  1244. X            }
  1245. X
  1246. X            /* push operator (if any) onto stack */
  1247. X
  1248. X            if (token != TK_ENDINPUT)
  1249. X                opr_stack[++opr] = MAKE_OPR(prec, value);
  1250. X
  1251. X            break;
  1252. X
  1253. X        default:        /* should never get here */
  1254. X            return EXPR_ERR;
  1255. X            break;
  1256. X
  1257. X        }
  1258. X
  1259. X        prev_token = token;
  1260. X
  1261. X    } while (token != TK_ENDINPUT);
  1262. X
  1263. X    /* done - check for dangling parens, and leftover operand/operators */
  1264. X
  1265. X    return plevel != 0 || opd != 0 || opr != -1 ?
  1266. X        EXPR_ERR :        /* leftover junk - return error */
  1267. X        opd_stack[0];        /* all OK - return final value */
  1268. }
  1269. X
  1270. SHAR_EOF
  1271. chmod 0666 exprpars.c ||
  1272. echo 'restore of exprpars.c failed'
  1273. Wc_c="`wc -c < 'exprpars.c'`"
  1274. test 8311 -eq "$Wc_c" ||
  1275.     echo 'exprpars.c: original size 8311, current size' "$Wc_c"
  1276. fi
  1277. # ============= moon91 ==============
  1278. if test -f 'moon91' -a X"$1" != X"-c"; then
  1279.     echo 'x - skipping moon91 (File already exists)'
  1280. else
  1281. echo 'x - extracting moon91 (Text)'
  1282. sed 's/^X//' << 'SHAR_EOF' > 'moon91' &&
  1283. # 1991 moon phase information for Pcal (from Old Farmer's Almanac)
  1284. #
  1285. # This file is to be called .moon91 (or moon91) for Un*x, moon91.dat for VMS;
  1286. # it is to live in the same directory as the .calendar file.
  1287. #
  1288. # Pcal originally used an extremely simplistic moon phase algorithm; this file
  1289. # (and the code to read it - cf. moonphas.c) was added to v4.0 to enable Pcal
  1290. # to interpolate the phase of the moon from the (presumably more accurate)
  1291. # information within.  More recently, the original moon phase algorithm was
  1292. # superseded by an astronomer-quality version (courtesy of Richard Dyson),
  1293. # largely obviating the need for this file; however, it will continue to be
  1294. # supported for the foreseeable future.
  1295. #
  1296. # Moon file syntax:
  1297. #
  1298. #    Entries in the moon file must conform to the following syntax:
  1299. #    
  1300. #      if -A flag (American date formats) specified:
  1301. #        <quarter> <month><sep><day> {<hour><sep><min>}
  1302. #    
  1303. #      if -E flag (European date formats) specified:
  1304. #        <quarter> <day><sep><month> {<hour><sep><min>}
  1305. #    
  1306. #    where
  1307. #    
  1308. #      <quarter> := "nm", "fq" or "1q", "fm", "lq" or "3q" (new
  1309. #                    moon, first quarter, full moon, last quarter)
  1310. #      <hour>    := number 0-23 (24-hour clock)
  1311. #      <min>     := number 0-59
  1312. #    
  1313. #    As in the date file, comments start with '#' and run through
  1314. #    end-of-line.  
  1315. #    
  1316. #    This file must contain entries for all quarter moons in the year,
  1317. #    in chronological order; if any errors (e.g., invalid date, date
  1318. #    or phase out of sequence, unrecognizable line) are encountered,
  1319. #    Pcal will revert to using its default algorithm.
  1320. #
  1321. # Dates and times below are for Boston (EST), in -A format; you may wish to
  1322. # adjust these dates and times to conform to your location.
  1323. X
  1324. 3q 01/07 13:37        # third quarter
  1325. nm 01/15 18:51        # new moon
  1326. 1q 01/23 09:23        # first quarter
  1327. fm 01/30 01:10        # full moon
  1328. X
  1329. 3q 02/06 08:53
  1330. nm 02/14 12:33
  1331. 1q 02/21 17:59
  1332. fm 02/28 13:26
  1333. X
  1334. 3q 03/08 05:33
  1335. nm 03/16 03:11
  1336. 1q 03/23 01:03
  1337. fm 03/30 02:18
  1338. X
  1339. 3q 04/07 01:47
  1340. nm 04/14 14:38
  1341. 1q 04/21 07:40
  1342. fm 04/28 16:00
  1343. X
  1344. 3q 05/06 19:48
  1345. nm 05/13 23:37
  1346. 1q 05/20 14:47
  1347. fm 05/28 06:38
  1348. X
  1349. 3q 06/05 10:31
  1350. nm 06/12 07:07
  1351. 1q 06/18 23:20
  1352. fm 06/26 22:00
  1353. X
  1354. 3q 07/04 21:51
  1355. nm 07/11 14:07
  1356. 1q 07/18 10:12
  1357. fm 07/26 13:25
  1358. X
  1359. 3q 08/03 06:27
  1360. nm 08/09 21:28
  1361. 1q 08/17 00:02
  1362. fm 08/25 04:08
  1363. X
  1364. 3q 09/01 13:17
  1365. nm 09/08 06:02
  1366. 1q 09/15 17:02
  1367. fm 09/23 17:41
  1368. 3q 09/30 19:31
  1369. X
  1370. nm 10/07 16:39
  1371. 1q 10/15 12:34
  1372. fm 10/23 06:09
  1373. 3q 10/30 02:12
  1374. X
  1375. nm 11/06 06:12
  1376. 1q 11/14 09:02
  1377. fm 11/21 17:58
  1378. 3q 11/28 10:22
  1379. X
  1380. nm 12/05 22:57
  1381. 1q 12/14 04:33
  1382. fm 12/21 05:24
  1383. 3q 12/27 20:56
  1384. SHAR_EOF
  1385. chmod 0666 moon91 ||
  1386. echo 'restore of moon91 failed'
  1387. Wc_c="`wc -c < 'moon91'`"
  1388. test 2504 -eq "$Wc_c" ||
  1389.     echo 'moon91: original size 2504, current size' "$Wc_c"
  1390. fi
  1391. true || echo 'restore of moonphas.c failed'
  1392. echo End of part 2, continue with part 3
  1393. exit 0
  1394. -- 
  1395.    ^      _   Joe Brownlee, Analysts International Corporation @ AT&T Bell Labs
  1396.   /_\  @ / `  471 E Broad St, Suite 2001, Columbus, Ohio 43215   (614) 860-7461
  1397.  /   \ | \_,  E-mail: jbr@cblph.att.com     Who pays attention to what _I_ say?
  1398.  "Scotty, we need warp speed in 3 minutes or we're all dead!" --- James T. Kirk
  1399.