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.c67
1 files changed, 43 insertions, 24 deletions
diff --git a/Src/loop.c b/Src/loop.c
index 84ac39e9a..38eeda7d6 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -52,15 +52,15 @@ execfor(Estate state, int do_exec)
     Wordcode end, loop;
     wordcode code = state->pc[-1];
     int iscond = (WC_FOR_TYPE(code) == WC_FOR_COND), ctok = 0, atok = 0;
+    int last = 0;
     char *name, *str, *cond = NULL, *advance = NULL;
     zlong val = 0;
-    LinkList args = NULL;
+    LinkList vars = NULL, args = NULL;
 
-    name = ecgetstr(state, EC_NODUP, NULL);
     end = state->pc + WC_FOR_SKIP(code);
 
     if (iscond) {
-	str = dupstring(name);
+	str = dupstring(ecgetstr(state, EC_NODUP, NULL));
 	singsub(&str);
 	if (isset(XTRACE)) {
 	    char *str2 = dupstring(str);
@@ -77,28 +77,32 @@ execfor(Estate state, int do_exec)
 	}
 	cond = ecgetstr(state, EC_NODUP, &ctok);
 	advance = ecgetstr(state, EC_NODUP, &atok);
-    } else if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
-	int htok = 0;
-
-	if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
-	    state->pc = end;
-	    return 0;
-	}
-	if (htok)
-	    execsubst(args);
     } else {
-	char **x;
+	vars = ecgetlist(state, *state->pc++, EC_NODUP, NULL);
 
-	args = newlinklist();
-	for (x = pparams; *x; x++)
-	    addlinknode(args, dupstring(*x));
+	if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
+	    int htok = 0;
+
+	    if (!(args = ecgetlist(state, *state->pc++, EC_DUPTOK, &htok))) {
+		state->pc = end;
+		return 0;
+	    }
+	    if (htok)
+		execsubst(args);
+	} else {
+	    char **x;
+
+	    args = newlinklist();
+	    for (x = pparams; *x; x++)
+		addlinknode(args, dupstring(*x));
+	}
     }
     lastval = 0;
     loops++;
     pushheap();
     cmdpush(CS_FOR);
     loop = state->pc;
-    for (;;) {
+    while (!last) {
 	if (iscond) {
 	    if (ctok) {
 		str = dupstring(cond);
@@ -127,14 +131,29 @@ execfor(Estate state, int do_exec)
 	    if (!val)
 		break;
 	} else {
-	    if (!args || !(str = (char *) ugetnode(args)))
-		break;
-	    if (isset(XTRACE)) {
-		printprompt4();
-		fprintf(xtrerr, "%s=%s\n", name, str);
-		fflush(xtrerr);
+	    LinkNode node;
+	    int count = 0;
+	    for (node = firstnode(vars); node; incnode(node))
+	    {
+		name = (char *)getdata(node);
+		if (!args || !(str = (char *) ugetnode(args)))
+		{
+		    if (count) { 
+			str = "";
+			last = 1;
+		    } else
+			break;
+		}
+		if (isset(XTRACE)) {
+		    printprompt4();
+		    fprintf(xtrerr, "%s=%s\n", name, str);
+		    fflush(xtrerr);
+		}
+		setsparam(name, ztrdup(str));
+		count++;
 	    }
-	    setsparam(name, ztrdup(str));
+	    if (!count)
+		break;
 	}
 	state->pc = loop;
 	execlist(state, 1, do_exec && args && empty(args));