[git commit] hush: remove code to track PS1/2 values dynamically - it's too much work

Denys Vlasenko vda.linux at googlemail.com
Thu May 16 13:39:19 UTC 2019


commit: https://git.busybox.net/busybox/commit/?id=4ebcdf7396b8e19ddf4e8b12a84b186fcbccabb8
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 shell/hush.c | 82 ++++++++++++++++--------------------------------------------
 1 file changed, 21 insertions(+), 61 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index ce341632a..e2927afc4 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


More information about the busybox-cvs mailing list