From 90b607d79a1377d6a5dda44ee112698c58432203 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 13 Apr 2023 09:20:24 +0200 Subject: hush: quote variable values printed by "set" (match ash behavior) function old new delta builtin_set 258 301 +43 Signed-off-by: Denys Vlasenko --- shell/hush.c | 19 +++++++++++++++++-- shell/hush_test/hush-misc/export-n.right | 4 ++-- 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'shell') diff --git a/shell/hush.c b/shell/hush.c index a938cc790..202c0993a 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -11147,6 +11147,12 @@ static int FAST_FUNC builtin_umask(char **argv) #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP static void print_escaped(const char *s) { +//TODO? bash "set" does not quote variables which contain only alnums and "%+,-./:=@_~", +// (but "export" quotes all variables, even with only these chars). +// I think quoting strings with %+,=~ looks better +// (example: "set" printing var== instead of var='=' looks strange) +// IOW: do not quote "-./:@_": / is used in pathnames, : in PATH, -._ often in file names, @ in emails + if (*s == '\'') goto squote; do { @@ -11401,8 +11407,17 @@ static int FAST_FUNC builtin_set(char **argv) if (arg == NULL) { struct variable *e; - for (e = G.top_var; e; e = e->next) - puts(e->varstr); + for (e = G.top_var; e; e = e->next) { + const char *s = e->varstr; + const char *p = strchr(s, '='); + + if (!p) /* wtf? take next variable */ + continue; + /* var= */ + printf("%.*s", (int)(p - s) + 1, s); + print_escaped(p + 1); + putchar('\n'); + } return EXIT_SUCCESS; } diff --git a/shell/hush_test/hush-misc/export-n.right b/shell/hush_test/hush-misc/export-n.right index 3d55bf752..6079a0124 100644 --- a/shell/hush_test/hush-misc/export-n.right +++ b/shell/hush_test/hush-misc/export-n.right @@ -2,8 +2,8 @@ export aaa1="'''" export aaa2='' export aaa3="'''"'abc' export aaa8='8' -aaa9=9 -aaa10=10 +aaa9='9' +aaa10='10' Nothing: Nothing: Nothing: -- cgit v1.2.3-55-g6feb From acae889dd97280ee59b7e04c18005bb8875cb0d2 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 13 Apr 2023 12:56:14 +0100 Subject: ash,hush: tab completion of functions and aliases Since commit 9e2a5668f (ash,hush: allow builtins to be tab-completed, closes 7532) ash and hush have supported tab completion of builtins. Other shells, bash and ksh for example, also support tab completion of functions and aliases. Add such support to ash and hush. function old new delta ash_command_name - 92 +92 hush_command_name - 63 +63 ash_builtin_name 17 - -17 hush_builtin_name 38 - -38 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 0/0 up/down: 169/-55) Total: 100 bytes Signed-off-by: Ron Yorston Signed-off-by: Avi Halachmi Signed-off-by: Denys Vlasenko --- shell/ash.c | 32 ++++++++++++++++++++++++++++---- shell/hush.c | 14 ++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) (limited to 'shell') diff --git a/shell/ash.c b/shell/ash.c index d4ee4c93e..d2c5c5d50 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9732,7 +9732,7 @@ evalpipe(union node *n, int flags) /* setinteractive needs this forward reference */ #if ENABLE_FEATURE_TAB_COMPLETION -static const char *get_builtin_name(int i) FAST_FUNC; +static const char *ash_command_name(int i) FAST_FUNC; #endif /* @@ -9769,7 +9769,7 @@ setinteractive(int on) if (!line_input_state) { line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); # if ENABLE_FEATURE_TAB_COMPLETION - line_input_state->get_exe_name = get_builtin_name; + line_input_state->get_exe_name = ash_command_name; # endif # if EDITING_HAS_sh_get_var line_input_state->sh_get_var = lookupvar; @@ -10284,9 +10284,33 @@ find_builtin(const char *name) #if ENABLE_FEATURE_TAB_COMPLETION static const char * FAST_FUNC -get_builtin_name(int i) +ash_command_name(int i) { - return /*i >= 0 &&*/ i < ARRAY_SIZE(builtintab) ? builtintab[i].name + 1 : NULL; + int n; + + if (/*i >= 0 &&*/ i < ARRAY_SIZE(builtintab)) + return builtintab[i].name + 1; + i -= ARRAY_SIZE(builtintab); + + for (n = 0; n < CMDTABLESIZE; n++) { + struct tblentry *cmdp; + for (cmdp = cmdtable[n]; cmdp; cmdp = cmdp->next) { + if (cmdp->cmdtype == CMDFUNCTION && --i < 0) + return cmdp->cmdname; + } + } + +# if ENABLE_ASH_ALIAS + for (n = 0; n < ATABSIZE; n++) { + struct alias *ap; + for (ap = atab[n]; ap; ap = ap->next) { + if (--i < 0) + return ap->name; + } + } +#endif + + return NULL; } #endif diff --git a/shell/hush.c b/shell/hush.c index 202c0993a..f8951d084 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8220,7 +8220,7 @@ static const struct built_in_command *find_builtin(const char *name) } #if ENABLE_HUSH_JOB && ENABLE_FEATURE_TAB_COMPLETION -static const char * FAST_FUNC get_builtin_name(int i) +static const char * FAST_FUNC hush_command_name(int i) { if (/*i >= 0 && */ i < ARRAY_SIZE(bltins1)) { return bltins1[i].b_cmd; @@ -8229,6 +8229,16 @@ static const char * FAST_FUNC get_builtin_name(int i) if (i < ARRAY_SIZE(bltins2)) { return bltins2[i].b_cmd; } +# if ENABLE_HUSH_FUNCTIONS + { + struct function *funcp; + i -= ARRAY_SIZE(bltins2); + for (funcp = G.top_func; funcp; funcp = funcp->next) { + if (--i < 0) + return funcp->name; + } + } +# endif return NULL; } #endif @@ -10716,7 +10726,7 @@ int hush_main(int argc, char **argv) # if ENABLE_FEATURE_EDITING G.line_input_state = new_line_input_t(FOR_SHELL); # if ENABLE_FEATURE_TAB_COMPLETION - G.line_input_state->get_exe_name = get_builtin_name; + G.line_input_state->get_exe_name = hush_command_name; # endif # if EDITING_HAS_sh_get_var G.line_input_state->sh_get_var = get_local_var_value; -- cgit v1.2.3-55-g6feb