mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-27 07:43:07 +02:00
commit bash-20180309 snapshot
This commit is contained in:
@@ -15047,3 +15047,25 @@ subst.c
|
||||
we are checking whether value is null, so we can have different
|
||||
error messages for ${x:?} and ${x?}. Report and fix from
|
||||
don fong <dfong@dfong.com>
|
||||
|
||||
3/5
|
||||
---
|
||||
lib/readline/bind.c
|
||||
- _rl_read_file: instead of calling stat/open on the passed filename,
|
||||
use open/fstat to avoid one possible filename translation and close
|
||||
a small (benign) race condition. Report and fix from Roy Ivy
|
||||
<roy.ivy.iii@gmail.com>
|
||||
|
||||
3/11
|
||||
----
|
||||
variables.c
|
||||
- makunbound: if new variable localvar_unset is non-zero, mark local
|
||||
vars in previous scopes as invisible and unset so they will show
|
||||
up as unset until that previous scope returns (similar to how local
|
||||
variables in the current local scope are handled). localvar_unset
|
||||
is currently set to 0 with no way for a script to change its value.
|
||||
Eventually there will be an option to modify it. From a bug-bash
|
||||
discussion started by Nikolai Kondrashov <spbnick@gmail.com> back
|
||||
on 2/11/2018
|
||||
|
||||
|
||||
|
||||
@@ -864,6 +864,7 @@ tests/array21.sub f
|
||||
tests/array22.sub f
|
||||
tests/array23.sub f
|
||||
tests/array24.sub f
|
||||
tests/array25.sub f
|
||||
tests/array-at-star f
|
||||
tests/array2.right f
|
||||
tests/assoc.tests f
|
||||
@@ -1125,6 +1126,7 @@ tests/nameref15.sub f
|
||||
tests/nameref16.sub f
|
||||
tests/nameref17.sub f
|
||||
tests/nameref18.sub f
|
||||
tests/nameref19.sub f
|
||||
tests/nameref.right f
|
||||
tests/new-exp.tests f
|
||||
tests/new-exp1.sub f
|
||||
@@ -1348,6 +1350,7 @@ tests/varenv6.sub f
|
||||
tests/varenv7.sub f
|
||||
tests/varenv8.sub f
|
||||
tests/varenv9.sub f
|
||||
tests/varenv10.sub f
|
||||
tests/version f
|
||||
tests/version.mini f
|
||||
tests/vredir.tests f
|
||||
|
||||
+15
-3
@@ -148,17 +148,20 @@ SYSTEM_FLAGS = -DPROGRAM='"$(Program)"' -DCONF_HOSTTYPE='"$(Machine)"' -DCONF_OS
|
||||
BASE_CCFLAGS = $(SYSTEM_FLAGS) $(LOCAL_DEFS) \
|
||||
$(DEFS) $(LOCAL_CFLAGS) $(INCLUDES)
|
||||
|
||||
CCFLAGS = $(ASAN_CFLAGS) $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS)
|
||||
CCFLAGS = $(ADDON_CFLAGS) $(BASE_CCFLAGS) ${PROFILE_FLAGS} $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
|
||||
|
||||
BASE_LDFLAGS = @LDFLAGS@ $(LOCAL_LDFLAGS) $(CFLAGS)
|
||||
LDFLAGS = ${ASAN_LDFLAGS} ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD}
|
||||
LDFLAGS = ${ADDON_LDFLAGS} ${BASE_LDFLAGS} ${PROFILE_FLAGS} ${STATIC_LD}
|
||||
LDFLAGS_FOR_BUILD = @LDFLAGS_FOR_BUILD@ $(LOCAL_LDFLAGS) $(CFLAGS_FOR_BUILD)
|
||||
|
||||
ASAN_XCFLAGS = -fsanitize=address -fno-omit-frame-pointer
|
||||
ASAN_XLDFLAGS = -fsanitize=address
|
||||
|
||||
GCOV_XCFLAGS = -fprofile-arcs -ftest-coverage
|
||||
GCOV_XLDFLAGS = -fprofile-arcs -ftest-coverage
|
||||
|
||||
INCLUDES = -I. @RL_INCLUDE@ -I$(srcdir) -I$(BASHINCDIR) -I$(LIBSRC) $(INTL_INC)
|
||||
|
||||
# Maybe add: -Wextra
|
||||
@@ -602,7 +605,12 @@ lint:
|
||||
${MAKE} ${MFLAGS} CFLAGS='${GCC_LINT_FLAGS}' .made
|
||||
|
||||
asan:
|
||||
${MAKE} ${MFLAGS} ASAN_CFLAGS='${ASAN_XCFLAGS}' ASAN_LDFLAGS='${ASAN_XLDFLAGS}' .made
|
||||
${MAKE} ${MFLAGS} ADDON_CFLAGS='${ASAN_XCFLAGS}' ADDON_LDFLAGS='${ASAN_XLDFLAGS}' .made
|
||||
|
||||
# cheating
|
||||
gcov:
|
||||
${MAKE} ${MFLAGS} ADDON_CFLAGS='${GCOV_XCFLAGS}' ADDON_LDFLAGS='${GCOV_XLDFLAGS}' .made
|
||||
|
||||
|
||||
# have to make this separate because making tests depend on $(PROGRAM)
|
||||
asan-tests: asan $(TESTS_SUPPORT)
|
||||
@@ -611,6 +619,10 @@ asan-tests: asan $(TESTS_SUPPORT)
|
||||
@( cd $(srcdir)/tests && \
|
||||
PATH=$(BUILD_DIR)/tests:$$PATH THIS_SH=$(THIS_SH) $(SHELL) ${TESTSCRIPT} )
|
||||
|
||||
profiling-tests: ${PROGRAM}
|
||||
@test "X$$PROFILE_FLAGS" == "X" && { echo "profiling-tests: must be built with profiling enabled" >&2; exit 1; }
|
||||
@${MAKE} ${MFLAGS} tests TESTSCRIPT=run-gprof
|
||||
|
||||
version.h: $(SOURCES) config.h Makefile patchlevel.h
|
||||
$(SHELL) $(SUPPORT_SRC)mkversion.sh -b -S ${topdir} -s $(RELSTATUS) -d $(Version) -o newversion.h \
|
||||
&& mv newversion.h version.h
|
||||
|
||||
@@ -94,7 +94,7 @@ INCLUDES = -I. -I.. @RL_INCLUDE@ -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib -I$
|
||||
BASE_CCFLAGS = ${PROFILE_FLAGS} $(DEFS) $(LOCAL_DEFS) $(SYSTEM_FLAGS) \
|
||||
${INCLUDES} $(LOCAL_CFLAGS)
|
||||
|
||||
CCFLAGS = ${ASAN_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
CCFLAGS = ${ADDON_CFLAGS} $(BASE_CCFLAGS) $(CPPFLAGS) $(CFLAGS)
|
||||
|
||||
CCFLAGS_FOR_BUILD = $(BASE_CCFLAGS) $(CPPFLAGS_FOR_BUILD) $(CFLAGS_FOR_BUILD)
|
||||
|
||||
|
||||
+19
-2
@@ -573,8 +573,9 @@ restart_new_var_name:
|
||||
}
|
||||
/* However, if we're turning off the nameref attribute on an existing
|
||||
nameref variable, we first follow the nameref chain to the end,
|
||||
modify the value of the variable this nameref variable references,
|
||||
*CHANGING ITS VALUE AS A SIDE EFFECT* then turn off the nameref
|
||||
modify the value of the variable this nameref variable references
|
||||
if there is an assignment statement argument,
|
||||
*CHANGING ITS VALUE AS A SIDE EFFECT*, then turn off the nameref
|
||||
flag *LEAVING THE NAMEREF VARIABLE'S VALUE UNCHANGED* */
|
||||
else if (var == 0 && (flags_off & att_nameref))
|
||||
{
|
||||
@@ -592,6 +593,16 @@ restart_new_var_name:
|
||||
any_failed++;
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
/* If all we're doing is turning off the nameref attribute, don't
|
||||
bother with VAR at all, whether it exists or not. Just turn it
|
||||
off and go on. */
|
||||
if (refvar && flags_on == 0 && offset == 0 && (flags_off & ~att_nameref) == 0)
|
||||
{
|
||||
VUNSETATTR (refvar, att_nameref);
|
||||
NEXT_VARIABLE ();
|
||||
}
|
||||
|
||||
if (refvar)
|
||||
/* XXX - use declare_find_variable here? */
|
||||
var = mkglobal ? find_global_variable (nameref_cell (refvar)) : find_variable (nameref_cell (refvar));
|
||||
@@ -671,6 +682,12 @@ restart_new_var_name:
|
||||
value = name + namelen;
|
||||
}
|
||||
free (oldname);
|
||||
|
||||
/* OK, let's turn off the nameref attribute.
|
||||
Now everything else applies to VAR. */
|
||||
if (flags_off & att_nameref)
|
||||
VUNSETATTR (refvar, att_nameref);
|
||||
|
||||
goto restart_new_var_name;
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ extern int glob_asciirange;
|
||||
extern int lastpipe_opt;
|
||||
extern int inherit_errexit;
|
||||
extern int localvar_inherit;
|
||||
extern int localvar_unset;
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
extern int extended_glob;
|
||||
@@ -214,6 +215,9 @@ static struct {
|
||||
{ "lithist", &literal_history, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "localvar_inherit", &localvar_inherit, (shopt_set_func_t *)NULL },
|
||||
#if 0
|
||||
{ "localvar_unset", &localvar_unset, (shopt_set_func_t *)NULL },
|
||||
#endif
|
||||
{ "login_shell", &shopt_login_shell, set_login_shell },
|
||||
{ "mailwarn", &mail_warning, (shopt_set_func_t *)NULL },
|
||||
#if defined (READLINE)
|
||||
|
||||
@@ -53,7 +53,7 @@ BASHINCDIR = ${topdir}/include
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib
|
||||
|
||||
CCFLAGS = $(PROFILE_FLAGS) $(DEFS) $(LOCAL_DEFS) ${INCLUDES} $(CPPFLAGS) \
|
||||
$(LOCAL_CFLAGS) $(CFLAGS) ${ASAN_CFLAGS}
|
||||
$(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS}
|
||||
|
||||
# Here is a rule for making .o files from .c files that doesn't force
|
||||
# the type of the machine (like -sun3) into the flags.
|
||||
|
||||
@@ -65,7 +65,7 @@ LOCAL_DEFS = @LOCAL_DEFS@
|
||||
INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib
|
||||
|
||||
CCFLAGS = $(DEFS) $(LOCAL_DEFS) $(APP_CFLAGS) $(CPPFLAGS) ${INCLUDES} \
|
||||
$(LOCAL_CFLAGS) $(CFLAGS) ${ASAN_CFLAGS}
|
||||
$(LOCAL_CFLAGS) $(CFLAGS) ${ADDON_CFLAGS}
|
||||
|
||||
.c.o:
|
||||
${RM} $@
|
||||
|
||||
+7
-2
@@ -839,8 +839,13 @@ _rl_read_file (char *filename, size_t *sizep)
|
||||
char *buffer;
|
||||
int i, file;
|
||||
|
||||
if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0)
|
||||
return ((char *)NULL);
|
||||
file = -1;
|
||||
if (((file = open (filename, O_RDONLY, 0666)) < 0) || (fstat (file, &finfo) < 0))
|
||||
{
|
||||
if (file >= 0)
|
||||
close (file);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
file_size = (size_t)finfo.st_size;
|
||||
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(BASHINCDIR) -I$(srcdir) $(INTL_INC)
|
||||
|
||||
CCFLAGS = ${ASAN_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \
|
||||
CCFLAGS = ${ADDON_CFLAGS} ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) \
|
||||
$(LOCAL_CFLAGS) $(CFLAGS) $(CPPFLAGS)
|
||||
|
||||
GCC_LINT_FLAGS = -Wall -Wshadow -Wpointer-arith -Wcast-qual \
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
BUILD_DIR=/usr/local/build/chet/bash/bash-current
|
||||
BUILD_DIR=/usr/local/build/bash/bash-current
|
||||
THIS_SH=$BUILD_DIR/bash
|
||||
PATH=$PATH:$BUILD_DIR
|
||||
|
||||
|
||||
@@ -577,3 +577,47 @@ jkl
|
||||
abc
|
||||
def ghi
|
||||
jkl
|
||||
1. indexed:
|
||||
reference:
|
||||
./array25.sub: line 10: ${a[ ]}: bad substitution
|
||||
./array25.sub: line 11: ' ': syntax error: operand expected (error token is "' '")
|
||||
./array25.sub: line 12: ${a[ ]}: bad substitution
|
||||
4. 0
|
||||
5. 0
|
||||
6. 0
|
||||
assignment:
|
||||
1.declare -a a=([0]="10" [1]="1")
|
||||
2.declare -a a=([0]="11" [1]="1")
|
||||
3.declare -a a=([0]="12" [1]="1")
|
||||
4.declare -a a=([0]="13" [1]="1")
|
||||
arithmetic:
|
||||
1.declare -a a=([0]="0" [1]="1")
|
||||
2.declare -a a=([0]="0" [1]="1")
|
||||
3.declare -a a=([0]="0" [1]="1")
|
||||
4.declare -a a=([0]="0" [1]="1")
|
||||
5.declare -a a=([0]="0" [1]="1")
|
||||
6.declare -a a=([0]="11" [1]="1")
|
||||
7.declare -a a=([0]="0" [1]="1")
|
||||
8.declare -a a=([0]="13" [1]="1")
|
||||
2. associative:
|
||||
reference:
|
||||
./array25.sub: line 47: ${a[ ]}: bad substitution
|
||||
2.
|
||||
./array25.sub: line 49: ${a[ ]}: bad substitution
|
||||
4.
|
||||
5.
|
||||
6.
|
||||
assignment:
|
||||
1.declare -A a=([" "]="10" [0]="0" [1]="1" )
|
||||
2.declare -A a=([" "]="11" [0]="0" [1]="1" )
|
||||
3.declare -A a=([" "]="12" [0]="0" [1]="1" )
|
||||
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
arithmetic:
|
||||
1.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
2.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
3.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
4.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
5.declare -A a=([" "]="13" [0]="0" [1]="1" )
|
||||
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" )
|
||||
|
||||
@@ -400,3 +400,4 @@ ${THIS_SH} ./array21.sub
|
||||
${THIS_SH} ./array22.sub
|
||||
${THIS_SH} ./array23.sub
|
||||
${THIS_SH} ./array24.sub
|
||||
${THIS_SH} ./array25.sub
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# tests with blank subscripts, indexed and associative
|
||||
|
||||
echo 1. indexed:
|
||||
a[0]=0 a[1]=1
|
||||
|
||||
v=" "
|
||||
|
||||
echo reference:
|
||||
|
||||
echo 1. ${a[ ]}
|
||||
echo 2. ${a[' ']}
|
||||
echo 3. "${a[ ]}"
|
||||
echo 4. ${a[$v]}
|
||||
echo 5. ${a["$v"]}
|
||||
echo 6. "${a[$v]}"
|
||||
|
||||
echo assignment:
|
||||
|
||||
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
|
||||
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
|
||||
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
|
||||
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
|
||||
|
||||
echo arithmetic:
|
||||
|
||||
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
|
||||
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
|
||||
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
|
||||
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
|
||||
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
|
||||
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
|
||||
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
|
||||
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
|
||||
|
||||
unset -v a v
|
||||
|
||||
echo 2. associative:
|
||||
shopt -s assoc_expand_once
|
||||
|
||||
typeset -A a
|
||||
a[0]=0 a[1]=1
|
||||
|
||||
v=" "
|
||||
|
||||
echo reference:
|
||||
|
||||
echo 1. ${a[ ]}
|
||||
echo 2. ${a[' ']}
|
||||
echo 3. "${a[ ]}"
|
||||
echo 4. ${a[$v]}
|
||||
echo 5. ${a["$v"]}
|
||||
echo 6. "${a[$v]}"
|
||||
|
||||
echo assignment:
|
||||
|
||||
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
|
||||
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
|
||||
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
|
||||
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
|
||||
|
||||
echo arithmetic:
|
||||
|
||||
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
|
||||
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
|
||||
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
|
||||
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
|
||||
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
|
||||
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
|
||||
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
|
||||
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
|
||||
+16
-4
@@ -127,10 +127,22 @@ after 2: 1
|
||||
after 3: 1
|
||||
array after 1: 1
|
||||
array after 2: 1
|
||||
./errors6.sub: line 18: ${-3}: bad substitution
|
||||
./errors6.sub: line 19: -3: invalid variable name
|
||||
./errors6.sub: uvar: parameter not set
|
||||
./errors6.sub: uvar: parameter null or not set
|
||||
|
||||
./errors6.sub: uvar: parameter null or not set
|
||||
./errors6.sub: line 25: ${-3:-${-3}}: bad substitution
|
||||
./errors6.sub: line 26: ${-3}: bad substitution
|
||||
./errors6.sub: line 27: -3: invalid variable name
|
||||
after indir: 1
|
||||
./errors6.sub: line 18: ${-3}: bad substitution
|
||||
./errors6.sub: line 19: -3: invalid variable name
|
||||
./errors6.sub: line 30: -3: invalid variable name
|
||||
./errors6.sub: uvar: parameter not set
|
||||
./errors6.sub: uvar: parameter null or not set
|
||||
|
||||
./errors6.sub: uvar: parameter null or not set
|
||||
./errors6.sub: line 25: ${-3:-${-3}}: bad substitution
|
||||
./errors6.sub: line 26: ${-3}: bad substitution
|
||||
./errors6.sub: line 27: -3: invalid variable name
|
||||
after indir: 1
|
||||
./errors6.sub: line 30: -3: invalid variable name
|
||||
./errors.tests: line 278: `!!': not a valid identifier
|
||||
|
||||
@@ -15,6 +15,17 @@ echo array after 1: $?' 2>/dev/null
|
||||
${THIS_SH} -c 'typeset -A v ; v["0"]=one ; echo ${v[ ]}
|
||||
echo array after 2: $?' 2>/dev/null
|
||||
|
||||
${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
|
||||
${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
|
||||
export uvar=
|
||||
${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
|
||||
${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
|
||||
unset uvar
|
||||
|
||||
echo "${-3:-${-3}}"
|
||||
echo ${-3}
|
||||
x=-3; echo ${!x}
|
||||
echo after indir: $?
|
||||
|
||||
function ivar() { echo -n "${!1:-${1}}"; }
|
||||
ivar -3
|
||||
|
||||
@@ -417,3 +417,19 @@ declare -a var=([123]="")
|
||||
declare -n ref="var[123]"
|
||||
./nameref18.sub: line 54: declare: var[123]: not found
|
||||
declare -a var=([123]="X")
|
||||
declare -n foo="bar"
|
||||
declare -- foo="bar"
|
||||
./nameref19.sub: line 9: declare: bar: not found
|
||||
declare -n foo="bar"
|
||||
declare -- foo="bar"
|
||||
declare -i bar="11"
|
||||
declare -inx foo6
|
||||
declare -ix foo6
|
||||
declare -n foo="bar"
|
||||
declare -- bar="Hello World!"
|
||||
declare -- foo="bar"
|
||||
declare -- bar="Hello World!"
|
||||
declare -n foo="bar"
|
||||
declare -- bar
|
||||
declare -- foo="bar"
|
||||
declare -- bar
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# can we unset the nameref attribute on variables with values that reference
|
||||
# unset variables?
|
||||
|
||||
unset bar
|
||||
declare -n foo="bar"
|
||||
declare -p foo
|
||||
|
||||
declare +n foo
|
||||
declare -p foo bar
|
||||
|
||||
declare -n foo
|
||||
declare -p foo
|
||||
|
||||
# let's try removing the nameref attribute -- other attributes and assignments
|
||||
# apply to the nameref target
|
||||
|
||||
declare +n -i foo=7+4
|
||||
declare -p foo bar
|
||||
|
||||
unset foo bar
|
||||
|
||||
# but if the nameref variable doesn't have a value, the attributes apply to
|
||||
# the nameref variable itself. thanks ksh93
|
||||
|
||||
declare -n foo6
|
||||
declare -xi foo6
|
||||
declare -p foo6
|
||||
|
||||
# and when we remove the nameref attribute, the other attributes remain
|
||||
|
||||
declare +n foo6
|
||||
declare -p foo6
|
||||
|
||||
unset foo6
|
||||
|
||||
# make sure these cases continue to work
|
||||
|
||||
# nameref referencing an existing, set variable
|
||||
declare -n foo=bar
|
||||
bar='Hello World!'
|
||||
declare -p foo bar
|
||||
declare +n foo
|
||||
declare -p foo bar
|
||||
unset foo bar
|
||||
|
||||
# nameref referencing an existing, unset variable
|
||||
declare -n foo=bar
|
||||
declare bar
|
||||
declare -p foo bar
|
||||
declare +n foo
|
||||
declare -p foo bar
|
||||
@@ -119,6 +119,15 @@ declare -ar i4=([0]="a" [1]="b" [2]="c")
|
||||
declare -ar j4=([0]="1" [1]="2" [2]="3")
|
||||
./varenv9.sub: line 66: unset: i4: cannot unset: readonly variable
|
||||
./varenv9.sub: line 66: unset: j4: cannot unset: readonly variable
|
||||
main: unset
|
||||
inner: res unset
|
||||
outer: res: X Y
|
||||
main: after first call: X
|
||||
inner: X
|
||||
outer: res: X Y
|
||||
main: after second call: X
|
||||
func: null or unset
|
||||
after func: x = outside
|
||||
a=z
|
||||
a=b
|
||||
a=z
|
||||
|
||||
@@ -225,5 +225,8 @@ ${THIS_SH} ./varenv8.sub
|
||||
# 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
|
||||
|
||||
# make sure variable scoping is done right
|
||||
tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# various tests of unset when applied to variables at different local scopes
|
||||
|
||||
# function unsetting variable at previous local scope, uncovering global
|
||||
|
||||
inner()
|
||||
{
|
||||
unset res
|
||||
echo ${FUNCNAME}: ${res-res unset}
|
||||
if [[ $1 == "set" ]]; then
|
||||
res[0]="X"
|
||||
res[1]="Y"
|
||||
fi
|
||||
}
|
||||
|
||||
outer()
|
||||
{
|
||||
local res=
|
||||
inner "$1"
|
||||
echo ${FUNCNAME}: "res: ${res[@]}"
|
||||
}
|
||||
|
||||
echo main: ${res-unset}
|
||||
outer set
|
||||
echo main: after first call: ${res-unset}
|
||||
outer dontset
|
||||
echo main: after second call: ${res-unset}
|
||||
|
||||
unset -f outer inner
|
||||
unset res
|
||||
|
||||
# local scope, unset variable at the same scope as local declaration
|
||||
func()
|
||||
{
|
||||
typeset x=4
|
||||
|
||||
unset x
|
||||
echo ${FUNCNAME}: ${x:-null or unset}
|
||||
}
|
||||
|
||||
x=outside
|
||||
func
|
||||
echo after func: x = $x
|
||||
|
||||
unset -f func
|
||||
unset x
|
||||
+7
-1
@@ -124,6 +124,11 @@ int variable_context = 0;
|
||||
with the same name at a previous scope. */
|
||||
int localvar_inherit = 0;
|
||||
|
||||
/* If non-zero, calling `unset' on local variables in previous scopes marks
|
||||
them as invisible so lookups find them unset. This is the same behavior
|
||||
as local variables in the current local scope. */
|
||||
int localvar_unset = 0;
|
||||
|
||||
/* The set of shell assignments which are made only in the environment
|
||||
for a single command. */
|
||||
HASH_TABLE *temporary_env = (HASH_TABLE *)NULL;
|
||||
@@ -3706,7 +3711,8 @@ makunbound (name, vc)
|
||||
must be done so that if the variable is subsequently assigned a new
|
||||
value inside the function, the `local' attribute is still present.
|
||||
We also need to add it back into the correct hash table. */
|
||||
if (old_var && local_p (old_var) && variable_context == old_var->context)
|
||||
if (old_var && local_p (old_var) &&
|
||||
(old_var->context == variable_context || (localvar_unset && old_var->context < variable_context)))
|
||||
{
|
||||
if (nofree_p (old_var))
|
||||
var_setvalue (old_var, (char *)NULL);
|
||||
|
||||
Reference in New Issue
Block a user