allow builtins to assign to associative arrays using @ or * as keys; fixes to glob completion of command words

This commit is contained in:
Chet Ramey
2021-04-28 11:30:31 -04:00
parent 3fd77612fc
commit 046d0cc93b
10 changed files with 64 additions and 13 deletions
+36 -2
View File
@@ -10057,7 +10057,7 @@ lib/readline/search.c
subst.h
- ASS_ALLOWALLSUB: new assignment flag value, means to allow @ and * as
array subscripts when assigning to existing associative arrays
valid array subscripts when assigning to existing associative arrays
arrayfunc.c
- assign_array_element: allow assignment of key `@' to an existing
@@ -10068,9 +10068,43 @@ arrayfunc.c
builtins/declare.def
- declare_internal: allow assignment of key `@' to an existing
associative array by passing ASS_ALLOWALLSUB to assign_array_element
as part of local_aflags
as part of local_aflags. This affects declare, local, and typeset
subst.c
- do_assignment_internal: allow a[@]=value to an existing associative
array by passing ASS_ALLOWALLSUB to assign_array_element
4/27
----
builtins/common.[ch]
- builtin_bind_var_to_int: wrapper for bind_var_to_int to be used by
builtin commands; placeholder for future work
builtins/wait.def
- builtin_bind_var_to_int: use instead of bind_var_to_int
builtins/common.c
- builtin_bind_variable: allow assignment of key `@' to an existing
associative array by passing ASS_ALLOWALLSUB to assign_array_element.
This affects printf and read
builtins/variables.[ch]
- bind_var_to_int: add third `flags' argument to pass to bind_variable
instead of always passing 0
redir.c,builtins/common.c,builtins/printf.def
- bind_var_to_int: change callers, add third flags argument
builtins/common.c
- builtin_bind_var_to_int: pass ASS_ALLOWALLSUB to bind_var_to_int so
builtins like wait can assign to assoc[@] and assoc[*]
4/28
----
bashline.c
- command_word_completion_function: make sure to initialize
old_glob_ignore_case before trying to restore from it
- command_word_completion_function: if we are completing a glob
pattern, make sure to set rl_filename_completion_desired, so we get
quoting and appending -- we are completing a filename, after all.
From a report from Manuel Boni <ziosombrero@gmail.com>
+5 -1
View File
@@ -1939,7 +1939,7 @@ executable_completion (filename, searching_path)
f = savestring (filename);
#else
c = 0;
f = bash_quote_filename (filename, SINGLE_MATCH, &c);
f = bash_quote_filename ((char *)filename, SINGLE_MATCH, &c);
#endif
bash_directory_completion_hook (&f);
@@ -1992,6 +1992,8 @@ command_word_completion_function (hint_text, state)
temp = rl_variable_value ("completion-ignore-case");
igncase = RL_BOOLEAN_VARIABLE_VALUE (temp);
old_glob_ignore_case = glob_ignore_case;
if (glob_matches)
{
free (glob_matches);
@@ -2177,6 +2179,8 @@ globword:
{
if (state == 0)
{
rl_filename_completion_desired = 1;
glob_ignore_case = igncase;
glob_matches = shell_glob_filename (hint, 0);
glob_ignore_case = old_glob_ignore_case;
+13 -2
View File
@@ -1,6 +1,6 @@
/* common.c - utility functions for all builtins */
/* Copyright (C) 1987-2020 Free Software Foundation, Inc.
/* Copyright (C) 1987-2021 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -983,7 +983,7 @@ builtin_bind_variable (name, value, flags)
if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
v = bind_variable (name, value, flags);
else
v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0));
v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB);
#else /* !ARRAY_VARS */
v = bind_variable (name, value, flags);
#endif /* !ARRAY_VARS */
@@ -994,6 +994,17 @@ builtin_bind_variable (name, value, flags)
return v;
}
SHELL_VAR *
builtin_bind_var_to_int (name, val)
char *name;
intmax_t val;
{
SHELL_VAR *v;
v = bind_var_to_int (name, val, ASS_ALLOWALLSUB); /* XXX */
return v;
}
/* Like check_unbind_variable, but for use by builtins (only matters for
error messages). */
int
+1
View File
@@ -226,6 +226,7 @@ extern sh_builtin_func_t *this_shell_builtin;
extern sh_builtin_func_t *last_shell_builtin;
extern SHELL_VAR *builtin_bind_variable PARAMS((char *, char *, int));
extern SHELL_VAR *builtin_bind_var_to_int PARAMS((char *, intmax_t));
extern int builtin_unbind_variable PARAMS((const char *));
/* variables from evalfile.c */
+1 -1
View File
@@ -535,7 +535,7 @@ printf_builtin (list)
if (var && *var)
{
if (legal_identifier (var))
bind_var_to_int (var, tw);
bind_var_to_int (var, tw, 0);
else
{
sh_invalidid (var);
+2 -2
View File
@@ -214,7 +214,7 @@ wait_builtin (list)
status = wait_for_any_job (wflags, &pstat);
if (vname && status >= 0)
bind_var_to_int (vname, pstat.pid);
builtin_bind_var_to_int (vname, pstat.pid);
if (status < 0)
status = 127;
@@ -230,7 +230,7 @@ wait_builtin (list)
{
wait_for_background_pids (&pstat);
if (vname)
bind_var_to_int (vname, pstat.pid);
builtin_bind_var_to_int (vname, pstat.pid);
WAIT_RETURN (EXECUTION_SUCCESS);
}
+1 -1
View File
@@ -1434,7 +1434,7 @@ redir_varassign (redir, fd)
SHELL_VAR *v;
w = redir->redirector.filename;
v = bind_var_to_int (w->word, fd);
v = bind_var_to_int (w->word, fd, 0);
if (v == 0 || readonly_p (v) || noassign_p (v))
return BADVAR_REDIRECT;
+1 -1
View File
@@ -1,4 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
BUILD_DIR=/usr/local/build/chet/bash/bash-current
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+3 -2
View File
@@ -3488,14 +3488,15 @@ bind_int_variable (lhs, rhs, flags)
}
SHELL_VAR *
bind_var_to_int (var, val)
bind_var_to_int (var, val, flags)
char *var;
intmax_t val;
int flags;
{
char ibuf[INT_STRLEN_BOUND (intmax_t) + 1], *p;
p = fmtulong (val, 10, ibuf, sizeof (ibuf), 0);
return (bind_int_variable (var, p, 0));
return (bind_int_variable (var, p, flags));
}
/* Do a function binding to a variable. You pass the name and
+1 -1
View File
@@ -320,7 +320,7 @@ extern char *make_variable_value PARAMS((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_variable_value PARAMS((SHELL_VAR *, char *, int));
extern SHELL_VAR *bind_int_variable PARAMS((char *, char *, int));
extern SHELL_VAR *bind_var_to_int PARAMS((char *, intmax_t));
extern SHELL_VAR *bind_var_to_int PARAMS((char *, intmax_t, int));
extern int assign_in_env PARAMS((WORD_DESC *, int));