aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2009-04-02 22:50:40 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2009-04-02 22:50:40 +0000
commit027e3fddb580bf3b397f2392b7e6aeab69adac79 (patch)
treef84e1c28b015a77794d1fe00acec056ad725ce1e
parenta36258f288e8242e44feabce485c836885dda46e (diff)
downloadbusybox-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.c43
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 */
4219static int parse_stream(o_string *dest, struct parse_context *ctx, 4215static 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) */