about summary refs log tree commit diff
path: root/Src/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/loop.c')
-rw-r--r--Src/loop.c56
1 files changed, 36 insertions, 20 deletions
diff --git a/Src/loop.c b/Src/loop.c
index e645df862..829b36d64 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -51,12 +51,12 @@ execfor(Estate state, int do_exec)
 {
     Wordcode end, loop;
     wordcode code = state->pc[-1];
-    int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND);
+    int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
     char *name, *str, *cond = NULL, *advance = NULL;
     zlong val = 0;
     LinkList args = NULL;
 
-    name = ecgetstr(state, 0);
+    name = ecgetstr(state, EC_NODUP, NULL);
     end = state->pc + WC_FOR_SKIP(code);
 
     if (iscond) {
@@ -75,14 +75,17 @@ execfor(Estate state, int do_exec)
 	    state->pc = end;
 	    return lastval = errflag;
 	}
-	cond = ecgetstr(state, 0);
-	advance = ecgetstr(state, 0);
+	cond = ecgetstr(state, EC_NODUP, &ctok);
+	advance = ecgetstr(state, EC_NODUP, &atok);
     } else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
-	if (!(args = ecgetlist(state, *state->pc++, 1))) {
+	int htok = 0;
+
+	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
 	    state->pc = end;
 	    return 0;
 	}
-	execsubst(args);
+	if (htok)
+	    execsubst(args);
     } else {
 	char **x;
 
@@ -97,8 +100,11 @@ execfor(Estate state, int do_exec)
     loop = state->pc;
     for (;;) {
 	if (iscond) {
-	    str = dupstring(cond);
-	    singsub(&str);
+	    if (ctok) {
+		str = dupstring(cond);
+		singsub(&str);
+	    } else
+		str = cond;
 	    if (!errflag) {
 		while (iblank(*str))
 		    str++;
@@ -141,13 +147,16 @@ execfor(Estate state, int do_exec)
 	if (retflag)
 	    break;
 	if (iscond && !errflag) {
-	    str = dupstring(advance);
+	    if (atok) {
+		str = dupstring(advance);
+		singsub(&str);
+	    } else
+		str = advance;
 	    if (isset(XTRACE)) {
 		printprompt4();
 		fprintf(xtrerr, "%s\n", str);
 		fflush(xtrerr);
 	    }
-	    singsub(&str);
 	    if (!errflag)
 		matheval(str);
 	}
@@ -179,7 +188,7 @@ execselect(Estate state, int do_exec)
     LinkList args;
 
     end = state->pc + WC_FOR_SKIP(code);
-    name = ecgetstr(state, 0);
+    name = ecgetstr(state, EC_NODUP, NULL);
 
     if (WC_SELECT_TYPE(code) == WC_SELECT_PPARAM) {
 	char **x;
@@ -188,11 +197,14 @@ execselect(Estate state, int do_exec)
 	for (x = pparams; *x; x++)
 	    addlinknode(args, dupstring(*x));
     } else {
-	if (!(args = ecgetlist(state, *state->pc++, 1))) {
+	int htok = 0;
+
+	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
 	    state->pc = end;
 	    return 0;
 	}
-	execsubst(args);
+	if (htok)
+	    execsubst(args);
     }
     if (!args || empty(args)) {
 	state->pc = end;
@@ -391,14 +403,15 @@ execrepeat(Estate state, int do_exec)
 {
     Wordcode end, loop;
     wordcode code = state->pc[-1];
-    int count;
+    int count, htok = 0;
     char *tmp;
 
     end = state->pc + WC_REPEAT_SKIP(code);
 
     lastval = 0;
-    tmp = ecgetstr(state, 1);
-    singsub(&tmp);
+    tmp = ecgetstr(state, EC_DUPTOK, &htok);
+    if (htok)
+	singsub(&tmp);
     count = atoi(tmp);
     pushheap();
     cmdpush(CS_REPEAT);
@@ -487,7 +500,7 @@ execcase(Estate state, int do_exec)
 
     end = state->pc + WC_CASE_SKIP(code);
 
-    word = ecgetstr(state, 1);
+    word = ecgetstr(state, EC_DUP, NULL);
     singsub(&word);
     untokenize(word);
     lastval = 0;
@@ -509,7 +522,7 @@ execcase(Estate state, int do_exec)
 	if (isset(XTRACE)) {
 	    char *pat2, *opat;
 
-	    opat = pat = ecgetstr(state, 1);
+	    opat = pat = ecgetstr(state, EC_DUP, NULL);
 	    singsub(&pat);
 	    save = (!state->prog->heap &&
 		    !strcmp(pat, opat) && *spprog != dummy_patprog2);
@@ -529,9 +542,12 @@ execcase(Estate state, int do_exec)
 	if (!pprog) {
 	    if (!pat) {
 		char *opat;
+		int htok = 0;
 
-		opat = pat = dupstring(ecrawstr(state->prog, state->pc - 2));
-		singsub(&pat);
+		opat = pat = dupstring(ecrawstr(state->prog,
+						state->pc - 2, &htok));
+		if (htok)
+		    singsub(&pat);
 		save = (!state->prog->heap &&
 			!strcmp(pat, opat) && *spprog != dummy_patprog2);
 	    }