home *** CD-ROM | disk | FTP | other *** search
- From: dfs@doe.carleton.ca (David F. Skoll)
- Newsgroups: alt.sources
- Subject: REMIND 2.3.0 1/4
- Message-ID: <dfs.666900962@data>
- Date: 18 Feb 91 18:16:02 GMT
-
- Here is the next version of REMIND. There have been many changes; I'm
- reposting the source rather that distributing patches. Here's the
- synopsis of whats new:
-
- Version 2.3 - Added the UNTIL keyword for forcing reminders to expire.
-
- Added the "++" form of 'back' and the "--" form of 'delta' for
- ignoring OMIT information.
-
- Added the CLEAR-OMIT-CONTEXT, PUSH-OMIT-CONTEXT and POP-OMIT-CONTEXT
- keywords for isolating personal or peculiar reminders from the global
- OMIT context.
-
- Speeded up the parsing of tokens.
-
- Changed the source to recognize and exploit ANSI-C compilers which
- accept function prototypes.
-
- Added the "-n" option to output the next occurrence of each reminder
- in SimpleCalendar format
-
- Modified the calendar and SimpleCalendar formats so that the % escape
- substitutions ARE performed.
-
- Remind source code can also be obtained via FTP from alfred.ccs.carleton.ca
- (134.117.1.1) in pub/remind-2.3.0.tar.Z.
-
- --
- David F. Skoll
-
- #!/bin/sh
- # This is Remind 2.3.0, a shell archive (shar 3.32)
- # made 02/18/1991 18:12 UTC by dfs@data
- # Source directory /enterprise/transporter/dfs/work/.rem/work
- #
- # existing files will NOT be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 997 -rw------- COPYRIGHT
- # 1339 -rw------- Makefile
- # 1206 -rw------- README.DOS
- # 2180 -rw------- README.UNIX
- # 1388 -rw------- WHATSNEW.23
- # 4966 -rw------- cache.c
- # 785 -rw------- cache.h
- # 13183 -rw------- calendar.c
- # 2313 -rw------- defines.h
- # 11579 -rw------- dorem.c
- # 8427 -rw------- dosubst.c
- # 8388 -rw------- files.c
- # 1469 -rw------- globals.h
- # 6305 -rw------- init.c
- # 852 -rwx------ kall
- # 20411 -rw------- main.c
- # 8719 -rw------- nextdate.c
- # 10630 -rw------- omits.c
- # 2210 -rw------- protos.h
- # 1568 -rw------- remind-all.csh
- # 1589 -rw------- remind-all.sh
- # 40229 -rw------- remind.1
- # 940 -rw------- remind.mak
- # 2975 -rw------- test.rem
- # 7484 -rw------- timed.c
- #
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= COPYRIGHT ==============
- if test X"$1" != X"-c" -a -f 'COPYRIGHT'; then
- echo "File already exists: skipping 'COPYRIGHT'"
- else
- echo "x - extracting COPYRIGHT (Text)"
- sed 's/^X//' << 'SHAR_EOF' > COPYRIGHT &&
- XTHE REMIND COPYRIGHT
- X
- XREMIND refers to the entire set of files and documentation in the
- XREMIND package.
- X
- XREMIND is Copyright (C) 1990, 1991 by David Skoll, except for the file
- Xremind-all.sh, which is Copyright (C) 1990 by Bill Aten.
- X
- XYou may use REMIND for free, and may freely distribute it, providing
- Xyou do not charge the recipients to whom you distribute REMIND.
- X
- XYou may modify REMIND. However, you must clearly indicate such
- Xmodifications when you distribute REMIND, and must tell the
- Xrecipients of the modified version that it is modified. Place that
- Xnotice in the WHATSNEW.xx file.
- X
- XYou may incorporate parts of REMIND into your own programs, providing
- Xyou do not sell these programs. You must clearly indicate that the parts
- Xof REMIND you have incorporated are Copyright (C) 1990 by David Skoll.
- X
- XI will attempt to support REMIND as much as possible. However, you use
- Xit at your own risk. I am not responsible for any damages caused by
- Xthe use or misuse of REMIND.
- X--
- XDavid F. Skoll
- SHAR_EOF
- $TOUCH -am 0218130591 COPYRIGHT &&
- chmod 0600 COPYRIGHT ||
- echo "restore of COPYRIGHT failed"
- set `wc -c COPYRIGHT`;Wc_c=$1
- if test "$Wc_c" != "997"; then
- echo original size 997, current size $Wc_c
- fi
- fi
- # ============= Makefile ==============
- if test X"$1" != X"-c" -a -f 'Makefile'; then
- echo "File already exists: skipping 'Makefile'"
- else
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X# Makefile for REMIND - simple file
- X
- X#--------------- BEGINNING OF THINGS YOU CAN CHANGE --------------
- X
- X#If you have a BSD system:
- XCFLAGS= -O -DUNIX
- X
- X#If you have a SYSV system, comment previous line and uncomment next line:
- X#CFLAGS= -O -DUNIX -DSYSV
- X
- X#If your system does not include <malloc.h>, uncomment next line:
- X#CFLAGS += -DNO_MALLOC_H
- X
- X#If you have a SYSV system which does not implement the pid_t type,
- X#uncomment the next line:
- X#CFLAGS += -Dpid_t=int
- X
- X#If you want to use gcc:
- X#CC= gcc
- X
- X#Where do you want it installed?
- XBINDIR= /usr/local/bin
- XKALLDIR= /usr/share/bin
- XMANDIR= /usr/share/man
- XMANSECTION= 1
- X
- X#What program does the installation?
- XINSTALL= install
- X#INSTALL= cp
- X
- X#--------------- SHOULDN'T CHANGE STUFF BELOW HERE ---------------
- X
- Xall: dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o omits.o
- X $(CC) -o remind dorem.o files.o main.o nextdate.o init.o dosubst.o timed.o calendar.o cache.o omits.o
- X
- Xdorem.o: dorem.c
- X
- Xfiles.o: files.c
- X
- Xmain.o: main.c
- X
- Xomits.o: omits.c
- X
- Xnextdate.o: nextdate.c
- X
- Xinit.o: init.c
- X
- Xdosubst.o: dosubst.c
- X
- Xtimed.o: timed.c
- X
- Xcalendar.o: calendar.c
- X
- Xcache.o: cache.c
- X
- Xclean:
- X rm -f *.o core *~ remind
- X
- Xinstall:
- X $(INSTALL) remind $(BINDIR)
- X
- Xinstall.man:
- X $(INSTALL) remind.1 $(MANDIR)/man$(MANSECTION)/remind.$(MANSECTION)
- X
- Xinstall.kall:
- X $(INSTALL) kall $(KALLDIR)
- X
- SHAR_EOF
- $TOUCH -am 0218130591 Makefile &&
- chmod 0600 Makefile ||
- echo "restore of Makefile failed"
- set `wc -c Makefile`;Wc_c=$1
- if test "$Wc_c" != "1339"; then
- echo original size 1339, current size $Wc_c
- fi
- fi
- # ============= README.DOS ==============
- if test X"$1" != X"-c" -a -f 'README.DOS'; then
- echo "File already exists: skipping 'README.DOS'"
- else
- echo "x - extracting README.DOS (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README.DOS &&
- XREMIND 2.3 for MS-DOS
- X
- XFirst, read the files COPYRIGHT and WHATSNEW.23.
- X
- XREMIND was originally written for MS-DOS. To compile it, you need the
- XMicrosoft C compiler (at least version 5.1) and the Microsoft MAKE
- Xutility.
- X
- XBefore compiling the software, check if it includes patches. These are
- Xfiles called patch.xx. If there are patches, apply them all by typing
- X
- Xcat patch.* | patch
- X
- Xon a Unix machine. Then copy the software to your MS-DOS machine.
- X
- XTo compile the software, simply go to the source directory and type:
- X
- XMAKE REMIND.MAK
- X
- XThe file test.rem contains test reminders for verifying that REMIND's
- Xdate calculation routines are working correctly. The file test.out
- Xcontains the result of running: remind -dv test.rem 16 feb 1991
- X
- XNote that the MS-DOS version of REMIND operates slightly differently from
- Xthe UNIX version: MS-DOS has no concept of file access date. Thus, to
- Ximplement the "ONCE" keyword, REMIND will change the modification date
- Xof the top-level reminder file after it has run. This is equivalent to
- Xperforming a "touch" of the file after running REMIND.
- X
- XAlso, the MS-DOS version does not queue AT reminders for timed activation.
- X--
- XDavid F. Skoll <dfs@doe.carleton.ca>
- X
- SHAR_EOF
- $TOUCH -am 0218130591 README.DOS &&
- chmod 0600 README.DOS ||
- echo "restore of README.DOS failed"
- set `wc -c README.DOS`;Wc_c=$1
- if test "$Wc_c" != "1206"; then
- echo original size 1206, current size $Wc_c
- fi
- fi
- # ============= README.UNIX ==============
- if test X"$1" != X"-c" -a -f 'README.UNIX'; then
- echo "File already exists: skipping 'README.UNIX'"
- else
- echo "x - extracting README.UNIX (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README.UNIX &&
- XREMIND version 2.3 for UNIX
- X
- XFirst, read the files COPYRIGHT and WHATSNEW.23
- X
- XBefore compiling the software, check if it includes patches. These
- Xare files called patch.xx. If there are patches, apply them all by
- Xtyping
- X
- Xcat patch.* | patch
- X
- XNext, examine the Makefile and change any parameters which need to be
- Xchanged for your system. As it stands, the Makefile is set up for a
- XBSD system.
- X
- XTo compile REMIND, just go to the source directory and type "make".
- XThis creates the executable file "remind". You can type "make CC=gcc"
- Xif you want to use the Gnu C Compiler, or you can edit the Makefile to
- Xmake gcc the default.
- X
- XThe file test.rem contains test reminders for verifying that REMIND's
- Xdate calculation routines are working correctly. The file test.out
- Xcontains the result of running: remind -dv test.rem 16 feb 1991
- X
- XREMIND has been compiled on Sun3s and Sun4s under Sun OS 4.0, on an
- XIBM PC under MS-DOS and on a 386 Xenix system to name a few. REMIND
- Xshould compile on most systems without difficulty.
- X
- XOnce remind has been compiled, install it in your favourite system
- Xdirectory. Type "make install" to install the executable, and "make
- Xinstall.man" to install the manpage. If you want to install the "kall"
- Xscript, type "make install.kall"
- X
- XTwo shell scripts, "remind-all.csh" and "remind-all.sh" are provided.
- XThese allow automatic mailing of reminders to all users who create a
- X$HOME/.reminders file. These two scripts are equivalent; one is a
- X"sh" script and the other is a "csh" script. Pick the one you want to
- Xuse, and follow the instructions in the opening comments of the
- Xscript.
- X
- XA shell script called "kall" is provided which kills processes
- Xspecified by command name rather than process ID. You may have to
- Xedit it to work on your system, since the output of "ps" is not
- Xportable. You can use this script to kill all background remind
- Xprocesses in your .logout script by using "kall remind" Note that this
- Xversion of "kall" is different from the version of kall distributed
- Xwith 2.2 - the new version requires an exact match of command name,
- Xnot just a command name which contains the specified
- Xstring.
- X
- X--
- XDavid F. Skoll <dfs@doe.carleton.ca>
- SHAR_EOF
- $TOUCH -am 0218130591 README.UNIX &&
- chmod 0600 README.UNIX ||
- echo "restore of README.UNIX failed"
- set `wc -c README.UNIX`;Wc_c=$1
- if test "$Wc_c" != "2180"; then
- echo original size 2180, current size $Wc_c
- fi
- fi
- # ============= WHATSNEW.23 ==============
- if test X"$1" != X"-c" -a -f 'WHATSNEW.23'; then
- echo "File already exists: skipping 'WHATSNEW.23'"
- else
- echo "x - extracting WHATSNEW.23 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > WHATSNEW.23 &&
- XA BRIEF HISTORY OF REMIND:
- X
- XVersion 1.0 - never publicly released.
- X
- XVersion 2.0 - first public release. Included advanced date specifications,
- Xcharacter substitution, and the RUN keyword.
- X
- XVersion 2.1 - Added the "repeat" token for repeating reminders with a period
- Xother than 7 days. Also fixed some bugs from version 2.0
- X
- XVersion 2.2 - Added the AT keyword, the timed reminders daemon, and the
- Xcalendar facility.
- X
- XVersion 2.2 - Patch 3 - Added the MSG or RUN tokens in an OMIT command; also
- Xallowed RUN-type reminders to be explicitly included in the calendar by
- Xusing the %" escape sequence.
- X
- XVersion 2.2 - Patch 5 - Added the BEFORE, AFTER and SKIP tokens to make the
- Xhandling of holidays more sensible. Also corrected a few more bugs.
- X
- XVersion 2.3 - Added the UNTIL keyword for forcing reminders to expire.
- X
- XAdded the "++" form of 'back' and the "--" form of 'delta' for
- Xignoring OMIT information.
- X
- XAdded the CLEAR-OMIT-CONTEXT, PUSH-OMIT-CONTEXT and POP-OMIT-CONTEXT
- Xkeywords for isolating personal or peculiar reminders from the global
- XOMIT context.
- X
- XSpeeded up the parsing of tokens.
- X
- XChanged the source to recognize and exploit ANSI-C compilers which
- Xaccept function prototypes.
- X
- XAdded the "-n" option to output the next occurrence of each reminder
- Xin SimpleCalendar format
- X
- XModified the calendar and SimpleCalendar formats so that the % escape
- Xsubstitutions ARE performed.
- X
- SHAR_EOF
- $TOUCH -am 0218130591 WHATSNEW.23 &&
- chmod 0600 WHATSNEW.23 ||
- echo "restore of WHATSNEW.23 failed"
- set `wc -c WHATSNEW.23`;Wc_c=$1
- if test "$Wc_c" != "1388"; then
- echo original size 1388, current size $Wc_c
- fi
- fi
- # ============= cache.c ==============
- if test X"$1" != X"-c" -a -f 'cache.c'; then
- echo "File already exists: skipping 'cache.c'"
- else
- echo "x - extracting cache.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > cache.c &&
- X/***************************************************************/
- X/* */
- X/* CACHE.C */
- X/* */
- X/* Contains routines for caching reminder file to improve */
- X/* calendar performance. */
- X/* */
- X/* By David Skoll - 15 November 1990 */
- X/***************************************************************/
- X
- X#include <stdio.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include <string.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X#include "cache.h"
- X
- X/* Define a cached line */
- Xtypedef struct cached_line {
- X char *text;
- X struct cached_line *next;
- X} Centry;
- X
- XCentry Cache, *Current;
- X
- Xstatic int CacheDone, CacheFailed;
- X
- X/***************************************************************/
- X/* */
- X/* InitCache */
- X/* */
- X/* Initializes the caching system. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid InitCache(void)
- X#else
- Xvoid InitCache()
- X#endif
- X{
- X CacheDone = 0;
- X CacheFailed = 0;
- X Cache.next = NULL;
- X Current = &Cache;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* GetLine */
- X/* */
- X/* This function either reads a line from the file, or gets */
- X/* it from memory if it is cached. */
- X/* */
- X/* Returns 0 if more data to be read; otherwise, non-zero. */
- X/* */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint GetLine(void)
- X#else
- Xint GetLine()
- X#endif
- X{
- X int ret;
- X Token tok;
- X char *s;
- X Centry *c;
- X
- X if (CacheFailed) return ReadLine();
- X
- X if (!CacheDone) {
- X ret = ReadLine();
- X if (ret) {
- X CacheDone = 1;
- X strcpy(FileName, "* cache *");
- X CurLine = 0;
- X return ret;
- X }
- X /* Check if we should cache this line */
- X
- X s = Line;
- X tok = ParseToken(&s);
- X if (tok.type == Clear_t || tok.type == Push_t ||
- X tok.type == Pop_t || tok.type == Rem_t || tok.type == Omit_t) {
- X c = (Centry *) malloc(sizeof(Centry));
- X if (c == NULL) {
- X CacheFailed = 1;
- X DestroyCache();
- X return 0;
- X }
- X c->text = (char *) malloc(strlen(Line)+1);
- X if (c->text == NULL) {
- X CacheFailed = 1;
- X DestroyCache();
- X free(c);
- X return 0;
- X }
- X /* Insert the cache entry */
- X c->next = NULL;
- X strcpy(c->text, Line);
- X Current->next = c;
- X Current = c;
- X }
- X return ret;
- X } else { /* Over here, we've finished caching, so just return the line */
- X if (Current == NULL) return 1;
- X else {
- X strcpy(Line, Current->text);
- X Current = Current->next;
- X return 0;
- X }
- X }
- X}
- X/***************************************************************/
- X/* */
- X/* ResetCache */
- X/* Reset the cache to beginning, or reopen file if caching */
- X/* failed. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid ResetCache(void)
- X#else
- Xvoid ResetCache()
- X#endif
- X{
- X /* Reset the OMIT context */
- X ClearOmitContext();
- X
- X /* Get rid of any spurious stacked OMIT contexts */
- X FreeStackedOmits();
- X
- X if (CacheFailed) OpenFile(FileName);
- X else Current = Cache.next;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DestroyCache */
- X/* Frees all memory used by the cache. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid DestroyCache(void)
- X#else
- Xvoid DestroyCache()
- X#endif
- X{
- X Centry *p = &Cache;
- X Centry *c = p->next;
- X
- X while (c) {
- X if (c->text) free(c->text);
- X p = c;
- X c = c->next;
- X free(p);
- X }
- X Cache.next = NULL;
- X}
- X
- SHAR_EOF
- $TOUCH -am 0218130591 cache.c &&
- chmod 0600 cache.c ||
- echo "restore of cache.c failed"
- set `wc -c cache.c`;Wc_c=$1
- if test "$Wc_c" != "4966"; then
- echo original size 4966, current size $Wc_c
- fi
- fi
- # ============= cache.h ==============
- if test X"$1" != X"-c" -a -f 'cache.h'; then
- echo "File already exists: skipping 'cache.h'"
- else
- echo "x - extracting cache.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > cache.h &&
- X/***************************************************************/
- X/* */
- X/* CACHE.H */
- X/* */
- X/* Function prototypes, etc. for CACHE.C */
- X/* */
- X/* By David Skoll - 15 November 1990 */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid InitCache(void);
- Xint GetLine(void);
- Xvoid ResetCache(void);
- Xvoid DestroyCache(void);
- X#else
- Xvoid InitCache();
- Xint GetLine();
- Xvoid ResetCache();
- Xvoid DestroyCache();
- X#endif
- SHAR_EOF
- $TOUCH -am 0218130591 cache.h &&
- chmod 0600 cache.h ||
- echo "restore of cache.h failed"
- set `wc -c cache.h`;Wc_c=$1
- if test "$Wc_c" != "785"; then
- echo original size 785, current size $Wc_c
- fi
- fi
- # ============= calendar.c ==============
- if test X"$1" != X"-c" -a -f 'calendar.c'; then
- echo "File already exists: skipping 'calendar.c'"
- else
- echo "x - extracting calendar.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > calendar.c &&
- X/***************************************************************/
- X/* */
- X/* CALENDAR.C */
- X/* */
- X/* Contains routines and data structures for producing a */
- X/* calendar from a reminder file. */
- X/* */
- X/* By David Skoll - 14 November 1990 */
- X/* */
- X/***************************************************************/
- X#include <stdio.h>
- X#ifndef NO_MALLOC_H
- X#include <malloc.h>
- X#endif
- X#include <ctype.h>
- X#include <string.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X#include "cache.h"
- X
- X/* Convert (monday-sunday) sequence to (sunday-saturday) */
- X#define DayOfWeek(julian) ((((julian) % 7) + 1) % 7)
- X
- X/* To center an item of length l in a field of length f, how many spaces? */
- X#define PreCenter(f, l) (((f)-(l))/2)
- X
- X/* How many spaces AFTEr the centered item? */
- X#define PostCenter(f, l) ((f)-(l)-((f)-(l))/2)
- X
- X/* Define the structure of a calendar entry */
- Xtypedef struct CalEntry_t {
- X int tim;
- X char *text, *current;
- X struct CalEntry_t *next;
- X} CalEntry;
- X
- X/* Have a main calendar entry for each weekday */
- XCalEntry entry[7];
- Xint used[7]; /* These hold the day of the month for corresponding
- X entry - 0 if not used */
- X
- X/* Static integers for various stuff */
- Xstatic int TotalWidth;
- X
- X/* Make function prototypes local - they're not used anywhere else */
- X#ifdef __STDC__
- XCalEntry *CreateCalEntry(int type);
- Xvoid AddCalEntry(CalEntry *e);
- Xvoid EmitOneCalendarLine(void);
- Xvoid InitCalendar(int m, int y);
- Xvoid FinishCalendar(void);
- Xvoid DoEntries(void);
- X#else
- XCalEntry *CreateCalEntry();
- Xvoid AddCalEntry();
- Xvoid EmitOneCalendarLine();
- Xvoid InitCalendar();
- Xvoid FinishCalendar();
- Xvoid DoEntries();
- X#endif
- X
- X/***************************************************************/
- X/* */
- X/* DoCalendar - main loop for the calendar command. */
- X/* */
- X/***************************************************************/
- X#ifndef __STDC__
- Xvoid DoCalendar()
- X#else
- Xvoid DoCalendar(void)
- X#endif
- X{
- X int y, m, d, init;
- X
- X TotalWidth = 7*CalWidth + 8;
- X
- X /* Move back until beginning of month */
- X FromJulian(JulianToday, &d, &m, &y);
- X JulianToday -= (d-1);
- X
- X init = 0;
- X InitCache();
- X while (Calendar) {
- X FromJulian(JulianToday, &d, &m, &y);
- X CurDay = d;
- X CurMon = m;
- X CurYear = y;
- X if (init == 0 || CurDay == 1) { InitCalendar(m, y); init = 1; }
- X DoEntries();
- X if (d == DaysInMonth(m, y)) Calendar--;
- X JulianToday++;
- X if (Calendar) ResetCache();
- X }
- X if (CurDay != DaysInMonth(CurMon, CurYear)) FinishCalendar();
- X DestroyCache();
- X FreeStackedOmits();
- X}
- X
- X/***************************************************************/
- X/* */
- X/* PrintChars: Print n of the specified character */
- X/* CopyChars: Copy n of the character to the output buffer */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid PrintChars(int n, int c)
- X#else
- Xvoid PrintChars(n, c)
- Xint n, c;
- X#endif
- X{
- X while(n--) putchar(c);
- X}
- X
- X#ifdef __STDC__
- Xchar *CopyChars(int n, int c, char *dst)
- X#else
- Xchar *CopyChars(n, c, dst)
- Xint n, c;
- Xchar *dst;
- X#endif
- X{
- X while(n--) *dst++ = (char) c;
- X return dst;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* InitCalendar */
- X/* Print the calendar header */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid InitCalendar(int m, int y)
- X#else
- Xvoid InitCalendar(m, y)
- Xint y, m;
- X#endif
- X{
- X int i;
- X
- X if (SimpleCalendar) return;
- X
- X for (i=0; i<7; i++) {
- X entry[i].next = NULL;
- X used[i] = 0;
- X }
- X
- X /* Emit the calendar title */
- X putchar('+');
- X PrintChars(TotalWidth-2, '-');
- X putchar('+');
- X putchar('\n');
- X sprintf(TmpBuf, "%s %d", MonthName[m], y);
- X putchar('|');
- X PrintChars(PreCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
- X printf("%s", TmpBuf);
- X PrintChars(PostCenter(TotalWidth-2, strlen(TmpBuf)), ' ');
- X putchar('|');
- X putchar('\n');
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X
- X /* Put the weekdays in */
- X /* Argh! Do sunday first, then take care of rest */
- X i = 6;
- X putchar('|');
- X PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
- X printf(DayName[i]);
- X PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
- X
- X for (i=0; i<6; i++) {
- X putchar('|');
- X PrintChars(PreCenter(CalWidth, strlen(DayName[i])), ' ');
- X printf(DayName[i]);
- X PrintChars(PostCenter(CalWidth, strlen(DayName[i])), ' ');
- X }
- X putchar('|');
- X putchar('\n');
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* FinishCalendar */
- X/* Just print a form feed. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid FinishCalendar(void)
- X#else
- Xvoid FinishCalendar()
- X#endif
- X{
- X if (SimpleCalendar) return;
- X putchar('\f');
- X}
- X
- X/***************************************************************/
- X/* */
- X/* DoEntries */
- X/* Create all the calendar entries for this week */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid DoEntries(void)
- X#else
- Xvoid DoEntries()
- X#endif
- X{
- X int i;
- X CalEntry *e;
- X
- X while (1) {
- X used[DayOfWeek(JulianToday)] = CurDay;
- X if (GetLine()) break;
- X i = ProcessLine();
- X if (i>0) if (e = CreateCalEntry(i)) AddCalEntry(e);
- X }
- X
- X /* Now figure out if we should print the calendar */
- X if ((DayOfWeek(JulianToday) == 6 ) || CurDay == DaysInMonth(CurMon, CurYear))
- X EmitOneCalendarLine();
- X if (CurDay == DaysInMonth(CurMon, CurYear)) FinishCalendar();
- X}
- X
- X/***************************************************************/
- X/* */
- X/* AddCalEntry */
- X/* Add a calendar entry for the appropriate weekday. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid AddCalEntry(CalEntry *e)
- X#else
- Xvoid AddCalEntry(e)
- XCalEntry *e;
- X#endif
- X{
- X CalEntry *curr, *prev;
- X
- X prev = &entry[DayOfWeek(JulianToday)];
- X curr = prev->next;
- X while (curr) {
- X if (e->tim == -1 || (e->tim >= curr->tim && curr->tim != -1)) {
- X prev = curr;
- X curr = prev->next;
- X } else {
- X prev->next = e;
- X e->next = curr;
- X break;
- X }
- X }
- X if (!curr) {
- X prev->next = e;
- X e->next = NULL;
- X }
- X}
- X
- X#ifdef __STDC__
- Xvoid CopyWord(char **src, char **dst, int l)
- X#else
- Xvoid CopyWord(src, dst, l)
- Xchar **src, **dst;
- Xint l;
- X#endif
- X{
- X while(**src && !isspace(**src) && l--) *(*dst)++ = *(*src)++;
- X}
- X
- X#ifdef __STDC__
- Xint WordLen(char *src)
- X#else
- Xint WordLen(src)
- Xchar *src;
- X#endif
- X{
- X int len = 0;
- X while (*src && !isspace(*src)) { len++; src++; }
- X return len;
- X}
- X/***************************************************************/
- X/* */
- X/* CreateCalEntry */
- X/* */
- X/* Allocates and creates a calendar entry. */
- X/* */
- X/* Type = 1: MSG type = 2: RUN */
- X/* */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- XCalEntry *CreateCalEntry(int type)
- X#else
- XCalEntry *CreateCalEntry(type)
- Xint type;
- X#endif
- X{
- X CalEntry *e;
- X char *s, *t;
- X int column, l;
- X enum Token_t tok;
- X
- X if (type == 1) tok = Msg_t; else tok = Run_t;
- X
- X if (!SimpleCalendar) {
- X e = (CalEntry *) malloc(sizeof(CalEntry));
- X
- X if (e == NULL) {
- X fprintf(stderr, "remind: Can't malloc to create calendar entry.\n");
- X exit(1);
- X }
- X e->next = NULL;
- X e->tim = CalTime;
- X }
- X
- X DoSubst(WorkBuf, TmpBuf, CurDay, CurMon, CurYear, JulianToday, tok, CalTime, 1);
- X
- X /* If the buffer contains zero-length string; forget it. */
- X if (!*TmpBuf) {
- X if (!SimpleCalendar) free(e);
- X return (NULL);
- X }
- X
- X /* If we're doing a simple calendar, just spit out the text and end */
- X if (SimpleCalendar) {
- X printf("%04d/%02d/%02d: ", CurYear, 1+CurMon, CurDay);
- X Output(TmpBuf);
- X return (NULL);
- X }
- X
- X /* Now copy from TmpBuf to WorkBuf, splitting words as needed */
- X s = TmpBuf;
- X t = WorkBuf;
- X column = 0;
- X while (*s) {
- X l = WordLen(s);
- X if (column == 0 && l >= CalWidth) {
- X CopyWord(&s, &t, CalWidth);
- X *t++ = '\n';
- X while (isspace(*s)) s++;
- X }
- X else if (column != 0 && column+l > CalWidth) {
- X *t++ = '\n';
- X column = 0;
- X if (l >= CalWidth) {
- X CopyWord(&s, &t, CalWidth);
- X *t++ = '\n';
- X while (isspace(*s)) s++;
- X } else {
- X CopyWord(&s, &t, l);
- X *t++ = ' ';
- X while (isspace(*s)) s++;
- X column = l+1;
- X if (column >= CalWidth) {
- X *(t-1) = '\n';
- X column = 0;
- X }
- X
- X }
- X }
- X else {
- X column += l+1;
- X CopyWord(&s, &t, l);
- X while (isspace(*s)) s++;
- X *t++ = ' ';
- X if (column > CalWidth) {
- X *(t-1) = '\n';
- X column = 0;
- X }
- X }
- X }
- X *t = 0;
- X if (*(t-1) == '\n') *(t-1) = 0;
- X
- X /* Finally, copy the string to the calendar entry */
- X e->text = (char *) malloc(strlen(WorkBuf)+1);
- X
- X if (!e->text) {
- X fprintf(stderr, "remind: Can't malloc memory for calendar text!\n");
- X exit(1);
- X }
- X strcpy(e->text, WorkBuf);
- X e->current = e->text;
- X
- X return e;
- X}
- X
- X/***************************************************************/
- X/* */
- X/* EmitOneCalendarLine */
- X/* This is the biggie - we print out one line. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xvoid EmitOneCalendarLine(void)
- X#else
- Xvoid EmitOneCalendarLine()
- X#endif
- X{
- X int i, nlines, emit, j;
- X char *s, *dst;
- X CalEntry *e;
- X char pend[7]; /* Reminders with following blanks pending */
- X
- X if (SimpleCalendar) return;
- X
- X nlines = 0;
- X for (i=0; i<7; i++) pend[i] = 0;
- X putchar('|');
- X /* First, emit the days of the month */
- X for (i=0; i<7; i++) {
- X if (!used[i]) PrintChars(CalWidth, ' ');
- X else {
- X sprintf(TmpBuf, "%d", used[i]);
- X printf(TmpBuf);
- X PrintChars(CalWidth-strlen(TmpBuf), ' ');
- X }
- X putchar('|');
- X }
- X putchar('\n');
- X
- X /* Now cycle through all the reminders until there are none left */
- X emit = 1;
- X while(emit) {
- X dst = WorkBuf;
- X *dst++ = '|';
- X emit = 0;
- X for (i=0; i<7; i++) {
- X if (pend[i] || !used[i] || !entry[i].next) {
- X dst = CopyChars(CalWidth, ' ', dst);
- X *dst++ = '|';
- X if(pend[i]) {pend[i] = 0; emit = 1;}
- X continue;
- X }
- X s = entry[i].next->current;
- X j = 0;
- X emit = 1;
- X while (*s && *s != '\n') {
- X *dst++ = *s++;
- X j++;
- X }
- X dst = CopyChars(CalWidth - j, ' ', dst);
- X if (*s == '\n') entry[i].next->current = s+1;
- X else {
- X e = entry[i].next;
- X entry[i].next = e->next;
- X free(e->text);
- X free(e);
- X if (!entry[i].next) used[i] = 0;
- X else pend[i] = 1;
- X }
- X *dst++ = '|';
- X }
- X *dst = 0;
- X if(emit) printf("%s\n", WorkBuf);
- X nlines += emit;
- X }
- X while(nlines++ < 6) printf("%s\n", WorkBuf);
- X
- X putchar('+');
- X for (i=0; i<7; i++) {
- X PrintChars(CalWidth, '-');
- X putchar('+');
- X }
- X putchar('\n');
- X for (i=0; i<7; i++) used[i] = 0;
- X}
- SHAR_EOF
- $TOUCH -am 0218130591 calendar.c &&
- chmod 0600 calendar.c ||
- echo "restore of calendar.c failed"
- set `wc -c calendar.c`;Wc_c=$1
- if test "$Wc_c" != "13183"; then
- echo original size 13183, current size $Wc_c
- fi
- fi
- # ============= defines.h ==============
- if test X"$1" != X"-c" -a -f 'defines.h'; then
- echo "File already exists: skipping 'defines.h'"
- else
- echo "x - extracting defines.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > defines.h &&
- X/***************************************************************/
- X/* */
- X/* DEFINES.H */
- X/* */
- X/* Contains macros and #defines for REMIND program. */
- X/* */
- X/* By David Skoll - 30 Sept 1990. */
- X/* */
- X/***************************************************************/
- X
- X/* User-definable variables. BASE *must* be a year for which the
- X first of January is a Monday!!! FOMITSIZE and POMITSIZE control
- X the number of fully-specified (dd-mm-yy) and partially-specified
- X (dd-mm) holidays. */
- X#define BASE 1990
- X#define FOMITSIZE 150
- X#define POMITSIZE 75
- X
- X/* Useful macros */
- X
- X#define upper(c) ( ((c) >= 'a' && (c) <= 'z') ? ((c)-32) : (c) )
- X#define DaysInYear(y) (((y) % 4) ? 365 : ((!((y) % 100) && ((y) % 400)) ? 365 : 366 ))
- X#define IsLeapYear(y) (((y) % 4) ? 0 : ((!((y) % 100) && ((y) % 400)) ? 0 : 1 ))
- X#define DaysInMonth(m, y) ((m) != 1 ? MonthDays[m] : 28 + IsLeapYear(y))
- X#define TimeLess(h1, m1, h2, m2) (((h1) < (h2)) || (((h1) == (h2)) && ((m1) < (m2))))
- X#define MAX(x, y) ((x) < (y) ? (y) : (x))
- X#define MIN(x, y) ((x) < (y) ? (x) : (y))
- X#ifndef ABS
- X#define ABS(x) ((x) < 0 ? (-(x)) : (x))
- X#endif
- X
- X/* Bit masks for constraint map */
- X#define DAY_M 1
- X#define MONTH_M 2
- X#define YEAR_M 4
- X#define WKDAY_M 8
- X
- Xenum Token_t { Unknown_t, Year_t, Month_t, Day_t, WkDay_t, Msg_t, Run_t,
- X Omit_t, Banner_t, Rem_t, Delta_t, Back_t, Once_t, Include_t,
- X Repeat_t, At_t, Time_t, Skip_t, Until_t, Push_t, Pop_t,
- X Clear_t, Eol_t };
- X
- X/* Define the Token structure */
- X
- Xtypedef struct {
- X char *str;
- X enum Token_t type;
- X int val;
- X char len; /* Minimum length to match */
- X} Token;
- X
- X#ifdef UNIX
- X/* Define the structure of an AT entry */
- Xtypedef struct AtEntry_t{
- X int time; /* Time in minutes after midnight - 0 to 1439 */
- X int firsttime; /* Time of first triggering */
- X int repeat; /* Repeat period */
- X int delta; /* Delta time */
- X enum Token_t type; /* Run_t or Msg_t */
- X char *text;
- X struct AtEntry_t *next;
- X} AtEntry;
- X#endif
- X
- SHAR_EOF
- $TOUCH -am 0218130591 defines.h &&
- chmod 0600 defines.h ||
- echo "restore of defines.h failed"
- set `wc -c defines.h`;Wc_c=$1
- if test "$Wc_c" != "2313"; then
- echo original size 2313, current size $Wc_c
- fi
- fi
- # ============= dorem.c ==============
- if test X"$1" != X"-c" -a -f 'dorem.c'; then
- echo "File already exists: skipping 'dorem.c'"
- else
- echo "x - extracting dorem.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dorem.c &&
- X#include <stdio.h>
- X#ifndef UNIX
- X#include <stdlib.h>
- X#endif
- X#include <string.h>
- X#include <ctype.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* int DoRem(char **s) */
- X/* */
- X/* Process a reminder. Return 0 if reminder not emitted, */
- X/* positive if emitted, or negative if in the past and */
- X/* will never be emitted. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint DoRem(char **s)
- X#else
- Xint DoRem(s)
- Xchar **s;
- X
- X#endif
- X{
- X int d, m, y, wd, cons, delta, back, omit, done, jul, once, repeat, skip;
- X int ud, um, uy; /* Date of UNTIL */
- X int uj;
- X int tim, tdelta, trep;
- X int d2, m2, y2;
- X Token tok;
- X int trigger;
- X char NeedNewToken;
- X
- X uj = ud = um = uy = d = m = y = tim = tdelta = trep = -1;
- X back = delta = repeat = cons = wd = omit = once = skip = 0;
- X
- X
- X done = 0;
- X NeedNewToken = 1;
- X while (!done) {
- X if (NeedNewToken) tok = ParseToken(s);
- X NeedNewToken = 1;
- X switch (tok.type) {
- X
- X case Until_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch (tok.type) {
- X case Year_t:
- X if (uy != -1) {
- X Eprint("Year duplicated in UNTIL.\n");
- X return 0;
- X }
- X uy = tok.val;
- X break;
- X
- X case Month_t:
- X if (um != -1) {
- X Eprint("Month duplicated in UNTIL.\n");
- X return 0;
- X }
- X um = tok.val;
- X break;
- X
- X case Day_t:
- X if (ud != -1) {
- X Eprint("Day duplicated in UNTIL.\n");
- X return 0;
- X }
- X ud = tok.val;
- X break;
- X
- X default:
- X done = 1; break;
- X }
- X }
- X if (uy == -1 || um == -1 || ud == -1) {
- X Eprint("Year, month and day must all be specified after UNTIL\n");
- X return 0;
- X }
- X if (CheckDate(ud, um, uy)) {
- X Eprint("Invalid date for UNTIL.\n");
- X return 0;
- X }
- X uj = Julian(ud, um, uy);
- X done = 0; break;
- X
- X case Omit_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch(tok.type) {
- X case WkDay_t:
- X if (omit & (1 << tok.val)) {
- X Eprint("%s duplicated.\n", tok.str);
- X return 0;
- X }
- X omit |= 1 << tok.val;
- X break;
- X
- X default: done = 1; break;
- X }
- X }
- X done = 0;
- X break;
- X
- X case At_t:
- X NeedNewToken = 0;
- X while (!done) {
- X tok = ParseToken(s);
- X switch(tok.type) {
- X
- X case Time_t:
- X if (tim != -1) {
- X Eprint("Time specified twice.\n");
- X return 0;
- X }
- X else tim = tok.val;
- X break;
- X
- X case Repeat_t:
- X if (trep != -1) {
- X Eprint("Time repeat factor specified twice.\n");
- X return 0;
- X }
- X trep = tok.val;
- X if (trep <= 0) {
- X Eprint("Invalid value for timerepeat factor: %d\n", repeat);
- X return 0;
- X }
- X break;
- X
- X case Delta_t:
- X if (tdelta != -1) {
- X Eprint("Time delta specified twice.\n");
- X return 0;
- X }
- X tdelta = ABS(tok.val);
- X break;
- X
- X default: done = 1; break;
- X }
- X }
- X done = 0; break;
- X
- X case Eol_t:
- X Eprint("Missing MSG or RUN in reminder.\n");
- X return 0;
- X
- X case Run_t:
- X case Msg_t: done = 1; break;
- X
- X case Skip_t:
- X if (skip) {
- X Eprint("Can only have one of BEFORE, AFTER or SKIP.\n");
- X return 0;
- X }
- X skip = tok.val;
- X break;
- X
- X case Unknown_t:
- X Eprint("Unknown token %s in reminder.\n", tok.str);
- X return 0;
- X
- X case Repeat_t:
- X if (repeat) {
- X Eprint("Repeat factor specified twice.\n");
- X return 0;
- X }
- X repeat = tok.val;
- X if (repeat <= 0) {
- X Eprint("Invalid value for repeat factor: %d\n", repeat);
- X return 0;
- X }
- X break;
- X
- X case WkDay_t:
- X if (wd & (1 << tok.val)) {
- X Eprint("%s duplicated.\n", tok.str);
- X return 0;
- X }
- X wd |= 1 << tok.val;
- X cons |= WKDAY_M;
- X break;
- X
- X case Year_t:
- X if (y != -1) {
- X Eprint("Year specified twice.\n");
- X return 0;
- X }
- X y = tok.val;
- X cons |= YEAR_M;
- X break;
- X
- X case Month_t:
- X if (m != -1) {
- X Eprint("Month specified twice.\n");
- X return 0;
- X }
- X m = tok.val;
- X cons |= MONTH_M;
- X break;
- X
- X case Day_t:
- X if (d != -1) {
- X Eprint("Day specified twice.\n");
- X return 0;
- X }
- X d = tok.val;
- X cons |= DAY_M;
- X break;
- X
- X case Delta_t:
- X if (delta) {
- X Eprint("Delta specified twice.\n");
- X return 0;
- X }
- X delta = tok.val;
- X break;
- X
- X case Back_t:
- X if (back) {
- X Eprint("Back specified twice.\n");
- X return 0;
- X }
- X back = tok.val;
- X break;
- X
- X case Once_t:
- X if (once) {
- X Eprint("ONCE specified twice. (How's that for an error message??)\n");
- X return 0;
- X }
- X once = 1;
- X break;
- X
- X default:
- X Eprint("Can't use token %s here.\n", tok.str);
- X return 0;
- X }
- X }
- X
- X /* Do some sanity checking on the reminder */
- X if (repeat && (d == -1 || m == -1 || y == -1)) {
- X Eprint("Can't use repeat counter unless you fully specify the date.\n");
- X return 0;
- X }
- X
- X if (skip && (wd & omit)) {
- X Eprint("Conflict between weekday list and local OMIT\n");
- X return 0;
- X }
- X
- X if (d != -1 && m != -1 && CheckDate(d, m, y)) {
- X Eprint("Illegal date specification.\n");
- X return 0;
- X }
- X if (y != -1 && (y < BASE || y > BASE + 85)) {
- X Eprint("Illegal date specification.\n");
- X return 0;
- X }
- X
- X /* Print some helpful stuff if debugging */
- X if (Debug) {
- X if (back > 7) Eprint("Warning: 'back' > 7 could slow execution severely.\n");
- X if (delta > 30 && (omit || NumFullOmit || NumPartOmit))
- X Eprint("Warning: 'delta' > 30 with OMITs could slow execution severely.\n");
- X }
- X
- X if (omit == 127) {
- X Eprint("Can't omit every day!\n");
- X return 0;
- X }
- X
- X if (IgOnce) once = 0;
- X
- X /* Check if we can quickly determine reminder is not to be emitted */
- X if (once && !Debug && !Purge && (LastRun == JulianToday)) return 0;
- X
- X /* Have we passed the UNTIL date ? */
- X if (uj != -1 && uj < JulianToday) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X }
- X
- X jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip);
- X if (uj != -1 && uj < jul) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X }
- X
- X if (Calendar) {
- X if (jul == JulianToday) {
- X while (isspace(**s)) (*s)++;
- X strcpy(WorkBuf, *s);
- X CalTime = tim;
- X if (tok.type == Run_t) return 2; else return 1;
- X } else return 0;
- X }
- X
- X if (jul == -1) {
- X if (Debug) Eprint("Reminder has expired.\n");
- X return -1;
- X } else if (jul == -2) return 0;
- X
- X FromJulian(jul, &d2, &m2, &y2);
- X
- X /* If we're in "Next" mode, output this one in simple-calendar format */
- X if (Next) {
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 1);
- X if (!*WorkBuf) return 0;
- X printf("%04d/%02d/%02d: ", y2, m2+1, d2);
- X printf("%s\n", WorkBuf);
- X return 0;
- X }
- X
- X /* Figure out if the reminder should be triggered */
- X
- X trigger = MoveBack(jul, delta, omit);
- X
- X if(Debug) {
- X Eprint("%sTrigger date: %s, %d %s, %d.\n",
- X (trigger <= JulianToday ? "*" : ""), DayName[jul % 7],
- X d2, MonthName[m2], y2);
- X return 0;
- X }
- X if (Purge || (once && (LastRun == JulianToday))) return 0;
- X
- X while (isspace(**s)) (*s)++;
- X
- X if (trigger <= JulianToday && !(tok.type == Run_t && IgRun)) {
- X /* Trigger a reminder */
- X#ifdef UNIX
- X if (QueueAts && (jul == JulianToday) && (tim != -1)) {
- X DoAt(tim, tdelta, trep, *s, tok.type);
- X }
- X if (!PrintAts && (jul == JulianToday) && tim != -1) return 0;
- X#endif
- X if (tok.type == Msg_t) {
- X if (NumEmitted == 0) {
- X NumEmitted++;
- X DoSubst(Banner, WorkBuf, CurDay, CurMon, CurYear,
- X JulianToday, Msg_t, (int) (SystemTime()/ 60), 0);
- X printf("%s\n", WorkBuf);
- X }
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 0);
- X printf("%s\n", WorkBuf);
- X }
- X else if (tok.type == Run_t) {
- X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim, 0);
- X system(WorkBuf);
- X }
- X else Eprint("Error: Invalid token type %d\n", tok.type);
- X return 1;
- X } else return 0;
- X
- X}
- X
- X/***************************************************************/
- X/* */
- X/* GetTriggerDate */
- X/* */
- X/* Gets the trigger date for a reminder, returns the julian */
- X/* date, or -1 if the reminder has expired. */
- X/* Returns -2 if an error occurs. */
- X/* */
- X/***************************************************************/
- X#ifdef __STDC__
- Xint GetTriggerDate(int d, int m, int y, int wd, int cons, int back, int repeat, int omit, int skip)
- X#else
- Xint GetTriggerDate(d, m, y, wd, cons, back, repeat, omit, skip)
- Xint d, m, y, wd, cons, back, repeat, omit, skip;
- X#endif
- X#define MAXATTEMPTS 25 /* Maximum number of attempts before giving up */
- X
- X{
- X int i, d2, m2, y2, jul;
- X int d1, m1, y1, julstart;
- X int nattempts = 0;
- X
- X julstart = JulianToday;
- X
- X /* If we have a skip factor of 3 (AFTER), then we must back up to
- X the beginning of the block of omitted days. */
- X if (skip == 3) while(julstart>=1 && IsOmitted(julstart-1, omit)) julstart--;
- X
- X FromJulian(julstart, &d1, &m1, &y1);
- X
- X /* Make a first stab at the date */
- X i = TryNextDate(&d2, &m2, &y2, d1, m1, y1, d, m, y, wd, cons, 0);
- X if (!i || repeat) jul = Julian(d2, m2, y2);
- X
- X if (!repeat && !back && !skip) {
- X if (i) return -1; else return jul;
- X }
- X
- X if (i && !repeat) return -1;
- X
- X while (nattempts++ < MAXATTEMPTS) {
- X if (back) jul = MoveBack(jul, back, omit);
- X if (repeat) {
- X if (jul < julstart) {
- X jul += ((julstart - jul) / repeat) * repeat;
- X if (jul < julstart) jul += repeat;
- X }
- X }
- X if (skip == 2) while (IsOmitted(jul, omit)) jul--;
- X else if (skip == 3) while (IsOmitted(jul, omit)) jul++;
- X if ((skip == 1 && IsOmitted(jul, omit)) || jul < JulianToday) {
- X if (!repeat) {
- X i = TryNextDate(&d2, &m2, &y2, d2, m2, y2, d, m, y, wd, cons, 1);
- X if (i) return -1;
- X jul = Julian(d2, m2, y2);
- X } else {
- X jul += repeat;
- X back = 0; /* We've already handled the back! */
- X }
- X } else return jul;
- X }
- X Eprint("Couldn't compute a trigger date - check that date is sensible.\n");
- X return -2;
- X}
- SHAR_EOF
- $TOUCH -am 0218130591 dorem.c &&
- chmod 0600 dorem.c ||
- echo "restore of dorem.c failed"
- set `wc -c dorem.c`;Wc_c=$1
- if test "$Wc_c" != "11579"; then
- echo original size 11579, current size $Wc_c
- fi
- fi
- # ============= dosubst.c ==============
- if test X"$1" != X"-c" -a -f 'dosubst.c'; then
- echo "File already exists: skipping 'dosubst.c'"
- else
- echo "x - extracting dosubst.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dosubst.c &&
- X#include <ctype.h>
- X#include <stdio.h>
- X#include <string.h>
- X#include "defines.h"
- X#include "globals.h"
- X#include "protos.h"
- X
- X/***************************************************************/
- X/* */
- X/* DOSUBST.C */
- X/* */
- X/* Performs line substitution for reminders. */
- X/* */
- X/* If mode = 0, ignore %" escapes. */
- X/* If mode = 1, process %" escapes. If a RUN type reminder */
- X/* does not have %" escape, return the empty string. */
- X/* */
- X/***************************************************************/
- X
- Xstatic char TODAY[] = "today";
- Xstatic char TOMORROW[] = "tomorrow";
- X
- X#ifdef __STDC__
- Xint DoSubst(char *src, char *dst, int d, int m, int y, int jul, enum Token_t t, int tim, int mode)
- X#else
- Xint DoSubst(src, dst, d, m, y, jul, t, tim, mode)
- X char *src;
- X char *dst;
- X int d;
- X int m;
- X int y;
- X int jul;
- X enum Token_t t;
- X int tim;
- X int mode;
- X#endif
- X{
- X int diff = jul - JulianToday;
- X char c;
- X char *od, *s;
- X int wkday = jul % 7;
- X char *plu, *pm;
- X int curtim = (int) (SystemTime() / 60);
- X int done;
- X int h;
- X int hh;
- X int min;
- X int tdiff;
- X int adiff, mdiff, hdiff;
- X char *mplu, *hplu, *when;
- X
- X if (mode == 1) {
- X s = src;
- X od = src;
- X while (*s) {
- X if (*s == '%' && *(s+1) == '\"') {
- X src = s+2;
- X break;
- X }
- X s++;
- X }
- X if (src == od && t == Run_t) {
- X *dst = 0;
- X return 0;
- X }
- X if (*src == '%' && *(src+1) == '\"') {
- X *dst = 0;
- X return 0;
- X }
- X if (tim != -1) {
- X sprintf(dst, "%02d:%02d ", (tim / 60), (tim % 60));
- X dst += strlen(dst);
- X }
- X }
- X
- X if (tim == -1) tim = curtim;
- X tdiff = tim - curtim;
- X adiff = ABS(tdiff);
- X mdiff = adiff % 60;
- X hdiff = adiff / 60;
- X mplu = (mdiff == 1 ? "" : "s");
- X hplu = (hdiff == 1 ? "" : "s");
- X when = (tdiff < 0 ? "ago" : "from now");
- X
- X h = tim / 60;
- X min = tim % 60;
- X
- X if (h >= 12) pm = "pm"; else pm = "am";
- X if (h == 12) hh = 12; else hh = h % 12;
- X
- X *dst = 0;
- X
- X switch(d) {
- X case 1:
- X case 21:
- X case 31: plu = "st"; break;
- X
- X case 2:
- X case 22: plu = "nd"; break;
- X
- X case 3:
- X case 23: plu = "rd"; break;
- X
- X default: plu = "th"; break;
- X }
- X
- X
- X while (c = *src++) {
- X if (c == '\n') continue;
- X else if (c != '%') { *dst++ = c; *dst = 0; }
- X else {
- X od = dst;
- X c = *src++;
- X done = 0;
- X if (diff <= 1) {
- X switch(upper(c)) {
- X case 'A':
- X case 'B':
- X case 'C':
- X case 'E':
- X case 'F':
- X case 'G':
- X case 'H':
- X case 'I':
- X case 'J':
- X case 'K':
- X case 'L':
- X case 'U':
- X case 'V': sprintf(dst, "%s", (diff ? TOMORROW : TODAY));
- X dst += strlen(dst);
- X done = 1;
- X break;
- X
- X default: done = 0;
- X }
- X }
- X
- X if (!done) switch(upper(c)) {
- X case 0: *dst = 0; return 0;
- X
- X case '\"': if (mode == 1) {
- X *dst = 0;
- X return 0;
- X }
- X break;
- X
- X case 'A':
- X sprintf(dst, "on %s, %d %s, %d", DayName[wkday], d,
- X MonthName[m], y);
- X dst += strlen(dst);
- X break;
- X
- X case 'B':
- X sprintf(dst, "in %d days' time", diff);
- X dst += strlen(dst);
- X break;
- X
- X case 'C':
- X sprintf(dst, "on %s", DayName[wkday]);
- X dst += strlen(dst);
- X break;
- X
- X case 'D':
- X sprintf(dst, "%d", d);
- X dst += strlen(dst);
- X break;
- X
- X case 'E':
- X sprintf(dst, "on %02d/%02d/%04d", d, m+1, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'F':
- X sprintf(dst, "on %02d/%02d/%04d", m+1, d, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'G':
- X sprintf(dst, "on %s, %d %s", DayName[wkday], d, MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'H':
- X sprintf(dst, "on %02d/%02d", d, m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'I':
- X sprintf(dst, "on %02d/%02d", m+1, d);
- X dst += strlen(dst);
- X break;
- X
- X case 'J':
- X sprintf(dst, "on %s, %s %d%s, %d", DayName[wkday],
- X MonthName[m], d, plu, y);
- X dst += strlen(dst);
- X break;
- X
- X case 'K':
- X sprintf(dst, "on %s, %s %d%s", DayName[wkday],
- X MonthName[m], d, plu);
- X dst += strlen(dst);
- X break;
- X
- X case 'L':
- X sprintf(dst, "on %04d/%02d/%02d", y, m+1, d);
- X dst += strlen(dst);
- X break;
- X
- X case 'M':
- X sprintf(dst, "%s", MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'N':
- X sprintf(dst, "%d", m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'O':
- X if (RealToday == JulianToday) sprintf(dst, " (today)");
- X dst += strlen(dst);
- X break;
- X
- X case 'P':
- X sprintf(dst, (diff == 1 ? "" : "s"));
- X dst += strlen(dst);
- X break;
- X
- X case 'Q':
- X sprintf(dst, (diff == 1 ? "'s" : "s'"));
- X dst += strlen(dst);
- X break;
- X
- X case 'R':
- X sprintf(dst, "%02d", d);
- X dst += strlen(dst);
- X break;
- X
- X case 'S':
- X sprintf(dst, plu);
- X dst += strlen(dst);
- X break;
- X
- X case 'T':
- X sprintf(dst, "%02d", m+1);
- X dst += strlen(dst);
- X break;
- X
- X case 'U':
- X sprintf(dst, "on %s, %d%s %s, %d", DayName[wkday], d,
- X plu, MonthName[m], y);
- X dst += strlen(dst);
- X break;
- X
- X case 'V':
- X sprintf(dst, "on %s, %d%s %s", DayName[wkday], d, plu,
- X MonthName[m]);
- X dst += strlen(dst);
- X break;
- X
- X case 'W':
- X sprintf(dst, DayName[wkday]);
- X dst += strlen(dst);
- X break;
- X
- X case 'X':
- X sprintf(dst, "%d", diff);
- X dst += strlen(dst);
- X break;
- X
- X case 'Y':
- X sprintf(dst, "%d", y);
- X dst += strlen(dst);
- X break;
- X
- X case 'Z':
- X sprintf(dst, "%d", y % 100);
- X dst += strlen(dst);
- X break;
- X
- X case '1':
- X if (tdiff == 0)
- X sprintf(dst, "now");
- X else if (hdiff == 0)
- X sprintf(dst, "%d minute%s %s", mdiff, mplu, when);
- X else if (mdiff == 0)
- X sprintf(dst, "%d hour%s %s", hdiff, hplu, when);
- X else
- X sprintf(dst, "%d hour%s and %d minute%s %s", hdiff, hplu, mdiff, mplu, when);
- X dst += strlen(dst);
- X break;
- X
- X case '2':
- X sprintf(dst, "at %d:%02d%s", hh, min, pm);
- X dst += strlen(dst);
- X break;
- X
- X case '3': sprintf(dst, "at %02d:%02d", h, min);
- X dst += strlen(dst);
- X break;
- X
- X case '4': sprintf(dst, "%d", tdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '5': sprintf(dst, "%d", adiff);
- X dst += strlen(dst);
- X break;
- X
- X case '6': sprintf(dst, when);
- X dst += strlen(dst);
- X break;
- X
- X case '7': sprintf(dst, "%d", hdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '8': sprintf(dst, "%d", mdiff);
- X dst += strlen(dst);
- X break;
- X
- X case '9': sprintf(dst, mplu);
- X dst += strlen(dst);
- X break;
- X
- X case '0': sprintf(dst, hplu);
- X dst += strlen(dst);
- X break;
- X
- X case '!': sprintf(dst, (tdiff >= 0 ? "is" : "was"));
- X dst += strlen(dst);
- X break;
- X
- X case '_': *dst++ = '\n'; *dst = 0;
- X break;
- X
- X default:
- X *dst++ = c;
- X *dst = 0;
- X }
- X if (isupper(c)) *od = upper(*od);
- X }
- X }
- X if (t == Msg_t && mode == 0) *dst++ = '\n';
- X *dst = 0;
- X return 0;
- X}
- SHAR_EOF
- $TOUCH -am 0218130591 dosubst.c &&
- chmod 0600 dosubst.c ||
- echo "restore of dosubst.c failed"
- set `wc -c dosubst.c`;Wc_c=$1
- if test "$Wc_c" != "8427"; then
- echo original size 8427, current size $Wc_c
- fi
- fi
- echo "End of part 1, continue with part 2"
- exit 0
-