summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2019-05-16 15:39:19 +0200
committerDenys Vlasenko2019-05-16 15:39:19 +0200
commit4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8 (patch)
tree80503d42301ee7ff16368a4a2f94e2b9b165564c
parenta51eec0b5aaee3835a54ca35c65e3cfc87004b97 (diff)
downloadbusybox-4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8.zip
busybox-4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8.tar.gz
hush: remove code to track PS1/2 values dynamically - it's too much work
Assignments / exports / unsets of variables are far more frequent than prompt printing, and if we show prompt, we are likely to be limited by user typing speed - do not optimize for that scenario. Just re-query $PS1 / $PS2 values when need to show the prompt. function old new delta fgetc_interactive 236 259 +23 set_vars_and_save_old 150 147 -3 pseudo_exec_argv 597 594 -3 hush_main 1110 1105 -5 enter_var_nest_level 38 32 -6 builtin_local 56 50 -6 run_pipe 1857 1834 -23 leave_var_nest_level 127 98 -29 handle_changed_special_names 111 79 -32 cmdedit_update_prompt 57 - -57 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/8 up/down: 23/-164) Total: -141 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c82
1 files changed, 21 insertions, 61 deletions
diff --git a/shell/hush.c b/shell/hush.c
index ce34163..e2927af 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -854,8 +854,7 @@ struct globals {
/* 'interactive_fd' is a fd# open to ctty, if we have one
* _AND_ if we decided to act interactively */
int interactive_fd;
- const char *PS1;
- IF_FEATURE_EDITING_FANCY_PROMPT(const char *PS2;)
+ IF_NOT_FEATURE_EDITING_FANCY_PROMPT(char *PS1;)
# define G_interactive_fd (G.interactive_fd)
#else
# define G_interactive_fd 0
@@ -1448,13 +1447,6 @@ static void syntax_error_unexpected_ch(unsigned lineno UNUSED_PARAM, int ch)
#endif
-#if ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
-static void cmdedit_update_prompt(void);
-#else
-# define cmdedit_update_prompt() ((void)0)
-#endif
-
-
/* Utility functions
*/
/* Replace each \x with x in place, return ptr past NUL. */
@@ -2248,33 +2240,22 @@ static const char* FAST_FUNC get_local_var_value(const char *name)
return NULL;
}
-#if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT) \
- || (ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
+#if ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS
static void handle_changed_special_names(const char *name, unsigned name_len)
{
- if (ENABLE_HUSH_INTERACTIVE && ENABLE_FEATURE_EDITING_FANCY_PROMPT
- && name_len == 3 && name[0] == 'P' && name[1] == 'S'
- ) {
- if (G_interactive_fd)
- cmdedit_update_prompt();
- return;
- }
-
- if ((ENABLE_HUSH_LINENO_VAR || ENABLE_HUSH_GETOPTS)
- && name_len == 6
- ) {
-#if ENABLE_HUSH_LINENO_VAR
+ if (name_len == 6) {
+# if ENABLE_HUSH_LINENO_VAR
if (strncmp(name, "LINENO", 6) == 0) {
G.lineno_var = NULL;
return;
}
-#endif
-#if ENABLE_HUSH_GETOPTS
+# endif
+# if ENABLE_HUSH_GETOPTS
if (strncmp(name, "OPTIND", 6) == 0) {
G.getopt_count = 0;
return;
}
-#endif
+# endif
}
}
#else
@@ -2470,7 +2451,7 @@ static int unset_local_var_len(const char *name, int name_len)
cur_pp = &cur->next;
}
- /* Handle "unset PS1" et al even if did not find the variable to unset */
+ /* Handle "unset LINENO" et al even if did not find the variable to unset */
handle_changed_special_names(name, name_len);
return EXIT_SUCCESS;
@@ -2500,11 +2481,6 @@ static void add_vars(struct variable *var)
} else {
debug_printf_env("%s: restoring variable '%s'/%u\n", __func__, var->varstr, var->var_nest_level);
}
- /* Testcase (interactive):
- * f() { local PS1='\w \$ '; }; f
- * the below call is needed to notice restored PS1 when f returns.
- */
- handle_changed_special_names(var->varstr, endofname(var->varstr) - var->varstr);
var = next;
}
}
@@ -2594,36 +2570,27 @@ static void reinit_unicode_for_hush(void)
* \
* It exercises a lot of corner cases.
*/
-# if ENABLE_FEATURE_EDITING_FANCY_PROMPT
-static void cmdedit_update_prompt(void)
-{
- G.PS1 = get_local_var_value("PS1");
- if (G.PS1 == NULL)
- G.PS1 = "";
- G.PS2 = get_local_var_value("PS2");
- if (G.PS2 == NULL)
- G.PS2 = "";
-}
-# endif
static const char *setup_prompt_string(void)
{
const char *prompt_str;
debug_printf_prompt("%s promptmode:%d\n", __func__, G.promptmode);
- IF_FEATURE_EDITING_FANCY_PROMPT( prompt_str = G.PS2;)
- IF_NOT_FEATURE_EDITING_FANCY_PROMPT(prompt_str = "> ";)
+# if ENABLE_FEATURE_EDITING_FANCY_PROMPT
+ prompt_str = get_local_var_value(G.promptmode == 0 ? "PS1" : "PS2");
+ if (!prompt_str)
+ prompt_str = "";
+# else
+ prompt_str = "> "; /* if PS2, else... */
if (G.promptmode == 0) { /* PS1 */
- if (!ENABLE_FEATURE_EDITING_FANCY_PROMPT) {
- /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
- free((char*)G.PS1);
- /* bash uses $PWD value, even if it is set by user.
- * It uses current dir only if PWD is unset.
- * We always use current dir. */
- G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
- }
- prompt_str = G.PS1;
+ /* No fancy prompts supported, (re)generate "CURDIR $ " by hand */
+ free(G.PS1);
+ /* bash uses $PWD value, even if it is set by user.
+ * It uses current dir only if PWD is unset.
+ * We always use current dir. */
+ G.PS1 = xasprintf("%s %c ", get_cwd(0), (geteuid() != 0) ? '$' : '#');
}
+# endif
debug_printf("prompt_str '%s'\n", prompt_str);
return prompt_str;
}
@@ -7904,11 +7871,6 @@ static void remove_nested_vars(void)
*cur_pp = cur->next;
/* Free */
if (!cur->max_len) {
- /* Testcase (interactive):
- * f() { local PS1='\w \$ '; }; f
- * we should forget local PS1:
- */
- handle_changed_special_names(cur->varstr, endofname(cur->varstr) - cur->varstr);
debug_printf_env("freeing nested '%s'/%u\n", cur->varstr, cur->var_nest_level);
free(cur->varstr);
}
@@ -9997,8 +9959,6 @@ int hush_main(int argc, char **argv)
#endif
/* Initialize some more globals to non-zero values */
- cmdedit_update_prompt();
-
die_func = restore_ttypgrp_and__exit;
/* Shell is non-interactive at first. We need to call