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>
This commit is contained in:
parent
a51eec0b5a
commit
4ebcdf7396
82
shell/hush.c
82
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
|
||||
|
Loading…
Reference in New Issue
Block a user