From 9dda9270df3108bb85b29c6d382a3477aeb3344b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 27 Jul 2018 14:12:05 +0200 Subject: hush: fix "set -x" output prefix overlapping for v="..`cmd`.." case Was printing initial "+" prefix for the assignment, that printing "+ cmd" then printing the expanded " v=VAL" string. Delay printing of "+" prefix for the assignment to after expansion. function old new delta run_pipe 1883 1902 +19 builtin_eval 127 133 +6 expand_vars_to_list 1103 1106 +3 dump_cmd_in_x_mode 144 142 -2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/1 up/down: 28/-2) Total: 26 bytes Signed-off-by: Denys Vlasenko --- shell/hush.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 1ac2db3..e9212ce 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -896,7 +896,6 @@ struct globals { char o_opt[NUM_OPT_O]; #if ENABLE_HUSH_MODE_X - smalluint x_mode_depth; # define G_x_mode (G.o_opt[OPT_O_XTRACE]) #else # define G_x_mode 0 @@ -956,6 +955,9 @@ struct globals { # endif struct function *top_func; #endif +#if ENABLE_HUSH_MODE_X + unsigned x_mode_depth; +#endif /* Signal and trap handling */ #if ENABLE_HUSH_FAST unsigned count_SIGCHLD; @@ -7247,6 +7249,7 @@ static int generate_stream_from_string(const char *s, pid_t *pid_p) CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ reset_traps_to_defaults(); IF_HUSH_MODE_X(G.x_mode_depth++;) + //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); parse_and_run_string(s); _exit(G.last_exitcode); # else @@ -8032,17 +8035,16 @@ static void dump_cmd_in_x_mode(char **argv) if (G_x_mode && argv) { /* We want to output the line in one write op */ char *buf, *p; - int len; - int n; + unsigned len; + unsigned n; - len = G.x_mode_depth + 3; /* "+[+++...]\n\0" */ + len = G.x_mode_depth + 3; /* "+[+++...][ cmd...]\n\0" */ n = 0; while (argv[n]) len += strlen(argv[n++]) + 1; p = buf = xmalloc(len); n = G.x_mode_depth; - while (n-- >= 0) - *p++ = '+'; + do *p++ = '+'; while ((int)(--n) >= 0); n = 0; while (argv[n]) p += sprintf(p, " %s", argv[n++]); @@ -8835,21 +8837,23 @@ static NOINLINE int run_pipe(struct pipe *pi) restore_redirects(squirrel); /* Set shell variables */ -#if ENABLE_HUSH_MODE_X - if (G_x_mode) { - int n = G.x_mode_depth; - while (n-- >= 0) - bb_putchar_stderr('+'); - } -#endif i = 0; while (i < command->assignment_cnt) { char *p = expand_string_to_string(argv[i], EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1 ); - if (G_x_mode) +#if ENABLE_HUSH_MODE_X + if (G_x_mode) { + if (i == 0) { + unsigned n = G.x_mode_depth; + do + bb_putchar_stderr('+'); + while ((int)(--n) >= 0); + } fprintf(stderr, " %s", p); + } +#endif debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); if (set_local_var(p, /*flag:*/ 0)) { /* assignment to readonly var / putenv error? */ @@ -10246,6 +10250,7 @@ static int FAST_FUNC builtin_eval(char **argv) return EXIT_SUCCESS; IF_HUSH_MODE_X(G.x_mode_depth++;) + //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); if (!argv[1]) { /* bash: * eval "echo Hi; done" ("done" is syntax error): @@ -10276,6 +10281,7 @@ static int FAST_FUNC builtin_eval(char **argv) free(str); } IF_HUSH_MODE_X(G.x_mode_depth--;) + //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth); return G.last_exitcode; } -- cgit v1.1