aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-07-19 13:45:54 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-07-20 16:27:26 +0200
commit168579a34c6fc6c2f2cd20256367ceb61f50bf68 (patch)
tree19ee47b4f503940d77c35d6958aa294f3f24822d
parent8a6a4615048d51af0e765e893211073faa7951cc (diff)
downloadbusybox-w32-168579a34c6fc6c2f2cd20256367ceb61f50bf68.tar.gz
busybox-w32-168579a34c6fc6c2f2cd20256367ceb61f50bf68.tar.bz2
busybox-w32-168579a34c6fc6c2f2cd20256367ceb61f50bf68.zip
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>
-rw-r--r--shell/hush.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/shell/hush.c b/shell/hush.c
index ea259f53c..2d4e3fa66 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -534,6 +534,7 @@ typedef struct o_string {
534 * possibly empty one: word"", wo''rd etc. */ 534 * possibly empty one: word"", wo''rd etc. */
535 smallint has_quoted_part; 535 smallint has_quoted_part;
536 smallint has_empty_slot; 536 smallint has_empty_slot;
537 smallint ended_in_ifs;
537} o_string; 538} o_string;
538enum { 539enum {
539 EXP_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */ 540 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
5643/* Store given string, finalizing the word and starting new one whenever 5644/* Store given string, finalizing the word and starting new one whenever
5644 * we encounter IFS char(s). This is used for expanding variable values. 5645 * we encounter IFS char(s). This is used for expanding variable values.
5645 * End-of-string does NOT finalize word: think about 'echo -$VAR-'. 5646 * End-of-string does NOT finalize word: think about 'echo -$VAR-'.
5646 * Return in *ended_with_ifs: 5647 * Return in output->ended_in_ifs:
5647 * 1 - ended with IFS char, else 0 (this includes case of empty str). 5648 * 1 - ended with IFS char, else 0 (this includes case of empty str).
5648 */ 5649 */
5649static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const char *str) 5650static int expand_on_ifs(o_string *output, int n, const char *str)
5650{ 5651{
5651 int last_is_ifs = 0; 5652 int last_is_ifs = 0;
5652 5653
@@ -5709,8 +5710,7 @@ static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const cha
5709 } 5710 }
5710 } 5711 }
5711 5712
5712 if (ended_with_ifs) 5713 output->ended_in_ifs = last_is_ifs;
5713 *ended_with_ifs = last_is_ifs;
5714 debug_print_list("expand_on_ifs[1]", output, n); 5714 debug_print_list("expand_on_ifs[1]", output, n);
5715 return n; 5715 return n;
5716} 5716}
@@ -5955,14 +5955,14 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c
5955} 5955}
5956#endif /* BASH_PATTERN_SUBST */ 5956#endif /* BASH_PATTERN_SUBST */
5957 5957
5958static int append_str_maybe_ifs_split(o_string *output, int *ended_in_ifs, int n, 5958static int append_str_maybe_ifs_split(o_string *output, int n,
5959 int first_ch, const char *val) 5959 int first_ch, const char *val)
5960{ 5960{
5961 if (!(first_ch & 0x80)) { /* unquoted $VAR */ 5961 if (!(first_ch & 0x80)) { /* unquoted $VAR */
5962 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val, 5962 debug_printf_expand("unquoted '%s', output->o_escape:%d\n", val,
5963 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); 5963 !!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
5964 if (val && val[0]) 5964 if (val && val[0])
5965 n = expand_on_ifs(ended_in_ifs, output, n, val); 5965 n = expand_on_ifs(output, n, val);
5966 } else { /* quoted "$VAR" */ 5966 } else { /* quoted "$VAR" */
5967 output->has_quoted_part = 1; 5967 output->has_quoted_part = 1;
5968 debug_printf_expand("quoted '%s', output->o_escape:%d\n", val, 5968 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
5977 * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. 5977 * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct.
5978 */ 5978 */
5979static NOINLINE int expand_one_var(o_string *output, 5979static NOINLINE int expand_one_var(o_string *output,
5980 int *ended_in_ifs, int n, int first_ch, char *arg, char **pp) 5980 int n, int first_ch, char *arg, char **pp)
5981{ 5981{
5982 const char *val; 5982 const char *val;
5983 char *to_be_freed; 5983 char *to_be_freed;
@@ -6242,9 +6242,9 @@ static NOINLINE int expand_one_var(o_string *output,
6242 * $ f() { for i; do echo "|$i|"; done; }; 6242 * $ f() { for i; do echo "|$i|"; done; };
6243 * 6243 *
6244 * $ x=; f ${x:?'x y' z} 6244 * $ x=; f ${x:?'x y' z}
6245 * bash: x: x y z 6245 * bash: x: x y z #BUG: does not abort, ${} results in empty expansion
6246 * $ x=; f "${x:?'x y' z}" 6246 * $ x=; f "${x:?'x y' z}"
6247 * bash: x: x y z # dash prints: dash: x: 'x y' z 6247 * bash: x: x y z # dash prints: dash: x: 'x y' z #BUG: does not abort, ${} results in ""
6248 * 6248 *
6249 * $ x=; f ${x:='x y' z} 6249 * $ x=; f ${x:='x y' z}
6250 * |x| 6250 * |x|
@@ -6290,7 +6290,7 @@ static NOINLINE int expand_one_var(o_string *output,
6290 /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/ 6290 /*: (exp_save == ':' ? "parameter null or not set" : "parameter not set")*/
6291 ); 6291 );
6292//TODO: how interactive bash aborts expansion mid-command? 6292//TODO: how interactive bash aborts expansion mid-command?
6293//It aborts the entire line: 6293//It aborts the entire line, returns to prompt:
6294// $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO 6294// $ f() { for i; do echo "|$i|"; done; }; x=; f "${x:?'x y' z}"; echo YO
6295// bash: x: x y z 6295// bash: x: x y z
6296// $ 6296// $
@@ -6319,7 +6319,7 @@ static NOINLINE int expand_one_var(o_string *output,
6319 arg[0] = arg0; 6319 arg[0] = arg0;
6320 *pp = p; 6320 *pp = p;
6321 6321
6322 n = append_str_maybe_ifs_split(output, ended_in_ifs, n, first_ch, val); 6322 n = append_str_maybe_ifs_split(output, n, first_ch, val);
6323 6323
6324 free(to_be_freed); 6324 free(to_be_freed);
6325 return n; 6325 return n;
@@ -6336,9 +6336,10 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6336 * expansion of right-hand side of assignment == 1-element expand. 6336 * expansion of right-hand side of assignment == 1-element expand.
6337 */ 6337 */
6338 char cant_be_null = 0; /* only bit 0x80 matters */ 6338 char cant_be_null = 0; /* only bit 0x80 matters */
6339 int ended_in_ifs = 0; /* did last unquoted expansion end with IFS chars? */
6340 char *p; 6339 char *p;
6341 6340
6341 output->ended_in_ifs = 0; /* did last unquoted expansion end with IFS chars? */
6342
6342 debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg, 6343 debug_printf_expand("expand_vars_to_list: arg:'%s' singleword:%x\n", arg,
6343 !!(output->o_expflags & EXP_FLAG_SINGLEWORD)); 6344 !!(output->o_expflags & EXP_FLAG_SINGLEWORD));
6344 debug_print_list("expand_vars_to_list", output, n); 6345 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)
6352 char arith_buf[sizeof(arith_t)*3 + 2]; 6353 char arith_buf[sizeof(arith_t)*3 + 2];
6353#endif 6354#endif
6354 6355
6355 if (ended_in_ifs) { 6356 if (output->ended_in_ifs) {
6356 o_addchr(output, '\0'); 6357 o_addchr(output, '\0');
6357 n = o_save_ptr(output, n); 6358 n = o_save_ptr(output, n);
6358 ended_in_ifs = 0; 6359 output->ended_in_ifs = 0;
6359 } 6360 }
6360 6361
6361 o_addblock(output, arg, p - arg); 6362 o_addblock(output, arg, p - arg);
@@ -6386,7 +6387,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6386 cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */ 6387 cant_be_null |= first_ch; /* do it for "$@" _now_, when we know it's not empty */
6387 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ 6388 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
6388 while (G.global_argv[i]) { 6389 while (G.global_argv[i]) {
6389 n = expand_on_ifs(NULL, output, n, G.global_argv[i]); 6390 n = expand_on_ifs(output, n, G.global_argv[i]);
6390 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1); 6391 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, G.global_argc - 1);
6391 if (G.global_argv[i++][0] && G.global_argv[i]) { 6392 if (G.global_argv[i++][0] && G.global_argv[i]) {
6392 /* this argv[] is not empty and not last: 6393 /* 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)
6447 G.last_exitcode = process_command_subs(&subst_result, arg); 6448 G.last_exitcode = process_command_subs(&subst_result, arg);
6448 G.expand_exitcode = G.last_exitcode; 6449 G.expand_exitcode = G.last_exitcode;
6449 debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); 6450 debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
6450 n = append_str_maybe_ifs_split(output, &ended_in_ifs, n, first_ch, subst_result.data); 6451 n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
6451 o_free_unsafe(&subst_result); 6452 o_free_unsafe(&subst_result);
6452 goto restore; 6453 goto restore;
6453 } 6454 }
@@ -6467,7 +6468,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6467 } 6468 }
6468#endif 6469#endif
6469 default: 6470 default:
6470 n = expand_one_var(output, &ended_in_ifs, n, first_ch, arg, &p); 6471 n = expand_one_var(output, n, first_ch, arg, &p);
6471 goto restore; 6472 goto restore;
6472 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */ 6473 } /* switch (char after <SPECIAL_VAR_SYMBOL>) */
6473 6474
@@ -6483,7 +6484,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
6483 } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */ 6484 } /* end of "while (SPECIAL_VAR_SYMBOL is found) ..." */
6484 6485
6485 if (arg[0]) { 6486 if (arg[0]) {
6486 if (ended_in_ifs) { 6487 if (output->ended_in_ifs) {
6487 o_addchr(output, '\0'); 6488 o_addchr(output, '\0');
6488 n = o_save_ptr(output, n); 6489 n = o_save_ptr(output, n);
6489 } 6490 }