More work on -j ("Purge Mode") option.

This commit is contained in:
David F. Skoll
2010-04-19 15:57:35 -04:00
parent 2d798bc4ec
commit 184d29c592
10 changed files with 125 additions and 26 deletions

View File

@@ -922,7 +922,7 @@ static int DoCalRem(ParsePtr p, int col)
}
}
s = DBufValue(&obuf);
if (!DoSimpleCalendar) while (isspace(*s)) s++;
if (!DoSimpleCalendar) while (isempty(*s)) s++;
DBufPuts(&pre_buf, s);
s = DBufValue(&pre_buf);
e = NEW(CalEntry);

View File

@@ -60,6 +60,8 @@ int DoRem(ParsePtr p)
if (trig.typ == NO_TYPE) return E_EOLN;
if (trig.typ == SAT_TYPE) {
PurgeEchoLine("%s\n", "### Cannot purge SATISFY-type reminders");
PurgeEchoLine("%s\n", CurLine);
r=DoSatRemind(&trig, &tim, p);
if (r) return r;
if (!LastTrigValid) return OK;
@@ -88,6 +90,7 @@ int DoRem(ParsePtr p)
trig.typ = tok.val;
jul = LastTriggerDate;
if (!LastTrigValid) return OK;
if (PurgeMode) return OK;
} else {
/* Calculate the trigger date */
jul = ComputeTrigger(trig.scanfrom, &trig, &r, 1);

View File

@@ -132,7 +132,7 @@ static void CleanStack(void)
static char PeekChar(char const **s)
{
char const *t = *s;
while (*t && isspace(*t)) t++;
while (*t && isempty(*t)) t++;
return *t;
}
@@ -150,7 +150,7 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
DBufFree(buf);
/* Skip white space */
while (**in && isspace(**in)) (*in)++;
while (**in && isempty(**in)) (*in)++;
if (!**in) return OK;
@@ -283,7 +283,7 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
(*in)++;
}
/* Chew up any remaining white space */
while (**in && isspace(**in)) (*in)++;
while (**in && isempty(**in)) (*in)++;
/* Peek ahead - is it '('? Then we have a function call */
if (**in == '(') {

View File

@@ -17,6 +17,7 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <sys/stat.h>
@@ -97,6 +98,19 @@ static void DestroyCache (CachedFile *cf);
static int CheckSafety (void);
static int PopFile (void);
static void OpenPurgeFile(char const *fname, char const *mode)
{
DynamicBuffer fname_buf;
DBufInit(&fname_buf);
if (DBufPuts(&fname_buf, fname) != OK) return;
if (DBufPuts(&fname_buf, ".purged") != OK) return;
PurgeFP = fopen(DBufValue(&fname_buf), mode);
if (!PurgeFP) {
fprintf(ErrFp, "Cannot open `%s' for writing: %s\n", DBufValue(&fname_buf), strerror(errno));
}
DBufFree(&fname_buf);
}
static void FreeChainItem(FilenameChain *chain)
{
if (chain->filename) free((void *) chain->filename);
@@ -173,15 +187,25 @@ static int ReadLineFromFile(void)
}
if (feof(fp)) {
FCLOSE(fp);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
}
l = DBufLen(&buf);
if (l && (DBufValue(&buf)[l-1] == '\\')) {
DBufValue(&buf)[l-1] = '\n';
if (DBufPuts(&LineBuffer, DBufValue(&buf)) != OK) {
DBufFree(&buf);
DBufFree(&LineBuffer);
return E_NO_MEM;
}
if (DBufPutc(&LineBuffer, '\n') != OK) {
DBufFree(&buf);
DBufFree(&LineBuffer);
return E_NO_MEM;
}
continue;
}
if (DBufPuts(&LineBuffer, DBufValue(&buf)) != OK) {
@@ -236,6 +260,9 @@ int OpenFile(char const *fname)
/* If it's a dash, then it's stdin */
if (!strcmp(fname, "-")) {
fp = stdin;
if (PurgeMode) {
PurgeFP = stdout;
}
if (DebugFlag & DB_TRACE_FILES) {
fprintf(ErrFp, "Reading `-': Reading stdin\n");
}
@@ -244,6 +271,9 @@ int OpenFile(char const *fname)
if (DebugFlag & DB_TRACE_FILES) {
fprintf(ErrFp, "Reading `%s': Opening file on disk\n", fname);
}
if (PurgeMode) {
OpenPurgeFile(fname, "w");
}
}
if (!fp || !CheckSafety()) return E_CANT_OPEN;
CLine = NULL;
@@ -257,8 +287,10 @@ int OpenFile(char const *fname)
if (strcmp(fname, "-")) {
fp = fopen(fname, "r");
if (!fp || !CheckSafety()) return E_CANT_OPEN;
if (PurgeMode) OpenPurgeFile(fname, "w");
} else {
fp = stdin;
if (PurgeMode) PurgeFP = stdout;
}
}
}
@@ -289,12 +321,28 @@ static int CacheFile(char const *fname)
/* Create a file header */
cf = NEW(CachedFile);
cf->cache = NULL;
if (!cf) { ShouldCache = 0; FCLOSE(fp); return E_NO_MEM; }
if (!cf) {
ShouldCache = 0;
FCLOSE(fp);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
return E_NO_MEM;
}
cf->filename = StrDup(fname);
if (!cf->filename) {
ShouldCache = 0;
FCLOSE(fp);
free(cf);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
return E_NO_MEM;
}
@@ -311,11 +359,17 @@ static int CacheFile(char const *fname)
DestroyCache(cf);
ShouldCache = 0;
FCLOSE(fp);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
return r;
}
/* Skip blank chars */
s = DBufValue(&LineBuffer);
while (isspace(*s)) s++;
while (isempty(*s)) s++;
if (*s && *s!=';' && *s!='#') {
/* Add the line to the cache */
if (!cl) {
@@ -325,6 +379,12 @@ static int CacheFile(char const *fname)
DestroyCache(cf);
ShouldCache = 0;
FCLOSE(fp);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
return E_NO_MEM;
}
cl = cf->cache;
@@ -334,6 +394,12 @@ static int CacheFile(char const *fname)
DBufFree(&LineBuffer);
DestroyCache(cf);
ShouldCache = 0;
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
FCLOSE(fp);
return E_NO_MEM;
}
@@ -346,6 +412,12 @@ static int CacheFile(char const *fname)
if (!cl->text) {
DestroyCache(cf);
ShouldCache = 0;
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
FCLOSE(fp);
return E_NO_MEM;
}
@@ -424,8 +496,10 @@ static int PopFile(void)
if (strcmp(i->filename, "-")) {
fp = fopen(i->filename, "r");
if (!fp || !CheckSafety()) return E_CANT_OPEN;
if (PurgeMode) OpenPurgeFile(i->filename, "a");
} else {
fp = stdin;
if (PurgeMode) PurgeFP = stdout;
}
if (fp != stdin)
(void) fseek(fp, i->offset, 0); /* Trust that it works... */
@@ -618,6 +692,12 @@ int IncludeFile(char const *fname)
if (fp) {
i->offset = ftell(fp);
FCLOSE(fp);
if (PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) {
fclose(PurgeFP);
}
PurgeFP = NULL;
}
}
IStackPtr++;

View File

@@ -81,6 +81,7 @@ EXTERN INIT( char *FileName, NULL);
EXTERN INIT( int UseStdin, 0);
EXTERN INIT( int PurgeMode, 0);
EXTERN FILE *ErrFp;
EXTERN INIT( FILE *PurgeFP, NULL);
EXTERN INIT( int NumIfs, 0);
EXTERN INIT( unsigned int IfFlags, 0);
EXTERN INIT( int LastTriggerDate, 0);

View File

@@ -146,6 +146,8 @@ void InitRemind(int argc, char const *argv[])
DBufPuts(&Banner, L_BANNER);
PurgeFP = NULL;
/* Make sure remind is not installed set-uid or set-gid */
if (getgid() != getegid() ||
getuid() != geteuid()) {

View File

@@ -133,7 +133,9 @@ void PurgeEchoLine(char const *fmt, ...)
{
va_list argptr;
va_start(argptr, fmt);
(void) vfprintf(stdout, fmt, argptr);
if (PurgeFP != NULL) {
(void) vfprintf(PurgeFP, fmt, argptr);
}
va_end(argptr);
}
@@ -151,7 +153,7 @@ static void DoReminders(void)
Token tok;
char const *s;
Parser p;
int was_rem;
int purge_handled;
if (!UseStdin) {
FileAccessDate = GetAccessDate(InitialFile);
@@ -194,7 +196,7 @@ static void DoReminders(void)
}
}
else {
was_rem = 0;
purge_handled = 0;
/* Create a parser to parse the line */
CreateParser(s, &p);
switch(tok.type) {
@@ -203,13 +205,21 @@ static void DoReminders(void)
case T_Comment:
break;
case T_Rem: r=DoRem(&p); was_rem = 1; break;
case T_Rem: r=DoRem(&p); purge_handled = 1; break;
case T_ErrMsg: r=DoErrMsg(&p); break;
case T_If: r=DoIf(&p); break;
case T_IfTrig: r=DoIfTrig(&p); break;
case T_Else: r=DoElse(&p); break;
case T_EndIf: r=DoEndif(&p); break;
case T_Include: r=DoInclude(&p); break;
case T_Include:
/* In purge mode, include closes file, so we
need to echo it here! */
if (PurgeMode) {
PurgeEchoLine("%s\n", CurLine);
}
r=DoInclude(&p);
purge_handled = 1;
break;
case T_Exit: DoExit(&p); break;
case T_Flush: r=DoFlush(&p); break;
case T_Set: r=DoSet(&p); break;
@@ -224,7 +234,7 @@ static void DoReminders(void)
DestroyParser(&p);
CreateParser(s, &p);
r=DoRem(&p);
was_rem = 1;
purge_handled = 1;
}
break;
case T_Pop: r=PopOmitContext(&p); break;
@@ -235,7 +245,7 @@ static void DoReminders(void)
} else {
CreateParser(CurLine, &p);
r=DoRem(&p);
was_rem = 1;
purge_handled = 1;
}
break;
@@ -244,14 +254,14 @@ static void DoReminders(void)
/* Note: Since the parser hasn't been used yet, we don't */
/* need to destroy it here. */
default: CreateParser(CurLine, &p); was_rem = 1; r=DoRem(&p); break;
default: CreateParser(CurLine, &p); purge_handled = 1; r=DoRem(&p); break;
}
if (r && (!Hush || r != E_RUN_DISABLED)) {
Eprint("%s", ErrMsg[r]);
}
if (PurgeMode) {
if (!was_rem) {
if (!purge_handled) {
PurgeEchoLine("%s\n", CurLine);
} else {
if (r) {
@@ -413,7 +423,7 @@ int ParseNonSpaceChar(ParsePtr p, int *err, int peek)
ch = ParseChar(p, err, 1);
if (*err) return 0;
while (isspace(ch)) {
while (isempty(ch)) {
ParseChar(p, err, 0); /* Guaranteed to work */
ch = ParseChar(p, err, 1);
if (*err) return 0;
@@ -437,12 +447,12 @@ int ParseToken(ParsePtr p, DynamicBuffer *dbuf)
c = ParseChar(p, &err, 0);
if (err) return err;
while (c && isspace(c)) {
while (c && isempty(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
if (!c) return OK;
while (c && !isspace(c)) {
while (c && !isempty(c)) {
if (DBufPutc(dbuf, c) != OK) {
DBufFree(dbuf);
return E_NO_MEM;
@@ -473,7 +483,7 @@ int ParseIdentifier(ParsePtr p, DynamicBuffer *dbuf)
c = ParseChar(p, &err, 0);
if (err) return err;
while (c && isspace(c)) {
while (c && isempty(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
@@ -514,7 +524,7 @@ int EvaluateExpr(ParsePtr p, Value *v)
int r;
if (p->isnested) return E_PARSE_ERR; /* Can't nest expressions */
while (isspace(*p->pos)) (p->pos)++;
while (isempty(*p->pos)) (p->pos)++;
if (!p->pos) return E_PARSE_ERR; /* Missing expression */
if (*p->pos == BEG_OF_EXPR) {
(p->pos)++;
@@ -933,7 +943,7 @@ int DoBanner(ParsePtr p)
DBufInit(&buf);
c = ParseChar(p, &err, 0);
if (err) return err;
while (isspace(c)) {
while (isempty(c)) {
c = ParseChar(p, &err, 0);
if (err) return err;
}
@@ -1041,7 +1051,7 @@ int DoErrMsg(ParsePtr p)
return r;
}
s = DBufValue(&buf);
while (isspace(*s)) s++;
while (isempty(*s)) s++;
fprintf(ErrFp, "%s\n", s);
DBufFree(&buf);
return OK;

View File

@@ -16,6 +16,9 @@
/* Define a general malloc routine for creating pointers to objects */
#define NEW(type) (malloc(sizeof(type)))
/* Characters to ignore */
#define isempty(c) (isspace(c) || ((c) == '\\'))
#include "dynbuf.h"
int CallUserFunc (char const *name, int nargs);

View File

@@ -146,9 +146,9 @@ char const *FindInitialToken(Token *tok, char const *s)
tok->type = T_Illegal;
while (isspace(*s)) s++;
while (isempty(*s)) s++;
while (*s && !isspace(*s)) {
while (*s && !isempty(*s)) {
if (DBufPutc(&buf, *s++) != OK) return s;
}

View File

@@ -299,7 +299,7 @@ int CallUserFunc(char const *name, int nargs)
s = f->text;
/* Skip the opening bracket, if there's one */
while (isspace(*s)) s++;
while (isempty(*s)) s++;
if (*s == BEG_OF_EXPR) s++;
h = Evaluate(&s, f->locals);
f->IsActive = 0;