commit bash-20200221 snapshot

This commit is contained in:
Chet Ramey
2020-02-24 10:41:37 -05:00
parent 89d788fb01
commit 0df4ddca3f
19 changed files with 412 additions and 109 deletions
+106
View File
@@ -7384,3 +7384,109 @@ execute_cmd.c
parse.y
- special_case_tokens: allow `time -- command'
2/21
----
subst.c
- get_var_and_type: if an unset variable (not an array) is supplied
with the `[@]' subscript, don't return "". Fix to bug reported by
Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>;
original bug introduced 7/29/2018
- array_transform: take a STARSUB argument instead of VARNAME, since
we've already computed what kind of index the array reference uses
in get_var_and_type, and passing VARNAME to figure out the index
type doesn't do the right thing when we're using indirect variable
expansion. Fixes bug reported by
Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
- array_remove_pattern: take the same new STARSUB argument for the
same reason
- parameter_brace_transform,parameter_brace_remove_pattern: change
callers to pass STARSUB instead of VARNAME
2/22
----
execute_cmd.c
- fix_assignment_words: if an assignment is supplied to a builtin that
creates or modifies local variables while a function is executing,
set the W_FORCELOCAL flag for that word in addition to any of the
various assignment flags
subst.c
- shell_expand_word_list: while processing a list of assignments that
are arguments to a builtin that creates or modifies local variables,
if make_internal_declare fails while attempting to create the local
variable (or give it attributes), skip attempting the assignment but
otherwise do not make this a fatal error. This results in two error
messages: one to create the variable or modify its attributes, and
one while attempting to assign the value, but the errors to not
cause the function to return immediately. Fixes inconsistency
reported by Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
2/23
----
trap.c
- first_pending_trap: generalize into first_pending_trap and
next_pending_trap
wait.def
- wait_builtin: close up the trapped-signal-arrives hole a little more
by looking for a signal that arrived between the last check for
pending traps and setting wait_intr_flag and behaving as if it
arrived while wait was executing. Use first_pending_trap and
next_pending_trap to find a pending trap that is not SIGCHLD
trap.c
- trap_handler: longjmp to wait_intr_buf unconditionally if
wait_intr_flag is set; don't bother with interrupt_immediately any
more
variables.c
- all_local_variables: now takes an arg saying whether to restrict
return value to visible variables or return all local variables,
even those that are unset (the new default)
- visible_variable_in_context: new function, restricts return values
to set local variables in the current context; variable_in_context
now returns all local variables in the current context, even the
unset ones
variables.h
- all_local_variables: change extern function declaration
builtins/setattr.def
- show_local_var_attributes: show all local variables at the current
variable context, including unset ones, and their attributes
- show_localname_attributes: show attributes for NAME as long as NAME
resolves to a local variable at the current variable context, even
if NAME is unset
builtins/common.h
- show_local_var_attributes, show_localname_attributes: new extern
declarations
builtins/declare.def
- declare_internal: allow `-p' option for `local' builtin
- declare_internal: if `local' is supplied without options, or with
the `-p' option, but no variable name arguments, display all local
variables at the current variable context by calling
show_local_var_attributes
- declare_internal: if `local -p' is supplied with variable name
arguments, call show_localname_attributes to display the attributes
for that name if it resolves to a local variable at the current
variable context. Fixes issue reported by
pepa65 <solusos@passchier.net>
subst.c
- array_var_assignment: if VAR is unset, print the declare command
without the assignment statement, just with the attributes
- array_transform: special-case the 'a' attribute and return the
attribute string even if the array variable is unset. Feature request
from Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
- parameter_brace_transform: if asked to display the attributes and
value ('A') of an unset variable, make sure we pass the variable, if
it exists with attributes but without a value, to string_transform
- string_transform: if we don't have a value but the operator is 'A',
pass the variable through to string_var_assignment
- string_var_assignment: if we have an unset variable with attributes,
return a declare command that just sets the attributes. Feature request
from Arfrever Frehtes Taifersar Arahesis <arfrever.fta@gmail.com>
+1
View File
@@ -1212,6 +1212,7 @@ tests/new-exp9.sub f
tests/new-exp10.sub f
tests/new-exp11.sub f
tests/new-exp12.sub f
tests/new-exp13.sub f
tests/new-exp.right f
tests/nquote.tests f
tests/nquote.right f
+2
View File
@@ -187,8 +187,10 @@ extern int describe_command PARAMS((char *, int));
/* Functions from setattr.def */
extern int set_or_show_attributes PARAMS((WORD_LIST *, int, int));
extern int show_all_var_attributes PARAMS((int, int));
extern int show_local_var_attributes PARAMS((int, int));
extern int show_var_attributes PARAMS((SHELL_VAR *, int, int));
extern int show_name_attributes PARAMS((char *, int));
extern int show_localname_attributes PARAMS((char *, int));
extern int show_func_attributes PARAMS((char *, int));
extern void set_var_attribute PARAMS((char *, int, int));
extern int var_attribute_string PARAMS((SHELL_VAR *, int, char *));
+4 -15
View File
@@ -202,7 +202,7 @@ declare_internal (list, local_var)
return (EX_USAGE);
#endif
case 'p':
if (local_var == 0)
/* if (local_var == 0) */
pflag++;
break;
case 'F':
@@ -271,20 +271,7 @@ declare_internal (list, local_var)
/* Show local variables defined at this context level if this is
the `local' builtin. */
if (local_var)
{
register SHELL_VAR **vlist;
register int i;
vlist = all_local_variables ();
if (vlist)
{
for (i = 0; vlist[i]; i++)
print_assignment (vlist[i]);
free (vlist);
}
}
show_local_var_attributes (0, nodefs); /* XXX - fix up args later */
else if (pflag && (flags_on == 0 || flags_on == att_function))
show_all_var_attributes (flags_on == 0, nodefs);
else if (flags_on == 0)
@@ -301,6 +288,8 @@ declare_internal (list, local_var)
{
if (flags_on & att_function)
pflag = show_func_attributes (list->word->word, nodefs);
else if (local_var)
pflag = show_localname_attributes (list->word->word, nodefs);
else
pflag = show_name_attributes (list->word->word, nodefs);
if (pflag)
+43 -5
View File
@@ -371,6 +371,30 @@ show_all_var_attributes (v, nodefs)
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
/* Show all local variable variables with their attributes. This shows unset
local variables (all_local_variables called with 0 argment). */
int
show_local_var_attributes (v, nodefs)
int v, nodefs;
{
SHELL_VAR **variable_list, *var;
int any_failed;
register int i;
variable_list = all_local_variables (0);
if (variable_list == 0)
return (EXECUTION_SUCCESS);
for (i = any_failed = 0; var = variable_list[i]; i++)
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
if (any_failed = sh_chkwrite (any_failed))
break;
}
free (variable_list);
return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
int
var_attribute_string (var, pattr, flags)
SHELL_VAR *var;
@@ -504,13 +528,27 @@ show_name_attributes (name, nodefs)
{
SHELL_VAR *var;
#if 0
var = find_variable_tempenv (name);
#else
var = find_variable_noref (name);
#endif
if (var /* && invisible_p (var) == 0 */)
if (var) /* show every variable with attributes, even unset ones */
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
}
else
return (1);
}
int
show_localname_attributes (name, nodefs)
char *name;
int nodefs;
{
SHELL_VAR *var;
var = find_variable_noref (name);
if (var && local_p (var) && var->context == variable_context) /* show every variable with attributes, even unset ones */
{
show_var_attributes (var, READONLY_OR_EXPORT, nodefs);
return (0);
+15
View File
@@ -176,6 +176,21 @@ wait_builtin (list)
WAIT_RETURN (status);
}
opt = first_pending_trap ();
#if defined (SIGCHLD)
/* We special case SIGCHLD when not in posix mode because we don't break
out of the wait even when the signal is trapped; we run the trap after
the wait completes. See how it's handled in jobs.c:waitchld(). */
if (opt == SIGCHLD && posixly_correct == 0)
opt = next_pending_trap (opt+1);
#endif
if (opt != -1)
{
last_command_exit_signal = wait_signal_received = opt;
status = opt + 128;
WAIT_RETURN (status);
}
/* We support jobs or pids.
wait <pid-or-job> [pid-or-job ...] */
+31 -30
View File
@@ -73,36 +73,37 @@ enum command_type { cm_for, cm_case, cm_while, cm_if, cm_simple, cm_select,
cm_arith, cm_cond, cm_arith_for, cm_subshell, cm_coproc };
/* Possible values for the `flags' field of a WORD_DESC. */
#define W_HASDOLLAR 0x000001 /* Dollar sign present. */
#define W_QUOTED 0x000002 /* Some form of quote character is present. */
#define W_ASSIGNMENT 0x000004 /* This word is a variable assignment. */
#define W_SPLITSPACE 0x000008 /* Split this word on " " regardless of IFS */
#define W_NOSPLIT 0x000010 /* Do not perform word splitting on this word because ifs is empty string. */
#define W_NOGLOB 0x000020 /* Do not perform globbing on this word. */
#define W_NOSPLIT2 0x000040 /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */
#define W_TILDEEXP 0x000080 /* Tilde expand this assignment word */
#define W_DOLLARAT 0x000100 /* $@ and its special handling */
#define W_DOLLARSTAR 0x000200 /* $* and its special handling */
#define W_NOCOMSUB 0x000400 /* Don't perform command substitution on this word */
#define W_ASSIGNRHS 0x000800 /* Word is rhs of an assignment statement */
#define W_NOTILDE 0x001000 /* Don't perform tilde expansion on this word */
#define W_ITILDE 0x002000 /* Internal flag for word expansion */
#define W_EXPANDRHS 0x004000 /* Expanding word in ${paramOPword} */
#define W_COMPASSIGN 0x008000 /* Compound assignment */
#define W_ASSNBLTIN 0x010000 /* word is a builtin command that takes assignments */
#define W_ASSIGNARG 0x020000 /* word is assignment argument to command */
#define W_HASQUOTEDNULL 0x040000 /* word contains a quoted null character */
#define W_DQUOTE 0x080000 /* word should be treated as if double-quoted */
#define W_NOPROCSUB 0x100000 /* don't perform process substitution */
#define W_SAWQUOTEDNULL 0x200000 /* word contained a quoted null that was removed */
#define W_ASSIGNASSOC 0x400000 /* word looks like associative array assignment */
#define W_ASSIGNARRAY 0x800000 /* word looks like a compound indexed array assignment */
#define W_ARRAYIND 0x1000000 /* word is an array index being expanded */
#define W_ASSNGLOBAL 0x2000000 /* word is a global assignment to declare (declare/typeset -g) */
#define W_NOBRACE 0x4000000 /* Don't perform brace expansion */
#define W_COMPLETE 0x8000000 /* word is being expanded for completion */
#define W_CHKLOCAL 0x10000000 /* check for local vars on assignment */
#define W_NOASSNTILDE 0x20000000 /* don't do tilde expansion like an assignment statement */
#define W_HASDOLLAR (1 << 0) /* Dollar sign present. */
#define W_QUOTED (1 << 1) /* Some form of quote character is present. */
#define W_ASSIGNMENT (1 << 2) /* This word is a variable assignment. */
#define W_SPLITSPACE (1 << 3) /* Split this word on " " regardless of IFS */
#define W_NOSPLIT (1 << 4) /* Do not perform word splitting on this word because ifs is empty string. */
#define W_NOGLOB (1 << 5) /* Do not perform globbing on this word. */
#define W_NOSPLIT2 (1 << 6) /* Don't split word except for $@ expansion (using spaces) because context does not allow it. */
#define W_TILDEEXP (1 << 7) /* Tilde expand this assignment word */
#define W_DOLLARAT (1 << 8) /* $@ and its special handling -- UNUSED */
#define W_DOLLARSTAR (1 << 9) /* $* and its special handling -- UNUSED */
#define W_NOCOMSUB (1 << 10) /* Don't perform command substitution on this word */
#define W_ASSIGNRHS (1 << 11) /* Word is rhs of an assignment statement */
#define W_NOTILDE (1 << 12) /* Don't perform tilde expansion on this word */
#define W_ITILDE (1 << 13) /* Internal flag for word expansion */
#define W_EXPANDRHS (1 << 14) /* Expanding word in ${paramOPword} */
#define W_COMPASSIGN (1 << 15) /* Compound assignment */
#define W_ASSNBLTIN (1 << 16) /* word is a builtin command that takes assignments */
#define W_ASSIGNARG (1 << 17) /* word is assignment argument to command */
#define W_HASQUOTEDNULL (1 << 18) /* word contains a quoted null character */
#define W_DQUOTE (1 << 19) /* word should be treated as if double-quoted */
#define W_NOPROCSUB (1 << 20) /* don't perform process substitution */
#define W_SAWQUOTEDNULL (1 << 21) /* word contained a quoted null that was removed */
#define W_ASSIGNASSOC (1 << 22) /* word looks like associative array assignment */
#define W_ASSIGNARRAY (1 << 23) /* word looks like a compound indexed array assignment */
#define W_ARRAYIND (1 << 24) /* word is an array index being expanded */
#define W_ASSNGLOBAL (1 << 25) /* word is a global assignment to declare (declare/typeset -g) */
#define W_NOBRACE (1 << 26) /* Don't perform brace expansion */
#define W_COMPLETE (1 << 27) /* word is being expanded for completion */
#define W_CHKLOCAL (1 << 28) /* check for local vars on assignment */
#define W_NOASSNTILDE (1 << 29) /* don't do tilde expansion like an assignment statement */
#define W_FORCELOCAL (1 << 30) /* force assignments to be to local variables, non-fatal on assignment errors */
/* Flags for the `pflags' argument to param_expand() and various
parameter_brace_expand_xxx functions; also used for string_list_dollar_at */
+2 -4
View File
@@ -4120,10 +4120,8 @@ fix_assignment_words (words)
an existing local variable, if there is one. */
if (b && ((b->flags & (ASSIGNMENT_BUILTIN|LOCALVAR_BUILTIN)) == ASSIGNMENT_BUILTIN))
w->word->flags |= W_ASSNGLOBAL|W_CHKLOCAL;
#if 0
else if (b && (b->flags & ASSIGNMENT_BUILTIN) && (b->flags & LOCALVAR_BUILTIN))
w->word->flags |= W_CHKLOCAL;
#endif
else if (b && (b->flags & ASSIGNMENT_BUILTIN) && (b->flags & LOCALVAR_BUILTIN) && variable_context)
w->word->flags |= W_FORCELOCAL;
}
#if defined (ARRAY_VARS)
/* Note that we saw an associative array option to a builtin that takes
+2 -4
View File
@@ -2739,8 +2739,7 @@ wait_sigint_handler (sig)
if (interrupt_immediately ||
(this_shell_builtin && this_shell_builtin == wait_builtin))
{
last_command_exit_value = 128+SIGINT;
set_pipestatus_from_exit (last_command_exit_value);
set_exit_status (128+SIGINT);
restore_sigint_handler ();
/* If we got a SIGINT while in `wait', and SIGINT is trapped, do
what POSIX.2 says (see builtins/wait.def for more info). */
@@ -2774,8 +2773,7 @@ wait_sigint_handler (sig)
wait_sigint_received = 1;
else
{
last_command_exit_value = 128+SIGINT;
set_pipestatus_from_exit (last_command_exit_value);
set_exit_status (128+SIGINT);
restore_sigint_handler ();
kill (getpid (), SIGINT);
}
+69 -41
View File
@@ -285,7 +285,7 @@ static char *variable_remove_pattern PARAMS((char *, char *, int, int));
static char *list_remove_pattern PARAMS((WORD_LIST *, char *, int, int, int));
static char *parameter_list_remove_pattern PARAMS((int, char *, int, int));
#ifdef ARRAY_VARS
static char *array_remove_pattern PARAMS((SHELL_VAR *, char *, int, char *, int));
static char *array_remove_pattern PARAMS((SHELL_VAR *, char *, int, int, int));
#endif
static char *parameter_brace_remove_pattern PARAMS((char *, char *, int, char *, int, int, int));
@@ -298,7 +298,7 @@ static char *string_transform PARAMS((int, SHELL_VAR *, char *));
static char *list_transform PARAMS((int, SHELL_VAR *, WORD_LIST *, int, int));
static char *parameter_list_transform PARAMS((int, int, int));
#if defined ARRAY_VARS
static char *array_transform PARAMS((int, SHELL_VAR *, char *, int));
static char *array_transform PARAMS((int, SHELL_VAR *, int, int));
#endif
static char *parameter_brace_transform PARAMS((char *, char *, int, char *, int, int, int, int));
@@ -523,7 +523,12 @@ dump_word_flags (flags)
f &= ~W_CHKLOCAL;
fprintf (stderr, "W_CHKLOCAL%s", f ? "|" : "");
}
if (f & W_FORCELOCAL)
{
f &= ~W_FORCELOCAL;
fprintf (stderr, "W_FORCELOCAL%s", f ? "|" : "");
}
fprintf (stderr, "\n");
fflush (stderr);
}
@@ -5224,11 +5229,11 @@ parameter_list_remove_pattern (itype, pattern, patspec, quoted)
#if defined (ARRAY_VARS)
static char *
array_remove_pattern (var, pattern, patspec, varname, quoted)
array_remove_pattern (var, pattern, patspec, starsub, quoted)
SHELL_VAR *var;
char *pattern;
int patspec;
char *varname; /* so we can figure out how it's indexed */
int starsub; /* so we can figure out how it's indexed */
int quoted;
{
ARRAY *a;
@@ -5238,14 +5243,9 @@ array_remove_pattern (var, pattern, patspec, varname, quoted)
WORD_LIST *list;
SHELL_VAR *v;
/* compute itype from varname here */
v = array_variable_part (varname, 0, &ret, 0);
v = var; /* XXX - for now */
/* XXX */
if (v && invisible_p (v))
return ((char *)NULL);
itype = ret[0];
itype = starsub ? '*' : '@';
a = (v && array_p (v)) ? array_cell (v) : 0;
h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
@@ -5316,7 +5316,7 @@ parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flag
break;
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
temp1 = array_remove_pattern (v, pattern, patspec, starsub, quoted);
if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
{
val = quote_escapes (temp1);
@@ -7560,7 +7560,7 @@ get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
vtype = VT_VARIABLE;
*varp = v;
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
*valp = value ? dequote_string (value) : savestring ("");
*valp = value ? dequote_string (value) : (char *)NULL;
else
*valp = value ? dequote_escapes (value) : (char *)NULL;
}
@@ -7612,10 +7612,15 @@ string_var_assignment (v, s)
char flags[MAX_ATTRIBUTES], *ret, *val;
int i;
val = sh_quote_reusable (s, 0);
val = (v && (invisible_p (v) || var_isset (v) == 0)) ? (char *)NULL : sh_quote_reusable (s, 0);
i = var_attribute_string (v, 0, flags);
ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16 + MAX_ATTRIBUTES);
if (i > 0)
if (i == 0 && val == 0)
return (char *)NULL;
ret = (char *)xmalloc (i + STRLEN (val) + strlen (v->name) + 16 + MAX_ATTRIBUTES);
if (i > 0 && val == 0)
sprintf (ret, "declare -%s %s", flags, v->name);
else if (i > 0)
sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
else
sprintf (ret, "%s=%s", v->name, val);
@@ -7636,7 +7641,10 @@ array_var_assignment (v, itype, quoted)
return (char *)NULL;
val = array_p (v) ? array_to_assign (array_cell (v), 0)
: assoc_to_assign (assoc_cell (v), 0);
if (val == 0)
if (val == 0 && (invisible_p (v) || var_isset (v) == 0))
; /* placeholder */
else if (val == 0)
{
val = (char *)xmalloc (3);
val[0] = LPAREN;
@@ -7650,8 +7658,11 @@ array_var_assignment (v, itype, quoted)
val = ret;
}
i = var_attribute_string (v, 0, flags);
ret = (char *)xmalloc (i + strlen (val) + strlen (v->name) + 16);
sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
ret = (char *)xmalloc (i + STRLEN (val) + strlen (v->name) + 16);
if (val)
sprintf (ret, "declare -%s %s=%s", flags, v->name, val);
else
sprintf (ret, "declare -%s %s", flags, v->name);
free (val);
return ret;
}
@@ -7683,7 +7694,9 @@ string_transform (xc, v, s)
char *ret, flags[MAX_ATTRIBUTES], *t;
int i;
if (((xc == 'A' || xc == 'a') && v == 0) || (xc != 'a' && s == 0))
if (((xc == 'A' || xc == 'a') && v == 0))
return (char *)NULL;
else if (xc != 'a' && xc != 'A' && s == 0)
return (char *)NULL;
switch (xc)
@@ -7770,10 +7783,10 @@ parameter_list_transform (xc, itype, quoted)
#if defined (ARRAY_VARS)
static char *
array_transform (xc, var, varname, quoted)
array_transform (xc, var, starsub, quoted)
int xc;
SHELL_VAR *var;
char *varname; /* so we can figure out how it's indexed */
int starsub; /* so we can figure out how it's indexed */
int quoted;
{
ARRAY *a;
@@ -7783,21 +7796,26 @@ array_transform (xc, var, varname, quoted)
WORD_LIST *list;
SHELL_VAR *v;
/* compute itype from varname here */
v = array_variable_part (varname, 0, &ret, 0);
v = var; /* XXX - for now */
/* XXX */
if (v && invisible_p (v))
return ((char *)NULL);
itype = ret[0];
itype = starsub ? '*' : '@';
if (xc == 'A')
return (array_var_assignment (v, itype, quoted));
/* special case for unset arrays and attributes */
if (xc == 'a' && (invisible_p (v) || var_isset (v) == 0))
{
char flags[MAX_ATTRIBUTES];
int i;
i = var_attribute_string (v, 0, flags);
return ((i > 0) ? savestring (flags) : (char *)NULL);
}
a = (v && array_p (v)) ? array_cell (v) : 0;
h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
if (list == 0)
return ((char *)NULL);
@@ -7815,7 +7833,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, pflags, fl
char *xform;
int rtype, quoted, pflags, flags;
{
int vtype, xc;
int vtype, xc, starsub;
char *temp1, *val, *oname;
SHELL_VAR *v;
@@ -7847,13 +7865,16 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, pflags, fl
return &expand_param_error;
}
starsub = vtype & VT_STARSUB;
vtype &= ~VT_STARSUB;
/* If we are asked to display the attributes of an unset variable, V will
be NULL after the call to get_var_and_type. Double-check here. */
if (xc == 'a' && vtype == VT_VARIABLE && varname && v == 0)
if ((xc == 'a' || xc == 'A') && vtype == VT_VARIABLE && varname && v == 0)
v = find_variable (varname);
temp1 = (char *)NULL; /* shut up gcc */
switch (vtype & ~VT_STARSUB)
switch (vtype)
{
case VT_VARIABLE:
case VT_ARRAYMEMBER:
@@ -7871,7 +7892,7 @@ parameter_brace_transform (varname, value, ind, xform, rtype, quoted, pflags, fl
break;
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
temp1 = array_transform (xc, v, varname, quoted);
temp1 = array_transform (xc, v, starsub, quoted);
if (temp1 && quoted == 0 && ifs_is_null)
{
/* Posix interp 888 */
@@ -11479,7 +11500,7 @@ shell_expand_word_list (tlist, eflags)
{
int t;
char opts[16];
int opti;
int opti, skip;
opti = 0;
if (tlist->word->flags & (W_ASSIGNASSOC|W_ASSNGLOBAL|W_CHKLOCAL|W_ASSIGNARRAY))
@@ -11544,21 +11565,28 @@ shell_expand_word_list (tlist, eflags)
}
opts[opti] = '\0';
skip = 0;
if (opti > 0)
{
t = make_internal_declare (tlist->word->word, opts, wcmd ? wcmd->word->word : (char *)0);
if (t != EXECUTION_SUCCESS)
{
last_command_exit_value = t;
exp_jump_to_top_level (DISCARD);
if (tlist->word->flags & W_FORCELOCAL) /* non-fatal error */
skip = 1;
else
exp_jump_to_top_level (DISCARD);
}
}
t = do_word_assignment (tlist->word, 0);
if (t == 0)
if (skip == 0)
{
last_command_exit_value = EXECUTION_FAILURE;
exp_jump_to_top_level (DISCARD);
t = do_word_assignment (tlist->word, 0);
if (t == 0)
{
last_command_exit_value = EXECUTION_FAILURE;
exp_jump_to_top_level (DISCARD);
}
}
/* Now transform the word as ksh93 appears to do and go on */
-1
View File
@@ -1,5 +1,4 @@
BUILD_DIR=/usr/local/build/bash/bash-current
#BUILD_DIR=/fs2/chet/scratch/bash-20200214.fifo
THIS_SH=$BUILD_DIR/bash
PATH=$PATH:$BUILD_DIR
+32 -1
View File
@@ -670,7 +670,38 @@ prependå
HELLO;1 foo;2 foo;
PASS;1 foo;2 foo;
after: PASS
'zzz'
'zzz'
declare -rl VAR1
declare -rl VAR1
declare -rl VAR1
declare -rl VAR1
rl
rl
rl
rl
declare -arl VAR3
declare -arl VAR3
declare -arl VAR3
declare -arl VAR3
arl
arl
arl
arl
one
one
'aaa'
'aaa' 'bbb'
./new-exp13.sub: line 56: aaa bbb: invalid variable name
aaa bbb
0 1
'aaa'
'aaa' 'bbb'
'aaa' 'bbb'
'aaa' 'bbb'
a bbb
aaa bb
argv[1] = </>
argv[1] = </>
./new-exp.tests: line 640: ABXD: parameter unset
./new-exp.tests: line 643: ABXD: parameter unset
+3
View File
@@ -620,6 +620,9 @@ ${THIS_SH} ./new-exp11.sub
# indirect expansion with arrays and local variables
${THIS_SH} ./new-exp12.sub
# more indirect expansion and parameter transformation issues
${THIS_SH} ./new-exp13.sub
# problems with stray CTLNUL in bash-4.0-alpha
unset a
a=/a
+72
View File
@@ -0,0 +1,72 @@
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
declare -lr VAR1
declare -lr VAR2=zzz
declare -alr VAR3
var=VAR2
echo ${!var@Q}
echo ${VAR2@Q}
echo ${VAR1@A}
echo ${VAR1[@]@A}
echo "${VAR1@A}"
echo "${VAR1[@]@A}"
echo "${VAR1[@]@a}"
echo ${VAR1[@]@a}
echo "${VAR1@a}"
echo ${VAR1@a}
echo ${VAR3@A}
echo ${VAR3[@]@A}
echo "${VAR3@A}"
echo "${VAR3[@]@A}"
echo "${VAR3[@]@a}"
echo ${VAR3[@]@a}
echo "${VAR3@a}"
echo ${VAR3@a}
var=one
echo ${var}
echo ${var[@]}
VAR4=(aaa bbb)
varname=VAR4
echo ${!varname[@]@Q}
echo ${VAR4[@]@Q}
echo ${!VAR4[@]@Q}
echo ${VAR4[@]}
echo ${!VAR4[@]}
VAR5=(aaa bbb)
varname="VAR5[@]"
echo "${VAR5@Q}"
echo "${VAR5[@]@Q}"
echo "${!varname@Q}"
echo "${!varname[@]@Q}"
# caused core dumps through bash-5.0
echo "${!varname##aa}"
echo "${!varname[@]%b}"
+5 -2
View File
@@ -22,8 +22,8 @@ AVAR
AVAR
42
/bin:/usr/bin:/usr/local/bin:.
avar=([0]="/bin:/usr/bin:/usr/local/bin:.")
z=yy
declare -a avar=([0]="/bin:/usr/bin:/usr/local/bin:.")
declare -- z="yy"
42
declare -i ivar="10"
unset
@@ -61,6 +61,7 @@ g: v = , w =
f: v = , w =
FIN: v = two, w = one
./varenv4.sub: line 67: bbb: unique: cannot convert indexed to associative array
./varenv4.sub: line 67: declare: unique: cannot convert indexed to associative array
after bbb: 1
declare -Ar FOOBAR=([foo]="bar" )
declare -Ar FOOBAR=([foo]="bar" )
@@ -182,6 +183,8 @@ declare -a var=()
./varenv14.sub: line 25: warning: var: cannot inherit value from incompatible type
declare -a var=()
./varenv14.sub: line 31: f: var: cannot convert indexed to associative array
./varenv14.sub: line 31: declare: var: cannot convert indexed to associative array
declare -a var=([0]="12")
declare -a a=([0]="X")
declare -a s=([0]="X")
declare -a a=([0]="X" [1]="Y")
+9 -3
View File
@@ -487,7 +487,7 @@ trap_handler (sig)
if (this_shell_builtin && (this_shell_builtin == wait_builtin))
{
wait_signal_received = sig;
if (interrupt_immediately && wait_intr_flag)
if (/* interrupt_immediately && */wait_intr_flag)
sh_longjmp (wait_intr_buf, 1);
}
@@ -509,16 +509,22 @@ trap_handler (sig)
}
int
first_pending_trap ()
next_pending_trap (start)
{
register int i;
for (i = 1; i < NSIG; i++)
for (i = start; i < NSIG; i++)
if (pending_traps[i])
return i;
return -1;
}
int
first_pending_trap ()
{
return (next_pending_trap (1));
}
/* Return > 0 if any of the "real" signals (not fake signals like EXIT) are
trapped. */
int
+1
View File
@@ -115,6 +115,7 @@ extern void set_signal_hard_ignored PARAMS((int));
extern void set_signal_ignored PARAMS((int));
extern int signal_in_progress PARAMS((int));
extern int next_pending_trap PARAMS((int));
extern int first_pending_trap PARAMS((void));
extern int any_signals_trapped PARAMS((void));
extern void check_signals PARAMS((void));
+14 -2
View File
@@ -295,6 +295,7 @@ static int visible_var PARAMS((SHELL_VAR *));
static int visible_and_exported PARAMS((SHELL_VAR *));
static int export_environment_candidate PARAMS((SHELL_VAR *));
static int local_and_exported PARAMS((SHELL_VAR *));
static int visible_variable_in_context PARAMS((SHELL_VAR *));
static int variable_in_context PARAMS((SHELL_VAR *));
#if defined (ARRAY_VARS)
static int visible_array_vars PARAMS((SHELL_VAR *));
@@ -4488,12 +4489,20 @@ local_exported_variables ()
static int
variable_in_context (var)
SHELL_VAR *var;
{
return (local_p (var) && var->context == variable_context);
}
static int
visible_variable_in_context (var)
SHELL_VAR *var;
{
return (invisible_p (var) == 0 && local_p (var) && var->context == variable_context);
}
SHELL_VAR **
all_local_variables ()
all_local_variables (visible_only)
int visible_only;
{
VARLIST *vlist;
SHELL_VAR **ret;
@@ -4514,7 +4523,10 @@ all_local_variables ()
vlist = vlist_alloc (HASH_ENTRIES (vc->table));
flatten (vc->table, variable_in_context, vlist, 0);
if (visible_only)
flatten (vc->table, visible_variable_in_context, vlist, 0);
else
flatten (vc->table, variable_in_context, vlist, 0);
ret = vlist->list;
free (vlist);
+1 -1
View File
@@ -300,7 +300,7 @@ extern SHELL_VAR **all_visible_variables PARAMS((void));
extern SHELL_VAR **all_visible_functions PARAMS((void));
extern SHELL_VAR **all_exported_variables PARAMS((void));
extern SHELL_VAR **local_exported_variables PARAMS((void));
extern SHELL_VAR **all_local_variables PARAMS((void));
extern SHELL_VAR **all_local_variables PARAMS((int));
#if defined (ARRAY_VARS)
extern SHELL_VAR **all_array_variables PARAMS((void));
#endif