home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2041 < prev    next >
Internet Message Format  |  1990-12-28  |  16KB

  1. From: dfs@doe.carleton.ca (David F. Skoll)
  2. Newsgroups: alt.sources
  3. Subject: REMIND 2.1
  4. Message-ID: <dfs.657925666@chekov>
  5. Date: 6 Nov 90 21:07:46 GMT
  6.  
  7. The following patches convert Remind 2.0 to Remind 2.1
  8.  
  9. The first file (patch.01) was posted earlier.  It corrects the
  10. bug which caused remind to print "23th" instead of "23rd".  If
  11. you've already applied this patch, simply proceed with patch.02
  12.  
  13. The second patch adds the "repeating reminder" feature.  This allows
  14. you to have a reminder which repeats with an arbitrary period, rather
  15. than weekly, monthly, etc.  See the man page for more information.
  16.  
  17. To apply the patches:
  18.  
  19. o Extract the shar archive in the REMIND build directory
  20.  
  21. o Apply the patches (eg: cat patch.* | patch)
  22.  
  23. o Type make
  24.  
  25. o Re-install the new version of remind and the updated man page.
  26.  
  27. --------------- CUT HERE FOR PATCHES ARCHIVE ---------------
  28. #!/bin/sh
  29. # This is Patches for Remind 2.0, a shell archive (shar 3.32)
  30. # made 11/06/1990 21:03 UTC by dfs@chekov
  31. # Source directory /enterprise/navigation/dfs/work/.rem/remind-2.0
  32. #
  33. # existing files will NOT be overwritten
  34. #
  35. # This shar contains:
  36. # length  mode       name
  37. # ------ ---------- ------------------------------------------
  38. #   1026 -rw------- patch.01
  39. #  12130 -rw------- patch.02
  40. #
  41. if touch 2>&1 | fgrep 'amc' > /dev/null
  42.  then TOUCH=touch
  43.  else TOUCH=true
  44. fi
  45. # ============= patch.01 ==============
  46. if test X"$1" != X"-c" -a -f 'patch.01'; then
  47.     echo "File already exists: skipping 'patch.01'"
  48. else
  49. echo "x - extracting patch.01 (Text)"
  50. sed 's/^X//' << 'SHAR_EOF' > patch.01 &&
  51. X*** main.c    Fri Nov  2 12:26:17 1990
  52. X--- ../merged/main.c    Mon Nov  5 10:19:13 1990
  53. X***************
  54. X*** 282,288 ****
  55. X     if (! *Banner)
  56. X     {
  57. X        if (Debug) Eprint("Empty banner.\n");
  58. X!       strcpy(Banner, "Reminders for %d %m, %y%o:");
  59. X     }
  60. X     if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
  61. X     return 0;
  62. X--- 282,288 ----
  63. X     if (! *Banner)
  64. X     {
  65. X        if (Debug) Eprint("Empty banner.\n");
  66. X!       strcpy(Banner, "Reminders for %w, %d%s %m, %y%o:");
  67. X     }
  68. X     if (NumRem && Debug) Eprint("Warning: Banner after reminder.\n");
  69. X     return 0;
  70. X*** dosubst.c    Fri Nov  2 12:26:13 1990
  71. X--- ../merged/dosubst.c    Mon Nov  5 10:18:04 1990
  72. X***************
  73. X*** 51,57 ****
  74. X        case 2:
  75. X        case 22: plu = "nd"; break;
  76. X        
  77. X!       case 3:  plu = "rd"; break;
  78. X        
  79. X        default: plu = "th"; break;
  80. X     }
  81. X--- 51,58 ----
  82. X        case 2:
  83. X        case 22: plu = "nd"; break;
  84. X        
  85. X!       case 3:
  86. X!       case 23: plu = "rd"; break;
  87. X        
  88. X        default: plu = "th"; break;
  89. X     }
  90. SHAR_EOF
  91. $TOUCH -am 1106155890 patch.01 &&
  92. chmod 0600 patch.01 ||
  93. echo "restore of patch.01 failed"
  94. set `wc -c patch.01`;Wc_c=$1
  95. if test "$Wc_c" != "1026"; then
  96.     echo original size 1026, current size $Wc_c
  97. fi
  98. fi
  99. # ============= patch.02 ==============
  100. if test X"$1" != X"-c" -a -f 'patch.02'; then
  101.     echo "File already exists: skipping 'patch.02'"
  102. else
  103. echo "x - extracting patch.02 (Text)"
  104. sed 's/^X//' << 'SHAR_EOF' > patch.02 &&
  105. X*** ../remind-2.0-patch1/defines.h    Tue Nov  6 15:53:25 1990
  106. X--- defines.h    Tue Nov  6 14:48:17 1990
  107. X***************
  108. X*** 30,36 ****
  109. X  #define WKDAY_M 8
  110. X  
  111. X  enum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
  112. X!            Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t, Eol_t };
  113. X                 
  114. X  /* Define the Token structure */
  115. X  
  116. X--- 30,37 ----
  117. X  #define WKDAY_M 8
  118. X  
  119. X  enum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
  120. X!            Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t, 
  121. X!                Repeat_t, Eol_t };
  122. X                 
  123. X  /* Define the Token structure */
  124. X  
  125. X*** ../remind-2.0-patch1/dorem.c    Tue Nov  6 15:53:25 1990
  126. X--- dorem.c    Tue Nov  6 15:15:03 1990
  127. X***************
  128. X*** 24,36 ****
  129. X       
  130. X  #endif UNIX
  131. X  {
  132. X!    int d, m, y, wd, cons, delta, back, omit, done, i, jul, once;
  133. X     int d2, m2, y2;
  134. X     Token tok;
  135. X     int trigger;
  136. X  
  137. X     d = m = y = back = delta = -1;
  138. X!    cons = wd = omit = once = 0;
  139. X  
  140. X  
  141. X     done = 0;
  142. X--- 24,36 ----
  143. X       
  144. X  #endif UNIX
  145. X  {
  146. X!   int d, m, y, wd, cons, delta, back, omit, done, i, jul, once, repeat;
  147. X     int d2, m2, y2;
  148. X     Token tok;
  149. X     int trigger;
  150. X  
  151. X     d = m = y = back = delta = -1;
  152. X!    repeat = cons = wd = omit = once = 0;
  153. X  
  154. X  
  155. X     done = 0;
  156. X***************
  157. X*** 49,54 ****
  158. X--- 49,66 ----
  159. X          Eprint("Unknown token %s in reminder.\n", tok.str);
  160. X          return 0;
  161. X  
  162. X+          case Repeat_t:
  163. X+             if (repeat) {
  164. X+                Eprint("Repeat factor specified twice.\n");
  165. X+                return 0;
  166. X+             }
  167. X+             repeat = tok.val;
  168. X+             if (repeat <= 0) {
  169. X+                Eprint("Invalid value for repeat factor: %d\n", repeat);
  170. X+                return 0;
  171. X+             }
  172. X+             break;
  173. X+ 
  174. X       case Banner_t:
  175. X          Eprint("BANNER can't be used here.\n");
  176. X          return 0;
  177. X***************
  178. X*** 143,150 ****
  179. X          default:
  180. X             Eprint("Only weekdays are valid after a local OMIT.\n");
  181. X             return 0;
  182. X!      }
  183. X!       }
  184. X     }
  185. X     
  186. X     if (d != -1 && m != -1 && CheckDate(d, m, y)) {
  187. X--- 155,167 ----
  188. X          default:
  189. X             Eprint("Only weekdays are valid after a local OMIT.\n");
  190. X             return 0;
  191. X!            }
  192. X!        }
  193. X!     }
  194. X! 
  195. X!    if (repeat && (d == -1 || m == -1 || y == -1)) {
  196. X!       Eprint("Can't use repeat counter unless you fully specify the date.\n");
  197. X!       return 0;
  198. X     }
  199. X     
  200. X     if (d != -1 && m != -1 && CheckDate(d, m, y)) {
  201. X***************
  202. X*** 175,181 ****
  203. X  
  204. X     i = TryNextDate(&d2, &m2, &y2, CurDay, CurMon, CurYear,
  205. X             d, m, y, wd, cons, 0);
  206. X!    if (i) {
  207. X        if (Debug) Eprint("Reminder has expired.\n");
  208. X        return -1;
  209. X     }
  210. X--- 192,198 ----
  211. X  
  212. X     i = TryNextDate(&d2, &m2, &y2, CurDay, CurMon, CurYear,
  213. X             d, m, y, wd, cons, 0);
  214. X!    if (i && !repeat) {
  215. X        if (Debug) Eprint("Reminder has expired.\n");
  216. X        return -1;
  217. X     }
  218. X***************
  219. X*** 185,203 ****
  220. X     if (delta == -1) delta = 0;
  221. X  
  222. X     jul = Julian(d2, m2, y2);
  223. X!    if (back) {
  224. X!       jul = MoveBack(jul, back, d2, m2, y2, omit);
  225. X!       while (jul < JulianToday) {
  226. X!      i = TryNextDate(&d2, &m2, &y2, d2, m2, y2,
  227. X               d, m, y, wd, cons, 1);
  228. X!      if (i) {
  229. X!         if (Debug) Eprint("Reminder has expired.\n");
  230. X!         return -1;
  231. X!      }
  232. X!          jul = Julian(d2, m2, y2);
  233. X!      jul = MoveBack(jul, back, d2, m2, y2, omit);
  234. X        }
  235. X-       FromJulian(jul, &d2, &m2, &y2);
  236. X     }
  237. X     
  238. X     /* Figure out if the reminder should be triggered */
  239. X--- 202,231 ----
  240. X     if (delta == -1) delta = 0;
  241. X  
  242. X     jul = Julian(d2, m2, y2);
  243. X!    if (repeat) {
  244. X!       if (back) {
  245. X!          jul = MoveBack(jul, back, d2, m2, y2, omit);
  246. X!          FromJulian(jul, &d2, &m2, &y2);
  247. X!       }
  248. X!       if (jul < JulianToday) {
  249. X!          jul += ((JulianToday - jul) / repeat) * repeat + repeat;
  250. X!          FromJulian(jul, &d2, &m2, &y2);
  251. X!       }
  252. X!    } else {
  253. X!       if (back) {
  254. X!          jul = MoveBack(jul, back, d2, m2, y2, omit);
  255. X!          while (jul < JulianToday) {
  256. X!             i = TryNextDate(&d2, &m2, &y2, d2, m2, y2,
  257. X               d, m, y, wd, cons, 1);
  258. X!         if (i) {
  259. X!            if (Debug) Eprint("Reminder has expired.\n");
  260. X!            return -1;
  261. X!         }
  262. X!             jul = Julian(d2, m2, y2);
  263. X!         jul = MoveBack(jul, back, d2, m2, y2, omit);
  264. X!          }
  265. X!          FromJulian(jul, &d2, &m2, &y2);
  266. X        }
  267. X     }
  268. X     
  269. X     /* Figure out if the reminder should be triggered */
  270. X***************
  271. X*** 212,218 ****
  272. X     }
  273. X     if (Purge || (once && (LastRun == JulianToday))) return 0;
  274. X     while (isspace(**s)) (*s)++;
  275. X!    if (trigger <= JulianToday && !(tok.type == Run_t && IgRun)) { /* Trigger a reminder */
  276. X        if (NumEmitted == 0 && !Purge && !Debug) {
  277. X           DoSubst(Banner, WorkBuf, CurDay, CurMon, CurYear, JulianToday, Msg_t);
  278. X       printf("%s\n", WorkBuf);
  279. X--- 240,247 ----
  280. X     }
  281. X     if (Purge || (once && (LastRun == JulianToday))) return 0;
  282. X     while (isspace(**s)) (*s)++;
  283. X!    if (trigger <= JulianToday && !(tok.type == Run_t && IgRun)) { 
  284. X!       /* Trigger a reminder */
  285. X        if (NumEmitted == 0 && !Purge && !Debug) {
  286. X           DoSubst(Banner, WorkBuf, CurDay, CurMon, CurYear, JulianToday, Msg_t);
  287. X       printf("%s\n", WorkBuf);
  288. X*** ../remind-2.0-patch1/init.c    Tue Nov  6 15:53:26 1990
  289. X--- init.c    Tue Nov  6 15:26:23 1990
  290. X***************
  291. X*** 7,13 ****
  292. X  #include "globals.h"
  293. X  #include "protos.h"
  294. X  
  295. X! static char ErrMsg[] = "\n\t\tREMIND version 2.0 (C) 1990 by David Skoll.\n\nUsage: REMIND [-p | -d] [-v] [-o] [-r] filename [date]\n\n";
  296. X  static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
  297. X  /***************************************************************/
  298. X  /*                                                             */
  299. X--- 7,13 ----
  300. X  #include "globals.h"
  301. X  #include "protos.h"
  302. X  
  303. X! static char ErrMsg[] = "\n\t\tREMIND version 2.1 (C) 1990 by David Skoll.\n\nUsage: REMIND [-p | -d] [-v] [-o] [-r] filename [date]\n\n";
  304. X  static char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
  305. X  /***************************************************************/
  306. X  /*                                                             */
  307. X*** ../remind-2.0-patch1/main.c    Tue Nov  6 15:53:34 1990
  308. X--- main.c    Tue Nov  6 15:08:23 1990
  309. X***************
  310. X*** 496,514 ****
  311. X        return tok;
  312. X     }
  313. X  
  314. X!    /* Check if it's a number (optional +/- ahead of number */
  315. X     t = temp;
  316. X     if (isdigit(*t)) {
  317. X        while (*++t) if (!isdigit(*t)) return tok;
  318. X     }
  319. X!    else if (*t == '+' || *t == '-') {
  320. X        if (!isdigit(*++t)) return tok;
  321. X        while (*++t) if (!isdigit(*t)) return tok;
  322. X     }
  323. X     else return tok;
  324. X  
  325. X!    /* OK, here we have a number - either a pure number, a delta or a
  326. X!       backward look */
  327. X  
  328. X     if (*temp == '+') {
  329. X        tok.type = Delta_t;
  330. X--- 496,514 ----
  331. X        return tok;
  332. X     }
  333. X  
  334. X!    /* Check if it's a number (optional +/-/* ahead of number */
  335. X     t = temp;
  336. X     if (isdigit(*t)) {
  337. X        while (*++t) if (!isdigit(*t)) return tok;
  338. X     }
  339. X!    else if (*t == '+' || *t == '-' || *t == '*') {
  340. X        if (!isdigit(*++t)) return tok;
  341. X        while (*++t) if (!isdigit(*t)) return tok;
  342. X     }
  343. X     else return tok;
  344. X  
  345. X!    /* OK, here we have a number - either a pure number, a delta, a
  346. X!       back or a repeat marker */
  347. X  
  348. X     if (*temp == '+') {
  349. X        tok.type = Delta_t;
  350. X***************
  351. X*** 516,521 ****
  352. X--- 516,525 ----
  353. X     }
  354. X     else if (*temp == '-') {
  355. X        tok.type = Back_t;
  356. X+       tok.val = atoi(temp + 1);
  357. X+    }
  358. X+    else if (*temp == '*') {
  359. X+       tok.type = Repeat_t;
  360. X        tok.val = atoi(temp + 1);
  361. X     }
  362. X     else {
  363. X*** ../remind-2.0-patch1/nextdate.c    Tue Nov  6 15:53:26 1990
  364. X--- nextdate.c    Tue Nov  6 14:53:10 1990
  365. X***************
  366. X*** 132,142 ****
  367. X       return 0;
  368. X  
  369. X        case 7: /* Year, month and day constrained */
  370. X-      if (y > conyr || (y == conyr && m > conmon) ||
  371. X-          (y == conyr && m == conmon && d > conday)) return 1;
  372. X       *retday = conday;
  373. X       *retmon = conmon;
  374. X       *retyr = conyr;
  375. X       return 0;
  376. X  
  377. X        case 8: /* Only the weekday constrained.  Let's go to Julian mode */
  378. X--- 132,142 ----
  379. X       return 0;
  380. X  
  381. X        case 7: /* Year, month and day constrained */
  382. X       *retday = conday;
  383. X       *retmon = conmon;
  384. X       *retyr = conyr;
  385. X+      if (y > conyr || (y == conyr && m > conmon) ||
  386. X+          (y == conyr && m == conmon && d > conday)) return 1;
  387. X       return 0;
  388. X  
  389. X        case 8: /* Only the weekday constrained.  Let's go to Julian mode */
  390. X***************
  391. X*** 302,312 ****
  392. X       jul2 = Julian(d, m, y);
  393. X       jul = Julian(conday, conmon, conyr);
  394. X       while (!(wkday & (1 << (jul % 7)))) jul++;
  395. X-      if (jul < jul2) return 1;
  396. X       FromJulian(jul, retday, retmon, retyr);
  397. X       return 0;
  398. X     }
  399. X  }
  400. X- #ifndef UNIX
  401. X- 
  402. X- #endif UNIX
  403. X--- 302,309 ----
  404. X       jul2 = Julian(d, m, y);
  405. X       jul = Julian(conday, conmon, conyr);
  406. X       while (!(wkday & (1 << (jul % 7)))) jul++;
  407. X       FromJulian(jul, retday, retmon, retyr);
  408. X+      if (jul < jul2) return 1;
  409. X       return 0;
  410. X     }
  411. X  }
  412. X*** ../remind-2.0-patch1/remind.1    Tue Nov  6 15:53:27 1990
  413. X--- remind.1    Tue Nov  6 15:50:33 1990
  414. X***************
  415. X*** 134,182 ****
  416. X  .SH THE REM COMMAND
  417. X  The most-used command in a reminder file is the
  418. X  .I REM
  419. X! command.  This command is used to denote a reminder.  There are two
  420. X  forms of the
  421. X  .I REM
  422. X! command; they are:
  423. X  .RS
  424. X! REM [ONCE]
  425. X! [
  426. X! .I date_spec
  427. X! ]
  428. X! [
  429. X! .I delta
  430. X! ]
  431. X! [
  432. X! .I back
  433. X! ]
  434. X! [
  435. X! OMIT
  436. X! .I omit_list
  437. X! ]
  438. X! MSG
  439. X  .I body
  440. X- .PP
  441. X- REM [ONCE]
  442. X- [
  443. X- .I date_spec
  444. X- ]
  445. X- [
  446. X- .I delta
  447. X- ]
  448. X- [
  449. X- .I back
  450. X- ]
  451. X- [
  452. X- OMIT
  453. X- .I omit_list
  454. X- ]
  455. X- RUN
  456. X- .I body
  457. X  .RE
  458. X  The
  459. X! .I date_spec, delta
  460. X  and
  461. X! .I back
  462. X  can be specified in any order.  The 
  463. X  .I OMIT, 
  464. X  if present, must follow these three
  465. X--- 134,158 ----
  466. X  .SH THE REM COMMAND
  467. X  The most-used command in a reminder file is the
  468. X  .I REM
  469. X! command.  This command is used to denote a reminder.  There are many
  470. X  forms of the
  471. X  .I REM
  472. X! command; they are represented by:
  473. X! .PP
  474. X  .RS
  475. X! REM [ONCE] [\fIdate_spec\fR]
  476. X! [\fIdelta\fR]
  477. X! [\fIback\fR]
  478. X! [\fIrepeat\fR]
  479. X! [OMIT \fIomit_list\fR]
  480. X! [MSG | RUN]
  481. X  .I body
  482. X  .RE
  483. X+ .PP
  484. X  The
  485. X! .I date_spec, delta, back
  486. X  and
  487. X! .I repeat
  488. X  can be specified in any order.  The 
  489. X  .I OMIT, 
  490. X  if present, must follow these three
  491. X***************
  492. X*** 476,481 ****
  493. X--- 452,503 ----
  494. X  The reminder "Test3" will be triggered on the last Monday of every month,
  495. X  as well as the three days preceding it.
  496. X  .PP
  497. X+ .B Repeating Reminders
  498. X+ .PP
  499. X+ The
  500. X+ .I repeat
  501. X+ component in a reminder is a number preceded by an asterisk; for example,
  502. X+ "*14".  The
  503. X+ .I repeat
  504. X+ is used to remind you of events which occur regularly after a specified
  505. X+ start date.  For example, suppose you get paid every second Thursday,
  506. X+ and that your last payday was 8 November 1990.  The following reminder
  507. X+ would remind you of each payday 3 days in advance:
  508. X+ .PP
  509. X+ .nf
  510. X+     REM 8 Nov 1990 *14 +3 MSG Payday is %b!
  511. X+ .fi
  512. X+ .PP
  513. X+ The
  514. X+ .I repeat
  515. X+ component of "*14" would cause the reminder to be triggered every 14
  516. X+ days from the start date.
  517. X+ .PP
  518. X+ In order to use a
  519. X+ .I repeat,
  520. X+ you must fully specify the start date.  That means that if
  521. X+ you use a
  522. X+ .I repeat,
  523. X+ you must specify the
  524. X+ .I month, day
  525. X+ and
  526. X+ .I year.
  527. X+ You can also specify
  528. X+ .I weekday, back
  529. X+ and
  530. X+ .I local OMITs
  531. X+ but these only affect the calculation of the start date.  Once the
  532. X+ start date is calculated, the reminder is issued regularly every
  533. X+ .I repeat
  534. X+ days.  Note, in particular, that once the start date is calculated,
  535. X+ .B remind
  536. X+ ignores local and global
  537. X+ .I OMITs
  538. X+ when calculating the trigger date.  The final trigger date is strictly
  539. X+ a multiple of
  540. X+ .I repeat
  541. X+ days from the start date.
  542. X+ .PP
  543. X  .B The MSG Keyword
  544. X  .PP
  545. X  The
  546. X***************
  547. X*** 979,985 ****
  548. X  The file "notes.new" would contain all non-expired lines from "notes.old."
  549. X  All expired lines are echoed to the screen.
  550. X  .I INCLUDEd
  551. X! files are read an processed, but not purged.  You must purge each
  552. X  .I INCLUDEd
  553. X  file separately.
  554. X  .PP
  555. X--- 1001,1007 ----
  556. X  The file "notes.new" would contain all non-expired lines from "notes.old."
  557. X  All expired lines are echoed to the screen.
  558. X  .I INCLUDEd
  559. X! files are read and processed, but not purged.  You must purge each
  560. X  .I INCLUDEd
  561. X  file separately.
  562. X  .PP
  563. SHAR_EOF
  564. $TOUCH -am 1106155890 patch.02 &&
  565. chmod 0600 patch.02 ||
  566. echo "restore of patch.02 failed"
  567. set `wc -c patch.02`;Wc_c=$1
  568. if test "$Wc_c" != "12130"; then
  569.     echo original size 12130, current size $Wc_c
  570. fi
  571. fi
  572. exit 0
  573.