diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/loop.c | 67 | ||||
-rw-r--r-- | Src/parse.c | 31 | ||||
-rw-r--r-- | Src/text.c | 2 |
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++); |