aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-03 03:45:05 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-03 03:45:05 +0000
commit240c255d8b349f06c94cb3afc24c85b6c38b6608 (patch)
tree269ee41ce9cbd353764531d0086cd0925d8fbf9d /shell
parent3718168b87a5bf5009b90b1e1253bec2c7ce9edf (diff)
downloadbusybox-w32-240c255d8b349f06c94cb3afc24c85b6c38b6608.tar.gz
busybox-w32-240c255d8b349f06c94cb3afc24c85b6c38b6608.tar.bz2
busybox-w32-240c255d8b349f06c94cb3afc24c85b6c38b6608.zip
hush: simplify parse_stream
function old new delta parse_and_run_stream 292 289 -3 parse_stream 1218 1204 -14 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-17) Total: -17 bytes
Diffstat (limited to 'shell')
-rw-r--r--shell/hush.c48
1 files changed, 23 insertions, 25 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e2259ce38..aa05e3a83 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -3717,7 +3717,7 @@ static int redirect_opt_num(o_string *o)
3717} 3717}
3718 3718
3719static int parse_stream(o_string *dest, struct parse_context *ctx, 3719static int parse_stream(o_string *dest, struct parse_context *ctx,
3720 struct in_str *input0, const char *end_trigger); 3720 struct in_str *input0, int end_trigger);
3721 3721
3722#if ENABLE_HUSH_TICK 3722#if ENABLE_HUSH_TICK
3723static FILE *generate_stream_from_list(struct pipe *head) 3723static FILE *generate_stream_from_list(struct pipe *head)
@@ -3773,7 +3773,7 @@ static int process_command_subs(o_string *dest,
3773 struct in_str pipe_str; 3773 struct in_str pipe_str;
3774 3774
3775 /* Recursion to generate command */ 3775 /* Recursion to generate command */
3776 retcode = parse_stream(&result, &inner, input, NULL); 3776 retcode = parse_stream(&result, &inner, input, '\0');
3777 if (retcode != 0) 3777 if (retcode != 0)
3778 return retcode; /* syntax error or EOF */ 3778 return retcode; /* syntax error or EOF */
3779 o_free(&result); 3779 o_free(&result);
@@ -3818,7 +3818,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
3818 * Typically it's empty, but for function defs, 3818 * Typically it's empty, but for function defs,
3819 * it contains function name (without '()'). */ 3819 * it contains function name (without '()'). */
3820 int rcode; 3820 int rcode;
3821 const char *endch; 3821 int endch;
3822 struct parse_context sub; 3822 struct parse_context sub;
3823 struct command *command = ctx->command; 3823 struct command *command = ctx->command;
3824 3824
@@ -3840,9 +3840,9 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
3840 debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); 3840 debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n");
3841 return 1; 3841 return 1;
3842 } 3842 }
3843 endch = "}"; 3843 endch = '}';
3844 if (ch == '(') { 3844 if (ch == '(') {
3845 endch = ")"; 3845 endch = ')';
3846 command->grp_type = GRP_SUBSHELL; 3846 command->grp_type = GRP_SUBSHELL;
3847 } 3847 }
3848 rcode = parse_stream(dest, &sub, input, endch); 3848 rcode = parse_stream(dest, &sub, input, endch);
@@ -4220,7 +4220,7 @@ static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote
4220 * Net result is a list of pipes in ctx->list_head. 4220 * Net result is a list of pipes in ctx->list_head.
4221 */ 4221 */
4222static int parse_stream(o_string *dest, struct parse_context *ctx, 4222static int parse_stream(o_string *dest, struct parse_context *ctx,
4223 struct in_str *input, const char *end_trigger) 4223 struct in_str *input, int end_trigger)
4224{ 4224{
4225 int ch, m; 4225 int ch, m;
4226 int redir_fd; 4226 int redir_fd;
@@ -4232,8 +4232,9 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
4232 * A single-quote triggers a bypass of the main loop until its mate is 4232 * A single-quote triggers a bypass of the main loop until its mate is
4233 * found. When recursing, quote state is passed in via dest->o_escape. */ 4233 * found. When recursing, quote state is passed in via dest->o_escape. */
4234 4234
4235 debug_printf_parse("parse_stream entered, end_trigger='%s' " 4235 debug_printf_parse("parse_stream entered, end_trigger='%c' "
4236 "dest->o_assignment:%d\n", end_trigger, dest->o_assignment); 4236 "dest->o_assignment:%d\n", end_trigger ? : 'X'
4237 , dest->o_assignment);
4237 4238
4238 dest->o_assignment = MAYBE_ASSIGNMENT; 4239 dest->o_assignment = MAYBE_ASSIGNMENT;
4239 initialize_context(ctx); 4240 initialize_context(ctx);
@@ -4267,7 +4268,9 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
4267 } 4268 }
4268 continue; 4269 continue;
4269 } 4270 }
4271
4270 /* m is SPECIAL ($,`), IFS, or ORDINARY_IF_QUOTED (*,#) */ 4272 /* m is SPECIAL ($,`), IFS, or ORDINARY_IF_QUOTED (*,#) */
4273
4271 if (m == CHAR_IFS) { 4274 if (m == CHAR_IFS) {
4272 if (ch == EOF) 4275 if (ch == EOF)
4273 goto ret_EOF; 4276 goto ret_EOF;
@@ -4285,29 +4288,25 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
4285 continue; 4288 continue;
4286 } 4289 }
4287#endif 4290#endif
4288 /* Treat newline as a command separator. 4291 /* Treat newline as a command separator. */
4289 * [why don't we handle it exactly like ';'? --vda] */
4290 done_pipe(ctx, PIPE_SEQ); 4292 done_pipe(ctx, PIPE_SEQ);
4291 dest->o_assignment = MAYBE_ASSIGNMENT; 4293 dest->o_assignment = MAYBE_ASSIGNMENT;
4294 ch = ';';
4295 /* note: if (m == CHAR_IFS) continue;
4296 * will still trigger for us */
4292 } 4297 }
4293 } 4298 }
4294 if (end_trigger && strchr(end_trigger, ch)) { 4299 if (end_trigger && end_trigger == ch) {
4295 /* Special case: (...word) makes last word terminate, 4300//TODO: disallow "{ cmd }" without semicolon
4296 * as if ';' is seen */ 4301 done_word(dest, ctx);
4297 if (ch == ')') { 4302 done_pipe(ctx, PIPE_SEQ);
4298 done_word(dest, ctx); 4303 dest->o_assignment = MAYBE_ASSIGNMENT;
4299//err chk? 4304 /* Do we sit outside of any if's, loops or case's? */
4300 done_pipe(ctx, PIPE_SEQ);
4301 dest->o_assignment = MAYBE_ASSIGNMENT;
4302 }
4303 /* What do we check here? */
4304 if (!HAS_KEYWORDS 4305 if (!HAS_KEYWORDS
4305 IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0)) 4306 IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0))
4306 ) { 4307 ) {
4307 debug_printf_parse("parse_stream return 0: end_trigger char found\n"); 4308 debug_printf_parse("parse_stream return 0: end_trigger char found\n");
4308 /* this makes us return 0, not -1 */ 4309 return 0;
4309 end_trigger = NULL;
4310 goto ret;
4311 } 4310 }
4312 } 4311 }
4313 if (m == CHAR_IFS) 4312 if (m == CHAR_IFS)
@@ -4531,7 +4530,6 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
4531 /* Non-error returns */ 4530 /* Non-error returns */
4532 ret_EOF: 4531 ret_EOF:
4533 debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL)); 4532 debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL));
4534 ret:
4535 done_word(dest, ctx); 4533 done_word(dest, ctx);
4536 done_pipe(ctx, PIPE_SEQ); 4534 done_pipe(ctx, PIPE_SEQ);
4537 if (end_trigger) { 4535 if (end_trigger) {
@@ -4584,7 +4582,7 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
4584 * Example: "sleep 9999; echo TEST" + ctrl-C: 4582 * Example: "sleep 9999; echo TEST" + ctrl-C:
4585 * TEST should be printed */ 4583 * TEST should be printed */
4586 temp.o_assignment = MAYBE_ASSIGNMENT; 4584 temp.o_assignment = MAYBE_ASSIGNMENT;
4587 rcode = parse_stream(&temp, &ctx, inp, ";\n"); 4585 rcode = parse_stream(&temp, &ctx, inp, ';');
4588 debug_printf_parse("rcode %d ctx.old_flag %x\n", rcode, ctx.old_flag); 4586 debug_printf_parse("rcode %d ctx.old_flag %x\n", rcode, ctx.old_flag);
4589#if HAS_KEYWORDS 4587#if HAS_KEYWORDS
4590 if (rcode != 1 && ctx.old_flag != 0) { 4588 if (rcode != 1 && ctx.old_flag != 0) {