mirror of https://github.com/mirror/busybox.git
hush: store "ended_in_ifs" flag in o_string
This simplifies function parameter passing. function old new delta expand_one_var 1643 1639 -4 append_str_maybe_ifs_split 64 52 -12 expand_vars_to_list 1125 1112 -13 expand_on_ifs 361 345 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-45) Total: -45 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>pull/3/head
parent
8a6a461504
commit
168579a34c
37
shell/hush.c
37
shell/hush.c
|
@ -534,6 +534,7 @@ typedef struct o_string {
|
||||||
* possibly empty one: word"", wo''rd etc. */
|
* possibly empty one: word"", wo''rd etc. */
|
||||||
smallint has_quoted_part;
|
smallint has_quoted_part;
|
||||||
smallint has_empty_slot;
|
smallint has_empty_slot;
|
||||||
|
smallint ended_in_ifs;
|
||||||
} o_string;
|
} o_string;
|
||||||
enum {
|
enum {
|
||||||
EXP_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */
|
EXP_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */
|
||||||
|
@ -5643,10 +5644,10 @@ static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len
|
||||||
/* Store given string, finalizing the word and starting new one whenever
|
/* Store given string, finalizing the word and starting new one whenever
|
||||||
* we encounter IFS char(s). This is used for expanding variable values.
|
* we encounter IFS char(s). This is used for expanding variable values.
|
||||||
* End-of-string does NOT finalize word: think about 'echo -$VAR-'.
|
* End-of-string does NOT finalize word: think about 'echo -$VAR-'.
|
||||||
* Return in *ended_with_ifs:
|
* Return in output->ended_in_ifs:
|
||||||
* 1 - ended with IFS char, else 0 (this includes case of empty str).
|
* 1 - ended with IFS char, else 0 (this includes case of empty str).
|
||||||
*/
|
*/
|
||||||
static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const char *str)
|
static int expand_on_ifs(o_string *output, int n, const char *str)
|
||||||
{
|
{
|
||||||
int last_is_ifs = 0;
|
int last_is_ifs = 0;
|
||||||
|
|
||||||
|
@ -5709,8 +5710,7 @@ static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const cha
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ended_with_ifs)
|
output->ended_in_ifs = last_is_ifs;
|
||||||
*ended_with_ifs = last_is_ifs;
|
|
||||||
debug_print_list("expand_on_ifs[1]", output, n);
|
debug_print_list("expand_on_ifs[1]", output, n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
@ -5955,14 +5955,14 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c
|
||||||
}
|
}
|
||||||
#endif /* BASH_PATTERN_SUBST */
|
#endif /* BASH_PATTERN_SUBST */
|
||||||
|
|
||||||
static int append_str_maybe_ifs_split(o_string *output, int *ended_in_ifs, int n,
|
static int append_str_maybe_ifs_split(o_string *output, int n,
|
||||||
int first_ch, const char *val)
|
int first_ch, const char *val)
|
||||||
{
|
{
|
||||||
if (!(first_ch & 0x80)) { /* unquoted $VAR */
|
if (!(first_ch & 0x80)) { /* unquoted $VAR */
|
||||||
debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
|
debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
|
||||||
!!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
|
!!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
|
||||||
if (val && val[0])
|
if (val && val[0])
|
||||||
n = expand_on_ifs(ended_in_ifs, output, n, val);
|
n = expand_on_ifs(output, n, val);
|
||||||
} else { /* quoted "$VAR" */
|
} else { /* quoted "$VAR" */
|
||||||
output->has_quoted_part = 1;
|
output->has_quoted_part = 1;
|
||||||
debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
|
debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
|
||||||
|
@ -5977,7 +5977,7 @@ static int append_str_maybe_ifs_split(o_string *output, int *ended_in_ifs, int n
|
||||||
* Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
|
* Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
|
||||||
*/
|
*/
|
||||||
static NOINLINE int expand_one_var(o_string *output,
|
static NOINLINE int expand_one_var(o_string *output,
|
||||||
int *ended_in_ifs, int n, int first_ch, char *arg, char **pp)
|
int n, int first_ch, char *arg, char **pp)
|
||||||
{
|
{
|
||||||
const char *val;
|
const char *val;
|
||||||
char *to_be_freed;
|
char *to_be_freed;
|
||||||
|
@ -6242,9 +6242,9 @@ static NOINLINE int expand_one_var(o_string *output,
|
||||||
* $ f() { for i; do echo "|$i|"; done; };
|
* $ f() { for i; do echo "|$i|"; done; };
|
||||||
*
|
*
|
||||||
* $ x=; f ${x:?'x y' z}
|
* $ x=; f ${x:?'x y' z}
|
||||||
* bash: x: x y z
|
* bash: x: x y z #BUG: does not abort, ${} results in empty expansion
|
||||||
* $ x=; f "${x:?'x y' z}"
|
* $ x=; f "${x:?'x y' z}"
|
||||||
* bash: x: x y z # dash prints: dash: x: 'x y' z
|
* bash: x: x y z # dash prints: dash: x: 'x y' z #BUG: does not abort, ${} results in ""
|
||||||
*
|
*
|
||||||
* $ x=; f ${x:='x y' z}
|
* $ x=; f ${x:='x y' z}
|
||||||
* |x|
|
* |x|
|
||||||
|
@ -6290,7 +6290,7 @@ static NOINLINE int expand_one_var(o_string *output,
|
||||||
/*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
|
/*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
|
||||||
);
|
);
|
||||||
//TODO: how interactive bash aborts expansion mid-command?
|
//TODO: how interactive bash aborts expansion mid-command?
|
||||||
//It aborts the entire line:
|
//It aborts the entire line, returns to prompt:
|
||||||
// $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
|
// $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
|
||||||
// bash: x: x y z
|
// bash: x: x y z
|
||||||
// $
|
// $
|
||||||
|
@ -6319,7 +6319,7 @@ static NOINLINE int expand_one_var(o_string *output,
|
||||||
arg[0] = arg0;
|
arg[0] = arg0;
|
||||||
*pp = p;
|
*pp = p;
|
||||||
|
|
||||||
n = append_str_maybe_ifs_split(output, ended_in_ifs, n, first_ch, val);
|
n = append_str_maybe_ifs_split(output, n, first_ch, val);
|
||||||
|
|
||||||
free(to_be_freed);
|
free(to_be_freed);
|
||||||
return n;
|
return n;
|
||||||
|
@ -6336,9 +6336,10 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
* expansion of right-hand side of assignment == 1-element expand.
|
* expansion of right-hand side of assignment == 1-element expand.
|
||||||
*/
|
*/
|
||||||
char cant_be_null = 0; /* only bit 0x80 matters */
|
char cant_be_null = 0; /* only bit 0x80 matters */
|
||||||
int ended_in_ifs = 0; /* did last unquoted expansion end with IFS chars? */
|
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
output->ended_in_ifs = 0; /* did last unquoted expansion end with IFS chars? */
|
||||||
|
|
||||||
debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
|
debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
|
||||||
!!(output->o_expflags & EXP_FLAG_SINGLEWORD));
|
!!(output->o_expflags & EXP_FLAG_SINGLEWORD));
|
||||||
debug_print_list("expand_vars_to_list", output, n);
|
debug_print_list("expand_vars_to_list", output, n);
|
||||||
|
@ -6352,10 +6353,10 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
char arith_buf[sizeof(arith_t)*3 + 2];
|
char arith_buf[sizeof(arith_t)*3 + 2];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ended_in_ifs) {
|
if (output->ended_in_ifs) {
|
||||||
o_addchr(output, '\0');
|
o_addchr(output, '\0');
|
||||||
n = o_save_ptr(output, n);
|
n = o_save_ptr(output, n);
|
||||||
ended_in_ifs = 0;
|
output->ended_in_ifs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
o_addblock(output, arg, p - arg);
|
o_addblock(output, arg, p - arg);
|
||||||
|
@ -6386,7 +6387,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
|
cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
|
||||||
if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
|
if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
|
||||||
while (G.global_argv[i]) {
|
while (G.global_argv[i]) {
|
||||||
n = expand_on_ifs(NULL, output, n, G.global_argv[i]);
|
n = expand_on_ifs(output, n, G.global_argv[i]);
|
||||||
debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
|
debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
|
||||||
if (G.global_argv[i++][0] && G.global_argv[i]) {
|
if (G.global_argv[i++][0] && G.global_argv[i]) {
|
||||||
/* this argv[] is not empty and not last:
|
/* this argv[] is not empty and not last:
|
||||||
|
@ -6447,7 +6448,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
G.last_exitcode = process_command_subs(&subst_result, arg);
|
G.last_exitcode = process_command_subs(&subst_result, arg);
|
||||||
G.expand_exitcode = G.last_exitcode;
|
G.expand_exitcode = G.last_exitcode;
|
||||||
debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
|
debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
|
||||||
n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, subst_result.data);
|
n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
|
||||||
o_free_unsafe(&subst_result);
|
o_free_unsafe(&subst_result);
|
||||||
goto restore;
|
goto restore;
|
||||||
}
|
}
|
||||||
|
@ -6467,7 +6468,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
n = expand_one_var(output, &ended_in_ifs, n, first_ch, arg, &p);
|
n = expand_one_var(output, n, first_ch, arg, &p);
|
||||||
goto restore;
|
goto restore;
|
||||||
} /* switch (char after <SPECIAL_VAR_SYMBOL>) */
|
} /* switch (char after <SPECIAL_VAR_SYMBOL>) */
|
||||||
|
|
||||||
|
@ -6483,7 +6484,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
|
||||||
} /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
|
} /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
|
||||||
|
|
||||||
if (arg[0]) {
|
if (arg[0]) {
|
||||||
if (ended_in_ifs) {
|
if (output->ended_in_ifs) {
|
||||||
o_addchr(output, '\0');
|
o_addchr(output, '\0');
|
||||||
n = o_save_ptr(output, n);
|
n = o_save_ptr(output, n);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue