home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / remind / patch04a / patch.04.A < prev   
Encoding:
Text File  |  1993-03-07  |  52.0 KB  |  1,801 lines

  1. Prereq: "03.00.03"
  2. *** ../patch3/version.h    Tue Feb  2 14:36:05 1993
  3. --- ./version.h    Mon Feb 15 13:24:00 1993
  4. ***************
  5. *** 9,12 ****
  6.   /*                                                             */
  7.   /***************************************************************/
  8.   
  9. ! #define VERSION "03.00.03"
  10. --- 9,12 ----
  11.   /*                                                             */
  12.   /***************************************************************/
  13.   
  14. ! #define VERSION "03.00.04"
  15. *** ../patch3/COPYRIGHT    Fri Jan  8 13:26:53 1993
  16. --- ./COPYRIGHT    Wed Mar  3 17:13:09 1993
  17. ***************
  18. *** 1,29 ****
  19.   THE REMIND COPYRIGHT
  20.   
  21. ! REMIND refers to the entire set of files and documentation in the
  22.   REMIND package.
  23.   
  24. ! REMIND is Copyright 1990, 1991, 1992, 1993 by David Skoll, except for
  25.   the file remind-all.sh, which is Copyright 1990 by Bill Aten.
  26.   
  27. ! You may use REMIND for free, and may freely distribute it, providing
  28.   you do not charge the recipients to whom you distribute REMIND.
  29.   
  30. ! You may modify REMIND.  However, you must clearly indicate such
  31.   modifications when you distribute REMIND, and must tell the recipients
  32.   of the modified version that it is modified.  Place that notice in the
  33.   WHATSNEW.xx file.
  34.   
  35. ! You may incorporate parts of REMIND into your own programs, providing
  36.   you do not sell these programs.  You must clearly indicate that the
  37.   parts of REMIND you have incorporated are Copyright 1990, 1991, 1992,
  38. ! 1993 by David Skoll.
  39.   
  40. ! I will attempt to support REMIND as much as possible.  However, you
  41.   use it at your own risk.  I am not responsible for any damages caused
  42.   by the use or misuse of REMIND.
  43.   
  44. ! If you wish to contribute ideas or money to help the production of
  45.   software like REMIND, you can reply to the address shown at the end of
  46.   this file.  Note that you are under no obligation to send me money.
  47.   If you don't donate, you have full rights to use REMIND just as if you
  48. --- 1,40 ----
  49.   THE REMIND COPYRIGHT
  50.   
  51. ! 1. REMIND refers to the entire set of files and documentation in the
  52.   REMIND package.
  53.   
  54. ! 2. REMIND is Copyright 1990, 1991, 1992, 1993 by David Skoll, except for
  55.   the file remind-all.sh, which is Copyright 1990 by Bill Aten.
  56.   
  57. ! 3. You may use REMIND for free, and may freely distribute it, providing
  58.   you do not charge the recipients to whom you distribute REMIND.
  59.   
  60. ! 4. This means that if you distribute REMIND:
  61. ! - You may not charge more than cost for distribution media.
  62. ! - If you run a BBS or network service, you cannot charge more than
  63. !   the regular access fee for REMIND.  That is, REMIND must be accessible
  64. !   at the basic BBS access rate, with no surcharge.
  65. ! - You may not charge users support fees for REMIND.
  66. ! - No other fees may be levied for REMIND.
  67. ! - You cannot use REMIND to solicit donations.
  68. ! 5. You may modify REMIND.  However, you must clearly indicate such
  69.   modifications when you distribute REMIND, and must tell the recipients
  70.   of the modified version that it is modified.  Place that notice in the
  71.   WHATSNEW.xx file.
  72.   
  73. ! 6. You may incorporate parts of REMIND into your own programs, providing
  74.   you do not sell these programs.  You must clearly indicate that the
  75.   parts of REMIND you have incorporated are Copyright 1990, 1991, 1992,
  76. ! 1993 by David Skoll.  These programs can be distributed according to
  77. ! the terms of paragraphs 3 and 4.
  78.   
  79. ! 7. I will attempt to support REMIND as much as possible.  However, you
  80.   use it at your own risk.  I am not responsible for any damages caused
  81.   by the use or misuse of REMIND.
  82.   
  83. ! 8. If you wish to contribute ideas or money to help the production of
  84.   software like REMIND, you can reply to the address shown at the end of
  85.   this file.  Note that you are under no obligation to send me money.
  86.   If you don't donate, you have full rights to use REMIND just as if you
  87. ***************
  88. *** 32,37 ****
  89. --- 43,52 ----
  90.   of software like REMIND.  Should you wish to donate, the suggested
  91.   amount is $18.00 (Canadian)
  92.   
  93. + If you wish to incorporate Remind into a commercial product, or to
  94. + charge support fees for products incorporating Remind, contact
  95. + me for licensing arrangements.
  96.   ACKNOWLEDGEMENTS:
  97.   
  98.   I would like to thank the following people:
  99. ***************
  100. *** 52,57 ****
  101. --- 67,83 ----
  102.   Dave Wolfe <dwolfe@pffft.sps.mot.com> and Raphael Manfredi
  103.   <ram@eiffel.com> for noticing bugs and sending me fixes.
  104.   
  105. + Dave Rickel and George M. Sipe for sample reminders and holidays.
  106. + Michael Salmon for ISO encoding of PostScript output.
  107. + Darrel Hankerson for helping me provide some OS/2 support.  Sorry
  108. + it's not complete, Darrel!
  109. + Phillipp Slusallek for suggesting the -k option.
  110. + All of the language translators whose names are listed in lang.h
  111.   Timo Salmi, Keith Petersen, Bill Davidsen and Kent Landfield for
  112.   maintaining the uwasa and SIMTEL archives, and comp.binaries.ibm.pc
  113.   and comp.sources.misc in the face of a flurry of updates to REMIND.
  114. ***************
  115. *** 64,72 ****
  116.   
  117.   --
  118.   David F. Skoll <dfs@doe.carleton.ca>
  119. ! 4-317 LeBreton Street South
  120. ! Ottawa, Ontario K1S 4L4
  121.   CANADA
  122.   
  123. ! Tel. (613) 567-3662
  124.   
  125. --- 90,98 ----
  126.   
  127.   --
  128.   David F. Skoll <dfs@doe.carleton.ca>
  129. ! 986 Eiffel Avenue
  130. ! Ottawa, Ontario K2C 0J2
  131.   CANADA
  132.   
  133. ! Tel. (613) 225-8687
  134.   
  135. *** ../patch3/MANIFEST.DOS    Mon Jan 25 15:40:01 1993
  136. --- ./MANIFEST.DOS    Mon Mar  1 16:52:01 1993
  137. ***************
  138. *** 4,14 ****
  139. --- 4,16 ----
  140.   defs.rem
  141.   dorem.c
  142.   dosubst.c
  143. + dutch.h
  144.   english.h
  145.   err.h
  146.   expr.c
  147.   expr.h
  148.   files.c
  149. + finnish.h
  150.   funcs.c
  151.   german.h
  152.   globals.c
  153. ***************
  154. *** 41,46 ****
  155. --- 43,49 ----
  156.   remind-a.sh
  157.   remind.1
  158.   remind.def
  159. + sort.c
  160.   test-rem
  161.   test.cmp
  162.   test.rem
  163. *** ../patch3/MANIFEST.UNX    Mon Feb  8 14:26:43 1993
  164. --- ./MANIFEST.UNX    Mon Mar  1 16:51:53 1993
  165. ***************
  166. *** 11,21 ****
  167. --- 11,23 ----
  168.   defs.rem
  169.   dorem.c
  170.   dosubst.c
  171. + dutch.h
  172.   english.h
  173.   err.h
  174.   expr.c
  175.   expr.h
  176.   files.c
  177. + finnish.h
  178.   funcs.c
  179.   german.h
  180.   globals.c
  181. ***************
  182. *** 42,47 ****
  183. --- 44,50 ----
  184.   remind-all.sh
  185.   remind.1
  186.   remind.def
  187. + sort.c
  188.   test-rem
  189.   test.cmp
  190.   test.rem
  191. *** ../patch3/Makefile    Tue Feb  2 14:36:58 1993
  192. --- ./Makefile    Tue Mar  2 11:03:25 1993
  193. ***************
  194. *** 13,21 ****
  195.   # Uncomment the next line if you want to use gcc instead of default compiler
  196.   CC= gcc
  197.   
  198. ! # Put any additional flags for the C compiler here
  199.   CFLAGS= -O -ansi
  200.   CDEFS=
  201.   
  202.   #### INSTALLATION LOCATIONS ####
  203.   # Note that I use 'cp' rather than 'install' for improved portability.
  204. --- 13,22 ----
  205.   # Uncomment the next line if you want to use gcc instead of default compiler
  206.   CC= gcc
  207.   
  208. ! # Put any additional flags for the C compiler or linker here
  209.   CFLAGS= -O -ansi
  210.   CDEFS=
  211. + LDFLAGS=
  212.   
  213.   #### INSTALLATION LOCATIONS ####
  214.   # Note that I use 'cp' rather than 'install' for improved portability.
  215. ***************
  216. *** 45,62 ****
  217.   # YOU SHOULDN'T EDIT ANYTHING BELOW HERE.  You may want to change some things
  218.   # in config.h; then, you should be able to type 'make'.
  219.   #-----------------------------------------------------------------------------
  220. ! VERSION= 03.00.03
  221.   
  222. ! HDRS= config.h err.h expr.h globals.h protos.h types.h version.h lang.h
  223.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  224.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  225. ! main.c omit.c queue.c token.c trigger.c userfns.c utils.c var.c
  226.   
  227.   MANIFEST= README.UNIX README.DOS COPYRIGHT $(HDRS) $(SRCS) Makefile rem rem.1 \
  228.   remind.1 remind-all.csh remind-all.sh test.rem test-rem test.cmp makefile.tc \
  229.   makefile.msc lnk.msc lnk.tc MANIFEST.UNX MANIFEST.DOS WHATSNEW.30 kall kall.1 \
  230.   defs.rem README.OS2 makefile.os2 rem2ps.c rem2ps.h remind.def rem2ps.1 \
  231. ! lang.h english.h german.h tstlang.rem
  232.   
  233.   OBJS= $(SRCS:.c=.o)
  234.   
  235. --- 46,66 ----
  236.   # YOU SHOULDN'T EDIT ANYTHING BELOW HERE.  You may want to change some things
  237.   # in config.h; then, you should be able to type 'make'.
  238.   #-----------------------------------------------------------------------------
  239. ! VERSION= 03.00.04
  240.   
  241. ! HDRS= config.h err.h expr.h globals.h protos.h types.h version.h \
  242. ! lang.h english.h german.h dutch.h finnish.h
  243.   STDHDRS= config.h types.h protos.h globals.h err.h lang.h
  244.   SRCS= calendar.c dorem.c dosubst.c expr.c files.c funcs.c globals.c init.c \
  245. ! main.c omit.c sort.c queue.c token.c trigger.c userfns.c utils.c var.c
  246.   
  247.   MANIFEST= README.UNIX README.DOS COPYRIGHT $(HDRS) $(SRCS) Makefile rem rem.1 \
  248.   remind.1 remind-all.csh remind-all.sh test.rem test-rem test.cmp makefile.tc \
  249.   makefile.msc lnk.msc lnk.tc MANIFEST.UNX MANIFEST.DOS WHATSNEW.30 kall kall.1 \
  250.   defs.rem README.OS2 makefile.os2 rem2ps.c rem2ps.h remind.def rem2ps.1 \
  251. ! tstlang.rem
  252.   
  253.   OBJS= $(SRCS:.c=.o)
  254.   
  255. ***************
  256. *** 66,75 ****
  257.       $(CC) $(UNIX) $(SYSV) -c -o $*.o $(CFLAGS) $(CDEFS) $*.c
  258.   
  259.   rem2ps: rem2ps.o
  260. !     $(CC) -o rem2ps rem2ps.o
  261.   
  262.   remind: $(OBJS)
  263. !     $(CC) -o remind $(OBJS)
  264.   
  265.   clean:
  266.       rm -f *.o *~
  267. --- 70,79 ----
  268.       $(CC) $(UNIX) $(SYSV) -c -o $*.o $(CFLAGS) $(CDEFS) $*.c
  269.   
  270.   rem2ps: rem2ps.o
  271. !     $(CC) $(LDFLAGS) -o rem2ps rem2ps.o
  272.   
  273.   remind: $(OBJS)
  274. !     $(CC) $(LDFLAGS) -o remind $(OBJS)
  275.   
  276.   clean:
  277.       rm -f *.o *~
  278. ***************
  279. *** 91,96 ****
  280. --- 95,101 ----
  281.   init.o: init.c $(STDHDRS) expr.h version.h
  282.   main.o: main.c $(STDHDRS) expr.h
  283.   omit.o: omit.c $(STDHDRS)
  284. + sort.o: sort.c $(STDHDRS)
  285.   queue.o: queue.c $(STDHDRS)
  286.   token.o: token.c $(STDHDRS)
  287.   trigger.o: trigger.c $(STDHDRS) expr.h
  288. ***************
  289. *** 99,106 ****
  290.   var.o: var.c $(STDHDRS) expr.h
  291.   
  292.   tarZ:
  293. !     tar cvf remind-3.0.3.tar $(MANIFEST)
  294. !     compress -v remind-3.0.3.tar
  295.   
  296.   shar:
  297.       shar -x -n"Remind $(VERSION)" -l45 -o./Shar $(MANIFEST)
  298. --- 104,111 ----
  299.   var.o: var.c $(STDHDRS) expr.h
  300.   
  301.   tarZ:
  302. !     tar cvf remind-3.0.4.tar $(MANIFEST)
  303. !     compress -v remind-3.0.4.tar
  304.   
  305.   shar:
  306.       shar -x -n"Remind $(VERSION)" -l45 -o./Shar $(MANIFEST)
  307. *** ../patch3/README.DOS    Fri Jan 22 11:08:58 1993
  308. --- ./README.DOS    Wed Mar  3 17:15:06 1993
  309. ***************
  310. *** 40,48 ****
  311.   
  312.   --
  313.   David F. Skoll <dfs@doe.carleton.ca>
  314. ! 4-317 LeBreton Street South
  315. ! Ottawa, Ontario K1S 4L4
  316.   CANADA
  317.   
  318. ! Tel. (613) 567-3662
  319.   
  320. --- 40,48 ----
  321.   
  322.   --
  323.   David F. Skoll <dfs@doe.carleton.ca>
  324. ! 986 Eiffel Avenue
  325. ! Ottawa, Ontario K2C 0J2
  326.   CANADA
  327.   
  328. ! Tel. (613) 225-8687
  329.   
  330. *** ../patch3/README.OS2    Fri Jan 22 11:08:54 1993
  331. --- ./README.OS2    Wed Mar  3 17:14:49 1993
  332. ***************
  333. *** 48,56 ****
  334.   
  335.   --
  336.   David F. Skoll <dfs@doe.carleton.ca>
  337. ! 4-317 LeBreton Street South
  338. ! Ottawa, Ontario K1S 4L4
  339.   CANADA
  340.   
  341. ! Tel. (613) 567-3662
  342.   
  343. --- 48,56 ----
  344.   
  345.   --
  346.   David F. Skoll <dfs@doe.carleton.ca>
  347. ! 986 Eiffel Avenue
  348. ! Ottawa, Ontario K2C 0J2
  349.   CANADA
  350.   
  351. ! Tel. (613) 225-8687
  352.   
  353. *** ../patch3/README.UNIX    Fri Jan 29 13:43:01 1993
  354. --- ./README.UNIX    Wed Mar  3 17:14:29 1993
  355. ***************
  356. *** 79,86 ****
  357.   
  358.   --
  359.   David F. Skoll <dfs@doe.carleton.ca>
  360. ! 4-317 LeBreton Street South
  361. ! Ottawa, Ontario K1S 4L4
  362.   CANADA
  363.   
  364. ! Tel. (613) 567-3662
  365. --- 79,86 ----
  366.   
  367.   --
  368.   David F. Skoll <dfs@doe.carleton.ca>
  369. ! 986 Eiffel Avenue
  370. ! Ottawa, Ontario K2C 0J2
  371.   CANADA
  372.   
  373. ! Tel. (613) 225-8687
  374. *** ../patch3/WHATSNEW.30    Mon Feb  8 14:43:57 1993
  375. --- ./WHATSNEW.30    Wed Mar  3 17:16:40 1993
  376. ***************
  377. *** 1,9 ****
  378.   CHANGES TO REMIND
  379.   
  380. ! *** PLEASE NOTE:  AFTER 24 FEBRUARY, 1993, MY NEW ADDRESS WILL BE:
  381. ! 986 Eiffel Avenue,
  382. ! Ottawa, Ontario K2C 0J2
  383. ! Canada
  384.   
  385.   * Version 3.0 Patch 3
  386.   
  387. --- 1,63 ----
  388.   CHANGES TO REMIND
  389.   
  390. ! * Version 3.0 Patch 4
  391. ! - Added the -g option - this sorts reminders by date/time before
  392. !   issuing them.  (You can see I'm running out of letters to
  393. !   name options!)  This feature was suggested by George M. Sipe,
  394. !   Paul D. Smith, and Francois Pinard.
  395. ! - Added the "args()" and "dosubst()" built-in functions - see the
  396. !   man page for details.
  397. ! - Added more support for the ISO 8859-1 character set, and
  398. !   modified the german.h file to take advantage of this, thanks
  399. !   to Robert Joop.
  400. ! - Allowed any character to be used as date and time separator
  401. !   characters (not just "/-:.")
  402. ! - Added support for the Dutch and Finnish languages, thanks to
  403. !   Willem Kasdorp and Mikko Silvonen.  (Anyone care to contribute
  404. !   French?  Italian?  Spanish?)
  405. ! - Made Remind issue a warning if you try to redefine a built-in
  406. !   function.  This warning is disabled in 'Hush' mode.
  407. ! - Added the SCANFROM clause to the REM command.  This allows reasonably
  408. !   safe moveable OMITs such as the Labour Day example in the manual.
  409. ! - Added more examples to the defs.rem file, and cleaned up some old
  410. !   examples.  Note that there are now safe moveable holidays for most
  411. !   U.S. holidays provided in the defs.rem file.
  412. ! - Added the '-k' option, which allows MSG-type reminders to be passed
  413. !   to any system command.  (Idea and patch courtesy of Philipp Slusallek.)
  414. ! - Allowed selection of ':' or '.' as time separator characters at
  415. !   compile-time.
  416. ! - Edited the COPYRIGHT file to clarify the rules.  Please read them.
  417. ! - Removed hard-coding of "am" and "pm" and placed them in language-specific
  418. !   header files as #defines L_AM and L_PM
  419. ! - Fixed a bug in the FindToken() routine which had, through sheer luck,
  420. !   never been activated until the SCANFROM clause was added!
  421. ! - Fixed the UNTIL clause to check for a valid expiry date.
  422. ! - Removed identifiers in the C source beginning with "_" to conform
  423. !   to ANSI practice.
  424. !   
  425. ! - Fixed a bug in the -u option which resulted in environment variables
  426. !   SHELL and USER not being set correctly.  Also made -u set the LOGNAME
  427. !   environment variable.
  428. ! - Fixed a couple of typos in the man page; added LDFLAGS to the
  429. !   Makefile.  (Thanks to Dave Wolfe.)
  430. ! - Put my new mailing address in the README files.
  431.   
  432.   * Version 3.0 Patch 3
  433.   
  434. *** ../patch3/calendar.c    Fri Feb  5 14:47:40 1993
  435. --- ./calendar.c    Mon Mar  1 13:00:46 1993
  436. ***************
  437. *** 24,31 ****
  438.   #include "err.h"
  439.   
  440.   /* Data structures used by the calendar */
  441. ! typedef struct _cal_entry {
  442. !    struct _cal_entry *next;
  443.      char *text;
  444.      char *pos;
  445.      int time;
  446. --- 24,31 ----
  447.   #include "err.h"
  448.   
  449.   /* Data structures used by the calendar */
  450. ! typedef struct cal_entry {
  451. !    struct cal_entry *next;
  452.      char *text;
  453.      char *pos;
  454.      int time;
  455. ***************
  456. *** 328,334 ****
  457.      int i;
  458.   
  459.      for (i=0; i<d; i++) putchar(pad);
  460. !    printf("%s", s);
  461.      for (i=d+len; i<width; i++) putchar(pad);
  462.   }
  463.   
  464. --- 328,336 ----
  465.      int i;
  466.   
  467.      for (i=0; i<d; i++) putchar(pad);
  468. !    for (i=0; i<width; i++) {
  469. !       if (*s) putchar(*s++); else break;
  470. !    }
  471.      for (i=d+len; i<width; i++) putchar(pad);
  472.   }
  473.   
  474. ***************
  475. *** 625,631 ****
  476.      if (trig.typ == NO_TYPE) return E_EOLN;
  477.      if (trig.typ == SAT_TYPE) return DoSatRemind(&trig, &tim, p);
  478.      /* Calculate the trigger date */
  479. !    jul = ComputeTrigger(JulianToday, &trig, &r);
  480.      if (r) return r;
  481.   
  482.      /* If trigger date == today, add it to the current entry */   
  483. --- 627,633 ----
  484.      if (trig.typ == NO_TYPE) return E_EOLN;
  485.      if (trig.typ == SAT_TYPE) return DoSatRemind(&trig, &tim, p);
  486.      /* Calculate the trigger date */
  487. !    jul = ComputeTrigger(trig.scanfrom, &trig, &r);
  488.      if (r) return r;
  489.   
  490.      /* If trigger date == today, add it to the current entry */   
  491. ***************
  492. *** 765,771 ****
  493.           if (h == 0) hh=12;
  494.           else if (h > 12) hh=h-12;
  495.           else hh=h;
  496. !         sprintf(out, "%2d:%02d%s ", hh, min, (h>=12) ? "pm" : "am");
  497.            }
  498.        break;
  499.   
  500. --- 767,773 ----
  501.           if (h == 0) hh=12;
  502.           else if (h > 12) hh=h-12;
  503.           else hh=h;
  504. !         sprintf(out, "%2d%c%02d%s ", hh, TIMESEP, min, (h>=12) ? L_PM : L_AM);
  505.            }
  506.        break;
  507.   
  508. ***************
  509. *** 774,780 ****
  510.        else {
  511.           h = tim / 60;
  512.           min = tim % 60;
  513. !         sprintf(out, "%02d:%02d ", h, min);
  514.            }
  515.        break;
  516.      }
  517. --- 776,782 ----
  518.        else {
  519.           h = tim / 60;
  520.           min = tim % 60;
  521. !         sprintf(out, "%02d%c%02d ", h, TIMESEP, min);
  522.            }
  523.        break;
  524.      }
  525. *** ../patch3/config.h    Mon Feb  1 12:21:15 1993
  526. --- ./config.h    Tue Mar  2 12:12:49 1993
  527. ***************
  528. *** 19,24 ****
  529. --- 19,37 ----
  530.   /* #define DATESEP '-' */
  531.   
  532.   /*---------------------------------------------------------------------*/
  533. + /* TIMESEP:  The default time separator.  North American usage is ':'; */
  534. + /* others may prefer '.'.                                              */
  535. + /*---------------------------------------------------------------------*/
  536. + #define TIMESEP ':'
  537. + /* #define TIMESEP '.' */
  538. + /*---------------------------------------------------------------------*/
  539. + /* ISOLATIN1: uncomment the following line if your system uses the     */
  540. + /* ISO 8859-1 character set instead of ASCII.                          */
  541. + /*---------------------------------------------------------------------*/
  542. + /* #define ISOLATIN1 1 */
  543. + /*---------------------------------------------------------------------*/
  544.   /* WANT_U_OPTION: Comment out the next define to permanently disable   */
  545.   /* the -u option.  If you do this, however, remind-all.[c]sh will not  */
  546.   /* work.                                                               */
  547. *** ../patch3/defs.rem    Fri Jan  8 13:26:17 1993
  548. --- ./defs.rem    Fri Mar  5 11:46:11 1993
  549. ***************
  550. *** 3,15 ****
  551.   # DEFS.REM
  552.   #
  553.   # This file is a reminder script, which contains a few handy definitions.
  554. ! # Cut and paste as desired!
  555.   #
  556.   # This file is part of REMIND.
  557.   # Copyright (C) 1992, 1993 by David F. Skoll
  558.   #
  559.   # ---------------------------------------------------------------------------
  560.   
  561.   # It's handy to have symbolic constants for weekdays and month names
  562.   SET Sunday    0
  563.   SET Monday    1
  564. --- 3,28 ----
  565.   # DEFS.REM
  566.   #
  567.   # This file is a reminder script, which contains a few handy definitions.
  568. ! # Cut and paste as desired!  Also, near the end, there are a bunch of holiday
  569. ! # definitions for the U.S.
  570.   #
  571. + # Some examples provided by George M. Sipe <gsipe@pyratl.ga.pyramid.com>
  572. + #
  573. + # U.S. holidays provided by Dave Rickel <drickel@sjc.mentorg.com>
  574. + #
  575.   # This file is part of REMIND.
  576.   # Copyright (C) 1992, 1993 by David F. Skoll
  577.   #
  578.   # ---------------------------------------------------------------------------
  579.   
  580. + # Bombproofing
  581. + RUN OFF
  582. + IF version() < "03.00.04"
  583. +    ERRMSG This file requires at least version 03.00.04 of Remind.%
  584. +    ERRMSG This version is [version()].
  585. +    EXIT
  586. + ENDIF
  587.   # It's handy to have symbolic constants for weekdays and month names
  588.   SET Sunday    0
  589.   SET Monday    1
  590. ***************
  591. *** 19,24 ****
  592. --- 32,45 ----
  593.   SET Friday    5
  594.   SET Saturday  6
  595.   
  596. + SET Sun 0
  597. + SET Mon 1
  598. + SET Tue 2
  599. + SET Wed 3
  600. + SET Thu 4
  601. + SET Fri 5
  602. + SET Sat 6
  603.   # ---------------------------------------------------------------------------
  604.   
  605.   SET Jan 1
  606. ***************
  607. *** 53,67 ****
  608.   
  609.   # A function which, given a time, returns a string in "AM/PM" format.
  610.   # Unfortunately, has a leading zero.  Example call:
  611. ! #    set a ampm(now())
  612.   
  613. ! FSET ampm(x) iif(x<1:00, x+12*60+"am", \
  614. !              iif(x<12:00, x+"am", \
  615. !                  iif(x<13:00, x+"pm", x-12*60+"pm")))
  616.   
  617.   # A function which knocks off a single leading zero from a string
  618.   
  619. ! FSET no_lz(s) iif(substr(s, 1, 1)=="0", substr(s, 2), s)
  620.   
  621.   # ---------------------------------------------------------------------------
  622.   
  623. --- 74,88 ----
  624.   
  625.   # A function which, given a time, returns a string in "AM/PM" format.
  626.   # Unfortunately, has a leading zero.  Example call:
  627. ! #    set a _am_pm(now())
  628.   
  629. ! FSET _am_pm(tm)    IIF (tm<1:00, tm+12*60+"am", \
  630. !             IIF (tm<12:00, tm+"am", \
  631. !                 IIF (tm<13:00, tm+"pm", tm-12*60+"pm")))
  632.   
  633.   # A function which knocks off a single leading zero from a string
  634.   
  635. ! FSET _no_lz(s) IIF(SUBSTR(s, 1, 1)=="0", SUBSTR(s, 2), s)
  636.   
  637.   # ---------------------------------------------------------------------------
  638.   
  639. ***************
  640. *** 76,110 ****
  641.   # dependent upon the current date, it's tricky and results may not be
  642.   # what you expect.  You should try to make sure that the OMIT context
  643.   # "near" any current reminders will not change during a calendar run.
  644.   
  645. ! set thisyear year(today())
  646.   
  647. ! OMIT 4 July MSG The real thing!
  648.   
  649. ! # Check for Saturday case
  650. ! if wkdaynum(date(thisyear, 7, 4)) == Saturday
  651. !    OMIT 3 July [thisyear] MSG 4 July (observed)
  652. ! endif
  653.   
  654. ! # Check for Sunday case
  655. ! if wkdaynum(date(thisyear, 7, 4)) == Sunday
  656. !    OMIT 5 July [thisyear] MSG 4 July (observed)
  657. ! endif
  658.   
  659. ! # ---------------------------------------------------------------------------
  660.   
  661. ! # Here's the since() function - quite useful for remembering how
  662. ! # old kids are:
  663.   
  664. ! fset since(x) ord(year(trigdate())-x)
  665.   
  666. ! # Here's an example of how to use it:
  667. ! REM 1 Nov ++12 MSG %"Dean's [since(1984)] birthday%" is %b.
  668.   
  669.   # ---------------------------------------------------------------------------
  670.   
  671.   # How do we get a double-quote into a string????  Only works on ASCII
  672.   # machines
  673.   
  674.   set example "The last word of this sentence is in " \
  675. !     + char(34) + "quotes." + char(34)
  676. --- 97,299 ----
  677.   # dependent upon the current date, it's tricky and results may not be
  678.   # what you expect.  You should try to make sure that the OMIT context
  679.   # "near" any current reminders will not change during a calendar run.
  680. + # The SCANFROM clause should help make these OMITs very safe.
  681.   
  682. ! # Convenient function and variable for safe moveable OMITs
  683. ! FSET _safe(x) trigger(today()-x)
  684. ! # Usually, a safety margin of 7 is sufficient.  We can stick it in a
  685. ! # variable.  Note that you must NOT preserve this variable, because
  686. ! # it must be updated as today() is incremented.
  687. ! SET safe7 _safe(7)
  688.   
  689. ! # The usual holiday
  690. ! OMIT 4 July MSG Independence day
  691.   
  692. ! # Calculate a "potential" advanced holiday
  693. ! REM 3 July SCANFROM [safe7] SATISFY 1
  694.   
  695. ! # But only trigger it if it falls on a Friday
  696. ! IF WKDAYNUM(TRIGDATE()) == 5
  697. !    OMIT [TRIGGER(TRIGDATE())] MSG Independence day (observed)
  698. ! ENDIF
  699.   
  700. ! # Calculate a "potential" delayed holiday
  701. ! REM 5 July SCANFROM [safe7] SATISFY 1
  702.   
  703. ! # But only trigger it if it falls on a Monday
  704. ! IF WKDAYNUM(TRIGDATE()) == 1
  705. !    OMIT [TRIGGER(TRIGDATE())] MSG Independence day (observed)
  706. ! ENDIF
  707.   
  708. ! # ---------------------------------------------------------------------------
  709. ! # Function to calculate number of years since a given year or
  710. ! # number of months since a given month and year...  useful for kids'
  711. ! # birthdays.
  712.   
  713. ! FSET _yr_num(yr)    ORD(YEAR(TRIGDATE()) - yr)
  714. ! FSET _mo_num(mo, yr)    ORD(12 * (YEAR(TRIGDATE()) - yr) + \
  715. !                 MONNUM(TRIGDATE()) - mo)
  716.   
  717. + # Here's an example of how to use them:
  718. + REM 1 Nov ++12 MSG %"Dean's [_yr_num(1984)] birthday%" is %b.
  719. + REM 1 MSG Dean's [_mo_num(11, 1984)] 'monthly' anniversary
  720.   # ---------------------------------------------------------------------------
  721.   
  722.   # How do we get a double-quote into a string????  Only works on ASCII
  723.   # machines
  724.   
  725. + set Quote char(34)
  726.   set example "The last word of this sentence is in " \
  727. !     + Quote + "quotes." + Quote
  728. ! # ---------------------------------------------------------------------------
  729. ! # Function to send mail via elm's "fastmail" (by George M. Sipe)...
  730. ! #FSET _mail(from, subj)    "mailx -s " + \
  731. ! #                Quote + from + " : " + subj + Quote \
  732. ! #                getenv("LOGNAME") + " < /dev/null 1>&0"
  733. ! FSET _mail(from, subj)    "fastmail -f " + \
  734. !                 Quote + from + Quote + \
  735. !                 " -s " + Quote + subj + Quote + \
  736. !                 " /dev/null " + getenv("LOGNAME")
  737. ! # Example of use of _mail
  738. ! REM Feb 14 ONCE RUN [_mail("Someone you know", "Valentine's day is today")]
  739. ! # ---------------------------------------------------------------------------
  740. ! # A meeting on the first Monday of every month which is moved to the
  741. ! # second Monday in the event of a holiday.
  742. ! # First, the normal meeting.  However, the SKIP keyword means this
  743. ! # one won't be triggered if the first Monday is a holiday
  744. ! REM Mon 1 SKIP MSG Meeting
  745. ! # Now, calculate the "potential" delayed meeting
  746. ! REM Mon 8 SATISFY 1
  747. ! # But only actually trigger the delayed meeting if the previous
  748. ! # Monday was a holiday
  749. ! IF ISOMITTED(TRIGDATE()-7)
  750. !    REM [TRIGGER(TRIGDATE())] MSG Delayed meeting
  751. ! ENDIF
  752. ! # ---------------------------------------------------------------------------
  753. ! #
  754. ! # A very complicated reminder sent in by a Remind user.
  755. ! # This person gets paid every two weeks, starting from 8 January 1993.
  756. ! # If a pay date occurs before the twelfth of a month, then that
  757. ! # he pays his mortgage on that pay date.  Otherwise, he pays the mortgage
  758. ! # on the previous pay date.  Furthermore, he has to schedule his
  759. ! # mortgage payment six days before it is due.  He wants to be reminded
  760. ! # a further four days before the scheduling deadline.  He also
  761. ! # wants to be mailed a notice two weeks before the scheduling deadline.
  762. ! # Here's the solution - if you can follow this, consider yourself a
  763. ! # Remind programmer extraordinaire!
  764. ! # A function to determine whether or not a pay-date is a mortgage-date.
  765. ! FSET _IsMortDate(x) DAY(x) < 12 || (DAY(x+14) >= 12 && DAY(x+14) <= 14)
  766. ! # Paydays - for reference
  767. ! REM 8 Jan 1993 *14 MSG Payday
  768. ! # Calculate the mortgage payment six days ahead of time.  Note that this
  769. ! # is done "implicitly" by subtracting 6 from the starting date - we start
  770. ! # on 2 Jan rather than 8 Jan.  We add 6 to TRIGDATE() in _IsMortDate to
  771. ! # compensate.
  772. ! REM 2 Jan 1993 *14 SATISFY _IsMortDate(TRIGDATE()+6)
  773. ! REM [TRIGGER(TRIGDATE())] ++4 MSG %"Schedule mortgage payment%" for %a.
  774. ! # Now the mail reminder two weeks before the payment date - because two
  775. ! # weeks before a payment date is also a payment date, no pre-compensation
  776. ! # in the starting date of 8 Jan is necessary - convince yourself of this!
  777. ! # This uses the _mail() function defined earlier.
  778. ! REM 8 Jan 1993 *14 SATISFY _IsMortDate(TRIGDATE()+14)
  779. ! REM [TRIGGER(TRIGDATE())] ONCE RUN [_mail("Decatur Federal", \
  780. !     "Pay mortgage by the " + ORD(DAY(TRIGDATE()+14)))]
  781. ! # Make an entry on the calendar when the mortgage should be paid
  782. ! REM 8 Jan 1993 *14 SATISFY _IsMortDate(TRIGDATE())
  783. ! REM [TRIGGER(TRIGDATE())] CAL Mortgage payment
  784. ! # ---------------------------------------------------------------------------
  785. ! #
  786. ! # The following holidays were provided by Dave Rickel
  787. ! # Modified by D. Skoll to give safe OMITs for moveable holidays
  788. ! set thisyear year(today())
  789. ! if ! defined("eyear")
  790. !     set eyear 0
  791. ! endif
  792. ! # Note:  A shorter way to set a default value for eyear is the following:
  793. ! # set eyear value("eyear", 0) -- David S.
  794. ! if eyear != thisyear
  795. !     set a thisyear % 19
  796. !     set b thisyear / 100
  797. !     set c thisyear % 100
  798. !     set d b / 4
  799. !     set e b % 4
  800. !     set f (b + 8) % 25
  801. !     set g (b - f + 1) / 3
  802. !     set h (19 * a + b - d - g + 15) % 30
  803. !     set i c / 4
  804. !     set k c % 4
  805. !     set l (32 + e + e + i + i - h - k) % 7
  806. !     set m (a + 11 * h + 22 * l) / 451
  807. !     set a h + l - 7 * m + 114
  808. !     set n a / 31
  809. !     set p a % 31 + 1
  810. !     set eyear thisyear
  811. !     set emon mon(n)
  812. !     set eday p
  813. !     preserve eyear emon eday
  814. ! endif
  815. ! REM [emon] [eday] MSG Easter Sunday.
  816. ! # Some holidays are omitted, some are not.  You may want to change
  817. ! # which ones are omitted - use the general forms shown below.
  818. ! # You'll need the safe7 variable from way up above.
  819. ! REM Monday Feb 15 SCANFROM [safe7] SATISFY 1
  820. ! OMIT [trigger(trigdate())] MSG President's Day.
  821. ! REM Saturday Mar 31 MSG Daylight Savings Time begins tonight.
  822. ! REM Mon Tue Wed Thu Fri Sat 15 April MSG Income Tax Day.
  823. ! REM Saturday May 1 MSG Kentucky Derby Day.
  824. ! REM Sunday May 8 MSG Mother's Day.
  825. ! REM Monday May 25 SCANFROM [safe7] SATISFY 1
  826. ! OMIT [trigger(trigdate())] MSG Memorial Day.
  827. ! REM Sunday June 15 MSG Father's Day.
  828. ! REM Monday Sep 1 SCANFROM [safe7] SATISFY 1
  829. ! OMIT [trigger(trigdate())] MSG Labor Day.
  830. ! REM Monday Oct 8 SCANFROM [safe7] SATISFY 1
  831. ! OMIT [trigger(trigdate())] MSG Columbus Day.
  832. ! REM Monday Oct 22 SCANFROM [safe7] SATISFY 1
  833. ! OMIT [trigger(trigdate())] MSG Veteran's Day.
  834. ! REM Saturday Oct 24 MSG Daylight Savings Time ends tonight.
  835. ! REM Tuesday Nov 2 SCANFROM [safe7] SATISFY (year(trigdate()) % 4) == 0
  836. ! OMIT [trigger(trigdate())] MSG U.S. Election Day.
  837. ! REM Saturday Nov 12 MSG Sadie Hawkin's Day.
  838. ! REM Thursday Nov 22 SCANFROM [safe7] SATISFY 1
  839. ! OMIT [trigger(trigdate())] MSG Thanksgiving.
  840. *** ../patch3/dorem.c    Fri Feb  5 14:48:35 1993
  841. --- ./dorem.c    Tue Mar  2 16:20:33 1993
  842. ***************
  843. *** 26,31 ****
  844. --- 26,32 ----
  845.   
  846.   PRIVATE int ParseTimeTrig ARGS ((ParsePtr s, TimeTrig *tim));
  847.   PRIVATE int ParseLocalOmit ARGS ((ParsePtr s, Trigger *t));
  848. + PRIVATE int ParseScanFrom ARGS ((ParsePtr s, Trigger *t));
  849.   PRIVATE int ParseUntil ARGS ((ParsePtr s, Trigger *t));
  850.   
  851.   /***************************************************************/
  852. ***************
  853. *** 54,60 ****
  854.      if (trig.typ == NO_TYPE) return E_EOLN;
  855.      if (trig.typ == SAT_TYPE) return DoSatRemind(&trig, &tim, p);
  856.      /* Calculate the trigger date */
  857. !    jul = ComputeTrigger(JulianToday, &trig, &r);
  858.      if (r) return r;
  859.      
  860.   /* Queue the reminder, if necessary */
  861. --- 55,61 ----
  862.      if (trig.typ == NO_TYPE) return E_EOLN;
  863.      if (trig.typ == SAT_TYPE) return DoSatRemind(&trig, &tim, p);
  864.      /* Calculate the trigger date */
  865. !    jul = ComputeTrigger(trig.scanfrom, &trig, &r);
  866.      if (r) return r;
  867.      
  868.   /* Queue the reminder, if necessary */
  869. ***************
  870. *** 108,113 ****
  871. --- 109,115 ----
  872.      trig->skip = NO_SKIP;
  873.      trig->once = NO_ONCE;
  874.      trig->typ = NO_TYPE;
  875. +    trig->scanfrom = NO_DATE;
  876.      tim->ttime = NO_TIME;
  877.      tim->delta = NO_DELTA;
  878.      tim->rep   = NO_REP;
  879. ***************
  880. *** 149,154 ****
  881. --- 151,161 ----
  882.           if (r) return r;
  883.           break;
  884.   
  885. +      case T_Scanfrom:
  886. +         r=ParseScanFrom(s, trig);
  887. +         if (r) return r;
  888. +         break;
  889.        case T_RemType:
  890.           trig->typ = tok.val;
  891.           if (s->isnested) {
  892. ***************
  893. *** 155,160 ****
  894. --- 162,168 ----
  895.              Eprint("Can't nest '%s' in expression", TokBuffer);
  896.              return E_PARSE_ERR;
  897.               }
  898. +         if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
  899.           return OK;
  900.   
  901.        case T_Until:
  902. ***************
  903. *** 216,221 ****
  904. --- 224,230 ----
  905.           break;
  906.   
  907.        case T_Empty:
  908. +         if (trig->scanfrom == NO_DATE) trig->scanfrom = JulianToday;
  909.           return OK;
  910.   
  911.        default:
  912. ***************
  913. *** 363,368 ****
  914. --- 372,378 ----
  915.              Eprint("Incompletely specified UNTIL");
  916.              return E_PARSE_ERR;
  917.           }
  918. +         if (!DateOK(y, m, d)) return E_BAD_DATE;
  919.           t->until = Julian(y, m, d);
  920.           PushToken(TokBuffer);
  921.           return OK;
  922. ***************
  923. *** 372,377 ****
  924. --- 382,453 ----
  925.   
  926.   /***************************************************************/
  927.   /*                                                             */
  928. + /*  ParseScanFrom - parse the SCANFROM portion of a reminder   */
  929. + /*                                                             */
  930. + /***************************************************************/
  931. + #ifdef HAVE_PROTOS
  932. + PRIVATE int ParseScanFrom(ParsePtr s, Trigger *t)
  933. + #else
  934. + static int ParseScanFrom(s, t)
  935. + ParsePtr s;
  936. + Trigger *t;
  937. + #endif
  938. + {
  939. +    int y = NO_YR,
  940. +        m = NO_MON,
  941. +        d = NO_DAY;
  942. +    Token tok;
  943. +    int r;
  944. +    if (t->scanfrom != NO_DATE) {
  945. +       Eprint("Cannot specify SCANFROM twice");
  946. +       return E_PARSE_ERR;
  947. +    }
  948. +    while(1) {
  949. +       r = ParseToken(s, TokBuffer);
  950. +       if (r) return r;
  951. +       FindToken(TokBuffer, &tok);
  952. +       switch(tok.type) {
  953. +      case T_Year:
  954. +         if (y != NO_YR) {
  955. +            Eprint("Year specified twice in SCANFROM");
  956. +            return E_PARSE_ERR;
  957. +         }
  958. +         y = tok.val;
  959. +         break;
  960. +      case T_Month:
  961. +         if (m != NO_MON) {
  962. +            Eprint("Month specified twice in SCANFROM");
  963. +            return E_PARSE_ERR;
  964. +         }
  965. +         m = tok.val;
  966. +         break;
  967. +      case T_Day:
  968. +         if (d != NO_DAY) {
  969. +            Eprint("Day specified twice in SCANFROM");
  970. +            return E_PARSE_ERR;
  971. +         }
  972. +         d = tok.val;
  973. +         break;
  974. +      default:
  975. +         if (y == NO_YR || m == NO_MON || d == NO_DAY) {
  976. +            Eprint("Incompletely specified SCANFROM");
  977. +            return E_PARSE_ERR;
  978. +         }
  979. +         if (!DateOK(y, m, d)) return E_BAD_DATE;
  980. +         t->scanfrom = Julian(y, m, d);
  981. +         PushToken(TokBuffer);
  982. +         return OK;
  983. +       }
  984. +    }
  985. + }
  986. + /***************************************************************/
  987. + /*                                                             */
  988.   /*  TriggerReminder                                            */
  989.   /*                                                             */
  990.   /*  Trigger the reminder if it's a RUN or MSG type.            */
  991. ***************
  992. *** 388,412 ****
  993.   #endif
  994.   {
  995.      int r, y, m, d;
  996. -    Trigger tempTrig;
  997. -    TimeTrig tempTime;
  998. -    Parser tempP;
  999.   
  1000.      if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
  1001.      if (t->typ == CAL_TYPE) return OK;
  1002.   
  1003. ! /* If we're in Daemon mode, do nothing over here... */
  1004. ! /* If it's a MSG-type reminder, issue the banner. */
  1005. !    if (t->typ == MSG_TYPE && !NumTriggered && !NextMode) {
  1006. !       CreateParser(Banner, &tempP);
  1007. !       tempP.allownested = 0;
  1008. !       tempTrig.typ = MSG_TYPE;
  1009. !       tempTime.ttime = SystemTime()/60;
  1010. !       if (!(r=DoSubst(&tempP, SubstBuffer, &tempTrig,
  1011. !            &tempTime, JulianToday, NORMAL_MODE)))
  1012.            if (*SubstBuffer) printf("%s\n", SubstBuffer);
  1013. -       DestroyParser(&tempP);
  1014.      }
  1015.   
  1016.   /* If it's NextMode, process as a CAL-type entry, and issue simple-calendar
  1017. --- 464,477 ----
  1018.   #endif
  1019.   {
  1020.      int r, y, m, d;
  1021.   
  1022.      if (t->typ == RUN_TYPE && RunDisabled) return E_RUN_DISABLED;
  1023.      if (t->typ == CAL_TYPE) return OK;
  1024.   
  1025. ! /* If it's a MSG-type reminder, and no -k option was used, issue the banner. */
  1026. !    if (t->typ == MSG_TYPE && !NumTriggered && !NextMode && !MsgCommand) {
  1027. !       if (!DoSubstFromString(Banner, SubstBuffer, JulianToday, NO_TIME))
  1028.            if (*SubstBuffer) printf("%s\n", SubstBuffer);
  1029.      }
  1030.   
  1031.   /* If it's NextMode, process as a CAL-type entry, and issue simple-calendar
  1032. ***************
  1033. *** 424,433 ****
  1034.   /* Put the substituted string into the SubstBuffer */
  1035.      if ( (r=DoSubst(p, SubstBuffer, t, tim, jul, NORMAL_MODE)) ) return r;
  1036.   
  1037. ! /* Go for it... */
  1038. !    if (t->typ == MSG_TYPE) printf("%s\n", SubstBuffer);
  1039. !    else system(SubstBuffer);
  1040.   
  1041.      NumTriggered++;
  1042.      return OK;
  1043.   }
  1044. --- 489,517 ----
  1045.   /* Put the substituted string into the SubstBuffer */
  1046.      if ( (r=DoSubst(p, SubstBuffer, t, tim, jul, NORMAL_MODE)) ) return r;
  1047.   
  1048. ! /* If we are sorting, just queue it up in the sort buffer */
  1049. !    if (SortByDate) {
  1050. !       if (InsertIntoSortBuffer(jul, tim->ttime, SubstBuffer, t->typ) == OK) {
  1051. !          NumTriggered++;
  1052. !          return OK;
  1053. !       }
  1054. ! /* If we failed to insert the reminder into the sort buffer, issue the
  1055. !    reminder now. */
  1056. !    }
  1057.   
  1058. + /* Otherwise, issue the reminder now */
  1059. +    if (t->typ == MSG_TYPE) {
  1060. +       if (!MsgCommand)
  1061. +          printf("%s\n", SubstBuffer);
  1062. +       else {
  1063. +          char buf[LINELEN+TOKSIZE];
  1064. +          sprintf(buf, MsgCommand, SubstBuffer);
  1065. +      system(buf);
  1066. +       }
  1067. +    } else { /* Must be RUN_TYPE */
  1068. +       system(SubstBuffer);
  1069. +    }
  1070.      NumTriggered++;
  1071.      return OK;
  1072.   }
  1073. ***************
  1074. *** 519,525 ****
  1075.      char *s;
  1076.   
  1077.      iter = 0;
  1078. !    jul = JulianToday;
  1079.      while (iter++ < MaxSatIter) {
  1080.         jul = ComputeTrigger(jul, trig, &r);
  1081.         if (r) {
  1082. --- 603,609 ----
  1083.      char *s;
  1084.   
  1085.      iter = 0;
  1086. !    jul = trig->scanfrom;
  1087.      while (iter++ < MaxSatIter) {
  1088.         jul = ComputeTrigger(jul, trig, &r);
  1089.         if (r) {
  1090. *** ../patch3/dosubst.c    Mon Jan 25 16:09:28 1993
  1091. --- ./dosubst.c    Fri Mar  5 11:57:34 1993
  1092. ***************
  1093. *** 42,48 ****
  1094.   /*  mode==CAL_MODE, process the %" sequence.                   */
  1095.   /*                                                             */
  1096.   /***************************************************************/
  1097.   #ifdef HAVE_PROTOS
  1098.   PUBLIC int DoSubst(ParsePtr p, char *out, Trigger *t, TimeTrig *tt, int jul, int mode)
  1099.   #else
  1100. --- 42,47 ----
  1101. ***************
  1102. *** 82,94 ****
  1103.      h = tim / 60;
  1104.      min = tim % 60;
  1105.   
  1106. !    pm = (h < 12) ? "am" : "pm";
  1107.      hh = (h == 12) ? 12 : h % 12;
  1108.      
  1109.      ch = curtime / 60;
  1110.      cmin = curtime % 60;
  1111.   
  1112. !    cpm = (ch < 12) ? "am" : "pm";
  1113.      chh = (ch == 12) ? 12 : ch % 12;
  1114.   
  1115.   #ifdef L_ORDINAL_OVERRIDE
  1116. --- 81,101 ----
  1117.      h = tim / 60;
  1118.      min = tim % 60;
  1119.   
  1120. ! #ifdef L_AMPM_OVERRIDE
  1121. !    L_AMPM_OVERRIDE (pm, h)
  1122. ! #else
  1123. !    pm = (h < 12) ? L_AM : L_PM;
  1124. ! #endif
  1125.      hh = (h == 12) ? 12 : h % 12;
  1126.      
  1127.      ch = curtime / 60;
  1128.      cmin = curtime % 60;
  1129.   
  1130. ! #ifdef L_AMPM_OVERRIDE
  1131. !    L_AMPM_OVERRIDE (cpm, ch)
  1132. ! #else
  1133. !    cpm = (ch < 12) ? L_AM : L_PM;
  1134. ! #endif
  1135.      chh = (ch == 12) ? 12 : ch % 12;
  1136.   
  1137.   #ifdef L_ORDINAL_OVERRIDE
  1138. ***************
  1139. *** 114,120 ****
  1140.         if (err) return err;
  1141.         if (c == '\n') continue;
  1142.         if (!c) {
  1143. !          if (mode != CAL_MODE && t->typ != RUN_TYPE) *s++ = '\n';
  1144.        *s++ = 0;
  1145.        break;
  1146.         }
  1147. --- 121,128 ----
  1148.         if (err) return err;
  1149.         if (c == '\n') continue;
  1150.         if (!c) {
  1151. !          if (mode != CAL_MODE && t->typ != RUN_TYPE && !MsgCommand)
  1152. !         *s++ = '\n';
  1153.        *s++ = 0;
  1154.        break;
  1155.         }
  1156. ***************
  1157. *** 452,458 ****
  1158.   L_3_OVER
  1159.   #else
  1160.   
  1161. !         sprintf(s, "%s %02d:%02d", L_AT, h, min);
  1162.   #endif
  1163.           s += strlen(s);
  1164.           break;
  1165. --- 460,466 ----
  1166.   L_3_OVER
  1167.   #else
  1168.   
  1169. !         sprintf(s, "%s %02d%c%02d", L_AT, h, TIMESEP, min);
  1170.   #endif
  1171.           s += strlen(s);
  1172.           break;
  1173. ***************
  1174. *** 542,554 ****
  1175.   #ifdef L_HASH_OVER
  1176.   L_HASH_OVER
  1177.   #else
  1178. !         sprintf(s, "%02d:%02d", ch, cmin);
  1179.   #endif
  1180.           s += strlen(s);
  1181.           break;
  1182.   
  1183.            case '_': 
  1184. !             if (mode != CAL_MODE)
  1185.                  sprintf(s, "%s", NL);
  1186.               else
  1187.                  sprintf(s, " ");
  1188. --- 550,562 ----
  1189.   #ifdef L_HASH_OVER
  1190.   L_HASH_OVER
  1191.   #else
  1192. !         sprintf(s, "%02d%c%02d", ch, TIMESEP, cmin);
  1193.   #endif
  1194.           s += strlen(s);
  1195.           break;
  1196.   
  1197.            case '_': 
  1198. !             if (mode != CAL_MODE && !MsgCommand)
  1199.                  sprintf(s, "%s", NL);
  1200.               else
  1201.                  sprintf(s, " ");
  1202. ***************
  1203. *** 611,613 ****
  1204. --- 619,656 ----
  1205.   }
  1206.      
  1207.   
  1208. + /***************************************************************/
  1209. + /*                                                             */
  1210. + /*  DoSubstFromString                                          */
  1211. + /*                                                             */
  1212. + /*  DoSubst consumes input from a parser.  This function       */
  1213. + /*  consumes characters from a string.  It also provides       */
  1214. + /*  default triggers and a mode of NORMAL_MODE.                */
  1215. + /*                                                             */
  1216. + /***************************************************************/
  1217. + #ifdef HAVE_PROTOS
  1218. + PUBLIC int DoSubstFromString(char *source, char *dest, int jul, int tim)
  1219. + #else
  1220. + int DoSubstFromString(source, dest, jul, tim)
  1221. + char *source;
  1222. + char *dest;
  1223. + int jul;
  1224. + int tim;
  1225. + #endif
  1226. + {
  1227. +    Trigger tempTrig;
  1228. +    TimeTrig tempTime;
  1229. +    Parser tempP;
  1230. +    int r;
  1231. +    if (jul == NO_DATE) jul=JulianToday;
  1232. +    if (tim == NO_TIME) tim=SystemTime()/60;
  1233. +    CreateParser(source, &tempP);
  1234. +    tempP.allownested = 0;
  1235. +    tempTrig.typ = MSG_TYPE;
  1236. +    tempTime.ttime = tim;
  1237. +    
  1238. +    r = DoSubst(&tempP, dest, &tempTrig, &tempTime, jul, NORMAL_MODE);
  1239. +    DestroyParser(&tempP);
  1240. +    return r;
  1241. + }
  1242. *** ../patch3/english.h    Fri Jan 22 14:41:34 1993
  1243. --- ./english.h    Tue Feb 16 17:19:32 1993
  1244. ***************
  1245. *** 45,50 ****
  1246. --- 45,54 ----
  1247.   /* The default banner */
  1248.   #define L_BANNER "Reminders for %w, %d%s %m, %y%o:"
  1249.   
  1250. + /* "am" and "pm" */
  1251. + #define L_AM "am"
  1252. + #define L_PM "pm"
  1253.   /*** The following are only used in dosubst.c ***/
  1254.   #ifdef L_IN_DOSUBST
  1255.   
  1256. *** ../patch3/err.h    Fri Jan  8 13:25:56 1993
  1257. --- ./err.h    Mon Feb 15 20:41:25 1993
  1258. ***************
  1259. *** 70,76 ****
  1260.   = {
  1261.      "Ok",
  1262.      "Missing ']'",
  1263. !    "Missing double-quote",
  1264.      "Expression too complex - too many operators",
  1265.      "Expression too complex - too many operands",
  1266.      "Missing ')'",
  1267. --- 70,76 ----
  1268.   = {
  1269.      "Ok",
  1270.      "Missing ']'",
  1271. !    "Missing quote",
  1272.      "Expression too complex - too many operators",
  1273.      "Expression too complex - too many operands",
  1274.      "Missing ')'",
  1275. *** ../patch3/expr.c    Fri Feb  5 14:51:35 1993
  1276. --- ./expr.c    Wed Mar  3 17:35:34 1993
  1277. ***************
  1278. *** 44,50 ****
  1279.          GreaterOrEqual(void), LogAND(void), LogOR(void),
  1280.          UnMinus(void), LogNot(void),
  1281.          Compare(int);
  1282. - PRIVATE Operator *FindFunc(char *name, Operator where[], int num);
  1283.   #else
  1284.   PRIVATE int Multiply(), Divide(), Mod(), Add(),
  1285.          Subtract(), GreaterThan(), LessThan(),
  1286. --- 44,49 ----
  1287. ***************
  1288. *** 51,57 ****
  1289.          EqualTo(), NotEqual(), LessOrEqual(),
  1290.          GreaterOrEqual(), LogAND(), LogOR(),
  1291.              UnMinus(), LogNot(), Compare();
  1292. - PRIVATE Operator *FindFunc();
  1293.   #endif
  1294.   
  1295.   PRIVATE int MakeValue ARGS ((char *s, Value *v, Var *locals));
  1296. --- 50,55 ----
  1297. ***************
  1298. *** 227,232 ****
  1299. --- 225,231 ----
  1300.   
  1301.      /* Handle the parsing of quoted strings */
  1302.      if (c == '\"') {
  1303. +       if (!*(*in+1)) return E_MISS_QUOTE;
  1304.         while (**in) if ((c = *out++ = *(*in)++) == '\"') break;
  1305.         *out = 0;
  1306.         if (c == '\"') return OK ; else return E_MISS_QUOTE;
  1307. ***************
  1308. *** 234,239 ****
  1309. --- 233,239 ----
  1310.   
  1311.      /* Dates can be specified with single-quotes */
  1312.      if (c == '\'') {
  1313. +       if (!*(*in+1)) return E_MISS_QUOTE;
  1314.         while (**in) if ((c = *out++ = *(*in)++) == '\'') break;
  1315.         *out = 0;
  1316.         if (c == '\'') return OK ; else return E_MISS_QUOTE;
  1317. ***************
  1318. *** 245,251 ****
  1319.      }
  1320.   
  1321.      /* Parse a constant, variable name or function */
  1322. !    while (ISID(**in) || **in == ':') *out++ = *(*in)++;
  1323.   
  1324.      /* Chew up any remaining white space */
  1325.      while (**in && isspace(**in)) (*in)++;
  1326. --- 245,252 ----
  1327.      }
  1328.   
  1329.      /* Parse a constant, variable name or function */
  1330. !    while (ISID(**in) || **in == ':' || **in == '.' || **in == TIMESEP)
  1331. !       *out++ = *(*in)++;
  1332.   
  1333.      /* Chew up any remaining white space */
  1334.      while (**in && isspace(**in)) (*in)++;
  1335. ***************
  1336. *** 341,349 ****
  1337.           while(1) {
  1338.              args++;
  1339.              r = Evaluate(s, locals);
  1340. !            if (r) return r;
  1341.              if (*ExprBuf == ')') break;
  1342.              else if (*ExprBuf != ',') {
  1343.              Eprint("Expecting comma, found '%c'", *ExprBuf);
  1344.                 return E_ILLEGAL_CHAR;
  1345.                  }
  1346. --- 342,354 ----
  1347.           while(1) {
  1348.              args++;
  1349.              r = Evaluate(s, locals);
  1350. !            if (r) {
  1351. !               if (!f) free(ufname);
  1352. !               return r;
  1353. !            }
  1354.              if (*ExprBuf == ')') break;
  1355.              else if (*ExprBuf != ',') {
  1356. +               if (!f) free(ufname);
  1357.              Eprint("Expecting comma, found '%c'", *ExprBuf);
  1358.                 return E_ILLEGAL_CHAR;
  1359.                  }
  1360. ***************
  1361. *** 458,464 ****
  1362.            len *= 10;
  1363.            len += (*s++ - '0');
  1364.         }
  1365. !       if (*s == ':') { /* Must be a literal time */
  1366.        s++;
  1367.        if (!isdigit(*s)) return E_BAD_TIME;
  1368.        h = len;
  1369. --- 463,469 ----
  1370.            len *= 10;
  1371.            len += (*s++ - '0');
  1372.         }
  1373. !       if (*s == ':' || *s == '.' || *s == TIMESEP) { /* Must be a literal time */
  1374.        s++;
  1375.        if (!isdigit(*s)) return E_BAD_TIME;
  1376.        h = len;
  1377. ***************
  1378. *** 601,607 ****
  1379.         case STR_TYPE:
  1380.            switch(v->type) {
  1381.               case INT_TYPE: sprintf(CoerceBuf, "%d", v->v.val); break;
  1382. !             case TIM_TYPE: sprintf(CoerceBuf, "%02d:%02d", v->v.val / 60, v->v.val % 60);
  1383.                  break;
  1384.           case DATE_TYPE: FromJulian(v->v.val, &y, &m, &d);
  1385.                   sprintf(CoerceBuf, "%04d%c%02d%c%02d",
  1386. --- 606,613 ----
  1387.         case STR_TYPE:
  1388.            switch(v->type) {
  1389.               case INT_TYPE: sprintf(CoerceBuf, "%d", v->v.val); break;
  1390. !             case TIM_TYPE: sprintf(CoerceBuf, "%02d%c%02d", v->v.val / 60, 
  1391. !                    TIMESEP, v->v.val % 60);
  1392.                  break;
  1393.           case DATE_TYPE: FromJulian(v->v.val, &y, &m, &d);
  1394.                   sprintf(CoerceBuf, "%04d%c%02d%c%02d",
  1395. ***************
  1396. *** 686,692 ****
  1397.             h *= 10;
  1398.             h += *s++ - '0';
  1399.              }
  1400. !            if (*s++ != ':') return E_CANT_COERCE;
  1401.              if (!isdigit(*s)) return E_CANT_COERCE;
  1402.              while (isdigit(*s)) {
  1403.             m *= 10;
  1404. --- 692,700 ----
  1405.             h *= 10;
  1406.             h += *s++ - '0';
  1407.              }
  1408. !            if (*s != ':' && *s != '.' && *s != TIMESEP)
  1409. !               return E_CANT_COERCE;
  1410. !            s++;
  1411.              if (!isdigit(*s)) return E_CANT_COERCE;
  1412.              while (isdigit(*s)) {
  1413.             m *= 10;
  1414. ***************
  1415. *** 754,759 ****
  1416. --- 762,768 ----
  1417.      if ((v1.type == DATE_TYPE && v2.type == INT_TYPE) ||
  1418.          (v1.type == INT_TYPE && v2.type == DATE_TYPE)) {
  1419.         v1.v.val += v2.v.val;
  1420. +       if (v1.v.val < 0) return E_DATE_OVER;
  1421.         v1.type = DATE_TYPE;
  1422.         return PushValStack(&v1);
  1423.      }
  1424. ***************
  1425. *** 1128,1136 ****
  1426.   /*                                                             */
  1427.   /***************************************************************/
  1428.   #ifdef HAVE_PROTOS
  1429. ! PRIVATE Operator *FindFunc(char *name, Operator where[], int num)
  1430.   #else
  1431. ! static Operator *FindFunc(name, where, num)
  1432.   char *name;
  1433.   Operator where[];
  1434.   int num;
  1435. --- 1137,1145 ----
  1436.   /*                                                             */
  1437.   /***************************************************************/
  1438.   #ifdef HAVE_PROTOS
  1439. ! Operator *FindFunc(char *name, Operator where[], int num)
  1440.   #else
  1441. ! Operator *FindFunc(name, where, num)
  1442.   char *name;
  1443.   Operator where[];
  1444.   int num;
  1445. ***************
  1446. *** 1174,1180 ****
  1447.         if (*s) fprintf(fp, "...");
  1448.      }      
  1449.      else if (v->type == INT_TYPE) fprintf(fp, "%d", v->v.val);
  1450. !    else if (v->type == TIM_TYPE) fprintf(fp, "%02d:%02d", v->v.val / 60, v->v.val % 60);
  1451.      else if (v->type == DATE_TYPE) {
  1452.         FromJulian(v->v.val, &y, &m, &d);
  1453.         fprintf(fp, "%04d%c%02d%c%02d", y, DATESEP, m+1, DATESEP, d);
  1454. --- 1183,1190 ----
  1455.         if (*s) fprintf(fp, "...");
  1456.      }      
  1457.      else if (v->type == INT_TYPE) fprintf(fp, "%d", v->v.val);
  1458. !    else if (v->type == TIM_TYPE) fprintf(fp, "%02d%c%02d", v->v.val / 60, 
  1459. !                      TIMESEP, v->v.val % 60);
  1460.      else if (v->type == DATE_TYPE) {
  1461.         FromJulian(v->v.val, &y, &m, &d);
  1462.         fprintf(fp, "%04d%c%02d%c%02d", y, DATESEP, m+1, DATESEP, d);
  1463. ***************
  1464. *** 1234,1240 ****
  1465.         y *= 10;
  1466.         y += *(*s)++ - '0';
  1467.      }
  1468. !    if (**s != '/' && **s != '-') return E_BAD_DATE;
  1469.      (*s)++;
  1470.      if (!isdigit(**s)) return E_BAD_DATE;
  1471.      while (isdigit(**s)) {
  1472. --- 1244,1250 ----
  1473.         y *= 10;
  1474.         y += *(*s)++ - '0';
  1475.      }
  1476. !    if (**s != '/' && **s != '-' && **s != DATESEP) return E_BAD_DATE;
  1477.      (*s)++;
  1478.      if (!isdigit(**s)) return E_BAD_DATE;
  1479.      while (isdigit(**s)) {
  1480. ***************
  1481. *** 1242,1248 ****
  1482.         m += *(*s)++ - '0';
  1483.      }
  1484.      m--;
  1485. !    if (**s != '/' && **s != '-') return E_BAD_DATE;
  1486.      (*s)++;
  1487.      if (!isdigit(**s)) return E_BAD_DATE;
  1488.      while (isdigit(**s)) {
  1489. --- 1252,1258 ----
  1490.         m += *(*s)++ - '0';
  1491.      }
  1492.      m--;
  1493. !    if (**s != '/' && **s != '-' && **s != DATESEP) return E_BAD_DATE;
  1494.      (*s)++;
  1495.      if (!isdigit(**s)) return E_BAD_DATE;
  1496.      while (isdigit(**s)) {
  1497. ***************
  1498. *** 1249,1257 ****
  1499.         d *= 10;
  1500.         d += *(*s)++ - '0';
  1501.      }
  1502. !    if (y < BASE || y > BASE+YR_RANGE || m<0 ||
  1503. !         m>11 || d<1 || d>DaysInMonth(m, y)) return E_BAD_DATE;
  1504.      *jul = Julian(y, m, d);
  1505.   
  1506.      return OK;
  1507. --- 1259,1266 ----
  1508.         d *= 10;
  1509.         d += *(*s)++ - '0';
  1510.      }
  1511. !    if (!DateOK(y, m, d)) return E_BAD_DATE;
  1512. !    
  1513.      *jul = Julian(y, m, d);
  1514.   
  1515.      return OK;
  1516. *** ../patch3/files.c    Fri Feb  5 14:52:12 1993
  1517. --- ./files.c    Mon Mar  1 13:00:30 1993
  1518. ***************
  1519. *** 39,52 ****
  1520.   #include "err.h"
  1521.   
  1522.   /* Define the structures needed by the file caching system */
  1523. ! typedef struct _cache_ {
  1524. !    struct _cache_ *next;
  1525.      char *text;
  1526.      int LineNo;
  1527.   } CachedLine;
  1528.   
  1529. ! typedef struct _cheader_ {
  1530. !    struct _cheader_ *next;
  1531.      char *filename;
  1532.      CachedLine *cache;
  1533.   } CachedFile;
  1534. --- 39,52 ----
  1535.   #include "err.h"
  1536.   
  1537.   /* Define the structures needed by the file caching system */
  1538. ! typedef struct cache {
  1539. !    struct cache *next;
  1540.      char *text;
  1541.      int LineNo;
  1542.   } CachedLine;
  1543.   
  1544. ! typedef struct cheader {
  1545. !    struct cheader *next;
  1546.      char *filename;
  1547.      CachedLine *cache;
  1548.   } CachedFile;
  1549. *** ../patch3/funcs.c    Fri Feb  5 14:43:14 1993
  1550. --- ./funcs.c    Tue Mar  2 16:27:55 1993
  1551. ***************
  1552. *** 47,52 ****
  1553. --- 47,53 ----
  1554.   /* Function prototypes */
  1555.   PRIVATE    int    FAbs        ARGS ((void));
  1556.   PRIVATE    int    FAccess        ARGS ((void));
  1557. + PRIVATE int     FArgs        ARGS ((void));
  1558.   PRIVATE    int    FAsc        ARGS ((void));
  1559.   PRIVATE    int    FBaseyr        ARGS ((void));
  1560.   PRIVATE    int    FChar        ARGS ((void));
  1561. ***************
  1562. *** 56,61 ****
  1563. --- 57,63 ----
  1564.   PRIVATE    int    FDay        ARGS ((void));
  1565.   PRIVATE    int    FDaysinmon    ARGS ((void));
  1566.   PRIVATE    int    FDefined    ARGS ((void));
  1567. + PRIVATE    int    FDosubst    ARGS ((void));
  1568.   PRIVATE    int    FFilename    ARGS ((void));
  1569.   PRIVATE    int    FGetenv        ARGS ((void));
  1570.   PRIVATE    int    FHour        ARGS ((void));
  1571. ***************
  1572. *** 136,141 ****
  1573. --- 138,144 ----
  1574.   
  1575.       {   "abs",        1,    1,    FAbs    },
  1576.       {   "access",       2,      2,      FAccess },
  1577. +     {   "args",         1,      1,      FArgs   },
  1578.       {   "asc",        1,    1,    FAsc    },
  1579.       {   "baseyr",    0,    0,    FBaseyr    },
  1580.       {   "char",        1,    NO_MAX,    FChar    },
  1581. ***************
  1582. *** 145,150 ****
  1583. --- 148,154 ----
  1584.       {   "day",        1,    1,    FDay    },
  1585.       {   "daysinmon",    2,    2,    FDaysinmon },
  1586.       {   "defined",    1,    1,    FDefined },
  1587. +     {   "dosubst",    1,    3,    FDosubst },
  1588.       {   "filename",    0,    0,    FFilename },
  1589.       {   "getenv",    1,    1,    FGetenv },
  1590.       {   "hour",        1,    1,    FHour    },
  1591. ***************
  1592. *** 370,377 ****
  1593.      m = ARG(1).v.val - 1;
  1594.      d = ARG(2).v.val;
  1595.   
  1596. !    if (y < BASE || y > BASE+YR_RANGE || m < 0 || m > 11 || d < 1 ||
  1597. !        d > DaysInMonth(m, y)) return E_BAD_DATE;
  1598.   
  1599.      RetVal.type = DATE_TYPE;
  1600.      RetVal.v.val = Julian(y, m, d);
  1601. --- 374,380 ----
  1602.      m = ARG(1).v.val - 1;
  1603.      d = ARG(2).v.val;
  1604.   
  1605. !    if (!DateOK(y, m, d)) return E_BAD_DATE;
  1606.   
  1607.      RetVal.type = DATE_TYPE;
  1608.      RetVal.v.val = Julian(y, m, d);
  1609. ***************
  1610. *** 1435,1437 ****
  1611. --- 1438,1492 ----
  1612.   {
  1613.      return RetStrVal(L_LANGNAME);
  1614.   }
  1615. + /***************************************************************/
  1616. + /*                                                             */
  1617. + /*  FArgs                                                      */
  1618. + /*                                                             */
  1619. + /*  Implement the args() function.                             */
  1620. + /*                                                             */
  1621. + /***************************************************************/
  1622. + #ifdef HAVE_PROTOS
  1623. + PRIVATE int FArgs(void)
  1624. + #else
  1625. + static int FArgs()
  1626. + #endif
  1627. + {
  1628. +    if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
  1629. +    RetVal.type = INT_TYPE;
  1630. +    RetVal.v.val = UserFuncExists(ARG(0).v.str);
  1631. +    return OK;
  1632. + }
  1633. + /***************************************************************/
  1634. + /*                                                             */
  1635. + /*  FDosubst                                                   */
  1636. + /*                                                             */
  1637. + /*  Implement the dosubst() function.                          */
  1638. + /*                                                             */
  1639. + /***************************************************************/
  1640. + #ifdef HAVE_PROTOS
  1641. + PRIVATE int FDosubst(void)
  1642. + #else
  1643. + static int FDosubst()
  1644. + #endif
  1645. + {
  1646. +    int jul, tim, r;
  1647. +    char TmpBuf[LINELEN];
  1648. +    jul = NO_DATE;
  1649. +    tim = NO_TIME;
  1650. +    if (ARG(0).type != STR_TYPE) return E_BAD_TYPE;
  1651. +    if (Nargs >= 2) {
  1652. +       if (ARG(1).type != DATE_TYPE) return E_BAD_TYPE;
  1653. +       jul = ARG(1).v.val;
  1654. +       if (Nargs >= 3) {
  1655. +          if (ARG(2).type != TIM_TYPE) return E_BAD_TYPE;
  1656. +      tim = ARG(2).v.val;
  1657. +       }
  1658. +    }
  1659. +    if ((r=DoSubstFromString(ARG(0).v.str, TmpBuf, jul, tim))) return r;
  1660. +    return RetStrVal(TmpBuf);
  1661. + }
  1662. *** ../patch3/german.h    Fri Jan 22 14:41:16 1993
  1663. --- ./german.h    Tue Mar  2 12:15:26 1993
  1664. ***************
  1665. *** 31,37 ****
  1666.   /* Month names */
  1667.   #define L_JAN "Januar"
  1668.   #define L_FEB "Februar"
  1669. ! #define L_MAR "Maerz"
  1670.   #define L_APR "April"
  1671.   #define L_MAY "Mai"
  1672.   #define L_JUN "Juni"
  1673. --- 31,41 ----
  1674.   /* Month names */
  1675.   #define L_JAN "Januar"
  1676.   #define L_FEB "Februar"
  1677. ! #ifdef ISOLATIN1
  1678. ! #  define L_MAR "M\344rz"
  1679. ! #else
  1680. ! #  define L_MAR "Maerz"
  1681. ! #endif
  1682.   #define L_APR "April"
  1683.   #define L_MAY "Mai"
  1684.   #define L_JUN "Juni"
  1685. ***************
  1686. *** 47,54 ****
  1687.   #define L_TOMORROW "morgen"
  1688.   
  1689.   /* The default banner */
  1690. ! #define L_BANNER "Termine fuer %w, den %d %m %y%o:"
  1691.   
  1692.   /*** The following are only used in dosubst.c ***/
  1693.   #ifdef L_IN_DOSUBST
  1694.   
  1695. --- 51,66 ----
  1696.   #define L_TOMORROW "morgen"
  1697.   
  1698.   /* The default banner */
  1699. ! #ifdef ISOLATIN1
  1700. ! #  define L_BANNER "Termine f\374r %w, den %d. %m %y%o:"
  1701. ! #else
  1702. ! #  define L_BANNER "Termine fuer %w, den %d. %m %y%o:"
  1703. ! #endif
  1704.   
  1705. + /* "am" and "pm" */
  1706. + #define L_AM "am"
  1707. + #define L_PM "pm"
  1708.   /*** The following are only used in dosubst.c ***/
  1709.   #ifdef L_IN_DOSUBST
  1710.   
  1711.