diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-02 22:50:40 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-02 22:50:40 +0000 |
commit | 027e3fddb580bf3b397f2392b7e6aeab69adac79 (patch) | |
tree | f84e1c28b015a77794d1fe00acec056ad725ce1e | |
parent | a36258f288e8242e44feabce485c836885dda46e (diff) | |
download | busybox-w32-027e3fddb580bf3b397f2392b7e6aeab69adac79.tar.gz busybox-w32-027e3fddb580bf3b397f2392b7e6aeab69adac79.tar.bz2 busybox-w32-027e3fddb580bf3b397f2392b7e6aeab69adac79.zip |
hush: straighten parse_stream() API a bit
function old new delta
parse_stream 1240 1238 -2
expand_variables 2272 2242 -30
parse_and_run_stream 338 292 -46
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-78) Total: -78 bytes
-rw-r--r-- | shell/hush.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/shell/hush.c b/shell/hush.c index f0d372625..eeec13b3d 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -3765,14 +3765,10 @@ static int process_command_subs(o_string *dest, | |||
3765 | FILE *p; | 3765 | FILE *p; |
3766 | struct in_str pipe_str; | 3766 | struct in_str pipe_str; |
3767 | 3767 | ||
3768 | initialize_context(&inner); | ||
3769 | |||
3770 | /* Recursion to generate command */ | 3768 | /* Recursion to generate command */ |
3771 | retcode = parse_stream(&result, &inner, input, subst_end); | 3769 | retcode = parse_stream(&result, &inner, input, subst_end); |
3772 | if (retcode != 0) | 3770 | if (retcode != 0) |
3773 | return retcode; /* syntax error or EOF */ | 3771 | return retcode; /* syntax error or EOF */ |
3774 | done_word(&result, &inner); | ||
3775 | done_pipe(&inner, PIPE_SEQ); | ||
3776 | o_free(&result); | 3772 | o_free(&result); |
3777 | 3773 | ||
3778 | p = generate_stream_from_list(inner.list_head); | 3774 | p = generate_stream_from_list(inner.list_head); |
@@ -3812,10 +3808,10 @@ static int parse_group(o_string *dest, struct parse_context *ctx, | |||
3812 | struct in_str *input, int ch) | 3808 | struct in_str *input, int ch) |
3813 | { | 3809 | { |
3814 | /* dest contains characters seen prior to ( or {. | 3810 | /* dest contains characters seen prior to ( or {. |
3815 | * Typically it's empty, but for functions defs, | 3811 | * Typically it's empty, but for function defs, |
3816 | * it contains function name (without '()'). */ | 3812 | * it contains function name (without '()'). */ |
3817 | int rcode; | 3813 | int rcode; |
3818 | const char *endch = NULL; | 3814 | const char *endch; |
3819 | struct parse_context sub; | 3815 | struct parse_context sub; |
3820 | struct command *command = ctx->command; | 3816 | struct command *command = ctx->command; |
3821 | 3817 | ||
@@ -3837,7 +3833,6 @@ static int parse_group(o_string *dest, struct parse_context *ctx, | |||
3837 | debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); | 3833 | debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n"); |
3838 | return 1; | 3834 | return 1; |
3839 | } | 3835 | } |
3840 | initialize_context(&sub); | ||
3841 | endch = "}"; | 3836 | endch = "}"; |
3842 | if (ch == '(') { | 3837 | if (ch == '(') { |
3843 | endch = ")"; | 3838 | endch = ")"; |
@@ -3845,8 +3840,6 @@ static int parse_group(o_string *dest, struct parse_context *ctx, | |||
3845 | } | 3840 | } |
3846 | rcode = parse_stream(dest, &sub, input, endch); | 3841 | rcode = parse_stream(dest, &sub, input, endch); |
3847 | if (rcode == 0) { | 3842 | if (rcode == 0) { |
3848 | done_word(dest, &sub); /* finish off the final word in the subcontext */ | ||
3849 | done_pipe(&sub, PIPE_SEQ); /* and the final command there, too */ | ||
3850 | command->group = sub.list_head; | 3843 | command->group = sub.list_head; |
3851 | } | 3844 | } |
3852 | debug_printf_parse("parse_group return %d\n", rcode); | 3845 | debug_printf_parse("parse_group return %d\n", rcode); |
@@ -4211,11 +4204,14 @@ static int parse_stream_dquoted(o_string *dest, struct in_str *input, int dquote | |||
4211 | goto again; | 4204 | goto again; |
4212 | } | 4205 | } |
4213 | 4206 | ||
4214 | /* Scan input, call done_word() whenever full IFS delimited word was seen. | 4207 | /* Initalize ctx (i.e. caller does not need to do that). |
4208 | * Scan input, call done_word() whenever full IFS delimited word was seen. | ||
4215 | * Call done_pipe if '\n' was seen (and end_trigger != NULL). | 4209 | * Call done_pipe if '\n' was seen (and end_trigger != NULL). |
4216 | * Return code is 0 if end_trigger char is met, | 4210 | * Return code is 0 if end_trigger char is met, |
4217 | * -1 on EOF (but if end_trigger == NULL then return 0), | 4211 | * -1 on EOF (but if end_trigger == NULL then return 0), |
4218 | * 1 for syntax error */ | 4212 | * 1 for syntax error |
4213 | * Net result is a list of pipes in ctx->list_head. | ||
4214 | */ | ||
4219 | static int parse_stream(o_string *dest, struct parse_context *ctx, | 4215 | static int parse_stream(o_string *dest, struct parse_context *ctx, |
4220 | struct in_str *input, const char *end_trigger) | 4216 | struct in_str *input, const char *end_trigger) |
4221 | { | 4217 | { |
@@ -4230,6 +4226,7 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4230 | * found. When recursing, quote state is passed in via dest->o_escape. */ | 4226 | * found. When recursing, quote state is passed in via dest->o_escape. */ |
4231 | 4227 | ||
4232 | debug_printf_parse("parse_stream entered, end_trigger='%s' dest->o_assignment:%d\n", end_trigger, dest->o_assignment); | 4228 | debug_printf_parse("parse_stream entered, end_trigger='%s' dest->o_assignment:%d\n", end_trigger, dest->o_assignment); |
4229 | initialize_context(ctx); | ||
4233 | 4230 | ||
4234 | is_in_dquote = dest->o_escape; | 4231 | is_in_dquote = dest->o_escape; |
4235 | while (1) { | 4232 | while (1) { |
@@ -4269,7 +4266,7 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4269 | return 1; | 4266 | return 1; |
4270 | } | 4267 | } |
4271 | if (ch == EOF) | 4268 | if (ch == EOF) |
4272 | break; | 4269 | goto ret_EOF; |
4273 | /* If we aren't performing a substitution, treat | 4270 | /* If we aren't performing a substitution, treat |
4274 | * a newline as a command separator. | 4271 | * a newline as a command separator. |
4275 | * [why don't we handle it exactly like ';'? --vda] */ | 4272 | * [why don't we handle it exactly like ';'? --vda] */ |
@@ -4297,11 +4294,14 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4297 | done_pipe(ctx, PIPE_SEQ); | 4294 | done_pipe(ctx, PIPE_SEQ); |
4298 | dest->o_assignment = MAYBE_ASSIGNMENT; | 4295 | dest->o_assignment = MAYBE_ASSIGNMENT; |
4299 | } | 4296 | } |
4297 | /* What do we check here? */ | ||
4300 | if (!HAS_KEYWORDS | 4298 | if (!HAS_KEYWORDS |
4301 | IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0)) | 4299 | IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0)) |
4302 | ) { | 4300 | ) { |
4303 | debug_printf_parse("parse_stream return 0: end_trigger char found\n"); | 4301 | debug_printf_parse("parse_stream return 0: end_trigger char found\n"); |
4304 | return 0; | 4302 | /* this makes us return 0, not -1 */ |
4303 | end_trigger = NULL; | ||
4304 | goto ret; | ||
4305 | } | 4305 | } |
4306 | } | 4306 | } |
4307 | } | 4307 | } |
@@ -4522,9 +4522,16 @@ static int parse_stream(o_string *dest, struct parse_context *ctx, | |||
4522 | bb_error_msg_and_die("BUG: unexpected %c\n", ch); | 4522 | bb_error_msg_and_die("BUG: unexpected %c\n", ch); |
4523 | } | 4523 | } |
4524 | } /* while (1) */ | 4524 | } /* while (1) */ |
4525 | |||
4526 | /* Non-error returns */ | ||
4527 | ret_EOF: | ||
4525 | debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL)); | 4528 | debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL)); |
4526 | if (end_trigger) | 4529 | ret: |
4527 | return -1; | 4530 | done_word(dest, ctx); |
4531 | done_pipe(ctx, PIPE_SEQ); | ||
4532 | if (end_trigger) { | ||
4533 | return -1; /* EOF found while expecting end_trigger */ | ||
4534 | } | ||
4528 | return 0; | 4535 | return 0; |
4529 | } | 4536 | } |
4530 | 4537 | ||
@@ -4564,7 +4571,6 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag) | |||
4564 | int rcode; | 4571 | int rcode; |
4565 | 4572 | ||
4566 | do { | 4573 | do { |
4567 | initialize_context(&ctx); | ||
4568 | update_charmap(); | 4574 | update_charmap(); |
4569 | #if ENABLE_HUSH_INTERACTIVE | 4575 | #if ENABLE_HUSH_INTERACTIVE |
4570 | inp->promptmode = 0; /* PS1 */ | 4576 | inp->promptmode = 0; /* PS1 */ |
@@ -4574,16 +4580,15 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag) | |||
4574 | * TEST should be printed */ | 4580 | * TEST should be printed */ |
4575 | temp.o_assignment = MAYBE_ASSIGNMENT; | 4581 | temp.o_assignment = MAYBE_ASSIGNMENT; |
4576 | rcode = parse_stream(&temp, &ctx, inp, ";\n"); | 4582 | rcode = parse_stream(&temp, &ctx, inp, ";\n"); |
4583 | debug_printf_parse("rcode %d ctx.old_flag %x\n", rcode, ctx.old_flag); | ||
4577 | #if HAS_KEYWORDS | 4584 | #if HAS_KEYWORDS |
4578 | if (rcode != 1 && ctx.old_flag != 0) { | 4585 | if (rcode != 1 && ctx.old_flag != 0) { |
4579 | syntax(NULL); | 4586 | syntax(NULL); |
4580 | } | 4587 | } |
4581 | #endif | 4588 | #endif |
4582 | if (rcode != 1 IF_HAS_KEYWORDS(&& ctx.old_flag == 0)) { | 4589 | if (rcode != 1 IF_HAS_KEYWORDS(&& ctx.old_flag == 0)) { |
4583 | done_word(&temp, &ctx); | ||
4584 | done_pipe(&ctx, PIPE_SEQ); | ||
4585 | debug_print_tree(ctx.list_head, 0); | 4590 | debug_print_tree(ctx.list_head, 0); |
4586 | debug_printf_exec("parse_stream_outer: run_and_free_list\n"); | 4591 | debug_printf_exec("parse_and_run_stream: run_and_free_list\n"); |
4587 | run_and_free_list(ctx.list_head); | 4592 | run_and_free_list(ctx.list_head); |
4588 | } else { | 4593 | } else { |
4589 | /* We arrive here also if rcode == 1 (error in parse_stream) */ | 4594 | /* We arrive here also if rcode == 1 (error in parse_stream) */ |