aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e005b0a20..6e64efb70 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4488,7 +4488,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4488 } 4488 }
4489 if (ch == end_ch 4489 if (ch == end_ch
4490# if BASH_SUBSTR || BASH_PATTERN_SUBST 4490# if BASH_SUBSTR || BASH_PATTERN_SUBST
4491 || ch == end_char2 4491 || ch == end_char2
4492# endif 4492# endif
4493 ) { 4493 ) {
4494 if (!dbl) 4494 if (!dbl)
@@ -4500,6 +4500,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4500 } 4500 }
4501 } 4501 }
4502 o_addchr(dest, ch); 4502 o_addchr(dest, ch);
4503 //bb_error_msg("%s:o_addchr('%c')", __func__, ch);
4503 if (ch == '(' || ch == '{') { 4504 if (ch == '(' || ch == '{') {
4504 ch = (ch == '(' ? ')' : '}'); 4505 ch = (ch == '(' ? ')' : '}');
4505 if (!add_till_closing_bracket(dest, input, ch)) 4506 if (!add_till_closing_bracket(dest, input, ch))
@@ -4529,7 +4530,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4529 /* \x. Copy verbatim. Important for \(, \) */ 4530 /* \x. Copy verbatim. Important for \(, \) */
4530 ch = i_getch(input); 4531 ch = i_getch(input);
4531 if (ch == EOF) { 4532 if (ch == EOF) {
4532 syntax_error_unterm_ch(')'); 4533 syntax_error_unterm_ch(end_ch);
4533 return 0; 4534 return 0;
4534 } 4535 }
4535#if 0 4536#if 0
@@ -4540,6 +4541,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign
4540 } 4541 }
4541#endif 4542#endif
4542 o_addchr(dest, ch); 4543 o_addchr(dest, ch);
4544 //bb_error_msg("%s:o_addchr('%c') after '\\'", __func__, ch);
4543 continue; 4545 continue;
4544 } 4546 }
4545 } 4547 }
@@ -5842,17 +5844,24 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha
5842 unsigned scan_flags = pick_scan(exp_op, *exp_word); 5844 unsigned scan_flags = pick_scan(exp_op, *exp_word);
5843 if (exp_op == *exp_word) /* ## or %% */ 5845 if (exp_op == *exp_word) /* ## or %% */
5844 exp_word++; 5846 exp_word++;
5845 exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 1, /*unbackslash:*/ 1); 5847 debug_printf_expand("expand: exp_word:'%s'\n", exp_word);
5848 /*
5849 * process_bkslash:1 unbackslash:1 breaks this:
5850 * a='a\\'; echo ${a%\\\\} # correct output is: a
5851 * process_bkslash:1 unbackslash:0 breaks this:
5852 * a='a}'; echo ${a%\}} # correct output is: a
5853 */
5854 exp_exp_word = encode_then_expand_string(exp_word, /*process_bkslash:*/ 0, /*unbackslash:*/ 0);
5846 if (exp_exp_word) 5855 if (exp_exp_word)
5847 exp_word = exp_exp_word; 5856 exp_word = exp_exp_word;
5857 debug_printf_expand("expand: exp_exp_word:'%s'\n", exp_word);
5848 /* HACK ALERT. We depend here on the fact that 5858 /* HACK ALERT. We depend here on the fact that
5849 * G.global_argv and results of utoa and get_local_var_value 5859 * G.global_argv and results of utoa and get_local_var_value
5850 * are actually in writable memory: 5860 * are actually in writable memory:
5851 * scan_and_match momentarily stores NULs there. */ 5861 * scan_and_match momentarily stores NULs there. */
5852 t = (char*)val; 5862 t = (char*)val;
5853 loc = scan_and_match(t, exp_word, scan_flags); 5863 loc = scan_and_match(t, exp_word, scan_flags);
5854 //bb_error_msg("op:%c str:'%s' pat:'%s' res:'%s'", 5864 debug_printf_expand("op:%c str:'%s' pat:'%s' res:'%s'\n", exp_op, t, exp_word, loc);
5855 // exp_op, t, exp_word, loc);
5856 free(exp_exp_word); 5865 free(exp_exp_word);
5857 if (loc) { /* match was found */ 5866 if (loc) { /* match was found */
5858 if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */ 5867 if (scan_flags & SCAN_MATCH_LEFT_HALF) /* #[#] */
@@ -7172,21 +7181,22 @@ static const struct built_in_command *find_builtin(const char *name)
7172#if ENABLE_HUSH_FUNCTIONS 7181#if ENABLE_HUSH_FUNCTIONS
7173static struct function **find_function_slot(const char *name) 7182static struct function **find_function_slot(const char *name)
7174{ 7183{
7184 struct function *funcp;
7175 struct function **funcpp = &G.top_func; 7185 struct function **funcpp = &G.top_func;
7176 while (*funcpp) { 7186
7177 if (strcmp(name, (*funcpp)->name) == 0) { 7187 while ((funcp = *funcpp) != NULL) {
7188 if (strcmp(name, funcp->name) == 0) {
7189 debug_printf_exec("found function '%s'\n", name);
7178 break; 7190 break;
7179 } 7191 }
7180 funcpp = &(*funcpp)->next; 7192 funcpp = &funcp->next;
7181 } 7193 }
7182 return funcpp; 7194 return funcpp;
7183} 7195}
7184 7196
7185static const struct function *find_function(const char *name) 7197static ALWAYS_INLINE const struct function *find_function(const char *name)
7186{ 7198{
7187 const struct function *funcp = *find_function_slot(name); 7199 const struct function *funcp = *find_function_slot(name);
7188 if (funcp)
7189 debug_printf_exec("found function '%s'\n", name);
7190 return funcp; 7200 return funcp;
7191} 7201}
7192 7202