about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/loop.c67
-rw-r--r--Src/parse.c31
-rw-r--r--Src/text.c2
3 files changed, 65 insertions, 35 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));
diff --git a/Src/parse.c b/Src/parse.c
index b611e8e0c..fd7138605 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -878,7 +878,7 @@ static void
 par_for(int *complex)
 {
     int oecused = ecused, csh = (tok == FOREACH), p, sel = (tok == SELECT);
-    int type;
+    int type, ona = noaliases;
 
     p = ecadd(0);
 
@@ -903,19 +903,32 @@ par_for(int *complex)
 	yylex();
 	type = WC_FOR_COND;
     } else {
-	int posix_in;
+	int np, n, posix_in;
 	infor = 0;
 	if (tok != STRING || !isident(tokstr))
 	    YYERRORV(oecused);
-	ecstr(tokstr);
+	np = ecadd(0);
+	n = 0;
 	incmdpos = 1;
-	yylex();
+	noaliases = 1;
+	for (;;) {
+	    n++;
+	    ecstr(tokstr);
+	    yylex();	
+	    if (tok != STRING || !strcmp(tokstr, "in") || sel)
+		break;
+	    if (!isident(tokstr))
+	    {
+		noaliases = ona;
+		YYERRORV(oecused);
+	    }
+	}
+	noaliases = ona;
+	ecbuf[np] = n;
 	posix_in = isnewlin;
 	while (isnewlin)
-	  yylex();
-	if (tok == STRING && !strcmp(tokstr, "in")) {
-	    int np, n;
-
+	    yylex();
+        if (tok == STRING && !strcmp(tokstr, "in")) {
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
@@ -925,8 +938,6 @@ par_for(int *complex)
 	    ecbuf[np] = n;
 	    type = (sel ? WC_SELECT_LIST : WC_FOR_LIST);
 	} else if (!posix_in && tok == INPAR) {
-	    int np, n;
-
 	    incmdpos = 0;
 	    yylex();
 	    np = ecadd(0);
diff --git a/Src/text.c b/Src/text.c
index 27d16d378..7595c9add 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -415,7 +415,7 @@ gettext2(Estate state)
 		    taddstr(ecgetstr(state, EC_NODUP, NULL));
 		    taddstr(")) do");
 		} else {
-		    taddstr(ecgetstr(state, EC_NODUP, NULL));
+		    taddlist(state, *state->pc++);
 		    if (WC_FOR_TYPE(code) == WC_FOR_LIST) {
 			taddstr(" in ");
 			taddlist(state, *state->pc++);