mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-21 12:57:58 +02:00
commit bash-20200221 snapshot
This commit is contained in:
+106
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 ...] */
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user