about summary refs log tree commit diff
path: root/Src/cond.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/cond.c')
-rw-r--r--Src/cond.c125
1 files changed, 70 insertions, 55 deletions
diff --git a/Src/cond.c b/Src/cond.c
index 4a6144bb1..4a78bd5e7 100644
--- a/Src/cond.c
+++ b/Src/cond.c
@@ -39,95 +39,108 @@ static char *condstr[COND_MOD] = {
 
 /**/
 int
-evalcond(Cond c)
+evalcond(Estate state)
 {
     struct stat *st;
     char *left, *right = NULL;
+    wordcode code = *state->pc++;
+    int ctype = WC_COND_TYPE(code);
 
-    switch (c->type) {
+    switch (ctype) {
     case COND_NOT:
 	if (tracingcond)
-	    fprintf(stderr, " %s", condstr[c->type]);
-	return !evalcond(c->left);
+	    fprintf(stderr, " %s", condstr[ctype]);
+	return !evalcond(state);
     case COND_AND:
-	if (evalcond(c->left)) {
+	if (evalcond(state)) {
 	    if (tracingcond)
-		fprintf(stderr, " %s", condstr[c->type]);
-	    return evalcond(c->right);
-	} else
+		fprintf(stderr, " %s", condstr[ctype]);
+	    return evalcond(state);
+	} else {
+	    state->pc += WC_COND_SKIP(code) - 1;
 	    return 0;
+	}
     case COND_OR:
-	if (!evalcond(c->left)) {
+	if (!evalcond(state)) {
 	    if (tracingcond)
-		fprintf(stderr, " %s", condstr[c->type]);
-	    return evalcond(c->right);
-	} else
+		fprintf(stderr, " %s", condstr[ctype]);
+	    return evalcond(state);
+	} else {
+	    state->pc += WC_COND_SKIP(code) - 1;
 	    return 1;
+	}
     case COND_MOD:
     case COND_MODI:
 	{
 	    Conddef cd;
+	    char *name = ecgetstr(state, 0), **strs;
+	    int l = WC_COND_SKIP(code);
 
-	    if ((cd = getconddef((c->type == COND_MODI),
-				 ((char *) c->left) + 1, 1))) {
-		if (c->type == COND_MOD) {
-		    int l = arrlen((char **) c->right);
+	    if (ctype == COND_MOD)
+		strs = ecgetarr(state, l, 1);
+	    else {
+		char *sbuf[3];
 
-		    if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
-			zerr("unrecognized condition: `%s'", (char *) c->left, 0);
-			return 0;
-		    }
+		sbuf[0] = ecgetstr(state, 0);
+		sbuf[1] = ecgetstr(state, 0);
+		sbuf[2] = NULL;
+
+		strs = arrdup(sbuf);
+		l = 2;
+	    }
+	    if ((cd = getconddef((ctype == COND_MODI), name + 1, 1))) {
+		if (ctype == COND_MOD &&
+		    (l < cd->min || (cd->max >= 0 && l > cd->max))) {
+		    zerr("unrecognized condition: `%s'", name, 0);
+		    return 0;
 		}
 		if (tracingcond)
-		    tracemodcond((char *)c->left, (char **)c->right,
-				 c->type == COND_MODI);
-		return cd->handler((char **) c->right, cd->condid);
+		    tracemodcond(name, strs, ctype == COND_MODI);
+		return cd->handler(strs, cd->condid);
 	    }
 	    else {
-		char **a = (char **) c->right, *s = a[0];
+		char *s = strs[0];
 
-		if (s && s[0] == '-' &&
-		    (cd = getconddef(0, s + 1, 1))) {
-		    int l = arrlen(a);
+		strs[0] = dupstring(name);
+		name = s;
 
+		if (name && name[0] == '-' &&
+		    (cd = getconddef(0, name + 1, 1))) {
 		    if (l < cd->min || (cd->max >= 0 && l > cd->max)) {
-			zerr("unrecognized condition: `%s'", (char *) c->left, 0);
+			zerr("unrecognized condition: `%s'", name, 0);
 			return 0;
 		    }
 		    if (tracingcond)
-			tracemodcond((char *)c->left, a, c->type == COND_MODI);
-		    a[0] = (char *) c->left;
-		    return cd->handler(a, cd->condid);
+			tracemodcond(name, strs, ctype == COND_MODI);
+		    return cd->handler(strs, cd->condid);
 		} else
-		    zerr("unrecognized condition: `%s'", (char *) c->left, 0);
+		    zerr("unrecognized condition: `%s'", name, 0);
 	    }
 	    return 0;
 	}
     }
-    left = dupstring((char *) c->left);
+    left = ecgetstr(state, 1);
     singsub(&left);
     untokenize(left);
-    if (c->right && c->type != COND_STREQ && c->type != COND_STRNEQ) {
-	right = dupstring((char *) c->right);
+    if (ctype <= COND_GE && ctype != COND_STREQ && ctype != COND_STRNEQ) {
+	right = ecgetstr(state, 1);
 	singsub(&right);
 	untokenize(right);
     }
-
     if (tracingcond) {
-	if (c->type < COND_MOD) {
+	if (ctype < COND_MOD) {
 	    char *rt = (char *) right;
-	    if (c->type == COND_STREQ || c->type == COND_STRNEQ) {
-		rt = dupstring(c->right);
+	    if (ctype == COND_STREQ || ctype == COND_STRNEQ) {
+		rt = dupstring(ecrawstr(state->prog, state->pc));
 		singsub(&rt);
 		untokenize(rt);
 	    }
-	    fprintf(stderr, " %s %s %s", (char *)left, condstr[c->type],
-		    rt);
+	    fprintf(stderr, " %s %s %s", left, condstr[ctype], rt);
 	} else
-	    fprintf(stderr, " -%c %s", c->type, (char *)left);
+	    fprintf(stderr, " -%c %s", ctype, left);
     }
 
-    if (c->type >= COND_EQ && c->type <= COND_GE) {
+    if (ctype >= COND_EQ && ctype <= COND_GE) {
 	mnumber mn1, mn2;
 	mn1 = matheval(left);
 	mn2 = matheval(right);
@@ -144,7 +157,7 @@ evalcond(Cond c)
 		mn2.u.d = (double)mn2.u.l;
 	    }
 	}
-	switch(c->type) {
+	switch(ctype) {
 	case COND_EQ:
 	    return (mn1.type & MN_FLOAT) ? (mn1.u.d == mn2.u.d) :
 		(mn1.u.l == mn2.u.l);
@@ -166,30 +179,32 @@ evalcond(Cond c)
 	}
     }
 
-    switch (c->type) {
+    switch (ctype) {
     case COND_STREQ:
     case COND_STRNEQ:
 	{
-	    Patprog pprog = c->prog;
-	    int test;
+	    int test, npat = state->pc[1];
+	    Patprog pprog = state->prog->pats[npat];
 
 	    if (pprog == dummy_patprog1 || pprog == dummy_patprog2) {
 		char *opat;
 		int save;
 
-		right = opat = dupstring((char *) c->right);
+		right = opat = dupstring(ecrawstr(state->prog, state->pc));
 		singsub(&right);
-		save = (!strcmp(opat, right) && pprog != dummy_patprog2);
+		save = (!state->prog->heap &&
+			!strcmp(opat, right) && pprog != dummy_patprog2);
 
 		if (!(pprog = patcompile(right, (save ? PAT_ZDUP : PAT_STATIC),
 					 NULL)))
 		    zerr("bad pattern: %s", right, 0);
 		else if (save)
-		    c->prog = pprog;
-	    }		
+		    state->prog->pats[npat] = pprog;
+	    }
+	    state->pc += 2;
 	    test = (pprog && pattry(pprog, left));
 
-	    return (c->type == COND_STREQ ? test : !test);
+	    return (ctype == COND_STREQ ? test : !test);
 	}
     case COND_STRLT:
 	return strcmp(left, right) < 0;
@@ -255,7 +270,7 @@ evalcond(Cond c)
 	    a = st->st_mtime;
 	    if (!(st = getstat(right)))
 		return 0;
-	    return (c->type == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
+	    return (ctype == COND_NT) ? a > st->st_mtime : a < st->st_mtime;
 	}
     case COND_EF:
 	{
@@ -271,7 +286,7 @@ evalcond(Cond c)
 	    return d == st->st_dev && i == st->st_ino;
 	}
     default:
-	zerr("bad cond structure", NULL, 0);
+	zerr("bad cond code", NULL, 0);
     }
     return 0;
 }
@@ -390,7 +405,7 @@ tracemodcond(char *name, char **args, int inf)
 {
     char **aptr;
     MUSTUSEHEAP("tracemodcond");
-    args = duparray(args, (VFunc) dupstring);
+    args = arrdup(args);
     for (aptr = args; *aptr; aptr++)
 	untokenize(*aptr);
     if (inf) {