From 2dc823ee9663f2a011677aa95bfb5d183360d81f Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Mon, 26 Aug 2019 11:40:13 -0400 Subject: [PATCH] commit bash-20190823 snapshot --- patchlevel.h | 2 +- tests/varenv.right | 4 ++++ tests/varenv12.sub | 25 ++++++++++++++++++++++ variables.c | 52 ++++++++++++++++++++++++++++++++++------------ 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/patchlevel.h b/patchlevel.h index 02f1d6066..8002af709 100644 --- a/patchlevel.h +++ b/patchlevel.h @@ -25,6 +25,6 @@ regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh looks for to find the patch level (for the sccs version string). */ -#define PATCHLEVEL 9 +#define PATCHLEVEL 10 #endif /* _PATCHLEVEL_H_ */ diff --git a/tests/varenv.right b/tests/varenv.right index b86202273..82845dfe3 100644 --- a/tests/varenv.right +++ b/tests/varenv.right @@ -159,6 +159,10 @@ inside func1: var=value outside 3.0: var=value inside func2: var=global outside 4.0: var=outside +foo: hello world +after foo: var=outside +bar: hello world +after bar: var=bar: hello world ./varenv13.sub: line 3: `var[0]': not a valid identifier ./varenv13.sub: line 3: `var[@]': not a valid identifier ./varenv13.sub: line 1: declare: var: not found diff --git a/tests/varenv12.sub b/tests/varenv12.sub index 7e384ac77..f286cfbd7 100644 --- a/tests/varenv12.sub +++ b/tests/varenv12.sub @@ -131,3 +131,28 @@ func2() var=outside func2 echo -n 'outside 4.0: ' ; echo "var=${var-}" + +unset -v var +unset -f fecho foo bar + +fecho() { + echo $var +} + +foo() { + local var="foo: bye bye" + var="foo: hello world" fecho +} + +bar() { + var="bar: hello world" fecho +} + +var=global +var=outside foo +echo after foo: var=$var +var=global +var=outside bar +echo after bar: var=$var + +unset -v var diff --git a/variables.c b/variables.c index cbdd2d270..db3ccab60 100644 --- a/variables.c +++ b/variables.c @@ -4607,6 +4607,8 @@ push_posix_temp_var (data) "current execution environment." */ v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP); + /* XXX - do we need to worry about array variables here? */ + /* If this modifies an existing local variable, v->context will be non-zero. If it comes back with v->context == 0, we bound at the global context. Set binding_table appropriately. It doesn't matter whether it's correct @@ -4669,7 +4671,7 @@ push_temp_var (data) var->attributes &= ~(att_tempvar|att_propagate); else { - var->attributes |= att_propagate; + var->attributes |= att_propagate; /* XXX - propagate more than once? */ if (binding_table == shell_variables->table) shell_variables->flags |= VC_HASTMPVAR; } @@ -5299,10 +5301,10 @@ push_var_context (name, flags, tempvars) /* This can be called from one of two code paths: 1. pop_scope, which implements the posix rules for propagating variable assignments preceding special builtins to the surrounding scope - (push_builtin_var); + (push_builtin_var -- isbltin == 1); 2. pop_var_context, which is called from pop_context and implements the posix rules for propagating variable assignments preceding function - calls to the surrounding scope (push_func_var). + calls to the surrounding scope (push_func_var -- isbltin == 0) It takes variables out of a temporary environment hash table. We take the variable in data. @@ -5326,9 +5328,32 @@ push_posix_tempvar_internal (var, isbltin) posix_var_behavior = posixly_correct; #endif + v = 0; + if (local_p (var) && STREQ (var->name, "-")) set_current_options (value_cell (var)); +#if 0 /* TAG: bash-5.1 */ + /* This takes variable assignments preceding special builtins that can execute + multiple commands (source, eval, etc.) and performs the equivalent of + an assignment statement to modify the closest enclosing variable (the + posix "current execution environment"). This makes the behavior the same + as push_posix_temp_var; but the circumstances of calling are slightly + different. */ + else if (tempvar_p (var) && posix_var_behavior) + { + /* similar to push_posix_temp_var */ + v = bind_variable (var->name, value_cell (var), ASS_FORCE|ASS_NOLONGJMP); + if (v) + { + v->attributes |= var->attributes; + if (v->context == 0) + v->attributes &= ~(att_tempvar|att_propagate); + } + } + else if (tempvar_p (var) && propagate_p (var)) +#else else if (tempvar_p (var) && (posix_var_behavior || (var->attributes & att_propagate))) +#endif { /* Make sure we have a hash table to store the variable in while it is being propagated down to the global variables table. Create one if @@ -5339,16 +5364,6 @@ push_posix_tempvar_internal (var, isbltin) /* XXX - should we set v->context here? */ if (v) v->context = shell_variables->scope; -#if defined (ARRAY_VARS) - if (v && (array_p (var) || assoc_p (var))) - { - FREE (value_cell (v)); - if (array_p (var)) - var_setarray (v, array_copy (array_cell (var))); - else - var_setassoc (v, assoc_copy (assoc_cell (var))); - } -#endif if (shell_variables == global_variables) var->attributes &= ~(att_tempvar|att_propagate); else @@ -5359,6 +5374,17 @@ push_posix_tempvar_internal (var, isbltin) else stupidly_hack_special_variables (var->name); /* XXX */ +#if defined (ARRAY_VARS) + if (v && (array_p (var) || assoc_p (var))) + { + FREE (value_cell (v)); + if (array_p (var)) + var_setarray (v, array_copy (array_cell (var))); + else + var_setassoc (v, assoc_copy (assoc_cell (var))); + } +#endif + dispose_variable (var); } -- 2.47.2