hush: make "set -x" output closer to bash

function                                             old     new   delta
print_optionally_squoted                               -     145    +145
run_pipe                                            1902    1919     +17
dump_cmd_in_x_mode                                   142     110     -32
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 162/-32)           Total: 130 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
pull/3/head
Denys Vlasenko 2018-07-27 17:42:38 +02:00
parent 9dda9270df
commit 4b70c926bc
1 changed files with 60 additions and 18 deletions

View File

@ -8030,28 +8030,67 @@ static void execvp_or_die(char **argv)
} }
#if ENABLE_HUSH_MODE_X #if ENABLE_HUSH_MODE_X
static void print_optionally_squoted(FILE *fp, const char *str)
{
unsigned len;
const char *cp;
cp = str;
if (str[0] != '{' && str[0] != '(') for (;;) {
if (!*cp) {
/* string has no special chars */
fputs(str, fp);
return;
}
if (*cp == '\\') break;
if (*cp == '\'') break;
if (*cp == '"') break;
if (*cp == '$') break;
if (*cp == '!') break;
if (*cp == '*') break;
if (*cp == '[') break;
if (*cp == ']') break;
#if ENABLE_HUSH_TICK
if (*cp == '`') break;
#endif
if (isspace(*cp)) break;
cp++;
}
cp = str;
for (;;) {
/* print '....' up to EOL or first squote */
len = (int)(strchrnul(cp, '\'') - cp);
if (len != 0) {
fprintf(fp, "'%.*s'", len, cp);
cp += len;
}
if (*cp == '\0')
break;
/* string contains squote(s), print them as \' */
fprintf(fp, "\\'");
cp++;
}
}
static void dump_cmd_in_x_mode(char **argv) static void dump_cmd_in_x_mode(char **argv)
{ {
if (G_x_mode && argv) { if (G_x_mode && argv) {
/* We want to output the line in one write op */
char *buf, *p;
unsigned len;
unsigned n; unsigned n;
len = G.x_mode_depth + 3; /* "+[+++...][ cmd...]\n\0" */ /* "+[+++...][ cmd...]\n\0" */
n = 0;
while (argv[n])
len += strlen(argv[n++]) + 1;
p = buf = xmalloc(len);
n = G.x_mode_depth; n = G.x_mode_depth;
do *p++ = '+'; while ((int)(--n) >= 0); do bb_putchar_stderr('+'); while ((int)(--n) >= 0);
n = 0; n = 0;
while (argv[n]) while (argv[n]) {
p += sprintf(p, " %s", argv[n++]); if (argv[n][0] == '\0')
*p++ = '\n'; fputs(" ''", stderr);
*p = '\0'; else {
fputs(buf, stderr); bb_putchar_stderr(' ');
free(buf); print_optionally_squoted(stderr, argv[n]);
}
n++;
}
bb_putchar_stderr('\n');
} }
} }
#else #else
@ -8845,13 +8884,18 @@ static NOINLINE int run_pipe(struct pipe *pi)
); );
#if ENABLE_HUSH_MODE_X #if ENABLE_HUSH_MODE_X
if (G_x_mode) { if (G_x_mode) {
char *eq;
if (i == 0) { if (i == 0) {
unsigned n = G.x_mode_depth; unsigned n = G.x_mode_depth;
do do
bb_putchar_stderr('+'); bb_putchar_stderr('+');
while ((int)(--n) >= 0); while ((int)(--n) >= 0);
} }
fprintf(stderr, " %s", p); eq = strchrnul(p, '=');
fprintf(stderr, " %.*s=", (int)(eq - p), p);
if (*eq)
print_optionally_squoted(stderr, eq + 1);
bb_putchar_stderr('\n');
} }
#endif #endif
debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
@ -8861,8 +8905,6 @@ static NOINLINE int run_pipe(struct pipe *pi)
} }
i++; i++;
} }
if (G_x_mode)
bb_putchar_stderr('\n');
/* Redirect error sets $? to 1. Otherwise, /* Redirect error sets $? to 1. Otherwise,
* if evaluating assignment value set $?, retain it. * if evaluating assignment value set $?, retain it.
* Else, clear $?: * Else, clear $?: