more minor changes for builtins and array subscript expansion; fix to `wait -n'

This commit is contained in:
Chet Ramey
2021-05-17 12:03:03 -04:00
parent 88bdb448b4
commit 7b024db83e
14 changed files with 106 additions and 25 deletions
+38
View File
@@ -10320,3 +10320,41 @@ subst.c
that are backslash-quoted in subscripts after word expansion.
skipsubscript treats them specially, so you have to quote them to
do things like `key='"' ; array[$key]=1 ; [[ -v array[$key] ]]'
5/16
----
builtins/wait.def
- wait_builtin: if we longjmp to wait_intr_buf, call unset_waitlist if
we have called set_waitlist (wflags & JWAIT_WAITING). Fixes bug with
wait -n interrupted by a trapped signal (not SIGINT) reported by
Jonas Alfredsson <jonas.alfredsson@protonmail.com>
jobs.c
- wait_sigint_cleanup: restore the old sigint handler before we longjmp
out by calling restore_sigint_handler()
5/17
----
builtins/read.def
- bind_read_variable: now takes an additional argument, flags to pass
to builtin_bind_variable; change callers
- SET_VFLAGS: set vflags and bindflags
- read_builtin: call SET_VFLAGS to set vflags and bindflags from each
word before calling valid_array_reference and bind_read_variable
builtins/common.c
- builtin_bind_variable: set vflags (for valid_array_reference) and
bindflags (for bind_variable/assign_array_element) separately for
clarity
arrayfunc.c
- assign_array_element: sanity check: make sure that the suubscript
returned by array_variable_name consumes the entire NAME, otherwise
flag it as a subscript error. This keeps things like
`KEY=' ]'; read assoc[$KEY] <<< hello' from assigning to incomplete
subscripts
builtins/printf.def
- printf_builtin: if LIST_OPTFLAGS includes W_ARRAYREF, set VA_NOEXPAND
in VFLAGS
+2 -1
View File
@@ -344,7 +344,8 @@ assign_array_element (name, value, flags)
(ASS_ALLOWALLSUB) we allow it. */
if (((isassoc == 0 || (flags & (ASS_NOEXPAND|ASS_ALLOWALLSUB)) == 0) &&
(ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']')) ||
(sublen <= 1))
(sublen <= 1) ||
(sub[sublen] != '\0')) /* sanity check */
{
free (vname);
err_badarraysub (name);
+11 -2
View File
@@ -971,6 +971,7 @@ builtin_help ()
/* */
/* **************************************************************** */
/* Assign NAME=VALUE, passing FLAGS to the assignment functions. */
SHELL_VAR *
builtin_bind_variable (name, value, flags)
char *name;
@@ -978,6 +979,7 @@ builtin_bind_variable (name, value, flags)
int flags;
{
SHELL_VAR *v;
int vflags, bindflags;
#if defined (ARRAY_VARS)
/* Callers are responsible for calling this with array references that have
@@ -985,10 +987,17 @@ builtin_bind_variable (name, value, flags)
Affected builtins: read, printf
To make this really work, needs additional downstream support, starting
with assign_array_element and array_variable_name. */
if (valid_array_reference (name, assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0) == 0)
vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
bindflags = flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB;
if (flags & ASS_NOEXPAND)
vflags |= VA_NOEXPAND;
if (flags & ASS_ONEWORD)
vflags |= VA_ONEWORD;
if (valid_array_reference (name, vflags) == 0)
v = bind_variable (name, value, flags);
else
v = assign_array_element (name, value, flags | (assoc_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB);
v = assign_array_element (name, value, bindflags);
#else /* !ARRAY_VARS */
v = bind_variable (name, value, flags);
#endif /* !ARRAY_VARS */
+1 -1
View File
@@ -404,7 +404,7 @@ declare_internal (list, local_var)
name = savestring (list->word->word);
wflags = list->word->flags;
#if defined (ARRAY_VARS)
assoc_noexpand = assoc_expand_once && (wflags & W_ASSIGNMENT);
assoc_noexpand = (assoc_expand_once || expand_once_flag) && (wflags & W_ASSIGNMENT);
#else
assoc_noexpand = 0;
#endif
+1 -1
View File
@@ -269,7 +269,7 @@ printf_builtin (list)
#if defined (ARRAY_VARS)
arrayflags = assoc_expand_once ? VA_NOEXPAND : 0;
if (assoc_expand_once && (list_optflags & W_ARRAYREF))
arrayflags |= VA_ONEWORD; /* XXX - VA_NOEXPAND? */
arrayflags |= VA_ONEWORD|VA_NOEXPAND;
retval = legal_identifier (vname) || valid_array_reference (vname, arrayflags);
#else
retval = legal_identifier (vname);
+29 -9
View File
@@ -128,7 +128,7 @@ static void set_eol_delim PARAMS((int));
static void reset_eol_delim PARAMS((char *));
static void set_readline_timeout PARAMS((sh_timer *t, time_t, long));
#endif
static SHELL_VAR *bind_read_variable PARAMS((char *, char *));
static SHELL_VAR *bind_read_variable PARAMS((char *, char *, int));
#if defined (HANDLE_MULTIBYTE)
static int read_mbchar PARAMS((int, char *, int, int, int));
#endif
@@ -190,6 +190,20 @@ read_builtin_timeout (fd)
: shtimer_select (read_timeout));
}
#if defined (ARRAY_VARS)
#define SET_VFLAGS(wordflags) \
do { \
vflags = assoc_expand_once ? VA_NOEXPAND : 0; \
bindflags = assoc_expand_once ? ASS_NOEXPAND : 0; \
if (assoc_expand_once && (wordflags & W_ARRAYREF)) \
vflags |= VA_ONEWORD|VA_NOEXPAND; \
if (vflags & VA_NOEXPAND) \
bindflags |= ASS_NOEXPAND; \
if (vflags & VA_ONEWORD) \
bindflags |= ASS_ONEWORD; \
} while (0)
#endif
/* Read the value of the shell variables whose names follow.
The reading is done from the current input stream, whatever
that may be. Successive words of the input line are assigned
@@ -221,6 +235,7 @@ read_builtin (list)
WORD_LIST *alist;
int vflags;
#endif
int bindflags;
#if defined (READLINE)
char *rlbuf, *itext;
int rlind;
@@ -362,9 +377,11 @@ read_builtin (list)
/* Convenience: check early whether or not the first of possibly several
variable names is a valid identifier, and bail early if so. */
#if defined (ARRAY_VARS)
vflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
if (list)
SET_VFLAGS (list->word->flags);
if (list && legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
#else
bindflags = 0;
if (list && legal_identifier (list->word->word) == 0)
#endif
{
@@ -952,6 +969,7 @@ assign_vars:
{
varname = list->word->word;
#if defined (ARRAY_VARS)
SET_VFLAGS (list->word->flags);
if (legal_identifier (varname) == 0 && valid_array_reference (varname, vflags) == 0)
#else
if (legal_identifier (varname) == 0)
@@ -975,16 +993,16 @@ assign_vars:
if (t && saw_escape)
{
t1 = dequote_string (t);
var = bind_read_variable (varname, t1);
var = bind_read_variable (varname, t1, bindflags);
free (t1);
}
else
var = bind_read_variable (varname, t ? t : "");
var = bind_read_variable (varname, t ? t : "", bindflags);
}
else
{
t = (char *)0;
var = bind_read_variable (varname, "");
var = bind_read_variable (varname, "", bindflags);
}
FREE (t);
@@ -1000,6 +1018,7 @@ assign_vars:
/* Now assign the rest of the line to the last variable argument. */
#if defined (ARRAY_VARS)
SET_VFLAGS (list->word->flags);
if (legal_identifier (list->word->word) == 0 && valid_array_reference (list->word->word, vflags) == 0)
#else
if (legal_identifier (list->word->word) == 0)
@@ -1036,11 +1055,11 @@ assign_vars:
if (saw_escape && input_string && *input_string)
{
t = dequote_string (input_string);
var = bind_read_variable (list->word->word, t);
var = bind_read_variable (list->word->word, t, bindflags);
free (t);
}
else
var = bind_read_variable (list->word->word, input_string ? input_string : "");
var = bind_read_variable (list->word->word, input_string ? input_string : "", bindflags);
if (var)
{
@@ -1057,12 +1076,13 @@ assign_vars:
}
static SHELL_VAR *
bind_read_variable (name, value)
bind_read_variable (name, value, flags)
char *name, *value;
int flags;
{
SHELL_VAR *v;
v = builtin_bind_variable (name, value, 0);
v = builtin_bind_variable (name, value, flags);
return (v == 0 ? v
: ((readonly_p (v) || noassign_p (v)) ? (SHELL_VAR *)NULL : v));
}
+8
View File
@@ -151,7 +151,13 @@ wait_builtin (list)
#if defined (ARRAY_VARS)
int arrayflags;
#if 0
arrayflags = assoc_expand_once ? (VA_NOEXPAND|VA_ONEWORD) : 0;
if (assoc_expand_once && (list_optflags & W_ARRAYREF))
arrayflags |= VA_ONEWORD|VA_NOEXPAND;
#else
arrayflags = 0; /* not yet without builtin_bind_var_to_int support */
#endif
if (legal_identifier (vname) == 0 && valid_array_reference (vname, arrayflags) == 0)
#else
if (legal_identifier (vname) == 0)
@@ -180,6 +186,8 @@ wait_builtin (list)
last_command_exit_signal = wait_signal_received;
status = 128 + wait_signal_received;
wait_sigint_cleanup ();
if (wflags & JWAIT_WAITING)
unset_waitlist ();
WAIT_RETURN (status);
}
+4 -3
View File
@@ -2902,7 +2902,7 @@ For example, a\fB{\fPd,c,b\fB}\fPe expands into `ade ace abe'.
.PP
A sequence expression takes the form
\fB{\fP\fIx\fP\fB..\fP\fIy\fP\fB[..\fP\fIincr\fP\fB]}\fP,
where \fIx\fP and \fIy\fP are either integers or single characters,
where \fIx\fP and \fIy\fP are either integers or single letters,
and \fIincr\fP, an optional increment, is an integer.
When integers are supplied, the expression expands to each number between
\fIx\fP and \fIy\fP, inclusive.
@@ -2911,10 +2911,11 @@ same width.
When either \fIx\fP or \fPy\fP begins with a zero, the shell
attempts to force all generated terms to contain the same number of digits,
zero-padding where necessary.
When characters are supplied, the expression expands to each character
When letters are supplied, the expression expands to each character
lexicographically between \fIx\fP and \fIy\fP, inclusive,
using the default C locale.
Note that both \fIx\fP and \fIy\fP must be of the same type.
Note that both \fIx\fP and \fIy\fP must be of the same type
(integer or letter).
When the increment is supplied, it is used as the difference between
each term. The default increment is 1 or \-1 as appropriate.
.PP
+4 -3
View File
@@ -2075,7 +2075,7 @@ ade ace abe
@end example
A sequence expression takes the form @code{@{@var{x}..@var{y}[..@var{incr}]@}},
where @var{x} and @var{y} are either integers or single characters,
where @var{x} and @var{y} are either integers or letters,
and @var{incr}, an optional increment, is an integer.
When integers are supplied, the expression expands to each number between
@var{x} and @var{y}, inclusive.
@@ -2084,10 +2084,11 @@ same width.
When either @var{x} or @var{y} begins with a zero, the shell
attempts to force all generated terms to contain the same number of digits,
zero-padding where necessary.
When characters are supplied, the expression expands to each character
When letters are supplied, the expression expands to each character
lexicographically between @var{x} and @var{y}, inclusive,
using the default C locale.
Note that both @var{x} and @var{y} must be of the same type.
Note that both @var{x} and @var{y} must be of the same type
(integer or letter).
When the increment is supplied, it is used as the difference between
each term. The default increment is 1 or -1 as appropriate.
+1
View File
@@ -2741,6 +2741,7 @@ wait_sigint_cleanup ()
{
queue_sigchld = 0;
waiting_for_child = 0;
restore_sigint_handler ();
}
static void
+1 -1
View File
@@ -64,7 +64,7 @@
/* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef RETSIGTYPE SigHandler ();
typedef RETSIGTYPE SigHandler (int);
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
+1
View File
@@ -56,6 +56,7 @@
#define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */
#define ASS_NOINVIS 0x0400 /* don't resolve local invisible variables */
#define ASS_ALLOWALLSUB 0x0800 /* allow * and @ as associative array keys */
#define ASS_ONEWORD 0x1000 /* don't check array subscripts, assume higher level has done that */
/* Flags for the string extraction functions. */
#define SX_NOALLOC 0x0001 /* just skip; don't return substring */
+4 -3
View File
@@ -525,6 +525,7 @@ unary_test (op, arg, flags)
struct stat stat_buf;
struct timespec mtime, atime;
SHELL_VAR *v;
int aflags;
switch (op[1])
{
@@ -632,16 +633,16 @@ unary_test (op, arg, flags)
case 'v':
#if defined (ARRAY_VARS)
if (valid_array_reference (arg, assoc_expand_once ? VA_NOEXPAND : 0))
aflags = assoc_expand_once ? AV_NOEXPAND : 0;
if (valid_array_reference (arg, aflags))
{
char *t;
int rtype, ret, aflags;
int rtype, ret;
/* Let's assume that this has already been expanded once. */
/* XXX - TAG:bash-5.2 fix with corresponding fix to execute_cmd.c:
execute_cond_node() that passes TEST_ARRAYEXP in FLAGS */
aflags = assoc_expand_once ? AV_NOEXPAND : 0;
#if 0
/* TAG:bash-5.2 */
if (shell_compatibility_level > 51)
+1 -1
View File
@@ -745,7 +745,7 @@ argv[1] = <b+a>
declare -A A=([$'\t']="2" [" "]="2" )
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
./array27.sub: line 52: A[]]: bad array subscript
./array27.sub: line 52: read: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
./array27.sub: line 60: printf: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )