aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-14 08:26:47 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-14 08:26:47 +0000
commit757361f9f58e120ddb9855fa0f50e12b921c37f0 (patch)
treef3f7bbe64e3e0dcf394205b7c5c8fa6046c38d1e
parent395ae452165a607c6b5bc4623225516044619616 (diff)
downloadbusybox-w32-757361f9f58e120ddb9855fa0f50e12b921c37f0.tar.gz
busybox-w32-757361f9f58e120ddb9855fa0f50e12b921c37f0.tar.bz2
busybox-w32-757361f9f58e120ddb9855fa0f50e12b921c37f0.zip
hush: fix "... pattern) cmd;; esac" case
-rw-r--r--shell/hush.c6
-rw-r--r--shell/hush_doc.txt24
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)
2986 } 2986 }
2987#if HAS_KEYWORDS 2987#if HAS_KEYWORDS
2988#if ENABLE_HUSH_CASE 2988#if ENABLE_HUSH_CASE
2989 if (ctx->ctx_dsemicolon) { 2989 if (ctx->ctx_dsemicolon
2990 && strcmp(word->data, "esac") != 0 /* not "... pattern) cmd;; esac" */
2991 ) {
2990 /* already done when ctx_dsemicolon was set to 1: */ 2992 /* already done when ctx_dsemicolon was set to 1: */
2991 /* ctx->ctx_res_w = RES_MATCH; */ 2993 /* ctx->ctx_res_w = RES_MATCH; */
2992 ctx->ctx_dsemicolon = 0; 2994 ctx->ctx_dsemicolon = 0;
@@ -3112,7 +3114,7 @@ static void done_pipe(struct p_context *ctx, pipe_style type)
3112 if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) { 3114 if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) {
3113 struct pipe *new_p; 3115 struct pipe *new_p;
3114 debug_printf_parse("done_pipe: adding new pipe: " 3116 debug_printf_parse("done_pipe: adding new pipe: "
3115 " not_null:%d ctx->ctx_res_w:%d\n", 3117 "not_null:%d ctx->ctx_res_w:%d\n",
3116 not_null, ctx->ctx_res_w); 3118 not_null, ctx->ctx_res_w);
3117 new_p = new_pipe(); 3119 new_p = new_pipe();
3118 ctx->pipe->next = new_p; 3120 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
72parsing algorithm - done_pipe() appends new pipe struct beforehand 72parsing algorithm - done_pipe() appends new pipe struct beforehand
73and last one ends up empty and unused. 73and last one ends up empty and unused.
74 74
75"for" and "case" statements (ab)use progs[] to keep their data
76instead of argv vector progs[] usually do. "for" keyword is forcing
77pipe termination after first word, which makes hush see
78"for v in..." as "for v; in...". "case" keyword does the same.
79Other judiciuosly placed hacks make hush see
80"case word in a) cmd1;; b) cmd2;; esac" as if it was
81"case word; match a; cmd; match b; cmd2; esac"
82("match" is a fictitious keyword here):
83
84"case word in a) cmd1;; b) cmd2; esac" -
85pipe 0 res_word=NONE followup=1 SEQ
86 prog 0 group {}:
87 pipe 0 res_word=CASE followup=SEQ prog[0] 'word'
88 pipe 1 res_word=MATCH followup=SEQ prog[0] 'a'
89 pipe 2 res_word=CASEI followup=SEQ prog[0] 'cmd1'
90 pipe 3 res_word=MATCH followup=SEQ prog[0] 'b'
91 pipe 4 res_word=CASEI followup=SEQ prog[0] 'cmd2'
92 pipe 5 res_word=CASEI followup=SEQ prog[0] 'cmd3'
93 pipe 6 res_word=ESAC followup=SEQ
94 pipe 7 res_word=NONE followup=(null)
95pipe 1 res_word=NONE followup=1 SEQ
96
75 97
762008-01 982008-01
77 99
78 This is how hush runs commands: 100 Command execution
79 101
80/* callsite: process_command_subs */ 102/* callsite: process_command_subs */
81generate_stream_from_list(struct pipe *head) - handles `cmds` 103generate_stream_from_list(struct pipe *head) - handles `cmds`