Finish up Purge Mode:

o Make it recognize constant expressions (yay!)
o Make it not add a blank line to end of *.purged files.
o Make it nuke #!P comments in the source files.
This commit is contained in:
David F. Skoll
2010-04-21 09:02:25 -04:00
parent 70adbf90c2
commit a1faa8d804
16 changed files with 83 additions and 41 deletions

View File

@@ -871,7 +871,7 @@ static int DoCalRem(ParsePtr p, int col)
char evalBuf[64];
sprintf(evalBuf, "calprefix(%d)", trig.priority);
s2 = evalBuf;
r = EvalExpr(&s2, &v);
r = EvalExpr(&s2, &v, NULL);
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(&obuf, v.v.str) != OK) {
@@ -908,7 +908,7 @@ static int DoCalRem(ParsePtr p, int col)
char evalBuf[64];
sprintf(evalBuf, "calsuffix(%d)", trig.priority);
s2 = evalBuf;
r = EvalExpr(&s2, &v);
r = EvalExpr(&s2, &v, NULL);
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(&obuf, v.v.str) != OK) {

View File

@@ -109,8 +109,13 @@ int DoRem(ParsePtr p)
if (PurgeMode) {
if (trig.expired || jul < JulianToday) {
if (p->expr_happened) {
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains expression");
PurgeEchoLine("%s\n", CurLine);
if (p->nonconst_expr) {
PurgeEchoLine("%s\n", "#!P: Next line may have expired, but contains non-constant expression");
PurgeEchoLine("%s\n", CurLine);
} else {
PurgeEchoLine("%s\n", "#!P: Next line has expired, but contains expression... please verify");
PurgeEchoLine("#!P: Expired: %s\n", CurLine);
}
} else {
PurgeEchoLine("#!P: Expired: %s\n", CurLine);
}
@@ -780,7 +785,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (UserFuncExists("msgprefix") == 1) {
sprintf(PrioExpr, "msgprefix(%d)", t->priority);
s = PrioExpr;
r = EvalExpr(&s, &v);
r = EvalExpr(&s, &v, NULL);
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(&buf, v.v.str) != OK) {
@@ -799,7 +804,7 @@ int TriggerReminder(ParsePtr p, Trigger *t, TimeTrig *tim, int jul)
if (UserFuncExists("msgsuffix") == 1) {
sprintf(PrioExpr, "msgsuffix(%d)", t->priority);
s = PrioExpr;
r = EvalExpr(&s, &v);
r = EvalExpr(&s, &v, NULL);
if (!r) {
if (!DoCoerce(STR_TYPE, &v)) {
if (DBufPuts(&buf, v.v.str) != OK) {
@@ -1098,7 +1103,7 @@ static int ShouldTriggerBasedOnWarn(Trigger *t, int jul, int *err)
for (i=1; ; i++) {
sprintf(buffer, "%s(%d)", t->warn, i);
s = buffer;
r = EvalExpr(&s, &v);
r = EvalExpr(&s, &v, NULL);
if (r) {
Eprint("%s: `%s': %s", ErrMsg[M_BAD_WARN_FUNC],
t->warn, ErrMsg[r]);

View File

@@ -41,7 +41,7 @@ static int Multiply(void), Divide(void), Mod(void), Add(void),
UnMinus(void), LogNot(void),
Compare(int);
static int MakeValue (char const *s, Value *v, Var *locals);
static int MakeValue (char const *s, Value *v, Var *locals, ParsePtr p);
/* Binary operators - all left-associative */
@@ -303,14 +303,14 @@ static int ParseExprToken(DynamicBuffer *buf, char const **in)
/* Put the result into value pointed to by v. */
/* */
/***************************************************************/
int EvalExpr(char const **e, Value *v)
int EvalExpr(char const **e, Value *v, ParsePtr p)
{
int r;
OpStackPtr = 0;
ValStackPtr = 0;
r = Evaluate(e, NULL);
r = Evaluate(e, NULL, p);
/* Put last character parsed back onto input stream */
if (DBufLen(&ExprBuf)) (*e)--;
@@ -326,7 +326,7 @@ int EvalExpr(char const **e, Value *v)
}
/* Evaluate - do the actual work of evaluation. */
int Evaluate(char const **s, Var *locals)
int Evaluate(char const **s, Var *locals, ParsePtr p)
{
int OpBase, ValBase;
int r;
@@ -351,7 +351,7 @@ int Evaluate(char const **s, Var *locals)
if (*DBufValue(&ExprBuf) == '(') { /* Parenthesized expression */
DBufFree(&ExprBuf);
r = Evaluate(s, locals); /* Leaves the last parsed token in ExprBuf */
r = Evaluate(s, locals, p); /* Leaves the last parsed token in ExprBuf */
if (r) return r;
r = OK;
if (*DBufValue(&ExprBuf) != ')') {
@@ -376,7 +376,7 @@ int Evaluate(char const **s, Var *locals)
if (PeekChar(s) == ')') { /* Function has no arguments */
if (f) r = CallFunc(f, 0);
else {
r = CallUserFunc(ufname, 0);
r = CallUserFunc(ufname, 0, p);
free((char *) ufname);
}
if (r) return r;
@@ -385,7 +385,7 @@ int Evaluate(char const **s, Var *locals)
} else { /* Function has some arguments */
while(1) {
args++;
r = Evaluate(s, locals);
r = Evaluate(s, locals, p);
if (r) {
if (!f) free((char *) ufname);
return r;
@@ -401,7 +401,7 @@ int Evaluate(char const **s, Var *locals)
}
if (f) r = CallFunc(f, args);
else {
r = CallUserFunc(ufname, args);
r = CallUserFunc(ufname, args, p);
free((char *) ufname);
}
DBufFree(&ExprBuf);
@@ -422,7 +422,7 @@ int Evaluate(char const **s, Var *locals)
DBufFree(&ExprBuf);
return E_ILLEGAL_CHAR;
} else { /* Must be a literal value */
r = MakeValue(DBufValue(&ExprBuf), &va, locals);
r = MakeValue(DBufValue(&ExprBuf), &va, locals, p);
DBufFree(&ExprBuf);
if (r) return r;
PushValStack(va);
@@ -486,7 +486,7 @@ int Evaluate(char const **s, Var *locals)
/* a date or the value of a symbol. */
/* */
/***************************************************************/
static int MakeValue(char const *s, Value *v, Var *locals)
static int MakeValue(char const *s, Value *v, Var *locals, ParsePtr p)
{
int len;
int h, m, r;
@@ -541,6 +541,7 @@ static int MakeValue(char const *s, Value *v, Var *locals)
v->v.val = len;
return OK;
} else if (*s == '$') { /* A system variable */
if (p) p->nonconst_expr = 1;
if (DebugFlag & DB_PRTEXPR)
fprintf(ErrFp, "%s => ", s);
r = GetSysVar(s+1, v);
@@ -551,9 +552,11 @@ static int MakeValue(char const *s, Value *v, Var *locals)
Putc('\n', ErrFp);
}
return r;
} else /* Must be a symbol */
} else { /* Must be a symbol */
if (p) p->nonconst_expr = 1;
if (DebugFlag & DB_PRTEXPR)
fprintf(ErrFp, "%s => ", s);
}
r = GetVarValue(s, v, locals);
if (! (DebugFlag & DB_PRTEXPR)) return r;
if (r == OK) {

View File

@@ -200,6 +200,11 @@ static int ReadLineFromFile(void)
}
if (feof(fp)) {
FCLOSE(fp);
if ((DBufLen(&buf) == 0) &&
(DBufLen(&LineBuffer) == 0) && PurgeMode) {
if (PurgeFP != NULL && PurgeFP != stdout) fclose(PurgeFP);
PurgeFP = NULL;
}
}
l = DBufLen(&buf);
if (l && (DBufValue(&buf)[l-1] == '\\')) {

View File

@@ -80,7 +80,7 @@ EXTERN INIT( int MaxStringLen, MAX_STR_LEN);
EXTERN INIT( char *FileName, NULL);
EXTERN INIT( int UseStdin, 0);
EXTERN INIT( int PurgeMode, 0);
EXTERN INIT( int PurgeIncludeDepth, 99999);
EXTERN INIT( int PurgeIncludeDepth, 0);
EXTERN FILE *ErrFp;
EXTERN INIT( FILE *PurgeFP, NULL);
EXTERN INIT( int NumIfs, 0);

View File

@@ -754,7 +754,7 @@ static void InitializeVar(char const *str)
return;
}
r=EvalExpr(&expr, &val);
r=EvalExpr(&expr, &val, NULL);
if (r) {
fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]);
return;

View File

@@ -192,7 +192,9 @@ static void DoReminders(void)
{
/*** IGNORE THE LINE ***/
if (PurgeMode) {
PurgeEchoLine("%s\n", CurLine);
if (strncmp(CurLine, "#!P", 3)) {
PurgeEchoLine("%s\n", CurLine);
}
}
}
else {
@@ -203,6 +205,9 @@ static void DoReminders(void)
case T_Empty:
case T_Comment:
if (!strncmp(CurLine, "#!P", 3)) {
purge_handled = 1;
}
break;
case T_Rem: r=DoRem(&p); purge_handled = 1; break;
@@ -387,7 +392,7 @@ int ParseChar(ParsePtr p, int *err, int peek)
}
p->expr_happened = 1;
p->pos++;
r = EvalExpr(&(p->pos), &val);
r = EvalExpr(&(p->pos), &val, p);
if (r) {
*err = r;
DestroyParser(p);
@@ -530,7 +535,7 @@ int EvaluateExpr(ParsePtr p, Value *v)
(p->pos)++;
bracketed = 1;
}
r = EvalExpr(&(p->pos), v);
r = EvalExpr(&(p->pos), v, p);
if (r) return r;
if (bracketed) {
if (*p->pos != END_OF_EXPR) return E_MISS_END;
@@ -607,6 +612,7 @@ void CreateParser(char const *s, ParsePtr p)
p->allownested = 1;
p->tokenPushed = NULL;
p->expr_happened = 0;
p->nonconst_expr = 0;
DBufInit(&p->pushedToken);
}

View File

@@ -198,7 +198,7 @@ int IsOmitted(int jul, int localomit, char const *omitfunc, int *omit)
sprintf(expr, "%s('%04d-%02d-%02d')",
omitfunc, y, m+1, d);
s = expr;
r = EvalExpr(&s, &v);
r = EvalExpr(&s, &v, NULL);
if (r) return r;
if (v.type == INT_TYPE && v.v.val != 0) {
*omit = 1;

View File

@@ -21,7 +21,7 @@
#include "dynbuf.h"
int CallUserFunc (char const *name, int nargs);
int CallUserFunc (char const *name, int nargs, ParsePtr p);
int DoFset (ParsePtr p);
void ProduceCalendar (void);
char const *SimpleTime (int tim);
@@ -35,7 +35,7 @@ int ShouldTriggerReminder (Trigger *t, TimeTrig *tim, int jul, int *err);
int DoSubst (ParsePtr p, DynamicBuffer *dbuf, Trigger *t, TimeTrig *tt, int jul, int mode);
int DoSubstFromString (char const *source, DynamicBuffer *dbuf, int jul, int tim);
int ParseLiteralDate (char const **s, int *jul, int *tim);
int EvalExpr (char const **e, Value *v);
int EvalExpr (char const **e, Value *v, ParsePtr p);
int DoCoerce (char type, Value *v);
void PrintValue (Value *v, FILE *fp);
int CopyValue (Value *dest, const Value *src);
@@ -55,7 +55,7 @@ int ParseChar (ParsePtr p, int *err, int peek);
int ParseToken (ParsePtr p, DynamicBuffer *dbuf);
int ParseIdentifier (ParsePtr p, DynamicBuffer *dbuf);
int EvaluateExpr (ParsePtr p, Value *v);
int Evaluate (char const **s, Var *locals);
int Evaluate (char const **s, Var *locals, ParsePtr p);
int FnPopValStack (Value *val);
void Eprint (char const *fmt, ...);
void OutputLine (FILE *fp);

View File

@@ -411,7 +411,7 @@ static int CalculateNextTimeUsingSched(QueuedRem *q)
char exprBuf[VAR_NAME_LEN+32];
sprintf(exprBuf, "%s(%d)", q->sched, q->ntrig);
s = exprBuf;
r = EvalExpr(&s, &v);
r = EvalExpr(&s, &v, NULL);
if (r) {
q->sched[0] = 0;
return NO_TIME;

View File

@@ -181,7 +181,7 @@ static void IssueSortBanner(int jul)
FromJulian(jul, &y, &m, &d);
sprintf(BanExpr, "sortbanner('%04d/%02d/%02d')", y, m+1, d);
y = EvalExpr(&s, &v);
y = EvalExpr(&s, &v, NULL);
if (y) return;
if (DoCoerce(STR_TYPE, &v)) return;
DBufInit(&buf);

View File

@@ -96,6 +96,7 @@ typedef struct {
DynamicBuffer pushedToken; /* Pushed-back token */
char const *tokenPushed; /* NULL if no pushed-back token */
char expr_happened; /* Did we encounter an [expression] ? */
char nonconst_expr; /* Did we encounter a non-constant [expression] ? */
} Parser;
typedef Parser *ParsePtr; /* Pointer to parser structure */

View File

@@ -243,7 +243,7 @@ static void FSet(UserFunc *f)
/* Call a user-defined function. */
/* */
/***************************************************************/
int CallUserFunc(char const *name, int nargs)
int CallUserFunc(char const *name, int nargs, ParsePtr p)
{
UserFunc *f;
int h = HashVal(name) % FUNC_HASH_SIZE;
@@ -301,7 +301,7 @@ int CallUserFunc(char const *name, int nargs)
/* Skip the opening bracket, if there's one */
while (isempty(*s)) s++;
if (*s == BEG_OF_EXPR) s++;
h = Evaluate(&s, f->locals);
h = Evaluate(&s, f->locals, p);
f->IsActive = 0;
DestroyLocalVals(f);
if (DebugFlag &DB_PRTEXPR) {

View File

@@ -16,14 +16,26 @@ IFTRIG 1991
REM MSG wookie
ENDIF
REM [1990+1] MSG old-with-expression
REM [1990+1] MSG old-with-constant-expression
REM [1990+1] \
MSG Continued line
MSG Continued line-old-with-constant-expression
REM 1990 \
MSG expired-continued-line
set y 1990
REM [y+1] MSG old-with-nonconstant-expression
# A comment that should be preserved
#!P A comment that should be nuked because it \
starts with #!P
REM [y+1] \
MSG Continued-line-old-with-nonconstant-expression
OMIT 25 Dec MSG woaaahh!
OMIT 24 Dec

View File

@@ -68,7 +68,7 @@ echo "Sort Test" >> ../tests/test.out
(echo "REM AT 12:00 MSG Untimed"; echo "REM MSG Timed") | ../src/remind -gaaad - 1 Jan 2000 >> ../tests/test.out 2>&1
echo "Purge Test" >> ../tests/test.out
../src/remind -j ../tests/purge_dir/f1.rem >> ../tests/test.out 2>&1
../src/remind -j999 ../tests/purge_dir/f1.rem >> ../tests/test.out 2>&1
echo "F1" >> ../tests/test.out
cat ../tests/purge_dir/f1.rem.purged >> ../tests/test.out
echo "F2" >> ../tests/test.out

View File

@@ -2166,7 +2166,6 @@ REM 3 feb 2012 MSG new
#!P: Expired: REM 3 1998 MSG old
INCLUDE [filedir()]/f3.rem
F3
# This is f3.rem
@@ -2191,16 +2190,28 @@ IFTRIG 1991
REM MSG wookie
ENDIF
#!P: Next line may have expired, but contains expression
REM [1990+1] MSG old-with-expression
#!P: Next line has expired, but contains expression... please verify
#!P: Expired: REM [1990+1] MSG old-with-constant-expression
#!P: Next line may have expired, but contains expression
REM [1990+1] \
MSG Continued line
#!P: Next line has expired, but contains expression... please verify
#!P: Expired: REM [1990+1] \
MSG Continued line-old-with-constant-expression
#!P: Expired: REM 1990 \
MSG expired-continued-line
set y 1990
#!P: Next line may have expired, but contains non-constant expression
REM [y+1] MSG old-with-nonconstant-expression
# A comment that should be preserved
#!P: Next line may have expired, but contains non-constant expression
REM [y+1] \
MSG Continued-line-old-with-nonconstant-expression
OMIT 25 Dec MSG woaaahh!
OMIT 24 Dec
@@ -2222,7 +2233,6 @@ DUMP $
EXIT 0
PRESERVE i
../tests/runtest.rem(2): shell(): RUN disabled
../tests/runinc.rem(1): shell(): RUN disabled
../tests/runinc.rem(3): shell(): RUN disabled