diff options
Diffstat (limited to 'Src/loop.c')
-rw-r--r-- | Src/loop.c | 88 |
1 files changed, 51 insertions, 37 deletions
diff --git a/Src/loop.c b/Src/loop.c index d025fbb9f..e4e8e2df8 100644 --- a/Src/loop.c +++ b/Src/loop.c @@ -545,7 +545,7 @@ execcase(Estate state, int do_exec) Wordcode end, next; wordcode code = state->pc[-1]; char *word, *pat; - int npat, save; + int npat, save, nalts, ialt, patok; Patprog *spprog, pprog; end = state->pc + WC_CASE_SKIP(code); @@ -561,60 +561,74 @@ execcase(Estate state, int do_exec) if (wc_code(code) != WC_CASE) break; - pat = NULL; - pprog = NULL; save = 0; - npat = state->pc[1]; - spprog = state->prog->pats + npat; - next = state->pc + WC_CASE_SKIP(code); + nalts = *state->pc++; + ialt = patok = 0; if (isset(XTRACE)) { - char *opat; - - pat = dupstring(opat = ecrawstr(state->prog, state->pc, NULL)); - singsub(&pat); - save = (!(state->prog->flags & EF_HEAP) && - !strcmp(pat, opat) && *spprog != dummy_patprog2); - printprompt4(); fprintf(xtrerr, "case %s (", word); - quote_tokenized_output(pat, xtrerr); - fprintf(xtrerr, ")\n"); - fflush(xtrerr); } - state->pc += 2; - if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2) - pprog = *spprog; - - if (!pprog) { - if (!pat) { - char *opat; + while (!patok && nalts) { + npat = state->pc[1]; + spprog = state->prog->pats + npat; + pprog = NULL; + pat = NULL; + + if (isset(XTRACE)) { int htok = 0; - - pat = dupstring(opat = ecrawstr(state->prog, - state->pc - 2, &htok)); + pat = dupstring(ecrawstr(state->prog, state->pc, &htok)); if (htok) singsub(&pat); - save = (!(state->prog->flags & EF_HEAP) && - !strcmp(pat, opat) && *spprog != dummy_patprog2); + + if (ialt++) + fprintf(stderr, " | "); + quote_tokenized_output(pat, xtrerr); } - if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC), - NULL))) - zerr("bad pattern: %s", pat); - else if (save) - *spprog = pprog; + + if (*spprog != dummy_patprog1 && *spprog != dummy_patprog2) + pprog = *spprog; + + if (!pprog) { + if (!pat) { + char *opat; + int htok = 0; + + pat = dupstring(opat = ecrawstr(state->prog, + state->pc, &htok)); + if (htok) + singsub(&pat); + save = (!(state->prog->flags & EF_HEAP) && + !strcmp(pat, opat) && *spprog != dummy_patprog2); + } + if (!(pprog = patcompile(pat, (save ? PAT_ZDUP : PAT_STATIC), + NULL))) + zerr("bad pattern: %s", pat); + else if (save) + *spprog = pprog; + } + if (pprog && pattry(pprog, word)) + patok = 1; + state->pc += 2; + nalts--; + } + state->pc += 2 * nalts; + if (isset(XTRACE)) { + fprintf(xtrerr, ")\n"); + fflush(xtrerr); } - if (pprog && pattry(pprog, word)) { + if (patok) { execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) && do_exec)); while (!retflag && wc_code(code) == WC_CASE && WC_CASE_TYPE(code) == WC_CASE_AND) { state->pc = next; - code = *state->pc; - state->pc += 3; - next = state->pc + WC_CASE_SKIP(code) - 2; + code = *state->pc++; + next = state->pc + WC_CASE_SKIP(code); + nalts = *state->pc++; + state->pc += 2 * nalts; execlist(state, 1, ((WC_CASE_TYPE(code) == WC_CASE_OR) && do_exec)); } |