- expand_string_for_pat: make sure we preserve the value of
expand_no_split_dollar_star instead of just unconditionally setting
it back to 0 in case it was 1 before this function was called
+
+ 8/6
+ ---
+array.c
+ - array_modcase: rewrite to work in terms of a WORD_LIST * and call
+ string_list_pos_params on the result to be consistent with the
+ expansions of ${@,,} and ${*,,}
+
+assoc.c
+ - assoc_modcase: rewrite to work in terms of a WORD_LIST * and call
+ string_list_pos_params on the result to be consistent with the
+ expansions of ${@,,} and ${*,,}
+
+subst.c
+ - parameter_brace_casemod: change how return value of {array,assoc}_modcase
+ is treated to make it identical to pos_params_modcase, since they
+ all call string_list_pos_params now
+
+ 8/8
+ ---
+builtins/declare.def
+ - declare_internal: if we are making local variables, and not dealing
+ with the nameref attribute, make sure that any nameref variable we
+ followed when resolving the name given was at the same variable
+ context. If not, we just want to make or use a local variable with
+ the name passed; if so, we want to use the nameref value as the
+ variable name. Report from Grisha Levit <grishalevit@gmail.com>
+
+ 8/9
+ ---
+configure.ac
+ - globasciiranges: RRI now on by default, must be turned off explicitly
+ at configure time or runtime with `shopt -u globasciiranges'
tests/array23.sub f
tests/array24.sub f
tests/array25.sub f
+tests/array26.sub f
tests/array-at-star f
tests/array2.right f
tests/assoc.tests f
tests/nameref18.sub f
tests/nameref19.sub f
tests/nameref20.sub f
+tests/nameref21.sub f
tests/nameref.right f
tests/new-exp.tests f
tests/new-exp1.sub f
int modop;
int mflags;
{
- ARRAY *a2;
- ARRAY_ELEMENT *e;
- char *t, *sifs, *ifs;
- int slen;
+ char *t;
+ int pchar, qflags;
+ WORD_LIST *wl, *save;
if (a == 0 || array_head(a) == 0 || array_empty(a))
return ((char *)NULL);
- a2 = array_copy(a);
- for (e = element_forw(a2->head); e != a2->head; e = element_forw(e)) {
- t = sh_modcase(element_value(e), pat, modop);
- FREE(element_value(e));
- e->value = t;
+ wl = array_to_word_list(a);
+ if (wl == 0)
+ return ((char *)NULL);
+
+ for (save = wl; wl; wl = wl->next) {
+ t = sh_modcase(wl->word->word, pat, modop);
+ FREE(wl->word->word);
+ wl->word->word = t;
}
- if (mflags & MATCH_QUOTED)
- array_quote(a2);
- else
- array_quote_escapes(a2);
-
- if (mflags & MATCH_STARSUB) {
- array_remove_quoted_nulls (a2);
- if ((mflags & MATCH_QUOTED) == 0 && ifs_is_null)
- sifs = spacesep;
- else
- sifs = ifs_firstchar((int *)NULL);
- t = array_to_string (a2, sifs, 0);
- if (sifs != spacesep)
- free(sifs);
- } else if (mflags & MATCH_QUOTED) {
- /* ${array[@]} */
- sifs = ifs_firstchar (&slen);
- ifs = getifs ();
- if (ifs == 0 || *ifs == 0) {
- if (slen < 2)
- sifs = xrealloc (sifs, 2);
- sifs[0] = ' ';
- sifs[1] = '\0';
- }
- t = array_to_string (a2, sifs, 0);
- free(sifs);
- } else
- t = array_to_string (a2, " ", 0);
- array_dispose (a2);
+ pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
+ qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+
+ t = string_list_pos_params (pchar, save, qflags);
+ dispose_words(save);
return t;
}
+
/*
* Allocate and return a new array element with index INDEX and value
* VALUE.
int modop;
int mflags;
{
- BUCKET_CONTENTS *tlist;
- int i, slen;
- HASH_TABLE *h2;
- char *t, *sifs, *ifs;
+ char *t;
+ int pchar, qflags;
+ WORD_LIST *wl, *save;
if (h == 0 || assoc_empty (h))
return ((char *)NULL);
- h2 = assoc_copy (h);
- for (i = 0; i < h2->nbuckets; i++)
- for (tlist = hash_items (i, h2); tlist; tlist = tlist->next)
- {
- t = sh_modcase ((char *)tlist->data, pat, modop);
- FREE (tlist->data);
- tlist->data = t;
- }
-
- if (mflags & MATCH_QUOTED)
- assoc_quote (h2);
- else
- assoc_quote_escapes (h2);
+ wl = assoc_to_word_list (h);
+ if (wl == 0)
+ return ((char *)NULL);
- if (mflags & MATCH_STARSUB)
- {
- assoc_remove_quoted_nulls (h2);
- sifs = ifs_firstchar ((int *)NULL);
- t = assoc_to_string (h2, sifs, 0);
- free (sifs);
- }
- else if (mflags & MATCH_QUOTED)
+ for (save = wl; wl; wl = wl->next)
{
- /* ${array[@]} */
- sifs = ifs_firstchar (&slen);
- ifs = getifs ();
- if (ifs == 0 || *ifs == 0)
- {
- if (slen < 2)
- sifs = xrealloc (sifs, 2);
- sifs[0] = ' ';
- sifs[1] = '\0';
- }
- t = assoc_to_string (h2, sifs, 0);
- free(sifs);
+ t = sh_modcase (wl->word->word, pat, modop);
+ FREE (wl->word->word);
+ wl->word->word = t;
}
- else
- t = assoc_to_string (h2, " ", 0);
- assoc_dispose (h2);
+ pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
+ qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
+
+ t = string_list_pos_params (pchar, save, qflags);
+ dispose_words (save);
return t;
}
/* check name for validity here? */
var = find_variable (name);
- newname = (var == 0) ? nameref_transform_name (name, ASS_MKLOCAL) : name;
+ if (var == 0)
+ newname = nameref_transform_name (name, ASS_MKLOCAL);
+ else if ((flags_on & att_nameref) == 0 && (flags_off & att_nameref) == 0)
+ {
+ /* Ok, we're following namerefs here, so let's make sure that if
+ we followed one, it was at the same context (see below for
+ more details). */
+ refvar = find_variable_last_nameref (name, 1);
+ newname = (refvar && refvar->context != variable_context) ? name : var->name;
+ refvar = (SHELL_VAR *)NULL;
+ }
+ else
+ newname = name; /* dealing with nameref attribute */
+
#if defined (ARRAY_VARS)
/* Pass 1 as second argument to make_local_{assoc,array}_variable
return an existing {array,assoc} variable to be flagged as an
#! /bin/sh
-# From configure.ac for Bash 5.0, version 4.094.
+# From configure.ac for Bash 5.0, version 4.095.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bash 5.0-alpha.
#
opt_casemod_expansions=yes
opt_extglob_default=no
opt_dircomplete_expand_default=no
-opt_globascii_default=no
+opt_globascii_default=yes
opt_function_import=yes
opt_dev_fd_stat_broken=no
opt_net_redirs=no opt_progcomp=no opt_separate_help=no
opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
- opt_globascii_default=no
+ opt_globascii_default=yes
fi
# Check whether --enable-alias was given.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
-AC_REVISION([for Bash 5.0, version 4.094])dnl
+AC_REVISION([for Bash 5.0, version 4.095])dnl
define(bashvers, 5.0)
define(relstatus, alpha)
opt_casemod_expansions=yes
opt_extglob_default=no
opt_dircomplete_expand_default=no
-opt_globascii_default=no
+opt_globascii_default=yes
opt_function_import=yes
opt_dev_fd_stat_broken=no
opt_net_redirs=no opt_progcomp=no opt_separate_help=no
opt_multibyte=yes opt_cond_regexp=no opt_coproc=no
opt_casemod_attrs=no opt_casemod_expansions=no opt_extglob_default=no
- opt_globascii_default=no
+ opt_globascii_default=yes
fi
AC_ARG_ENABLE(alias, AC_HELP_STRING([--enable-alias], [enable shell aliases]), opt_alias=$enableval)
.\" Case Western Reserve University
.\" chet.ramey@case.edu
.\"
-.\" Last Change: Fri Jun 8 16:15:23 EDT 2018
+.\" Last Change: Tue Aug 7 12:01:07 EDT 2018
.\"
.\" bash_builtins, strip all but Built-Ins section
.if \n(zZ=1 .ig zZ
.if \n(zY=1 .ig zY
-.TH BASH 1 "2018 June 8" "GNU Bash 5.0"
+.TH BASH 1 "2018 August 7" "GNU Bash 5.0"
.\"
.\" There's some problem with having a `@'
.\" in a tagged paragraph with the BSD man macros.
.SM
.BR CDPATH ,
and the shell assigns the expanded value.
+.PP
+Bash also performs tilde expansion on words satisfying the conditions of
+variable assignments (as described above under
+.SM
+.BR PARAMETERS )
+when they appear as arguments to simple commands.
+Bash does not do this, except for the \fIdeclaration\fP commands listed
+above, when in \fIposix mode\fP.
.SS Parameter Expansion
.PP
The `\fB$\fP' character introduces parameter expansion,
The \fB\-r\fP option removes a completion specification for
each \fIname\fP, or, if no \fIname\fPs are supplied, all
completion specifications.
-The \fB\-D\fP option indicates that the remaining options and actions should
+The \fB\-D\fP option indicates that other supplied options and actions should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
-The \fB\-E\fP option indicates that the remaining options and actions should
+The \fB\-E\fP option indicates that other supplied options and actions should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
-The \fB\-I\fP option indicates that the remaining options and actions should
+The \fB\-I\fP option indicates that other supplied options and actions should
apply to completion on the inital non-assignment word on the line, or after
a command delimiter such as \fB;\fP or \fB|\fP, which is usually command
name completion.
If multiple options are supplied, the \fB\-D\fP option takes precedence
-over \fB\-E\fP, and both take precedence of \fB\-I\fP.
+over \fB\-E\fP, and both take precedence over \fB\-I\fP.
+If any of \fB\-D\fP, \fB\-E\fP, or \fB\-I\fP are supplied, any other
+\fIname\fP arguments are ignored; these completions only apply to the case
+specified by the option.
.sp 1
The process of applying these completion specifications when word completion
is attempted is described above under \fBProgrammable Completion\fP.
\fIname\fP or the current completion.
The possible values of \fIoption\fP are those valid for the \fBcomplete\fP
builtin described above.
-The \fB\-D\fP option indicates that the remaining options should
+The \fB\-D\fP option indicates that other supplied options should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
-The \fB\-E\fP option indicates that the remaining options should
+The \fB\-E\fP option indicates that other supplied options should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
-The \fB\-I\fP option indicates that the remaining options should
+The \fB\-I\fP option indicates that other supplied options should
apply to completion on the inital non-assignment word on the line,
or after a command delimiter such as \fB;\fP or \fB|\fP, which is usually
command name completion.
The string that would be displayed by @samp{dirs -@var{N}}
@end table
+Bash also performs tilde expansion on words satisfying the conditions of
+variable assignments (@pxref{Shell Parameters})
+when they appear as arguments to simple commands.
+Bash does not do this, except for the @var{declaration} commands listed
+above, when in @sc{posix} mode.
+
@node Shell Parameter Expansion
@subsection Shell Parameter Expansion
@cindex parameter expansion
Copyright (C) 1988-2018 Free Software Foundation, Inc.
@end ignore
-@set LASTCHANGE Fri Jun 8 15:40:43 EDT 2018
+@set LASTCHANGE Tue Aug 7 12:01:22 EDT 2018
@set EDITION 5.0
@set VERSION 5.0
-@set UPDATED 8 June 2018
-@set UPDATED-MONTH June 2018
+@set UPDATED 7 August 2018
+@set UPDATED-MONTH August 2018
The @option{-r} option removes a completion specification for
each @var{name}, or, if no @var{name}s are supplied, all
completion specifications.
-The @option{-D} option indicates that the remaining options and actions should
+The @option{-D} option indicates that other supplied options and actions should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
-The @option{-E} option indicates that the remaining options and actions should
+The @option{-E} option indicates that other supplied options and actions should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
-The @option{-I} option indicates that the remaining options and actions should
+The @option{-I} option indicates that other supplied options and actions should
apply to completion on the inital non-assignment word on the line, or after a
command delimiter such as @samp{;} or @samp{|}, which is usually command
name completion.
If multiple options are supplied, the @option{-D} option takes precedence
over @option{-E}, and both take precedence over @option{-I}.
+If any of @option{-D}, @option{-E}, or @option{-I} are supplied, any other
+@var{name} arguments are ignored; these completions only apply to the case
+specified by the option.
The process of applying these completion specifications when word completion
is attempted is described above (@pxref{Programmable Completion}).
@var{name} or the current completion.
The possible values of @var{option} are those valid for the @code{complete}
builtin described above.
-The @option{-D} option indicates that the remaining options should
+The @option{-D} option indicates that other supplied options should
apply to the ``default'' command completion; that is, completion attempted
on a command for which no completion has previously been defined.
-The @option{-E} option indicates that the remaining options should
+The @option{-E} option indicates that other supplied options should
apply to ``empty'' command completion; that is, completion attempted on a
blank line.
-The @option{-I} option indicates that the remaining options should
+The @option{-I} option indicates that other supplied options should
apply to completion on the inital non-assignment word on the line, or after a
command delimiter such as @samp{;} or @samp{|}, which is usually command
name completion.
int rptr, mtype, rxpand, mlen;
size_t rsize, l, replen, rslen;
- if (string == 0)
+ if (string == 0)
return (savestring (""));
mtype = mflags & MATCH_TYPEMASK;
{
/* Posix interp 888 */
}
- else if (temp && (mflags & MATCH_QUOTED) == 0)
+ else if (temp && (mflags & MATCH_QUOTED) == 0)
{
tt = quote_escapes (temp);
free (temp);
temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
: array_modcase (array_cell (v), pat, modop, mflags);
- /* Don't call quote_escapes; array_modcase calls array_quote_escapes
- as appropriate before adding the space separators; ditto for
- assoc_modcase. */
+
+ if (temp && quoted == 0 && ifs_is_null)
+ {
+ /* Posix interp 888 */
+ }
+ else if (temp && (mflags & MATCH_QUOTED) == 0)
+ {
+ tt = quote_escapes (temp);
+ free (temp);
+ temp = tt;
+ }
+
break;
#endif
}
argv[2] = <element2 with spaces>
argv[1] = <element1 with spaces>
argv[2] = <element2 with spaces>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[3] = <aa>
-argv[4] = <bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[3] = <aa>
-argv[4] = <bb>
-argv[1] = <aa+bb>
-argv[2] = <aa+bb>
-argv[1] = <aa>
-argv[2] = <bb>
-argv[3] = <aa>
-argv[4] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa+bb>
-argv[1] = <xa+bb>
-argv[1] = <xa+bb>
-argv[2] = <xa+bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa+bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xabb>
-argv[1] = <xabb>
-argv[1] = <xabb>
-argv[2] = <xabb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xa>
-argv[2] = <bb>
-argv[1] = <xabb>
nord!olz
rdholz
6.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
7.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="11" )
8.declare -A a=([" "]="13" [0]="0" [1]="1" ["\" \""]="13" )
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa+bb>
+argv[1] = <xa+bb>
+argv[1] = <xa+bb>
+argv[2] = <xa+bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa+bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xabb>
+argv[1] = <xabb>
+argv[1] = <xabb>
+argv[2] = <xabb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xabb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa+bb>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <a>
+argv[4] = <b>
+argv[1] = <a+b>
+argv[2] = <a+b>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <a>
+argv[4] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a+b>
${THIS_SH} ./array23.sub
${THIS_SH} ./array24.sub
${THIS_SH} ./array25.sub
+${THIS_SH} ./array26.sub
--- /dev/null
+# these should produce the same results
+a=(aa bb)
+set -- aa bb
+
+IFS=+
+
+recho ${a[@]}
+recho ${a[@]:0}
+
+recho $@
+recho ${@:1}
+
+A=${a[*]} B=${a[*]:0}
+recho $* ${*:1}
+recho ${a[*]} ${a[*]:0}
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+
+recho ${@/a/x}
+recho ${a[@]/a/x}
+recho "${@/a/x}"
+recho "${a[@]/a/x}"
+
+recho ${*/a/x}
+recho ${a[*]/a/x}
+recho "${*/a/x}"
+recho "${a[*]/a/x}"
+
+A=${*/a/x}
+B=${a[*]/a/x}
+
+recho "$A" "$B"
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]/a/x}
+recho "${A[@]/a/x}"
+recho ${A[*]/a/x}
+recho "${A[*]/a/x}"
+
+unset A
+IFS=
+
+recho ${@/a/x}
+recho ${a[@]/a/x}
+recho "${@/a/x}"
+recho "${a[@]/a/x}"
+
+recho ${*/a/x}
+recho ${a[*]/a/x}
+recho "${*/a/x}"
+recho "${a[*]/a/x}"
+
+A=${*/a/x}
+B=${a[*]/a/x}
+
+recho "$A" "$B"
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]/a/x}
+recho "${A[@]/a/x}"
+recho ${A[*]/a/x}
+recho "${A[*]/a/x}"
+
+unset A
+
+IFS=+
+
+recho ${a[@]}
+recho ${a[@],,}
+recho "${a[@]}"
+recho "${a[@],,}"
+
+A=${a[*]} B=${a[*],,}
+recho $* ${*,,}
+recho ${a[*]} ${a[*],,}
+recho "${a[*]}" "${a[*],,}"
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@],,}
+recho "${A[@],,}"
+recho ${A[*],,}
+recho "${A[*],,}"
+
+unset A
+
+recho ${a[@]#?}
+recho ${@#?}
+
+A=${a[*]#?} B=${a[*]#?}
+recho ${*#?} ${a[*]#?}
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]#?}
+recho "${A[@]#?}"
+recho ${A[*]#?}
+recho "${A[*]#?}"
IFS="$oIFS"
unset a a2 array foo
-
-# these should produce the same results
-a=(aa bb)
-set -- aa bb
-
-IFS=+
-
-recho ${a[@]}
-recho ${a[@]:0}
-
-recho $@
-recho ${@:1}
-
-A=${a[*]} B=${a[*]:0}
-recho $* ${*:1}
-recho ${a[*]} ${a[*]:0}
-recho "$A" "$B"
-recho $A $B
-
-unset A B
-
-recho ${@/a/x}
-recho ${a[@]/a/x}
-recho "${@/a/x}"
-recho "${a[@]/a/x}"
-
-recho ${*/a/x}
-recho ${a[*]/a/x}
-recho "${*/a/x}"
-recho "${a[*]/a/x}"
-
-A=${*/a/x}
-B=${a[*]/a/x}
-
-recho "$A" "$B"
-
-unset A B
-declare -A A
-A[0]=aa
-A[1]=bb
-
-recho ${A[@]/a/x}
-recho "${A[@]/a/x}"
-recho ${A[*]/a/x}
-recho "${A[*]/a/x}"
-
-unset A
-IFS=
-
-recho ${@/a/x}
-recho ${a[@]/a/x}
-recho "${@/a/x}"
-recho "${a[@]/a/x}"
-
-recho ${*/a/x}
-recho ${a[*]/a/x}
-recho "${*/a/x}"
-recho "${a[*]/a/x}"
-
-A=${*/a/x}
-B=${a[*]/a/x}
-
-recho "$A" "$B"
-
-unset A B
-declare -A A
-A[0]=aa
-A[1]=bb
-
-recho ${A[@]/a/x}
-recho "${A[@]/a/x}"
-recho ${A[*]/a/x}
-recho "${A[*]/a/x}"
declare -- ref="Y"
./nameref20.sub: line 61: declare: var: not found
ref=Y
+declare -n ref="var"
+declare -A var=([2]="" )
+declare -n ref="var"
+declare -A var=([2]="" )
+declare -n ref="var"
+declare -a var=([2]="")
+declare -n ref="var"
+declare -a var=([2]="")
+declare -n ref="var"
+declare -ai var=([1]="0")
+declare -n ref="var"
+declare -ai var=([1]="0")
+declare -n ref="var"
+declare -- var="1"
f
unset -n ref
+unset -f f
+
--- /dev/null
+# issues with local variables and local namerefs post-bash-4.4
+
+f()
+{
+ local -n ref=var
+ local -A ref=([1]=)
+# declare -p ref var
+ ref=([2]=)
+ declare -p ref var
+}
+
+unset ref var
+f
+
+unset ref; var=0
+f
+
+unset var
+unset -f f
+
+f()
+{
+ local -n ref=var
+ local -a ref=([1]=)
+ ref=([2]=)
+ declare -p ref var
+}
+
+unset ref var
+f
+
+unset ref; var=0
+f
+
+unset var
+unset -f f
+
+f() { local -n ref=var; local -i ref=([1]=); declare -p ref var; }
+
+unset var
+f
+
+var=0
+f
+
+unset var
+unset -f f
+
+f() { local -n ref=var; local ref=1; declare -p ref var; }
+
+var=0
+f
+
+unset var
+unset -f f
+
shopt -s extquote
shopt -u failglob
shopt -s force_fignore
-shopt -u globasciiranges
+shopt -s globasciiranges
shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
shopt -s expand_aliases
shopt -s extquote
shopt -s force_fignore
+shopt -s globasciiranges
shopt -s hostcomplete
shopt -s interactive_comments
shopt -s progcomp
shopt -u extdebug
shopt -u extglob
shopt -u failglob
-shopt -u globasciiranges
shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
extdebug off
extglob off
failglob off
-globasciiranges off
globstar off
gnu_errfmt off
histappend off