mirror of
https://github.com/sheumann/hush.git
synced 2025-01-18 07:31:34 +00:00
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
This commit is contained in:
parent
3718168b87
commit
240c255d8b
48
shell/hush.c
48
shell/hush.c
@ -3717,7 +3717,7 @@ static int redirect_opt_num(o_string *o)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int parse_stream(o_string *dest, struct parse_context *ctx,
|
static int parse_stream(o_string *dest, struct parse_context *ctx,
|
||||||
struct in_str *input0, const char *end_trigger);
|
struct in_str *input0, int end_trigger);
|
||||||
|
|
||||||
#if ENABLE_HUSH_TICK
|
#if ENABLE_HUSH_TICK
|
||||||
static FILE *generate_stream_from_list(struct pipe *head)
|
static FILE *generate_stream_from_list(struct pipe *head)
|
||||||
@ -3773,7 +3773,7 @@ static int process_command_subs(o_string *dest,
|
|||||||
struct in_str pipe_str;
|
struct in_str pipe_str;
|
||||||
|
|
||||||
/* Recursion to generate command */
|
/* Recursion to generate command */
|
||||||
retcode = parse_stream(&result, &inner, input, NULL);
|
retcode = parse_stream(&result, &inner, input, '\0');
|
||||||
if (retcode != 0)
|
if (retcode != 0)
|
||||||
return retcode; /* syntax error or EOF */
|
return retcode; /* syntax error or EOF */
|
||||||
o_free(&result);
|
o_free(&result);
|
||||||
@ -3818,7 +3818,7 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
|
|||||||
* Typically it's empty, but for function defs,
|
* Typically it's empty, but for function defs,
|
||||||
* it contains function name (without '()'). */
|
* it contains function name (without '()'). */
|
||||||
int rcode;
|
int rcode;
|
||||||
const char *endch;
|
int endch;
|
||||||
struct parse_context sub;
|
struct parse_context sub;
|
||||||
struct command *command = ctx->command;
|
struct command *command = ctx->command;
|
||||||
|
|
||||||
@ -3840,9 +3840,9 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
|
|||||||
debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n");
|
debug_printf_parse("parse_group return 1: syntax error, groups and arglists don't mix\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
endch = "}";
|
endch = '}';
|
||||||
if (ch == '(') {
|
if (ch == '(') {
|
||||||
endch = ")";
|
endch = ')';
|
||||||
command->grp_type = GRP_SUBSHELL;
|
command->grp_type = GRP_SUBSHELL;
|
||||||
}
|
}
|
||||||
rcode = parse_stream(dest, &sub, input, endch);
|
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
|
|||||||
* Net result is a list of pipes in ctx->list_head.
|
* Net result is a list of pipes in ctx->list_head.
|
||||||
*/
|
*/
|
||||||
static int parse_stream(o_string *dest, struct parse_context *ctx,
|
static int parse_stream(o_string *dest, struct parse_context *ctx,
|
||||||
struct in_str *input, const char *end_trigger)
|
struct in_str *input, int end_trigger)
|
||||||
{
|
{
|
||||||
int ch, m;
|
int ch, m;
|
||||||
int redir_fd;
|
int redir_fd;
|
||||||
@ -4232,8 +4232,9 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
|
|||||||
* A single-quote triggers a bypass of the main loop until its mate is
|
* A single-quote triggers a bypass of the main loop until its mate is
|
||||||
* found. When recursing, quote state is passed in via dest->o_escape. */
|
* found. When recursing, quote state is passed in via dest->o_escape. */
|
||||||
|
|
||||||
debug_printf_parse("parse_stream entered, end_trigger='%s' "
|
debug_printf_parse("parse_stream entered, end_trigger='%c' "
|
||||||
"dest->o_assignment:%d\n", end_trigger, dest->o_assignment);
|
"dest->o_assignment:%d\n", end_trigger ? : 'X'
|
||||||
|
, dest->o_assignment);
|
||||||
|
|
||||||
dest->o_assignment = MAYBE_ASSIGNMENT;
|
dest->o_assignment = MAYBE_ASSIGNMENT;
|
||||||
initialize_context(ctx);
|
initialize_context(ctx);
|
||||||
@ -4267,7 +4268,9 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* m is SPECIAL ($,`), IFS, or ORDINARY_IF_QUOTED (*,#) */
|
/* m is SPECIAL ($,`), IFS, or ORDINARY_IF_QUOTED (*,#) */
|
||||||
|
|
||||||
if (m == CHAR_IFS) {
|
if (m == CHAR_IFS) {
|
||||||
if (ch == EOF)
|
if (ch == EOF)
|
||||||
goto ret_EOF;
|
goto ret_EOF;
|
||||||
@ -4285,29 +4288,25 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Treat newline as a command separator.
|
/* Treat newline as a command separator. */
|
||||||
* [why don't we handle it exactly like ';'? --vda] */
|
|
||||||
done_pipe(ctx, PIPE_SEQ);
|
done_pipe(ctx, PIPE_SEQ);
|
||||||
dest->o_assignment = MAYBE_ASSIGNMENT;
|
dest->o_assignment = MAYBE_ASSIGNMENT;
|
||||||
|
ch = ';';
|
||||||
|
/* note: if (m == CHAR_IFS) continue;
|
||||||
|
* will still trigger for us */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (end_trigger && strchr(end_trigger, ch)) {
|
if (end_trigger && end_trigger == ch) {
|
||||||
/* Special case: (...word) makes last word terminate,
|
//TODO: disallow "{ cmd }" without semicolon
|
||||||
* as if ';' is seen */
|
done_word(dest, ctx);
|
||||||
if (ch == ')') {
|
done_pipe(ctx, PIPE_SEQ);
|
||||||
done_word(dest, ctx);
|
dest->o_assignment = MAYBE_ASSIGNMENT;
|
||||||
//err chk?
|
/* Do we sit outside of any if's, loops or case's? */
|
||||||
done_pipe(ctx, PIPE_SEQ);
|
|
||||||
dest->o_assignment = MAYBE_ASSIGNMENT;
|
|
||||||
}
|
|
||||||
/* What do we check here? */
|
|
||||||
if (!HAS_KEYWORDS
|
if (!HAS_KEYWORDS
|
||||||
IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0))
|
IF_HAS_KEYWORDS(|| (ctx->ctx_res_w == RES_NONE && ctx->old_flag == 0))
|
||||||
) {
|
) {
|
||||||
debug_printf_parse("parse_stream return 0: end_trigger char found\n");
|
debug_printf_parse("parse_stream return 0: end_trigger char found\n");
|
||||||
/* this makes us return 0, not -1 */
|
return 0;
|
||||||
end_trigger = NULL;
|
|
||||||
goto ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (m == CHAR_IFS)
|
if (m == CHAR_IFS)
|
||||||
@ -4531,7 +4530,6 @@ static int parse_stream(o_string *dest, struct parse_context *ctx,
|
|||||||
/* Non-error returns */
|
/* Non-error returns */
|
||||||
ret_EOF:
|
ret_EOF:
|
||||||
debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL));
|
debug_printf_parse("parse_stream return %d\n", -(end_trigger != NULL));
|
||||||
ret:
|
|
||||||
done_word(dest, ctx);
|
done_word(dest, ctx);
|
||||||
done_pipe(ctx, PIPE_SEQ);
|
done_pipe(ctx, PIPE_SEQ);
|
||||||
if (end_trigger) {
|
if (end_trigger) {
|
||||||
@ -4584,7 +4582,7 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
|
|||||||
* Example: "sleep 9999; echo TEST" + ctrl-C:
|
* Example: "sleep 9999; echo TEST" + ctrl-C:
|
||||||
* TEST should be printed */
|
* TEST should be printed */
|
||||||
temp.o_assignment = MAYBE_ASSIGNMENT;
|
temp.o_assignment = MAYBE_ASSIGNMENT;
|
||||||
rcode = parse_stream(&temp, &ctx, inp, ";\n");
|
rcode = parse_stream(&temp, &ctx, inp, ';');
|
||||||
debug_printf_parse("rcode %d ctx.old_flag %x\n", rcode, ctx.old_flag);
|
debug_printf_parse("rcode %d ctx.old_flag %x\n", rcode, ctx.old_flag);
|
||||||
#if HAS_KEYWORDS
|
#if HAS_KEYWORDS
|
||||||
if (rcode != 1 && ctx.old_flag != 0) {
|
if (rcode != 1 && ctx.old_flag != 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user