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

  1. From: dfs@doe.carleton.ca (David F. Skoll)
  2. Newsgroups: alt.sources
  3. Subject: REMIND 2.2 01/05
  4. Message-ID: <dfs.658780993@yar>
  5. Date: 16 Nov 90 18:43:13 GMT
  6.  
  7.  
  8. This is REMIND version 2.2.  It has all the advanced date calculation
  9. features of REMIND 2.1, as well as:
  10.  
  11. - The addition of a time field.
  12.  
  13. - The ability to run in the background and issue reminders at a specific
  14. time.  You can be reminded in advance of the time, and have the reminder
  15. repeatedly remind you with a specified interval.
  16.  
  17. - The addition of a "calendar" facility - REMIND will examine your reminder
  18. file, and produce an annotated calendar for printout.
  19.  
  20. - The source code has been cleaned up so that REMIND compiles quietly
  21. on an MS-DOS machine, and should work on SYSV machines with no modification.
  22.  
  23. Because so much code was modified, I'm posting the whole thing, rather than
  24. patches.  So here goes...
  25.  
  26. --
  27. David Skoll
  28.  
  29. ---- CUT HERE ----
  30. #!/bin/sh
  31. # This is Remind-2.2, a shell archive (shar 3.32)
  32. # made 11/16/1990 18:41 UTC by dfs@yar
  33. # Source directory /enterprise/navigation/dfs/work/.rem/work
  34. #
  35. # existing files will NOT be overwritten
  36. #
  37. # This shar contains:
  38. # length  mode       name
  39. # ------ ---------- ------------------------------------------
  40. #    991 -rw------- COPYRIGHT
  41. #    577 -rw------- Makefile
  42. #    934 -rw------- README.DOS
  43. #   1522 -rw------- README.UNIX
  44. #    417 -rw------- WHATSNEW.22
  45. #   4759 -rw------- cache.c
  46. #    782 -rw------- cache.h
  47. #  13495 -rw------- calendar.c
  48. #   2085 -rw------- defines.h
  49. #   8966 -rw------- dorem.c
  50. #   7683 -rw------- dosubst.c
  51. #   8338 -rw------- files.c
  52. #   1450 -rw------- globals.h
  53. #   5675 -rw------- init.c
  54. #  21719 -rw------- main.c
  55. #   8637 -rw------- nextdate.c
  56. #   1717 -rw------- protos.h
  57. #   1568 -rwx------ remind-all.csh
  58. #   1589 -rwx------ remind-all.sh
  59. #  32451 -rw------- remind.1
  60. #    847 -rw------- remind.mak
  61. #   7436 -rw------- timed.c
  62. #
  63. if touch 2>&1 | fgrep 'amc' > /dev/null
  64.  then TOUCH=touch
  65.  else TOUCH=true
  66. fi
  67. # ============= COPYRIGHT ==============
  68. if test X"$1" != X"-c" -a -f 'COPYRIGHT'; then
  69.     echo "File already exists: skipping 'COPYRIGHT'"
  70. else
  71. echo "x - extracting COPYRIGHT (Text)"
  72. sed 's/^X//' << 'SHAR_EOF' > COPYRIGHT &&
  73. XTHE REMIND COPYRIGHT
  74. X
  75. XREMIND refers to the entire set of files and documentation in the
  76. XREMIND package.
  77. X
  78. XREMIND is Copyright (C) 1990 by David Skoll, except for the file
  79. Xremind-all.sh, which is Copyright (C) 1990 by Bill Aten.
  80. X
  81. XYou may use REMIND for free, and may freely distribute it, providing
  82. Xyou do not charge the recipients to whom you distribute REMIND.
  83. X
  84. XYou may modify REMIND.  However, you must clearly indicate such
  85. Xmodifications when you distribute REMIND, and must tell the
  86. Xrecipients of the modified version that it is modified.  Place that
  87. Xnotice in the WHATSNEW.xx file.
  88. X
  89. XYou may incorporate parts of REMIND into your own programs, providing
  90. Xyou do not sell these programs.  You must clearly indicate that the parts
  91. Xof REMIND you have incorporated are Copyright (C) 1990 by David Skoll.
  92. X
  93. XI will attempt to support REMIND as much as possible.  However, you use
  94. Xit at your own risk.  I am not responsible for any damages caused by
  95. Xthe use or misuse of REMIND.
  96. X--
  97. XDavid F. Skoll
  98. SHAR_EOF
  99. $TOUCH -am 1116132790 COPYRIGHT &&
  100. chmod 0600 COPYRIGHT ||
  101. echo "restore of COPYRIGHT failed"
  102. set `wc -c COPYRIGHT`;Wc_c=$1
  103. if test "$Wc_c" != "991"; then
  104.     echo original size 991, current size $Wc_c
  105. fi
  106. fi
  107. # ============= Makefile ==============
  108. if test X"$1" != X"-c" -a -f 'Makefile'; then
  109.     echo "File already exists: skipping 'Makefile'"
  110. else
  111. echo "x - extracting Makefile (Text)"
  112. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  113. X# Makefile for REMIND - simple file
  114. X
  115. X#If you have a BSD system:
  116. XCFLAGS= -O -DUNIX
  117. X
  118. X#If you have a SYSV system, comment previous line and uncomment next line:
  119. X#CFLAGS= -O -DUNIX -DSYSV
  120. X
  121. Xall: dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  122. X    $(LINK.c) -o remind dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o
  123. X
  124. Xdorem.o: dorem.c
  125. X
  126. Xfiles.o: files.c
  127. X
  128. Xmain.o:  main.c
  129. X
  130. Xnextdate.o: nextdate.c
  131. X
  132. Xinit.o: init.c
  133. X
  134. Xdosubst.o: dosubst.c
  135. X
  136. Xtimed.o: timed.c
  137. X
  138. Xcalendar.o: calendar.c
  139. X
  140. Xcache.o: cache.c
  141. X
  142. Xclean:
  143. X    rm -f *.o core *~ remind
  144. X
  145. SHAR_EOF
  146. $TOUCH -am 1115153090 Makefile &&
  147. chmod 0600 Makefile ||
  148. echo "restore of Makefile failed"
  149. set `wc -c Makefile`;Wc_c=$1
  150. if test "$Wc_c" != "577"; then
  151.     echo original size 577, current size $Wc_c
  152. fi
  153. fi
  154. # ============= README.DOS ==============
  155. if test X"$1" != X"-c" -a -f 'README.DOS'; then
  156.     echo "File already exists: skipping 'README.DOS'"
  157. else
  158. echo "x - extracting README.DOS (Text)"
  159. sed 's/^X//' << 'SHAR_EOF' > README.DOS &&
  160. XREMIND 2.2 for MS-DOS
  161. X
  162. XFirst, read the files COPYRIGHT and WHATSNEW.22.
  163. X
  164. XREMIND was originally written for MS-DOS.  To compile it, you need
  165. Xthe Microsoft C compiler (at least version 5.1) and the Microsoft
  166. XMAKE utility.
  167. X
  168. XBefore compiling the software, check if it includes patches.  These
  169. Xare files called patch.xx.  If there are patches, apply them all by typing
  170. X
  171. Xcat patch.* | patch
  172. X
  173. XTo compile the software, simply go to the source directory and type:
  174. X
  175. XMAKE REMIND.MAK
  176. X
  177. XNote that the MS-DOS version of REMIND operates slightly differently from
  178. Xthe UNIX version:  MS-DOS has no concept of file access date.  Thus, to
  179. Ximplement the "ONCE" keyword, REMIND will change the modification date
  180. Xof the top-level reminder file after it has run.  This is equivalent to
  181. Xperforming a "touch" of the file after running REMIND.
  182. X
  183. XAlso, the MS-DOS version does not queue AT reminders for timed activation.
  184. X--
  185. XDavid F. Skoll <dfs@doe.carleton.ca>
  186. X
  187. SHAR_EOF
  188. $TOUCH -am 1116132890 README.DOS &&
  189. chmod 0600 README.DOS ||
  190. echo "restore of README.DOS failed"
  191. set `wc -c README.DOS`;Wc_c=$1
  192. if test "$Wc_c" != "934"; then
  193.     echo original size 934, current size $Wc_c
  194. fi
  195. fi
  196. # ============= README.UNIX ==============
  197. if test X"$1" != X"-c" -a -f 'README.UNIX'; then
  198.     echo "File already exists: skipping 'README.UNIX'"
  199. else
  200. echo "x - extracting README.UNIX (Text)"
  201. sed 's/^X//' << 'SHAR_EOF' > README.UNIX &&
  202. XREMIND version 2.2 for UNIX
  203. X
  204. XFirst, read the files COPYRIGHT and WHATSNEW.22
  205. X
  206. XBefore compiling the software, check if it includes patches.  These
  207. Xare files called patch.xx.  If there are patches, apply them all by typing
  208. X
  209. Xcat patch.* | patch
  210. X
  211. XThe Makefile is very simple and naive.  It is set up for a BSD system.
  212. XIf you have a SYSV system, edit the Makefile.  Comment out the line
  213. Xwhich reads:
  214. X
  215. X    CFLAGS= -O -DUNIX
  216. X
  217. Xand uncomment the line which reads:
  218. X
  219. X    CFLAGS= -O -DUNIX -DSYSV
  220. X
  221. XTo compile REMIND, just go to the source directory and type "make".
  222. XThis creates the executable file "remind".  You can type  "make CC=gcc"
  223. Xif you want to use the Gnu C Compiler.
  224. X
  225. XREMIND has been compiled on Sun3s and Sun4s under Sun OS 4.0.  A previous
  226. Xversion compiled successfully on a Xenix system.  REMIND should compile
  227. Xon most systems, as it makes very few system calls.
  228. X
  229. XOnce remind has been compiled, install it in your favourite system directory.
  230. XThe manual is in the file "remind.1".  You can install it in the appropriate
  231. Xman page directory.  Remember to change the file suffix if you install it
  232. Xin the "l" (local) or "n" (new) directory.
  233. X
  234. XTwo shell scripts, "remind-all.csh" and "remind-all.sh" are provided.  These
  235. Xallow automatic mailing of reminders to all users who create a $HOME/.reminders
  236. Xfile.  These two scripts are equivalent; one is a "sh" script and the other
  237. Xis a "csh" script.  Pick the one you want to use, and follow the instructions
  238. Xin the opening comments of the script.
  239. X--
  240. XDavid F. Skoll <dfs@doe.carleton.ca>
  241. SHAR_EOF
  242. $TOUCH -am 1116132890 README.UNIX &&
  243. chmod 0600 README.UNIX ||
  244. echo "restore of README.UNIX failed"
  245. set `wc -c README.UNIX`;Wc_c=$1
  246. if test "$Wc_c" != "1522"; then
  247.     echo original size 1522, current size $Wc_c
  248. fi
  249. fi
  250. # ============= WHATSNEW.22 ==============
  251. if test X"$1" != X"-c" -a -f 'WHATSNEW.22'; then
  252.     echo "File already exists: skipping 'WHATSNEW.22'"
  253. else
  254. echo "x - extracting WHATSNEW.22 (Text)"
  255. sed 's/^X//' << 'SHAR_EOF' > WHATSNEW.22 &&
  256. XA BRIEF HISTORY OF REMIND:
  257. X
  258. XVersion 1.0 - never publicly released.
  259. X
  260. XVersion 2.0 - first public release.  Included advanced date specifications,
  261. Xcharacter substitution, and the RUN keyword.
  262. X
  263. XVersion 2.1 - Added the "repeat" token for repeating reminders with a period
  264. Xother than 7 days.  Also fixed some bugs from version 2.0
  265. X
  266. XVersion 2.2 - Added the AT keyword, the timed reminders daemon, and the
  267. Xcalendar facility.
  268. SHAR_EOF
  269. $TOUCH -am 1116132290 WHATSNEW.22 &&
  270. chmod 0600 WHATSNEW.22 ||
  271. echo "restore of WHATSNEW.22 failed"
  272. set `wc -c WHATSNEW.22`;Wc_c=$1
  273. if test "$Wc_c" != "417"; then
  274.     echo original size 417, current size $Wc_c
  275. fi
  276. fi
  277. # ============= cache.c ==============
  278. if test X"$1" != X"-c" -a -f 'cache.c'; then
  279.     echo "File already exists: skipping 'cache.c'"
  280. else
  281. echo "x - extracting cache.c (Text)"
  282. sed 's/^X//' << 'SHAR_EOF' > cache.c &&
  283. X/***************************************************************/
  284. X/*                                                             */
  285. X/* CACHE.C                                                     */
  286. X/*                                                             */
  287. X/* Contains routines for caching reminder file to improve      */
  288. X/* calendar performance.                                       */
  289. X/*                                                             */
  290. X/* By David Skoll - 15 November 1990                           */
  291. X/***************************************************************/
  292. X
  293. X#include <stdio.h>
  294. X#include <malloc.h>
  295. X#ifndef UNIX
  296. X#include <string.h>
  297. X#endif
  298. X#include "defines.h"
  299. X#include "globals.h"
  300. X#include "protos.h"
  301. X#include "cache.h"
  302. X
  303. X/* Define a cached line */
  304. Xtypedef struct cached_line {
  305. X   char *text;
  306. X   struct cached_line *next;
  307. X} Centry;
  308. X
  309. XCentry Cache, *Current;
  310. X
  311. Xstatic int CacheDone, CacheFailed;
  312. X
  313. X/***************************************************************/
  314. X/*                                                             */
  315. X/*  InitCache                                                  */
  316. X/*                                                             */
  317. X/*  Initializes the caching system.                            */
  318. X/*                                                             */
  319. X/***************************************************************/
  320. X#ifndef UNIX
  321. Xvoid InitCache(void)
  322. X#else
  323. Xvoid InitCache()
  324. X#endif
  325. X{
  326. X   CacheDone   = 0;
  327. X   CacheFailed = 0;
  328. X   Cache.next  = NULL;
  329. X   Current     = &Cache;
  330. X}
  331. X
  332. X/***************************************************************/
  333. X/*                                                             */
  334. X/* GetLine                                                     */
  335. X/*                                                             */
  336. X/* This function either reads a line from the file, or gets    */
  337. X/* it from memory if it is cached.                             */
  338. X/*                                                             */
  339. X/* Returns 0 if more data to be read; otherwise, non-zero.     */
  340. X/*                                                             */
  341. X/*                                                             */
  342. X/***************************************************************/
  343. X#ifndef UNIX
  344. Xint GetLine(void)
  345. X#else
  346. Xint GetLine()
  347. X#endif
  348. X{
  349. X   int ret;
  350. X   Token tok;
  351. X   char *s;
  352. X   Centry *c;
  353. X
  354. X   if (CacheFailed) return ReadLine();
  355. X
  356. X   if (!CacheDone) {
  357. X      ret = ReadLine();
  358. X      if (ret) {
  359. X         CacheDone = 1;
  360. X         strcpy(FileName, "* cache *");
  361. X     CurLine = 0;
  362. X         return ret;
  363. X      }         
  364. X      /* Check if we should cache this line */
  365. X
  366. X      s = Line;
  367. X      tok = ParseToken(&s);
  368. X      if (tok.type == Rem_t) { /* Yup, this is a REM, so cache it */
  369. X         c = (Centry *) malloc(sizeof(Centry));
  370. X         if (c == NULL) {
  371. X            CacheFailed = 1;
  372. X            DestroyCache();
  373. X            return 0;
  374. X         }
  375. X         c->text = (char *) malloc(strlen(Line)+1);
  376. X         if (c->text == NULL) {
  377. X            CacheFailed = 1;
  378. X        DestroyCache();
  379. X            free(c);
  380. X        return 0;
  381. X         }
  382. X         /* Insert the cache entry */
  383. X         c->next = NULL;
  384. X         strcpy(c->text, Line);
  385. X         Current->next = c;
  386. X         Current = c;
  387. X      }
  388. X      return ret;
  389. X   } else { /* Over here, we've finished caching, so just return the line */
  390. X      if (Current == NULL) return 1;
  391. X      else {
  392. X         strcpy(Line, Current->text);
  393. X         Current = Current->next;
  394. X         return 0;
  395. X      }
  396. X   }
  397. X}
  398. X/***************************************************************/
  399. X/*                                                             */
  400. X/* ResetCache                                                  */
  401. X/* Reset the cache to beginning, or reopen file if caching     */
  402. X/* failed.                                                     */
  403. X/*                                                             */
  404. X/***************************************************************/
  405. X#ifndef UNIX
  406. Xvoid ResetCache(void)
  407. X#else
  408. Xvoid ResetCache()
  409. X#endif
  410. X{
  411. X   if (CacheFailed) OpenFile(FileName);
  412. X   else Current = Cache.next;
  413. X}
  414. X
  415. X/***************************************************************/
  416. X/*                                                             */
  417. X/* DestroyCache                                                */
  418. X/* Frees all memory used by the cache.                         */
  419. X/*                                                             */
  420. X/***************************************************************/
  421. X#ifndef UNIX
  422. Xvoid DestroyCache(void)
  423. X#else
  424. Xvoid DestroyCache()
  425. X#endif
  426. X{
  427. X   Centry *p = &Cache;
  428. X   Centry *c = p->next;
  429. X
  430. X   while (c) {
  431. X      if (c->text) free(c->text);
  432. X      p = c;
  433. X      c = c->next;
  434. X      free(p);
  435. X   }
  436. X   Cache.next = NULL;
  437. X}
  438. SHAR_EOF
  439. $TOUCH -am 1116133890 cache.c &&
  440. chmod 0600 cache.c ||
  441. echo "restore of cache.c failed"
  442. set `wc -c cache.c`;Wc_c=$1
  443. if test "$Wc_c" != "4759"; then
  444.     echo original size 4759, current size $Wc_c
  445. fi
  446. fi
  447. # ============= cache.h ==============
  448. if test X"$1" != X"-c" -a -f 'cache.h'; then
  449.     echo "File already exists: skipping 'cache.h'"
  450. else
  451. echo "x - extracting cache.h (Text)"
  452. sed 's/^X//' << 'SHAR_EOF' > cache.h &&
  453. X/***************************************************************/
  454. X/*                                                             */
  455. X/*  CACHE.H                                                    */
  456. X/*                                                             */
  457. X/*  Function prototypes, etc. for CACHE.C                      */
  458. X/*                                                             */
  459. X/*  By David Skoll - 15 November 1990                          */
  460. X/*                                                             */
  461. X/***************************************************************/
  462. X#ifndef UNIX
  463. Xvoid InitCache(void);
  464. Xint GetLine(void);
  465. Xvoid ResetCache(void);
  466. Xvoid DestroyCache(void);
  467. X#else
  468. Xvoid InitCache();
  469. Xint GetLine();
  470. Xvoid ResetCache();
  471. Xvoid DestroyCache();
  472. X#endif
  473. SHAR_EOF
  474. $TOUCH -am 1116093790 cache.h &&
  475. chmod 0600 cache.h ||
  476. echo "restore of cache.h failed"
  477. set `wc -c cache.h`;Wc_c=$1
  478. if test "$Wc_c" != "782"; then
  479.     echo original size 782, current size $Wc_c
  480. fi
  481. fi
  482. # ============= calendar.c ==============
  483. if test X"$1" != X"-c" -a -f 'calendar.c'; then
  484.     echo "File already exists: skipping 'calendar.c'"
  485. else
  486. echo "x - extracting calendar.c (Text)"
  487. sed 's/^X//' << 'SHAR_EOF' > calendar.c &&
  488. X/***************************************************************/
  489. X/*                                                             */
  490. X/* CALENDAR.C                                                  */
  491. X/*                                                             */
  492. X/* Contains routines and data structures for producing a       */
  493. X/* calendar from a reminder file.                              */
  494. X/*                                                             */
  495. X/* By David Skoll - 14 November 1990                           */
  496. X/*                                                             */
  497. X/***************************************************************/
  498. X#include <stdio.h>
  499. X#include <malloc.h>
  500. X#include <ctype.h>
  501. X#ifndef UNIX
  502. X#include <string.h>
  503. X#include <stdlib.h>
  504. X#endif
  505. X#include "defines.h"
  506. X#include "globals.h"
  507. X#include "protos.h"
  508. X#include "cache.h"
  509. X
  510. X/* Convert (monday-sunday) sequence to (sunday-saturday) */
  511. X#define DayOfWeek(julian) ((((julian) % 7) + 1) % 7)
  512. X
  513. X/* To center an item of length l in a field of length f, how many spaces? */
  514. X#define PreCenter(f, l) (((f)-(l))/2)
  515. X
  516. X/* How many spaces AFTEr the centered item? */
  517. X#define PostCenter(f, l) ((f)-(l)-((f)-(l))/2)
  518. X
  519. X/* Define the structure of a calendar entry */
  520. Xtypedef struct CalEntry_t {
  521. X   int tim;
  522. X   char *text, *current;
  523. X   struct CalEntry_t *next;
  524. X} CalEntry;
  525. X
  526. X/* Have a main calendar entry for each weekday */
  527. XCalEntry entry[7];
  528. Xint used[7];  /* These hold the day of the month for corresponding
  529. X                 entry - 0 if not used */
  530. X
  531. X/* Static integers for various stuff */
  532. Xstatic int TotalWidth;
  533. X
  534. X/* Make function prototypes local - they're not used anywhere else */
  535. X#ifndef UNIX
  536. XCalEntry *CreateCalEntry(void);
  537. Xvoid AddCalEntry(CalEntry *e);
  538. Xvoid EmitOneCalendarLine(void);
  539. Xvoid InitCalendar(int m, int y);
  540. Xvoid FinishCalendar(void);
  541. Xvoid DoEntries(void);
  542. X#else
  543. XCalEntry *CreateCalEntry();
  544. Xvoid AddCalEntry();
  545. Xvoid EmitOneCalendarLine();
  546. Xvoid InitCalendar();
  547. Xvoid FinishCalendar();
  548. Xvoid DoEntries();
  549. X#endif
  550. X
  551. X/***************************************************************/
  552. X/*                                                             */
  553. X/* DoCalendar - main loop for the calendar command.            */
  554. X/*                                                             */
  555. X/***************************************************************/
  556. X#ifdef UNIX
  557. Xvoid DoCalendar()
  558. X#else
  559. Xvoid DoCalendar(void)
  560. X#endif
  561. X{
  562. X   int y, m, d, init;
  563. X
  564. X   TotalWidth = 7*CalWidth + 8;
  565. X
  566. X   /* Move back until beginning of month */
  567. X   FromJulian(JulianToday, &d, &m, &y);
  568. X   while (d != 1) {
  569. X      JulianToday--;
  570. X      FromJulian(JulianToday, &d, &m, &y);
  571. X   }
  572. X
  573. X   init = 0;
  574. X   InitCache();
  575. X   while (Calendar) {
  576. X      FromJulian(JulianToday, &d, &m, &y);
  577. X      CurDay = d;
  578. X      CurMon = m;
  579. X      CurYear = y;
  580. X      if (init == 0 || CurDay == 1) { InitCalendar(m, y); init = 1; }
  581. X      DoEntries();
  582. X      if (d == DaysInMonth(m, y)) Calendar--;
  583. X      JulianToday++;
  584. X      if (Calendar) ResetCache();
  585. X   }
  586. X   if (CurDay != DaysInMonth(CurMon, CurYear)) FinishCalendar();
  587. X   DestroyCache();
  588. X}
  589. X
  590. X/***************************************************************/
  591. X/*                                                             */
  592. X/* PrintChars:  Print n of the specified character             */
  593. X/* CopyChars:  Copy n of the character to the output buffer    */
  594. X/*                                                             */
  595. X/***************************************************************/
  596. X#ifndef UNIX
  597. Xvoid PrintChars(int n, int c)
  598. X#else
  599. Xvoid PrintChars(n, c)
  600. Xint n, c;
  601. X#endif
  602. X{
  603. X   while(n--) putchar(c);
  604. X}
  605. X
  606. X#ifndef UNIX
  607. Xchar *CopyChars(int n, int c, char *dst)
  608. X#else
  609. Xchar *CopyChars(n, c, dst)
  610. Xint n, c;
  611. Xchar *dst;
  612. X#endif
  613. X{
  614. X   while(n--) *dst++ = (char) c;
  615. X   return dst;
  616. X}
  617. X
  618. X/***************************************************************/
  619. X/*                                                             */
  620. X/* InitCalendar                                                */
  621. X/* Print the calendar header                                   */
  622. X/*                                                             */
  623. X/***************************************************************/
  624. X#ifndef UNIX
  625. Xvoid InitCalendar(int m, int y)
  626. X#else
  627. Xvoid InitCalendar(m, y)
  628. Xint y, m;
  629. X#endif
  630. X{
  631. X   int i;
  632. X
  633. X   if (SimpleCalendar) return;
  634. X   
  635. X   for (i=0; i<7; i++) {
  636. X      entry[i].next = NULL;
  637. X      used[i] = 0;
  638. X   }
  639. X
  640. X   /* Emit the calendar title */
  641. X   putchar('+');
  642. X   PrintChars(TotalWidth-2, '-');
  643. X   putchar('+');
  644. X   putchar('\n');
  645. X   sprintf(TmpBuf, "%s %d", MonthName[m], y);
  646. X   putchar('|');
  647. X   PrintChars(PreCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
  648. X   printf("%s", TmpBuf);
  649. X   PrintChars(PostCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
  650. X   putchar('|');
  651. X   putchar('\n');
  652. X   putchar('+');
  653. X   for (i=0; i<7; i++) {
  654. X      PrintChars(CalWidth, '-');
  655. X      putchar('+');
  656. X   }
  657. X   putchar('\n');
  658. X
  659. X   /* Put the weekdays in */
  660. X   /* Argh! Do sunday first, then take care of rest */
  661. X   i = 6;
  662. X   putchar('|');
  663. X   PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
  664. X   printf(DayName[i]);
  665. X   PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
  666. X
  667. X   for (i=0; i<6; i++) {
  668. X      putchar('|');
  669. X      PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
  670. X      printf(DayName[i]);
  671. X      PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
  672. X   }
  673. X   putchar('|');
  674. X   putchar('\n');
  675. X   putchar('+');
  676. X   for (i=0; i<7; i++) {
  677. X      PrintChars(CalWidth, '-');
  678. X      putchar('+');
  679. X   }
  680. X   putchar('\n');
  681. X}
  682. X
  683. X/***************************************************************/
  684. X/*                                                             */
  685. X/* FinishCalendar                                              */
  686. X/* Just print a form feed.                                     */
  687. X/*                                                             */
  688. X/***************************************************************/
  689. X#ifndef UNIX
  690. Xvoid FinishCalendar(void)
  691. X#else
  692. Xvoid FinishCalendar()
  693. X#endif
  694. X{
  695. X   if (SimpleCalendar) return;
  696. X   putchar('\f');
  697. X   putchar('\n');
  698. X}
  699. X
  700. X/***************************************************************/
  701. X/*                                                             */
  702. X/* DoEntries                                                   */
  703. X/* Create all the calendar entries for this week               */
  704. X/*                                                             */
  705. X/***************************************************************/
  706. X#ifndef UNIX
  707. Xvoid DoEntries(void)
  708. X#else
  709. Xvoid DoEntries()
  710. X#endif
  711. X{
  712. X   int i;
  713. X   CalEntry *e;
  714. X
  715. X   while (1) {
  716. X      used[DayOfWeek(JulianToday)] = CurDay;
  717. X      if (GetLine()) break;
  718. X      i = ProcessLine();
  719. X      if (i) if (e = CreateCalEntry()) AddCalEntry(e);
  720. X   }
  721. X
  722. X   /* Now figure out if we should print the calendar */
  723. X   if ((DayOfWeek(JulianToday) == 6 ) || CurDay == DaysInMonth(CurMon, CurYear))
  724. X      EmitOneCalendarLine();
  725. X   if (CurDay == DaysInMonth(CurMon, CurYear)) FinishCalendar();
  726. X}
  727. X
  728. X/***************************************************************/
  729. X/*                                                             */
  730. X/* AddCalEntry                                                 */
  731. X/* Add a calendar entry for the appropriate weekday.           */
  732. X/*                                                             */
  733. X/***************************************************************/
  734. X#ifndef UNIX
  735. Xvoid AddCalEntry(CalEntry *e)
  736. X#else
  737. Xvoid AddCalEntry(e)
  738. XCalEntry *e;
  739. X#endif
  740. X{
  741. X   CalEntry *curr, *prev;
  742. X
  743. X   prev = &entry[DayOfWeek(JulianToday)];
  744. X   curr = prev->next;
  745. X   while (curr) {
  746. X      if (e->tim == -1 || (e->tim >= curr->tim && curr->tim != -1)) {
  747. X         prev = curr;
  748. X         curr = prev->next;
  749. X      } else {
  750. X         prev->next = e;
  751. X     e->next    = curr;
  752. X         break;
  753. X      }
  754. X   }
  755. X   if (!curr) {
  756. X      prev->next = e;
  757. X      e->next = NULL;
  758. X   }
  759. X}
  760. X
  761. X#ifndef UNIX
  762. Xvoid CopyWord(char **src, char **dst, int l)
  763. X#else
  764. Xvoid CopyWord(src, dst, l)
  765. Xchar **src, **dst;
  766. Xint l;
  767. X#endif
  768. X{
  769. X   while(**src && !isspace(**src) && l--) *(*dst)++ = *(*src)++;
  770. X}
  771. X
  772. X#ifndef UNIX
  773. Xint WordLen(char *src)
  774. X#else
  775. Xint WordLen(src)
  776. Xchar *src;
  777. X#endif
  778. X{
  779. X   int len = 0;
  780. X   while (*src && !isspace(*src)) { len++; src++; }
  781. X   return len;
  782. X}
  783. X/***************************************************************/
  784. X/*                                                             */
  785. X/* CreateCalEntry                                              */
  786. X/*                                                             */
  787. X/* Allocates and creates a calendar entry.                     */
  788. X/*                                                             */
  789. X/***************************************************************/
  790. X#ifndef UNIX
  791. XCalEntry *CreateCalEntry(void)
  792. X#else
  793. XCalEntry *CreateCalEntry()
  794. X#endif
  795. X{
  796. X   CalEntry *e;
  797. X   char *s, *t;
  798. X   int column, l;
  799. X   if (!SimpleCalendar) {
  800. X      e = (CalEntry *) malloc(sizeof(CalEntry));
  801. X
  802. X      if (e == NULL) {
  803. X         fprintf(stderr, "remind: Can't malloc to create calendar entry.\n");
  804. X         exit(1);
  805. X      }
  806. X      e->next = NULL;
  807. X      e->tim  = CalTime;
  808. X   }
  809. X
  810. X   /* Process the text:  First, look for %" marks.  Then, copy the time
  811. X      and delete any newlines. */
  812. X   s = WorkBuf;
  813. X   t = WorkBuf;
  814. X
  815. X   while (*s) {
  816. X      if (*s == '%' && *(s+1) == '\"') {
  817. X         t = s+2;
  818. X         break;
  819. X      }
  820. X      s++;
  821. X   }
  822. X
  823. X   /* If we found one, look for another */
  824. X   if (t != s) {
  825. X      s = t;
  826. X      while (*s) {
  827. X         if (*s == '%' && *(s+1) == '\"') {
  828. X            *s = 0;
  829. X            break;
  830. X         }
  831. X         s++;
  832. X      }
  833. X   }
  834. X
  835. X   /* Use temporary buffer to create the text */
  836. X   *TmpBuf = 0;
  837. X
  838. X   /* Copy over the text */
  839. X   if(CalTime != -1) sprintf(TmpBuf, "%02d:%02d ", CalTime / 60, CalTime % 60);
  840. X   s = TmpBuf + strlen(TmpBuf);
  841. X   strcpy(s, t);
  842. X   
  843. X   /* If the buffer contains zero-length string; forget it. */
  844. X   if (!*s) {
  845. X      if (!SimpleCalendar) free(e);
  846. X      return (NULL);
  847. X   }
  848. X
  849. X   /* If we're doing a simple calendar, just spit out the text and end */
  850. X   if (SimpleCalendar) {
  851. X      printf("%04d/%02d/%02d: ", CurYear, 1+CurMon, CurDay);
  852. X      Output(TmpBuf);
  853. X      return (NULL);
  854. X   }
  855. X
  856. X   /* Now copy from TmpBuf to WorkBuf, splitting words as needed */
  857. X   s = TmpBuf;
  858. X   t = WorkBuf;
  859. X   column = 0;
  860. X   while (*s) {
  861. X      l = WordLen(s);
  862. X      if (column == 0 && l >= CalWidth) {
  863. X         CopyWord(&s, &t, CalWidth);
  864. X         *t++ = '\n';
  865. X         while (isspace(*s)) s++;
  866. X      }
  867. X      else if (column != 0 && column+l >= CalWidth) {
  868. X         *t++ = '\n';
  869. X         column = 0;
  870. X         if (l >= CalWidth) {
  871. X            CopyWord(&s, &t, CalWidth);
  872. X            *t++ = '\n';
  873. X            while (isspace(*s)) s++;
  874. X         } else {
  875. X            CopyWord(&s, &t, l);
  876. X            *t++ = ' ';
  877. X            while (isspace(*s)) s++;
  878. X            column = l+1;
  879. X            if (column >= CalWidth) {
  880. X              *(t-1) = '\n';
  881. X              column = 0;
  882. X            }
  883. X     
  884. X         }
  885. X      }
  886. X      else {
  887. X         column += l+1;
  888. X     CopyWord(&s, &t, l);
  889. X         while (isspace(*s)) s++;
  890. X         *t++ = ' ';
  891. X     if (column == CalWidth) {
  892. X           *(t-1) = '\n';
  893. X           column = 0;
  894. X         }
  895. X      }
  896. X   }
  897. X   *t = 0;
  898. X   if (*(t-1) == '\n') *(t-1) = 0;
  899. X
  900. X   /* Finally, copy the string to the calendar entry */
  901. X   e->text = (char *) malloc(strlen(WorkBuf)+1);
  902. X
  903. X   if (!e->text) {
  904. X      fprintf(stderr, "remind: Can't malloc memory for calendar text!\n");
  905. X      exit(1);
  906. X   }
  907. X   strcpy(e->text, WorkBuf);
  908. X   e->current = e->text;
  909. X
  910. X   return e;
  911. X}
  912. X
  913. X/***************************************************************/
  914. X/*                                                             */
  915. X/* EmitOneCalendarLine                                         */
  916. X/* This is the biggie - we print out one line.                 */
  917. X/*                                                             */
  918. X/***************************************************************/
  919. X#ifndef UNIX
  920. Xvoid EmitOneCalendarLine(void)
  921. X#else
  922. Xvoid EmitOneCalendarLine()
  923. X#endif
  924. X{
  925. X   int i, nlines, emit, j;
  926. X   char *s, *dst;
  927. X   CalEntry *e;
  928. X   char pend[7];  /* Reminders with following blanks pending */
  929. X
  930. X   if (SimpleCalendar) return;
  931. X   
  932. X   nlines = 0;
  933. X   for (i=0; i<7; i++) pend[i] = 0;
  934. X   putchar('|');
  935. X   /* First, emit the days of the month */
  936. X   for (i=0; i<7; i++) {
  937. X      if (!used[i]) PrintChars(CalWidth, ' ');
  938. X      else {
  939. X         sprintf(TmpBuf, "%d", used[i]);
  940. X         printf(TmpBuf);
  941. X         PrintChars(CalWidth-strlen(TmpBuf), ' ');
  942. X      }
  943. X      putchar('|');
  944. X   }
  945. X   putchar('\n');
  946. X
  947. X   /* Now cycle through all the reminders until there are none left */
  948. X   emit = 1;
  949. X   while(emit) {
  950. X      dst = WorkBuf;
  951. X      *dst++ = '|';
  952. X      emit = 0;
  953. X      for (i=0; i<7; i++) {
  954. X         if (pend[i] || !used[i] || !entry[i].next) {
  955. X            dst = CopyChars(CalWidth, ' ', dst);
  956. X        *dst++ = '|';
  957. X        if(pend[i]) {pend[i] = 0; emit = 1;}
  958. X            continue;
  959. X         }
  960. X         s = entry[i].next->current;
  961. X     j = 0;
  962. X     emit = 1;
  963. X     while (*s && *s != '\n') {
  964. X        *dst++ = *s++;
  965. X        j++;
  966. X     }
  967. X     dst = CopyChars(CalWidth - j, ' ', dst);
  968. X         if (*s == '\n') entry[i].next->current = s+1;
  969. X         else {
  970. X            e = entry[i].next;
  971. X        entry[i].next = e->next;
  972. X            free(e->text);
  973. X            free(e);
  974. X        if (!entry[i].next) used[i] = 0;
  975. X        else pend[i] = 1;
  976. X         }
  977. X         *dst++ = '|';
  978. X      }
  979. X      *dst = 0;
  980. X      if(emit) printf("%s\n", WorkBuf);
  981. X      nlines += emit;
  982. X   }
  983. X   while(nlines++ < 6) printf("%s\n", WorkBuf);
  984. X
  985. X   putchar('+');
  986. X   for (i=0; i<7; i++) {
  987. X      PrintChars(CalWidth, '-');
  988. X      putchar('+');
  989. X   }
  990. X   putchar('\n');
  991. X   for (i=0; i<7; i++) used[i] = 0;
  992. X}
  993. SHAR_EOF
  994. $TOUCH -am 1116095790 calendar.c &&
  995. chmod 0600 calendar.c ||
  996. echo "restore of calendar.c failed"
  997. set `wc -c calendar.c`;Wc_c=$1
  998. if test "$Wc_c" != "13495"; then
  999.     echo original size 13495, current size $Wc_c
  1000. fi
  1001. fi
  1002. # ============= defines.h ==============
  1003. if test X"$1" != X"-c" -a -f 'defines.h'; then
  1004.     echo "File already exists: skipping 'defines.h'"
  1005. else
  1006. echo "x - extracting defines.h (Text)"
  1007. sed 's/^X//' << 'SHAR_EOF' > defines.h &&
  1008. X/***************************************************************/
  1009. X/*                                                             */
  1010. X/*  DEFINES.H                                                  */
  1011. X/*                                                             */
  1012. X/*  Contains macros and #defines for REMIND program.           */
  1013. X/*                                                             */
  1014. X/*  By David Skoll - 30 Sept 1990.                             */
  1015. X/*                                                             */
  1016. X/***************************************************************/
  1017. X
  1018. X/* User-definable variables.  BASE *must* be a year for which the
  1019. X   first of January is a Monday!!!  FOMITSIZE and POMITSIZE control
  1020. X   the number of fully-specified (dd-mm-yy) and partially-specified
  1021. X   (dd-mm) holidays. */
  1022. X#define BASE 1990
  1023. X#define FOMITSIZE 100
  1024. X#define POMITSIZE 75
  1025. X
  1026. X/* Useful macros */
  1027. X
  1028. X#define upper(c) ( ((c) >= 'a' && (c) <= 'z') ? ((c)-32) : (c) )
  1029. X#define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 ))
  1030. X#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
  1031. X#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
  1032. X#define TimeLess(h1, m1, h2, m2) (((h1) < (h2)) || (((h1) == (h2)) && ((m1) < (m2))))
  1033. X
  1034. X/* Bit masks for constraint map */
  1035. X#define DAY_M 1
  1036. X#define MONTH_M 2
  1037. X#define YEAR_M 4
  1038. X#define WKDAY_M 8
  1039. X
  1040. Xenum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
  1041. X           Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t, 
  1042. X               Repeat_t, At_t, Time_t, Eol_t };
  1043. X               
  1044. X/* Define the Token structure */
  1045. X
  1046. Xtypedef struct {
  1047. X   char *str;
  1048. X   enum Token_t type;
  1049. X   int val;
  1050. X} Token;
  1051. X
  1052. X#ifdef UNIX
  1053. X/* Define the structure of an AT entry */
  1054. Xtypedef struct AtEntry_t{
  1055. X   int time;      /* Time in minutes after midnight - 0 to 1439 */
  1056. X   int firsttime; /* Time of first triggering */
  1057. X   int repeat;    /* Repeat period */
  1058. X   int delta;     /* Delta time */
  1059. X   enum Token_t type;    /* Run_t or Msg_t */
  1060. X   char *text;
  1061. X   struct AtEntry_t *next;
  1062. X} AtEntry;
  1063. X#endif
  1064. X
  1065. SHAR_EOF
  1066. $TOUCH -am 1115094190 defines.h &&
  1067. chmod 0600 defines.h ||
  1068. echo "restore of defines.h failed"
  1069. set `wc -c defines.h`;Wc_c=$1
  1070. if test "$Wc_c" != "2085"; then
  1071.     echo original size 2085, current size $Wc_c
  1072. fi
  1073. fi
  1074. echo "End of part 1, continue with part 2"
  1075. exit 0
  1076.