REMIND 2.2 02/05
David F. Skoll
dfs at doe.carleton.ca
Sat Nov 17 05:46:49 AEST 1990
#!/bin/sh
# This is part 02 of Remind-2.2
if touch 2>&1 | fgrep 'amc' > /dev/null
then TOUCH=touch
else TOUCH=true
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#include <string.h>
X#endif
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#ifndef UNIX
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;
X int tim, tdelta, trep;
X int d2, m2, y2;
X Token tok;
X int trigger;
X
X d = m = y = back = delta = tim = tdelta = trep = -1;
X repeat = cons = wd = omit = once = 0;
X
X
X done = 0;
X while (!done) {
X tok = ParseToken(s);
X switch (tok.type) {
X case Eol_t:
X Eprint("Missing MSG or RUN in reminder.\n");
X return 0;
X
X case At_t:
X case Omit_t:
X case Run_t:
X case Msg_t: done = 1; 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 Banner_t:
X Eprint("BANNER can't be used here.\n");
X return 0;
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 != -1) {
X Eprint("Delta specified twice.\n");
X return 0;
X }
X delta = tok.val;
X break;
X
X case Back_t:
X if (back != -1) {
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 if (tok.type == Omit_t) {
X done = 0;
X while (!done) {
X tok = ParseToken(s);
X switch(tok.type) {
X
X case At_t:
X case Msg_t:
X case Run_t: done = 1; break;
X
X case Eol_t:
X Eprint("Missing MSG or RUN in reminder.\n");
X return 0;
X
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:
X Eprint("Only weekdays are valid after a local OMIT.\n");
X return 0;
X }
X }
X }
X if (tok.type == At_t) {
X done = 0;
X while (!done) {
X tok = ParseToken(s);
X switch(tok.type) {
X
X case Msg_t:
X case Run_t: done = 1; break;
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 = tok.val;
X break;
X
X default: Eprint("Can't use token %s in an AT.\n", tok.str);
X return 0;
X }
X }
X }
X
X
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 (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 /* Tweak the back and delta values to their defaults */
X if (back == -1) back = 0;
X if (delta == -1) delta = 0;
X
X jul = GetTriggerDate(d, m, y, wd, cons, back, repeat, omit);
X if (Calendar) {
X if (jul == JulianToday && tok.type == Msg_t) {
X while (isspace(**s)) (*s)++;
X strcpy(WorkBuf, *s);
X CalTime = tim;
X return 1;
X } else return 0;
X }
X
X if (jul == -1) {
X if (Debug) Eprint("Reminder has expired.\n");
X return -1;
X }
X FromJulian(jul, &d2, &m2, &y2);
X
X /* Figure out if the reminder should be triggered */
X
X trigger = MoveBack(jul, delta, d2, m2, y2, 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));
X printf("%s\n", WorkBuf);
X }
X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim);
X printf("%s\n", WorkBuf);
X }
X else if (tok.type == Run_t) {
X DoSubst(*s, WorkBuf, d2, m2, y2, jul, tok.type, tim);
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/* */
X/***************************************************************/
X#ifndef UNIX
Xint GetTriggerDate(int d, int m, int y, int wd, int cons, int back, int repeat, int omit)
X#else
Xint GetTriggerDate(d, m, y, wd, cons, back, repeat, omit)
Xint d, m, y, wd, cons, back, repeat, omit;
X#endif
X{
X int i, d2, m2, y2, jul;
X
X i = TryNextDate(&d2, &m2, &y2, CurDay, CurMon, CurYear,
X d, m, y, wd, cons, 0);
X
X if (i && !repeat) return -1;
X
X jul = Julian(d2, m2, y2);
X if (repeat) {
X if (back) jul = MoveBack(jul, back, d2, m2, y2, omit);
X
X if (jul < JulianToday) {
X jul += ((JulianToday - jul) / repeat) * repeat;
X if (jul < JulianToday) jul += repeat;
X }
X return jul;
X
X } else {
X if (back) {
X jul = MoveBack(jul, back, d2, m2, y2, omit);
X while (jul < JulianToday) {
X i = TryNextDate(&d2, &m2, &y2, d2, m2, y2,
X d, m, y, wd, cons, 1);
X if (i) return -1;
X jul = Julian(d2, m2, y2);
X jul = MoveBack(jul, back, d2, m2, y2, omit);
X }
X
X }
X return jul;
X }
X}
SHAR_EOF
$TOUCH -am 1115094090 dorem.c &&
chmod 0600 dorem.c ||
echo "restore of dorem.c failed"
set `wc -c dorem.c`;Wc_c=$1
if test "$Wc_c" != "8966"; then
echo original size 8966, 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#ifndef UNIX
X#include <string.h>
X#endif
X#include "defines.h"
X#include "globals.h"
X#include "protos.h"
X
X#define ABS(x) ( ((x) < 0) ? (-(x)) : (x))
X
X/***************************************************************/
X/* */
X/* DOSUBST.C */
X/* */
X/* Performs line substitution for reminders. */
X/* */
X/***************************************************************/
X
Xstatic char TODAY[] = "today";
Xstatic char TOMORROW[] = "tomorrow";
X
X#ifndef UNIX
Xint DoSubst(char *src, char *dst, int d, int m, int y, int jul, enum Token_t t, int tim)
X#else
Xint DoSubst(src, dst, d, m, y, jul, t, tim)
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#endif
X{
X int diff = jul - JulianToday;
X char c;
X char *od;
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 (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 '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 case '\"': break; /* Ignore the %" marker */
X
X default:
X *dst++ = c;
X *dst = 0;
X }
X if (isupper(c)) *od = upper(*od);
X }
X }
X if (t == Msg_t) *dst++ = '\n';
X *dst = 0;
X return 0;
X}
SHAR_EOF
$TOUCH -am 1116095790 dosubst.c &&
chmod 0600 dosubst.c ||
echo "restore of dosubst.c failed"
set `wc -c dosubst.c`;Wc_c=$1
if test "$Wc_c" != "7683"; then
echo original size 7683, current size $Wc_c
fi
fi
# ============= files.c ==============
if test X"$1" != X"-c" -a -f 'files.c'; then
echo "File already exists: skipping 'files.c'"
else
echo "x - extracting files.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > files.c &&
X#include <stdio.h>
X#ifndef UNIX
X#include <stdlib.h>
X#endif
X#include <string.h>
X#include <malloc.h>
X#ifndef UNIX
X#include <dos.h>
X#endif
X#include <fcntl.h>
X#ifdef UNIX
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <time.h>
X#endif
X#include "defines.h"
X#include "globals.h"
X#include "protos.h"
X
X#ifndef UNIX
Xstatic int PopFile(void);
X#else
Xstatic int PopFile();
X#endif
X
X/***************************************************************/
X/* */
X/* FILES.C */
X/* */
X/* All the routines for opening initial file, getting */
X/* and settting initial file's date, closing files, */
X/* handling INCLUDE commands, etc. */
X/* */
X/***************************************************************/
X
X/* Define the structure for saving info about a file */
Xtypedef struct {
X long offset;
X int curline;
X char *name;
X} FileSave;
X
X#define MAXINCLUDE 10
X/* Set up array of MAXINCLUDE file save areas */
Xstatic FileSave stack[MAXINCLUDE];
Xstatic int SP;
X
Xstatic FILE *fp;
X
X/***************************************************************/
X/* */
X/* OpenFile */
X/* */
X/* Open the named file, initialize stack, get file date. */
X/* If there's a problem, print an error msg and die. */
X/* */
X/***************************************************************/
X#ifndef UNIX
Xvoid OpenFile(char *s)
X#else
Xvoid OpenFile(s)
X char *s;
X
X#endif
X{
X unsigned date, time;
X#ifndef UNIX
X unsigned handle;
X#endif
X int d, m, y;
X#ifndef UNIX
X
X /* Get the file's modification date */
X if(_dos_open(s, O_RDONLY, &handle)) {
X fprintf(stderr, "remind: Can't open %s.\n", s);
X exit(1);
X#else
X struct stat t;
X struct tm *t1;
X
X /* Get the file's access date */
X if (stat(s, &t)) {
X fprintf(stderr, "remind: Can't find file %s.\n", s);
X exit(1);
X#endif
X }
X#ifndef UNIX
X _dos_getftime(handle, &date, &time);
X d = date & 0x1F;
X m = (date >> 5) & 0xF;
X y = (date >> 9) + 1980;
X#else
X t1 = localtime(&(t.st_atime));
X#endif
X
X#ifndef UNIX
X if (y < BASE) LastRun = 0; else LastRun = Julian(d, m-1, y);
X _dos_close(handle);
X#else
X y = t1->tm_year + 1900;
X m = t1->tm_mon;
X d = t1->tm_mday;
X
X if (y < BASE) LastRun = 0; else LastRun = Julian(d, m, y);
X#endif
X fp = fopen(s, "r");
X if (fp == NULL) {
X fprintf(stderr, "remind: Can't open %s.\n", s);
X exit(1);
X }
X
X CurLine = 0;
X strcpy(FileName, s);
X SP = 0;
X
X return;
X}
X
X/***************************************************************/
X/* */
X/* DoInclude */
X/* */
X/* Push the state of the current file and open a new file. */
X/* */
X/***************************************************************/
X#ifndef UNIX
Xvoid DoInclude(char **s)
X#else
Xvoid DoInclude(s)
X char **s;
X
X#endif
X{
X Token tok;
X tok = ParseToken(s);
X
X /* First, check if there's room on the stack */
X if (SP == MAXINCLUDE) {
X Eprint("Too many levels of INCLUDE\n");
X return;
X }
X
X /* Save current data */
X#ifndef UNIX
X stack[SP].offset = ftell(fp) - 1L;
X#else
X stack[SP].offset = ftell(fp);
X#endif
X stack[SP].curline = CurLine;
X stack[SP].name = (char *) malloc(strlen(FileName)+1);
X if (stack[SP].name == NULL) {
X Eprint("Out of memory for INCLUDE\n");
X return;
X }
X strcpy(stack[SP].name, FileName);
X
X SP++;
X
X /* Close the current file */
X fclose(fp);
X
X /* Open the new file */
X fp = fopen(tok.str, "r");
X if (fp == NULL) {
X Eprint("Can't open %s for INCLUDE\n", tok.str);
X PopFile();
X return;
X }
X if (Debug || Purge) {
X Eprint("INCLUDING file %s\n", tok.str);
X }
X
X /* Set the global variables */
X CurLine = 0;
X strcpy(FileName, tok.str);
X return;
X}
X
X/***************************************************************/
X/* */
X/* PopFile */
X/* */
X/* Pop to the previous file, if there is one. Return 0 for */
X/* OK, non-zero for no more files. If we can't pop back */
X/* to a file, print an error message and die. */
X/* */
X/***************************************************************/
X#ifndef UNIX
Xstatic int PopFile(void)
X#else
Xstatic int PopFile()
X#endif
X{
X#ifndef UNIX
X unsigned handle, date, time;
X struct dostime_t t;
X#endif
X
X if (fp) fclose(fp);
X#ifndef UNIX
X if (!SP) {
X if (!Debug && !Purge && (JulianToday == RealToday)) {
X if (_dos_open(FileName, O_RDONLY, &handle)) {
X fprintf(stderr, "Could not reset date of %s", FileName);
X return 1;
X }
X _dos_gettime(&t);
X date = CurDay;
X date |= (CurMon + 1) << 5;
X date |= (CurYear - 1980) << 9;
X time = t.second / 2;
X time |= t.minute << 5;
X time |= t.hour << 11;
X _dos_setftime(handle, date, time);
X }
X return 1;
X }
X
X#else
X if (!SP) return -1;
X
X#endif
X SP--;
X fp = fopen(stack[SP].name, "r");
X if (fp == NULL) {
X Eprint("Argh! Can't return to %s from INCLUDE file %s", stack[SP].name, FileName);
X exit(1);
X }
X#ifndef UNIX
X if (fseek(fp, stack[SP].offset, SEEK_SET)) {
X#else
X if (fseek(fp, stack[SP].offset, 0)) {
X#endif
X Eprint("Argh! Can't fseek %s after returning from INCLUDE file %s", stack[SP].name, FileName);
X exit(1);
X }
X
X if (Debug || Purge) {
X Eprint("Returning to file %s\n", stack[SP].name);
X }
X CurLine = stack[SP].curline;
X strcpy(FileName, stack[SP].name);
X free(stack[SP].name);
X return 0;
X}
X/***************************************************************/
X/* */
X/* ReadLine */
X/* */
X/* Reads a line from the file. If EOF, pops to previous file */
X/* if there was one. Returns 0 if more input, non-zero */
X/* if no more input. Updates CurLine. */
X/* */
X/***************************************************************/
Xint ReadLine()
X{
X int done = 0;
X int len;
X
X Fresh = 1;
X while (!done) {
X CurLine++;
X if (fgets(Line, 512, fp) == NULL) {
X if (ferror(fp)) Eprint("Error reading %s", FileName);
X if (PopFile()) return 1;
X } else {
X len = strlen(Line);
X /* Remove the newline */
X if (*Line && (*(Line + len-1)=='\n')) {
X *(Line + strlen(Line)-1) = 0;
X len--;
X }
X done = 1;
X while(*Line && (*(Line + len-1) == '\\') && len<512) {
X *(Line + len-1) = '\n';
X if (fgets(Line+len, 512-len,fp) == NULL) {
X *(Line + len) = 0;
X break;
X }
X
X CurLine++;
X len = strlen(Line);
X /* Remove the newline */
X if (*Line && (*(Line + len-1)=='\n')) {
X *(Line + strlen(Line)-1) = 0;
X len--;
X }
X }
X }
X }
X return 0;
X}
X
X/***************************************************************/
X/* */
X/* TopLevel - Returns 1 if current file is top level, 0 */
X/* if it is INCLUDEd. */
X/* */
X/***************************************************************/
X#ifndef UNIX
Xint TopLevel(void) { return (SP == 0); }
X#else
Xint TopLevel()
X{
X return (SP == 0);
X}
X#endif
SHAR_EOF
$TOUCH -am 1115093990 files.c &&
chmod 0600 files.c ||
echo "restore of files.c failed"
set `wc -c files.c`;Wc_c=$1
if test "$Wc_c" != "8338"; then
echo original size 8338, current size $Wc_c
fi
fi
# ============= globals.h ==============
if test X"$1" != X"-c" -a -f 'globals.h'; then
echo "File already exists: skipping 'globals.h'"
else
echo "x - extracting globals.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > globals.h &&
X/***************************************************************/
X/* */
X/* GLOBALS.H */
X/* */
X/* Global variables for REMIND. */
X/* */
X/* By David Skoll - 30 Sept. 1990 */
X/* */
X/***************************************************************/
X
Xextern char *MonthName[];
Xextern char *DayName[];
Xextern Token keywd[];
Xextern int MonthDays[];
Xextern int MonthIndex[2][12];
Xextern int FullOmitArray[];
Xextern int PartOmitArray[];
Xextern char Line[];
Xextern char WorkBuf[];
Xextern char TmpBuf[];
Xextern int Fresh;
Xextern int Purge;
Xextern int Debug;
Xextern int Verbose;
Xextern char FileName[];
Xextern int CurLine;
Xextern int NumEmitted;
Xextern int NumRem;
Xextern int NumFullOmit;
Xextern int NumPartOmit;
Xextern int JulianToday;
Xextern int LastRun;
Xextern int CurYear;
Xextern int CurMon;
Xextern int CurDay;
Xextern char Banner[];
Xextern int RealToday;
Xextern int IgRun;
Xextern int IgOnce;
Xextern int NumAtsQueued;
Xextern int QueueAts;
Xextern int PrintAts;
Xextern int Calendar;
Xextern int CalTime;
Xextern int CalWidth;
Xextern int SimpleCalendar;
SHAR_EOF
$TOUCH -am 1115094990 globals.h &&
chmod 0600 globals.h ||
echo "restore of globals.h failed"
set `wc -c globals.h`;Wc_c=$1
if test "$Wc_c" != "1450"; then
echo original size 1450, current size $Wc_c
fi
fi
# ============= init.c ==============
if test X"$1" != X"-c" -a -f 'init.c'; then
echo "File already exists: skipping 'init.c'"
else
echo "x - extracting init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > init.c &&
X#include <stdio.h>
X#ifndef UNIX
X#include <stdlib.h>
X#endif
X#include <string.h>
X#include "defines.h"
X#include "globals.h"
X#include "protos.h"
X
X#define PATCHLEVEL 0
X
Xstatic char DPMsg[] = "Debug and Purge options conflict - Purge chosen.\n";
Xstatic char DPCMsg[] = "Calendar overrides Debug and Purge options.\n";
X/***************************************************************/
X/* */
X/* void initialize(int argc, char *argv[]) */
X/* */
X/* Reads command line options, sets appropriate flags */
X/* and FileName. Also exits with error if invoked */
X/* incorrectly. */
X/* */
X/***************************************************************/
X#ifndef UNIX
Xvoid initialize(int argc, char *argv[])
X#else
Xvoid initialize(argc, argv)
X int argc;
X char *argv[];
X#endif
X{
X int i;
X char *s;
X int d, m, y, t;
X Token tok;
X
X Debug = 0;
X Purge = 0;
X Verbose = 0;
X IgOnce = 0;
X IgRun = 0;
X Calendar = 0;
X PrintAts = 1;
X QueueAts = 1;
X CalWidth = 10;
X SimpleCalendar = 0;
X
X if(argc == 1) {
X fprintf(stderr, "\nREMIND 2.2 Patch Level %d (C) 1990 by David Skoll.\n\n", PATCHLEVEL);
X#ifdef UNIX
X fprintf(stderr, "Usage: remind [-d | -p | -c# [-w# | -s]] [-voraq] filename [date]\n\n");
X#else
X fprintf(stderr, "Usage: remind [-d | -p | -c# [-w# | -s]] [-vor] filename [date]\n\n");
X#endif
X fprintf(stderr, "-d Debug reminder file\n-p Purge reminder file\n");
X fprintf(stderr, "-c# Produce calendar for # months\n");
X fprintf(stderr, "-w# Make calendar # columns wide\n");
X fprintf(stderr, "-s Produce simple calendar listing\n");
X fprintf(stderr, "-v Verbose messages\n-o Ignore ONCE directives\n");
X fprintf(stderr, "-r Ignore RUN directives\n");
X#ifdef UNIX
X fprintf(stderr, "-a Do not trigger current AT reminders in foreground\n");
X fprintf(stderr, "-q Do not queue current AT reminders\n\n");
X#endif
X exit(1);
X }
X
X i = 1;
X s = argv[i];
X
X /* Process options */
X while (*s == '-') {
X while (*++s) {
X switch(upper(*s)) {
X
X case 'P': Purge = 1;
X if (Calendar) {
X Debug = Purge = 0;
X fprintf(stderr, DPCMsg);
X }
X if (Debug) {
X Debug = 0;
X fprintf(stderr, DPMsg);
X }
X break;
X
X case 'D': Debug = 1;
X if (Calendar) {
X Debug = Purge = 0;
X fprintf(stderr, DPCMsg);
X }
X if (Purge) {
X Debug = 0;
X fprintf(stderr, DPMsg);
X }
X break;
X
X case 'C': Calendar = 1;
X if (Debug || Purge) {
X Debug = Purge = 0;
X fprintf(stderr, DPCMsg);
X }
X t = atoi(s + 1);
X if (t > 0 && t <= 12) Calendar = t;
X /* Skip remaining chars on this option */
X while (*++s) ;
X s--;
X break;
X
X case 'W': CalWidth = (atoi(s+1)-9)/7;
X if (CalWidth < 10) CalWidth = 10;
X if (CalWidth > 40) CalWidth = 40;
X while (*++s) ;
X s--;
X break;
X
X case 'S': SimpleCalendar = 1; break;
X
X case 'V': Verbose = 1; break;
X
X case 'O': IgOnce = 1; break;
X
X case 'R': IgRun = 1; break;
X#ifdef UNIX
X case 'A': PrintAts = 0; break;
X
X case 'Q': QueueAts = 0; break;
X#endif
X default: fprintf(stderr, "Unknown option '%c' ignored.\n", *s);
X }
X }
X i++;
X if (i >= argc) {
X fprintf(stderr, "Missing filename - type 'remind' for usage information.\n");
X exit(1);
X }
X s = argv[i];
X }
X
X /* Set FileName */
X strcpy(FileName, argv[i++]);
X
X /* Get date, if supplied */
X if (i < argc) {
X *WorkBuf = 0;
X while (i < argc) {
X strcat(WorkBuf, argv[i++]);
X strcat(WorkBuf, " ");
X }
X /* Parse the date */
X d = m = y = -1;
X tok.type = Unknown_t;
X s = WorkBuf;
X while (tok.type != Eol_t) {
X tok = ParseToken(&s);
X switch(tok.type) {
X
X case Eol_t: break;
X
X case Year_t: if (y == -1)
X y = tok.val;
X else {
X fprintf(stderr, "Year specified twice!\n");
X exit(1);
X }
X break;
X
X case Month_t: if (m == -1)
X m = tok.val;
X else {
X fprintf(stderr, "Month specified twice!\n");
X exit(1);
X }
X break;
X
X case Day_t: if (d == -1)
X d = tok.val;
X else {
X fprintf(stderr, "Day specified twice!\n");
X exit(1);
X }
X break;
X
X default: fprintf(stderr, "Illegal token %s on command line.\n", tok.str);
X exit(1);
X
X }
X }
X
X if (d == -1 || m == -1 || y == -1) {
X fprintf(stderr, "Date on command line must be fully specified.\n");
X exit(1);
X }
X if (CheckDate(d, m, y)) {
X fprintf(stderr, "Illegal date on command line.\n");
X exit(1);
X }
X
X CurDay = d;
X CurMon = m;
X CurYear = y;
X JulianToday = Julian(d, m, y);
X }
X OpenFile(FileName);
X if (Debug) {
X FromJulian(LastRun, &d, &m, &y);
X#ifndef UNIX
X fprintf(stderr, "\nFile %s last modified on %s, %d %s, %d\n", FileName,
X#else
X fprintf(stderr, "\nFile %s last accessed on %s, %d %s, %d\n", FileName,
X#endif
X DayName[LastRun % 7], d, MonthName[m], y);
X }
X return;
X}
SHAR_EOF
$TOUCH -am 1116094290 init.c &&
chmod 0600 init.c ||
echo "restore of init.c failed"
set `wc -c init.c`;Wc_c=$1
if test "$Wc_c" != "5675"; then
echo original size 5675, current size $Wc_c
fi
fi
echo "End of part 2, continue with part 3"
exit 0
More information about the Alt.sources
mailing list