hush: fix "... pattern) cmd;; esac" case
No binary (build failed)
—
(log yok)
| @@ -2986,7 +2986,9 @@ static int done_word(o_string *word, struct p_context *ctx) | |
| } | |
| #if HAS_KEYWORDS | |
| #if ENABLE_HUSH_CASE | |
| - | if (ctx->ctx_dsemicolon) { |
| + | if (ctx->ctx_dsemicolon |
| + | && strcmp(word->data, "esac") != 0 /* not "... pattern) cmd;; esac" */ |
| + | ) { |
| /* already done when ctx_dsemicolon was set to 1: */ | |
| /* ctx->ctx_res_w = RES_MATCH; */ | |
| ctx->ctx_dsemicolon = 0; | |
| @@ -3112,7 +3114,7 @@ static void done_pipe(struct p_context *ctx, pipe_style type) | |
| if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) { | |
| struct pipe *new_p; | |
| debug_printf_parse("done_pipe: adding new pipe: " | |
| - | " not_null:%d ctx->ctx_res_w:%d\n", |
| + | "not_null:%d ctx->ctx_res_w:%d\n", |
| not_null, ctx->ctx_res_w); | |
| new_p = new_pipe(); | |
| ctx->pipe->next = new_p; | |
| @@ -72,10 +72,32 @@ Dummy trailing pipes with no commands are artifacts of imperfect | |
| parsing algorithm - done_pipe() appends new pipe struct beforehand | |
| and last one ends up empty and unused. | |
| + | "for" and "case" statements (ab)use progs[] to keep their data |
| + | instead of argv vector progs[] usually do. "for" keyword is forcing |
| + | pipe termination after first word, which makes hush see |
| + | "for v in..." as "for v; in...". "case" keyword does the same. |
| + | Other judiciuosly placed hacks make hush see |
| + | "case word in a) cmd1;; b) cmd2;; esac" as if it was |
| + | "case word; match a; cmd; match b; cmd2; esac" |
| + | ("match" is a fictitious keyword here): |
| + | |
| + | "case word in a) cmd1;; b) cmd2; esac" - |
| + | pipe 0 res_word=NONE followup=1 SEQ |
| + | prog 0 group {}: |
| + | pipe 0 res_word=CASE followup=SEQ prog[0] 'word' |
| + | pipe 1 res_word=MATCH followup=SEQ prog[0] 'a' |
| + | pipe 2 res_word=CASEI followup=SEQ prog[0] 'cmd1' |
| + | pipe 3 res_word=MATCH followup=SEQ prog[0] 'b' |
| + | pipe 4 res_word=CASEI followup=SEQ prog[0] 'cmd2' |
| + | pipe 5 res_word=CASEI followup=SEQ prog[0] 'cmd3' |
| + | pipe 6 res_word=ESAC followup=SEQ |
| + | pipe 7 res_word=NONE followup=(null) |
| + | pipe 1 res_word=NONE followup=1 SEQ |
| + | |
| 2008-01 | |
| - | This is how hush runs commands: |
| + | Command execution |
| /* callsite: process_command_subs */ | |
| generate_stream_from_list(struct pipe *head) - handles `cmds` | |