summaryrefslogtreecommitdiff
path: root/Src
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2001-06-25 16:07:51 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2001-06-25 16:07:51 +0000
commit1897a361bf68faf47c5d5d0fa662127cbf5c2c95 (patch)
tree4462548ebeb9b13aba825601baa8386a0e4abf94 /Src
parentbbd2a98f4171a474cec10f58ff80df197fae6491 (diff)
downloadzsh-1897a361bf68faf47c5d5d0fa662127cbf5c2c95.tar.gz
zsh-1897a361bf68faf47c5d5d0fa662127cbf5c2c95.zip
15030: multi-parameter `for' loops
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++);