home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume36 / remind / patch04a < prev    next >
Encoding:
Text File  |  1993-03-06  |  60.3 KB  |  2,009 lines

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