commit bash-20180803 snapshot

This commit is contained in:
Chet Ramey
2018-08-06 08:58:26 -04:00
parent b3bb7f6081
commit 057a9fbdb4
16 changed files with 635 additions and 141 deletions
+44
View File
@@ -4109,3 +4109,47 @@ subst.c
subst.c
- get_var_and_type: if VALUE is NULL, check before calling dequote_string.
Report and fix from Grisha Levit <grishalevit@gmail.com>
7/30
----
variables.c
- make_local_{array,assoc}_variable: make sure we're not trying to
inherit a value from an incompatible array type. Fixes issue raised
by Grisha Levit <grishalevit@gmail.com>
- nameref_transform_name: if we're trying to resolve a nameref that
will be used to create a local variable, make sure the nameref is
at the same variable scope. Report from Grisha Levit
<grishalevit@gmail.com>
8/2
---
array.c
- array_subrange: change to use string_list_pos_params after creating a
WORD_LIST from the array slice, like assoc_subrange does
subst.c
- parameter_brace_substring: since assoc_subrange and array_subrange
both call string_list_pos_params now, treat the results the same as
the VT_POSPARAMS case (pos_params also calls string_list_pos_params).
Fixes behavior difference between ${a[@]:sub} and ${@:sub} reported
by Ilkka Virta <itvirta@iki.fi>
8/3
---
array.c
- array_patsub: 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 ${@/pat/rep} and ${*/pat/rep}
assoc.c
- assoc_patsub: 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 ${@/pat/rep} and ${*/pat/rep}
subst.c
- parameter_brace_patsub: change how return value of {array,assoc}_patsub
is treated to make it identical to pos_params_pat_subst, since they
all call string_list_pos_params now
- 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
+2 -1
View File
@@ -1359,7 +1359,7 @@ tests/unicode1.sub f
tests/unicode2.sub f
tests/unicode3.sub f
tests/varenv.right f
tests/varenv.sh f
tests/varenv.tests f
tests/varenv1.sub f
tests/varenv2.sub f
tests/varenv3.sub f
@@ -1373,6 +1373,7 @@ tests/varenv10.sub f
tests/varenv11.sub f
tests/varenv12.sub f
tests/varenv13.sub f
tests/varenv14.sub f
tests/version f
tests/version.mini f
tests/vredir.tests f
+22 -64
View File
@@ -406,8 +406,8 @@ int starsub, quoted;
ARRAY *a2;
ARRAY_ELEMENT *h, *p;
arrayind_t i;
char *ifs, *sifs, *t;
int slen;
char *t;
WORD_LIST *wl;
p = a ? array_head (a) : 0;
if (p == 0 || array_empty (a) || start > array_max_index(a))
@@ -432,32 +432,12 @@ int starsub, quoted;
a2 = array_slice(a, h, p);
if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
array_quote(a2);
else
array_quote_escapes(a2);
if (starsub && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))) {
/* ${array[*]} */
array_remove_quoted_nulls (a2);
sifs = ifs_firstchar ((int *)NULL);
t = array_to_string (a2, sifs, 0);
free (sifs);
} else if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) {
/* ${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);
wl = array_to_word_list(a2);
array_dispose(a2);
if (wl == 0)
return (char *)NULL;
t = string_list_pos_params(starsub ? '*' : '@', wl, quoted);
dispose_words(wl);
return t;
}
@@ -468,50 +448,28 @@ ARRAY *a;
char *pat, *rep;
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 = pat_subst(element_value(e), pat, rep, mflags);
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 = pat_subst (wl->word->word, pat, rep, mflags);
FREE (wl->word->word);
wl->word->word = t;
}
if (mflags & MATCH_QUOTED)
array_quote(a2);
else
array_quote_escapes(a2);
pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
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);
t = string_list_pos_params (pchar, save, qflags);
dispose_words(save);
return t;
}
+15 -40
View File
@@ -305,54 +305,29 @@ assoc_patsub (h, pat, rep, mflags)
char *pat, *rep;
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 = pat_subst ((char *)tlist->data, pat, rep, mflags);
FREE (tlist->data);
tlist->data = t;
}
wl = assoc_to_word_list (h);
if (wl == 0)
return (char *)NULL;
if (mflags & MATCH_QUOTED)
assoc_quote (h2);
else
assoc_quote_escapes (h2);
if (mflags & MATCH_STARSUB)
for (save = wl; wl; wl = wl->next)
{
assoc_remove_quoted_nulls (h2);
sifs = ifs_firstchar ((int *)NULL);
t = assoc_to_string (h2, sifs, 0);
free (sifs);
t = pat_subst (wl->word->word, pat, rep, mflags);
FREE (wl->word->word);
wl->word->word = t;
}
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 = assoc_to_string (h2, sifs, 0);
free(sifs);
}
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;
}
+39 -26
View File
@@ -3903,15 +3903,17 @@ expand_string_for_pat (string, quoted, dollar_at_p, expanded_p)
{
WORD_DESC td;
WORD_LIST *tresult;
int oexp;
if (string == 0 || *string == '\0')
return (WORD_LIST *)NULL;
oexp = expand_no_split_dollar_star;
expand_no_split_dollar_star = 1;
td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
td.word = string;
tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, expanded_p);
expand_no_split_dollar_star = 0;
expand_no_split_dollar_star = oexp;
return (tresult);
}
@@ -7706,7 +7708,7 @@ parameter_brace_substring (varname, value, ind, substr, quoted, pflags, flags)
int quoted, pflags, flags;
{
intmax_t e1, e2;
int vtype, r, starsub, qflags;
int vtype, r, starsub;
char *temp, *val, *tt, *oname;
SHELL_VAR *v;
@@ -7755,9 +7757,23 @@ parameter_brace_substring (varname, value, ind, substr, quoted, pflags, flags)
FREE (tt);
break;
case VT_POSPARMS:
qflags = quoted;
tt = pos_params (varname, e1, e2, qflags);
/* string_list_dollar_at will quote the list if ifs_is_null != 0 */
case VT_ARRAYVAR:
if (vtype == VT_POSPARMS)
tt = pos_params (varname, e1, e2, quoted);
#if defined (ARRAY_VARS)
/* assoc_subrange and array_subrange both call string_list_pos_params,
so we can treat this case just like VT_POSPARAMS. */
else if (assoc_p (v))
/* we convert to list and take first e2 elements starting at e1th
element -- officially undefined for now */
tt = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
else
/* We want E2 to be the number of elements desired (arrays can be
sparse, so verify_substring_values just returns the numbers
specified and we rely on array_subrange to understand how to
deal with them). */
tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
#endif
/* We want to leave this alone in every case where pos_params/
string_list_pos_params quotes the list members */
if (tt && quoted == 0 && ifs_is_null)
@@ -7772,21 +7788,7 @@ parameter_brace_substring (varname, value, ind, substr, quoted, pflags, flags)
else
temp = tt;
break;
#if defined (ARRAY_VARS)
case VT_ARRAYVAR:
if (assoc_p (v))
/* we convert to list and take first e2 elements starting at e1th
element -- officially undefined for now */
temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
else
/* We want E2 to be the number of elements desired (arrays can be sparse,
so verify_substring_values just returns the numbers specified and we
rely on array_subrange to understand how to deal with them). */
temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
/* array_subrange now calls array_quote_escapes as appropriate, so the
caller no longer needs to. */
break;
#endif
default:
temp = (char *)NULL;
}
@@ -7978,7 +7980,7 @@ pos_params_pat_subst (string, pat, rep, mflags)
qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
/* If we are expanding in a context where word splitting will not be
performed, treat as quoted. This changes how $* will be expanded. */
performed, treat as quoted. This changes how $* will be expanded. */
if (pchar == '*' && (mflags & MATCH_ASSIGNRHS) && expand_no_split_dollar_star && ifs_is_null)
qflags |= Q_DOUBLE_QUOTES; /* Posix interp 888 */
@@ -8145,11 +8147,22 @@ parameter_brace_patsub (varname, value, ind, patsub, quoted, pflags, flags)
if ((mflags & MATCH_STARSUB) && (mflags & MATCH_ASSIGNRHS) && ifs_is_null)
mflags |= MATCH_QUOTED; /* Posix interp 888 */
temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
: array_patsub (array_cell (v), p, rep, mflags);
/* Don't call quote_escapes anymore; array_patsub calls
array_quote_escapes as appropriate before adding the
space separators; ditto for assoc_patsub. */
/* these eventually call string_list_pos_params */
if (assoc_p (v))
temp = assoc_patsub (assoc_cell (v), p, rep, mflags);
else
temp = array_patsub (array_cell (v), p, rep, mflags);
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
}
+68
View File
@@ -270,6 +270,74 @@ argv[1] = <element1 with spaces>
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
+73
View File
@@ -113,3 +113,76 @@ recho $@
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}"
+6
View File
@@ -463,3 +463,9 @@ outside:
./nameref20.sub: line 45: declare: var: not found
declare -n ref="var"
declare -a var=([0]="Y")
declare -- ref="Y"
declare -- var="X"
ref=Y
declare -- ref="Y"
./nameref20.sub: line 61: declare: var: not found
ref=Y
+13
View File
@@ -54,3 +54,16 @@ f()
declare -p ref var
}
f
unset -f f
declare -n ref=var
f() { local ref=Y; declare -p ref var; local; }
var=X
f
unset -v var
f
unset -n ref
+10
View File
@@ -119,3 +119,13 @@ argv[3] = <uv^Aw^Axy>
argv[1] = <@2>
argv[2] = <uv^Aw^Axy>
argv[3] = <uv^Aw^Axy>
argv[1] = <aa1>
argv[2] = <uv^A^A>
argv[1] = <aa2>
argv[2] = <uv^A^A>
argv[1] = <aa3>
argv[2] = <uv^A^Awx>
argv[3] = <uv^A^Awx>
argv[1] = <aa4>
argv[2] = <uv^A^Awx>
argv[3] = <uv^A^Awx>
+9
View File
@@ -95,3 +95,12 @@ recho d2 "${1:2:2}"
recho @1 ${@:1:2}
recho @2 "${@:1:2}"
declare -A assoc
assoc=( [0]=$e [1]=$e )
recho aa1 ${assoc:0:4}
recho aa2 "${assoc:0:4}"
recho aa3 ${assoc[@]:0:2}
recho aa4 "${assoc[@]:0:2}"
+1 -1
View File
@@ -1,2 +1,2 @@
${THIS_SH} ./varenv.sh 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
${THIS_SH} ./varenv.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
diff ${BASH_TSTOUT} varenv.right && rm -f ${BASH_TSTOUT}
+17
View File
@@ -160,6 +160,23 @@ declare -A var=([0]="X" )
help
./varenv13.sub: line 21: `var[0]': not a valid identifier
1
./varenv14.sub: line 6: warning: var: cannot inherit value from incompatible type
declare -a var=([0]="X")
./varenv14.sub: line 9: warning: var: cannot inherit value from incompatible type
declare -a var=([0]="Y")
./varenv14.sub: line 10: warning: var: cannot inherit value from incompatible type
declare -a var=([0]="Y")
./varenv14.sub: line 11: warning: var: cannot inherit value from incompatible type
declare -a var=()
./varenv14.sub: line 12: warning: var: cannot inherit value from incompatible type
declare -a var=()
./varenv14.sub: line 18: f: var: cannot convert indexed to associative array
declare -a a=([0]="X")
declare -a s=([0]="X")
declare -a a=([0]="X" [1]="Y")
declare -a s=([0]="X" [1]="Y")
declare -a a=([0]="XY")
declare -a s=([0]="XY")
a=z
a=b
a=z
+244
View File
@@ -0,0 +1,244 @@
#
# varenv.sh
#
# Test the behavior of the shell with respect to variable and environment
# assignments
#
expect()
{
echo expect "$@"
}
a=1
b=2
c=3
d=4
e=5
f=6 g=7 h=8
a=3 b=4 $CHMOD $MODE $FN
# This should echo "3 4" according to Posix.2
expect "3 4"
echo $a $b
set -k
# Assignment statements made when no words are left affect the shell's
# environment
a=5 b=6 $CHMOD c=7 $MODE d=8 $FN e=9
expect "5 6 7 8 9"
echo $a $b $c $d $e
$CHMOD f=7 $MODE g=8 $FN h=9
expect "7 8 9"
echo $f $g $h
set +k
# The temporary environment does not affect variable expansion, only the
# environment given to the command
export HOME=/usr/chet
expect $HOME
echo $HOME
expect $HOME
HOME=/a/b/c /bin/echo $HOME
expect $HOME
echo $HOME
# This should echo /a/b/c
expect /a/b/c
HOME=/a/b/c printenv HOME
set -k
# This should echo $HOME 9, NOT /a/b/c 9
expect "$HOME"
HOME=/a/b/c /bin/echo $HOME c=9
expect "$HOME 7"
echo $HOME $c
# I claim the next two echo calls should give identical output.
# ksh agrees, the System V.3 sh does not
expect "/a/b/c 9 /a/b/c"
HOME=/a/b/c $ECHO a=$HOME c=9
echo $HOME $c $a
expect "/a/b/c 9 /a/b/c"
HOME=/a/b/c a=$HOME c=9
echo $HOME $c $a
set +k
# How do assignment statements affect subsequent assignments on the same
# line?
expect "/a/b/c /a/b/c"
HOME=/a/b/c a=$HOME
echo $HOME $a
# The system V.3 sh does this wrong; the last echo should output "1 1",
# but the system V.3 sh has it output "2 2". Posix.2 says the assignment
# statements are processed left-to-right. bash and ksh output the right
# thing
c=1
d=2
expect "1 2"
echo $c $d
d=$c c=$d
expect "1 1"
echo $c $d
# just for completeness
unset d c
expect unset
echo ${d-unset}
# no output
export a
a=bcde
export a
/bin/true 2>/dev/null
func()
{
local YYZ
YYZ="song by rush"
echo $YYZ
echo $A
}
YYZ="toronto airport"
A="AVAR"
echo $YYZ
echo $A
A=BVAR func
echo $YYZ
echo $A
export A
# Make sure expansion doesn't use assignment statements preceding a builtin
A=ZVAR echo $A
XPATH=/bin:/usr/bin:/usr/local/bin:.
func2()
{
local z=yy
local -a avar=( ${XPATH//: } )
echo ${avar[@]}
local
}
avar=42
echo $avar
func2
echo $avar
# try to set an attribute for an unset variable; make sure it persists
# when the variable is assigned a value
declare -i ivar
ivar=10
declare -p ivar
unset ivar
# export an unset variable, make sure it is not suddenly set, but make
# sure the export attribute persists when the variable is assigned a
# value
export ivar
echo ${ivar-unset}
ivar=42
declare -p ivar
# make sure set [-+]o ignoreeof and $IGNOREEOF are reflected
unset IGNOREEOF
set +o ignoreeof
set -o ignoreeof
if [ "$IGNOREEOF" -ne 10 ]; then
echo "./varenv.sh: set -o ignoreeof is not reflected in IGNOREEOF" >&2
fi
unset IGNOREEOF
set +o ignoreeof
# older versions of bash used to not reset RANDOM in subshells correctly
[[ $RANDOM -eq $(echo $RANDOM) ]] && echo "RANDOM: problem with subshells"
# make sure that shopt -o is reflected in $SHELLOPTS
# first, get rid of things that might be set automatically via shell
# variables
set +o posix
set +o ignoreeof
set +o monitor
echo $-
echo ${SHELLOPTS}
shopt -so physical
echo $-
echo ${SHELLOPTS}
# and make sure it is readonly
readonly -p | grep SHELLOPTS
# This was an error in bash versions prior to bash-2.04. The `set -a'
# should cause the assignment statement that's an argument to typeset
# to create an exported variable
unset FOOFOO
FOOFOO=bar
set -a
typeset FOOFOO=abcde
printenv FOOFOO
# test out export behavior of variable assignments preceding builtins and
# functions
$THIS_SH ./varenv1.sub
# more tests; bugs in bash up to version 2.05a
$THIS_SH ./varenv2.sub
# more tests; bugs in bash IFS scoping up through version 4.2
$THIS_SH ./varenv3.sub
# scoping problems with declare -g through bash-4.2
${THIS_SH} ./varenv4.sub
# more scoping and declaration problems with -g and arrays through bash-4.2
${THIS_SH} ./varenv5.sub
# variable scoping in the presence of nameref
${THIS_SH} ./varenv6.sub
# variable declaration problems with arrays and readonly local variables
${THIS_SH} ./varenv7.sub
# variable visibility problems with process substitution subshells in
# redirections
${THIS_SH} ./varenv8.sub
# make sure that builtins like readonly and export modify local array variables
# if executed in shell functions, like they modify local scalar variables
${THIS_SH} ./varenv9.sub
# more tests of unset and local variables with dynamic scoping
${THIS_SH} ./varenv10.sub
# tests of compound assignments in function scope
${THIS_SH} ./varenv11.sub
# temporary environment variable propagation and scoping in posix mode
${THIS_SH} ./varenv12.sub
# temporary environment and invalid shell indentifier names
${THIS_SH} ./varenv13.sub
# localvar_inherit
${THIS_SH} ./varenv14.sub
# make sure variable scoping is done right
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
+33
View File
@@ -0,0 +1,33 @@
# testing framework for local variable inheritence
shopt -s localvar_inherit
declare -A var
f() { declare var+=([0]=X); declare -p var; }
f
f() { declare var=([Y]=Y); declare -p var; }; f
f() { declare var+=([Y]=Y); declare -p var; }; f
f() { declare var+=(); declare -p var; }; f
f() { declare var=(); declare -p var; }; f
unset -f f
unset -v var
declare -a var=( [0]=12 )
f() { declare -A var+=([0]=X); declare -p var; }
f
unset -f f
unset a s
a=(X) s=X
f() { local -a a s; declare -p a s; }
f
f() { local a+=(Y) s+=(Y); declare -p a s; }
f
f() { local -a a+=Y s+=Y; declare -p a s; }
f
+39 -9
View File
@@ -2282,7 +2282,13 @@ nameref_transform_name (name, flags)
v = 0;
if (flags & ASS_MKLOCAL)
v = find_variable_last_nameref (name, 1);
{
v = find_variable_last_nameref (name, 1);
/* If we're making local variables, only follow namerefs that point to
non-existant variables at the same variable context. */
if (v && v->context != variable_context)
v = 0;
}
else if (flags & ASS_MKGLOBAL)
v = (flags & ASS_CHKLOCAL) ? find_variable_last_nameref (name, 1)
: find_global_variable_last_nameref (name, 1);
@@ -2781,11 +2787,23 @@ make_local_array_variable (name, assoc_ok)
/* Validate any value we inherited from a variable instance at a previous
scope and disard anything that's invalid. */
if (localvar_inherit && assoc_p (var))
{
internal_warning ("%s: cannot inherit value from incompatible type", name);
VUNSETATTR (var, att_assoc);
dispose_variable_value (var);
array = array_create ();
var_setarray (var, array);
}
else if (localvar_inherit)
var = convert_var_to_array (var); /* XXX */
else
{
dispose_variable_value (var);
array = array_create ();
var_setarray (var, array);
}
array = array_create ();
dispose_variable_value (var);
var_setarray (var, array);
VSETATTR (var, att_array);
return var;
}
@@ -2822,11 +2840,23 @@ make_local_assoc_variable (name, array_ok)
/* Validate any value we inherited from a variable instance at a previous
scope and disard anything that's invalid. */
if (localvar_inherit && array_p (var))
{
internal_warning ("%s: cannot inherit value from incompatible type", name);
VUNSETATTR (var, att_array);
dispose_variable_value (var);
hash = assoc_create (0);
var_setassoc (var, hash);
}
else if (localvar_inherit)
var = convert_var_to_assoc (var); /* XXX */
else
{
dispose_variable_value (var);
hash = assoc_create (0);
var_setassoc (var, hash);
}
dispose_variable_value (var);
hash = assoc_create (0);
var_setassoc (var, hash);
VSETATTR (var, att_assoc);
return var;
}