From 757361f9f58e120ddb9855fa0f50e12b921c37f0 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 14 Jul 2008 08:26:47 +0000 Subject: [PATCH] hush: fix "... pattern) cmd;; esac" case --- shell/hush.c | 6 ++++-- shell/hush_doc.txt | 24 +++++++++++++++++++++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index db608018c..47cdf6f02 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -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; diff --git a/shell/hush_doc.txt b/shell/hush_doc.txt index ec5dd00f2..b2fd24426 100644 --- a/shell/hush_doc.txt +++ b/shell/hush_doc.txt @@ -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`