mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-24 22:37:59 +02:00
more minor changes for builtins and array subscript expansion; fix to `wait -n'
This commit is contained in:
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -2741,6 +2741,7 @@ wait_sigint_cleanup ()
|
||||
{
|
||||
queue_sigchld = 0;
|
||||
waiting_for_child = 0;
|
||||
restore_sigint_handler ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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" )
|
||||
|
||||
Reference in New Issue
Block a user