mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-11 20:50:42 +02:00
bash-5.0-beta release
This commit is contained in:
+297
-45
@@ -110,6 +110,8 @@ VAR_CONTEXT *shell_variables = (VAR_CONTEXT *)NULL;
|
||||
the environment. */
|
||||
HASH_TABLE *shell_functions = (HASH_TABLE *)NULL;
|
||||
|
||||
HASH_TABLE *invalid_env = (HASH_TABLE *)NULL;
|
||||
|
||||
#if defined (DEBUGGER)
|
||||
/* The table of shell function definitions that the user defined or that
|
||||
came from the environment. */
|
||||
@@ -229,7 +231,9 @@ static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *get_groupset __P((SHELL_VAR *));
|
||||
|
||||
# if defined (DEBUGGER)
|
||||
static SHELL_VAR *get_bashargcv __P((SHELL_VAR *));
|
||||
# endif
|
||||
static SHELL_VAR *build_hashcmd __P((SHELL_VAR *));
|
||||
static SHELL_VAR *get_hashcmd __P((SHELL_VAR *));
|
||||
static SHELL_VAR *assign_hashcmd __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
@@ -245,6 +249,10 @@ static SHELL_VAR *init_funcname_var __P((void));
|
||||
|
||||
static void initialize_dynamic_variables __P((void));
|
||||
|
||||
static SHELL_VAR *bind_invalid_envvar __P((const char *, char *, int));
|
||||
|
||||
static int var_sametype __P((SHELL_VAR *, SHELL_VAR *));
|
||||
|
||||
static SHELL_VAR *hash_lookup __P((const char *, HASH_TABLE *));
|
||||
static SHELL_VAR *new_shell_variable __P((const char *));
|
||||
static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
|
||||
@@ -391,7 +399,7 @@ initialize_shell_variables (env, privmode)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (temp_var = bind_variable (name, string, 0))
|
||||
if (temp_var = bind_invalid_envvar (name, string, 0))
|
||||
{
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
array_needs_making = 1;
|
||||
@@ -432,17 +440,24 @@ initialize_shell_variables (env, privmode)
|
||||
if (temp_var)
|
||||
VUNSETATTR (temp_var, att_readonly);
|
||||
}
|
||||
temp_var = bind_variable (name, string, 0);
|
||||
if (temp_var)
|
||||
if (legal_identifier (name))
|
||||
{
|
||||
if (legal_identifier (name))
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
else
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
if (ro)
|
||||
VSETATTR (temp_var, att_readonly);
|
||||
array_needs_making = 1;
|
||||
temp_var = bind_variable (name, string, 0);
|
||||
if (temp_var)
|
||||
{
|
||||
VSETATTR (temp_var, (att_exported | att_imported));
|
||||
if (ro)
|
||||
VSETATTR (temp_var, att_readonly);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_var = bind_invalid_envvar (name, string, 0);
|
||||
if (temp_var)
|
||||
VSETATTR (temp_var, (att_exported | att_imported | att_invisible));
|
||||
}
|
||||
if (temp_var)
|
||||
array_needs_making = 1;
|
||||
}
|
||||
|
||||
name[char_index] = '=';
|
||||
@@ -1652,6 +1667,27 @@ get_groupset (self)
|
||||
return (self);
|
||||
}
|
||||
|
||||
# if defined (DEBUGGER)
|
||||
static SHELL_VAR *
|
||||
get_bashargcv (self)
|
||||
SHELL_VAR *self;
|
||||
{
|
||||
static int self_semaphore = 0;
|
||||
|
||||
/* Backwards compatibility: if we refer to BASH_ARGV or BASH_ARGC at the
|
||||
top level without enabling debug mode, and we don't have an instance
|
||||
of the variable set, initialize the arg arrays.
|
||||
This will already have been done if debugging_mode != 0. */
|
||||
if (self_semaphore == 0 && variable_context == 0 && debugging_mode == 0) /* don't do it for shell functions */
|
||||
{
|
||||
self_semaphore = 1;
|
||||
init_bash_argv ();
|
||||
self_semaphore = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
# endif
|
||||
|
||||
static SHELL_VAR *
|
||||
build_hashcmd (self)
|
||||
SHELL_VAR *self;
|
||||
@@ -1777,6 +1813,11 @@ assign_aliasvar (self, value, ind, key)
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
{
|
||||
if (legal_alias_name (key, 0) == 0)
|
||||
{
|
||||
report_error (_("`%s': invalid alias name"), key);
|
||||
return (self);
|
||||
}
|
||||
add_alias (key, value);
|
||||
return (build_aliasvar (self));
|
||||
}
|
||||
@@ -1877,8 +1918,8 @@ initialize_dynamic_variables ()
|
||||
v = init_dynamic_array_var ("GROUPS", get_groupset, null_array_assign, att_noassign);
|
||||
|
||||
# if defined (DEBUGGER)
|
||||
v = init_dynamic_array_var ("BASH_ARGC", get_self, null_array_assign, att_noassign|att_nounset);
|
||||
v = init_dynamic_array_var ("BASH_ARGV", get_self, null_array_assign, att_noassign|att_nounset);
|
||||
v = init_dynamic_array_var ("BASH_ARGC", get_bashargcv, null_array_assign, att_noassign|att_nounset);
|
||||
v = init_dynamic_array_var ("BASH_ARGV", get_bashargcv, null_array_assign, att_noassign|att_nounset);
|
||||
# endif /* DEBUGGER */
|
||||
v = init_dynamic_array_var ("BASH_SOURCE", get_self, null_array_assign, att_noassign|att_nounset);
|
||||
v = init_dynamic_array_var ("BASH_LINENO", get_self, null_array_assign, att_noassign|att_nounset);
|
||||
@@ -2226,6 +2267,36 @@ find_variable_nameref_for_assignment (name, flags)
|
||||
return (var);
|
||||
}
|
||||
|
||||
/* If find_variable (name) returns NULL, check that it's not a nameref
|
||||
referencing a variable that doesn't exist. If it is, return the new
|
||||
name. If not, return the original name. Kind of like the previous
|
||||
function, but dealing strictly with names. This takes assignment flags
|
||||
so it can deal with the various assignment modes used by `declare'. */
|
||||
char *
|
||||
nameref_transform_name (name, flags)
|
||||
char *name;
|
||||
int flags;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
char *newname;
|
||||
|
||||
v = 0;
|
||||
if (flags & ASS_MKLOCAL)
|
||||
{
|
||||
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);
|
||||
if (v && nameref_p (v) && valid_nameref_value (nameref_cell (v), 1))
|
||||
return nameref_cell (v);
|
||||
return name;
|
||||
}
|
||||
|
||||
/* Find a variable, forcing a search of the temporary environment first */
|
||||
SHELL_VAR *
|
||||
find_variable_tempenv (name)
|
||||
@@ -2438,6 +2509,42 @@ sh_get_env_value (v)
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static int
|
||||
var_sametype (v1, v2)
|
||||
SHELL_VAR *v1;
|
||||
SHELL_VAR *v2;
|
||||
{
|
||||
if (v1 == 0 || v2 == 0)
|
||||
return 0;
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (assoc_p (v1) && assoc_p (v2))
|
||||
return 1;
|
||||
else if (array_p (v1) && array_p (v2))
|
||||
return 1;
|
||||
else if (array_p (v1) || array_p (v2))
|
||||
return 0;
|
||||
else if (assoc_p (v1) || assoc_p (v2))
|
||||
return 0;
|
||||
#endif
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
validate_inherited_value (var, type)
|
||||
SHELL_VAR *var;
|
||||
int type;
|
||||
{
|
||||
#if defined (ARRAY_VARS)
|
||||
if (type == att_array && assoc_p (var))
|
||||
return 0;
|
||||
else if (type == att_assoc && array_p (var))
|
||||
return 0;
|
||||
else
|
||||
#endif
|
||||
return 1; /* should we run convert_var_to_array here or let the caller? */
|
||||
}
|
||||
|
||||
/* Set NAME to VALUE if NAME has no value. */
|
||||
SHELL_VAR *
|
||||
set_if_not (name, value)
|
||||
@@ -2672,13 +2779,31 @@ make_local_array_variable (name, assoc_ok)
|
||||
ARRAY *array;
|
||||
|
||||
var = make_local_variable (name, 0); /* XXX for now */
|
||||
/* If ASSOC_OK is non-zero, assume that we are ok with letting an assoc
|
||||
variable return to the caller without converting it. The caller will
|
||||
either flag an error or do the conversion itself. */
|
||||
if (var == 0 || array_p (var) || (assoc_ok && assoc_p (var)))
|
||||
return var;
|
||||
|
||||
array = array_create ();
|
||||
/* 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);
|
||||
}
|
||||
|
||||
dispose_variable_value (var);
|
||||
var_setarray (var, array);
|
||||
VSETATTR (var, att_array);
|
||||
return var;
|
||||
}
|
||||
@@ -2699,20 +2824,39 @@ make_new_assoc_variable (name)
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
make_local_assoc_variable (name)
|
||||
make_local_assoc_variable (name, array_ok)
|
||||
char *name;
|
||||
int array_ok;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
HASH_TABLE *hash;
|
||||
|
||||
var = make_local_variable (name, 0); /* XXX for now */
|
||||
if (var == 0 || assoc_p (var))
|
||||
/* If ARRAY_OK is non-zero, assume that we are ok with letting an array
|
||||
variable return to the caller without converting it. The caller will
|
||||
either flag an error or do the conversion itself. */
|
||||
if (var == 0 || assoc_p (var) || (array_ok && array_p (var)))
|
||||
return var;
|
||||
|
||||
dispose_variable_value (var);
|
||||
hash = assoc_create (0);
|
||||
/* 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);
|
||||
}
|
||||
|
||||
var_setassoc (var, hash);
|
||||
VSETATTR (var, att_assoc);
|
||||
return var;
|
||||
}
|
||||
@@ -2911,7 +3055,12 @@ bind_variable_internal (name, value, table, hflags, aflags)
|
||||
}
|
||||
else if (entry && nameref_p (entry))
|
||||
{
|
||||
newval = nameref_cell (entry);
|
||||
newval = nameref_cell (entry); /* XXX - newval can't be NULL here */
|
||||
if (valid_nameref_value (newval, 0) == 0)
|
||||
{
|
||||
sh_invalidid (newval);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
#if defined (ARRAY_VARS)
|
||||
/* declare -n foo=x[2] ; foo=bar */
|
||||
if (valid_array_reference (newval, 0))
|
||||
@@ -3124,6 +3273,17 @@ bind_global_variable (name, value, flags)
|
||||
return (bind_variable_internal (name, value, global_variables->table, 0, flags));
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
bind_invalid_envvar (name, value, flags)
|
||||
const char *name;
|
||||
char *value;
|
||||
int flags;
|
||||
{
|
||||
if (invalid_env == 0)
|
||||
invalid_env = hash_create (64); /* XXX */
|
||||
return (bind_variable_internal (name, value, invalid_env, HASH_NOSRCH, flags));
|
||||
}
|
||||
|
||||
/* Make VAR, a simple shell variable, have value VALUE. Once assigned a
|
||||
value, variables are no longer invisible. This is a duplicate of part
|
||||
of the internals of bind_variable. If the variable is exported, or
|
||||
@@ -3374,6 +3534,12 @@ assign_in_env (word, flags)
|
||||
aflags |= ASS_APPEND;
|
||||
}
|
||||
|
||||
if (legal_identifier (name) == 0)
|
||||
{
|
||||
sh_invalidid (name);
|
||||
return (0);
|
||||
}
|
||||
|
||||
var = find_variable (name);
|
||||
if (var == 0)
|
||||
{
|
||||
@@ -4741,7 +4907,7 @@ maybe_make_export_env ()
|
||||
{
|
||||
register char **temp_array;
|
||||
int new_size;
|
||||
VAR_CONTEXT *tcxt;
|
||||
VAR_CONTEXT *tcxt, *icxt;
|
||||
|
||||
if (array_needs_making)
|
||||
{
|
||||
@@ -4753,7 +4919,7 @@ maybe_make_export_env ()
|
||||
variables are not (yet) exported, this will always be big enough
|
||||
for the exported variables and functions. */
|
||||
new_size = n_shell_variables () + HASH_ENTRIES (shell_functions) + 1 +
|
||||
HASH_ENTRIES (temporary_env);
|
||||
HASH_ENTRIES (temporary_env) + HASH_ENTRIES (invalid_env);
|
||||
if (new_size > export_env_size)
|
||||
{
|
||||
export_env_size = new_size;
|
||||
@@ -4774,11 +4940,23 @@ maybe_make_export_env ()
|
||||
}
|
||||
else
|
||||
tcxt = shell_variables;
|
||||
|
||||
if (invalid_env)
|
||||
{
|
||||
icxt = new_var_context ((char *)NULL, 0);
|
||||
icxt->table = invalid_env;
|
||||
icxt->down = tcxt;
|
||||
}
|
||||
else
|
||||
icxt = tcxt;
|
||||
|
||||
temp_array = make_var_export_array (tcxt);
|
||||
temp_array = make_var_export_array (icxt);
|
||||
if (temp_array)
|
||||
add_temp_array_to_env (temp_array, 0, 0);
|
||||
|
||||
if (icxt != tcxt)
|
||||
free (icxt);
|
||||
|
||||
if (tcxt != shell_variables)
|
||||
free (tcxt);
|
||||
|
||||
@@ -4893,13 +5071,14 @@ push_var_context (name, flags, tempvars)
|
||||
|
||||
/* As of IEEE Std 1003.1-2017, assignment statements preceding shell
|
||||
functions no longer behave like assignment statements preceding
|
||||
special builtins, and do not persist in the current shell environment. */
|
||||
posix_func_behavior = posixly_correct; /* placeholder for later */
|
||||
special builtins, and do not persist in the current shell environment.
|
||||
This is austin group interp #654, though nobody implements it yet. */
|
||||
posix_func_behavior = posixly_correct;
|
||||
|
||||
vc = new_var_context (name, flags);
|
||||
/* Posix interp 1009, temporary assignments preceding function calls modify
|
||||
the current environment *before* the command is executed. */
|
||||
if (posix_func_behavior && tempvars == temporary_env)
|
||||
if (posix_func_behavior && (flags & VC_FUNCENV) && tempvars == temporary_env)
|
||||
merge_temporary_env ();
|
||||
else if (tempvars)
|
||||
{
|
||||
@@ -4923,24 +5102,25 @@ push_var_context (name, flags, tempvars)
|
||||
calls to the surrounding scope.
|
||||
|
||||
It takes variables out of a temporary environment hash table. We take the
|
||||
variable in data
|
||||
variable in data.
|
||||
*/
|
||||
static void
|
||||
push_func_var (data)
|
||||
PTR_T data;
|
||||
{
|
||||
SHELL_VAR *var, *v;
|
||||
int posix_func_behavior;
|
||||
int posix_var_behavior;
|
||||
|
||||
var = (SHELL_VAR *)data;
|
||||
/* As of IEEE Std 1003.1-2017, assignment statements preceding shell
|
||||
functions no longer behave like assignment statements preceding
|
||||
special builtins, and do not persist in the current shell environment. */
|
||||
posix_func_behavior = posixly_correct; /* placeholder for later */
|
||||
special builtins, and do not persist in the current shell environment.
|
||||
This is austin group interp #654, though nobody implements it yet. */
|
||||
posix_var_behavior = posixly_correct;
|
||||
|
||||
if (local_p (var) && STREQ (var->name, "-"))
|
||||
set_current_options (value_cell (var));
|
||||
else if (tempvar_p (var) && (posix_func_behavior || (var->attributes & att_propagate)))
|
||||
else if (tempvar_p (var) && (posix_var_behavior || (var->attributes & att_propagate)))
|
||||
{
|
||||
/* 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
|
||||
@@ -5110,10 +5290,64 @@ pop_scope (is_special)
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
static WORD_LIST **dollar_arg_stack = (WORD_LIST **)NULL;
|
||||
struct saved_dollar_vars {
|
||||
char **first_ten;
|
||||
WORD_LIST *rest;
|
||||
};
|
||||
|
||||
static struct saved_dollar_vars *dollar_arg_stack = (struct saved_dollar_vars *)NULL;
|
||||
static int dollar_arg_stack_slots;
|
||||
static int dollar_arg_stack_index;
|
||||
|
||||
/* Functions to manipulate dollar_vars array. Need to keep these in sync with
|
||||
whatever remember_args() does. */
|
||||
static char **
|
||||
save_dollar_vars ()
|
||||
{
|
||||
char **ret;
|
||||
int i;
|
||||
|
||||
ret = strvec_create (10);
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
ret[i] = dollar_vars[i];
|
||||
dollar_vars[i] = (char *)NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
restore_dollar_vars (args)
|
||||
char **args;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
dollar_vars[i] = args[i];
|
||||
}
|
||||
|
||||
static void
|
||||
free_dollar_vars ()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
{
|
||||
FREE (dollar_vars[i]);
|
||||
dollar_vars[i] = (char *)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_saved_dollar_vars (args)
|
||||
char **args;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < 10; i++)
|
||||
FREE (args[i]);
|
||||
}
|
||||
|
||||
/* XXX - should always be followed by remember_args () */
|
||||
void
|
||||
push_context (name, is_subshell, tempvars)
|
||||
@@ -5145,35 +5379,53 @@ push_dollar_vars ()
|
||||
{
|
||||
if (dollar_arg_stack_index + 2 > dollar_arg_stack_slots)
|
||||
{
|
||||
dollar_arg_stack = (WORD_LIST **)
|
||||
dollar_arg_stack = (struct saved_dollar_vars *)
|
||||
xrealloc (dollar_arg_stack, (dollar_arg_stack_slots += 10)
|
||||
* sizeof (WORD_LIST *));
|
||||
* sizeof (struct saved_dollar_vars));
|
||||
}
|
||||
dollar_arg_stack[dollar_arg_stack_index++] = list_rest_of_args ();
|
||||
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
|
||||
|
||||
dollar_arg_stack[dollar_arg_stack_index].first_ten = save_dollar_vars ();
|
||||
dollar_arg_stack[dollar_arg_stack_index++].rest = rest_of_args;
|
||||
rest_of_args = (WORD_LIST *)NULL;
|
||||
|
||||
dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
|
||||
dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
|
||||
}
|
||||
|
||||
/* Restore the positional parameters from our stack. */
|
||||
void
|
||||
pop_dollar_vars ()
|
||||
{
|
||||
if (!dollar_arg_stack || dollar_arg_stack_index == 0)
|
||||
if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
|
||||
return;
|
||||
|
||||
remember_args (dollar_arg_stack[--dollar_arg_stack_index], 1);
|
||||
dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
|
||||
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
|
||||
/* Do what remember_args (xxx, 1) would have done. */
|
||||
free_dollar_vars ();
|
||||
dispose_words (rest_of_args);
|
||||
|
||||
rest_of_args = dollar_arg_stack[--dollar_arg_stack_index].rest;
|
||||
restore_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten);
|
||||
free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
|
||||
|
||||
dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
|
||||
dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
|
||||
|
||||
set_dollar_vars_unchanged ();
|
||||
invalidate_cached_quoted_dollar_at ();
|
||||
}
|
||||
|
||||
void
|
||||
dispose_saved_dollar_vars ()
|
||||
{
|
||||
if (!dollar_arg_stack || dollar_arg_stack_index == 0)
|
||||
if (dollar_arg_stack == 0 || dollar_arg_stack_index == 0)
|
||||
return;
|
||||
|
||||
dispose_words (dollar_arg_stack[dollar_arg_stack_index]);
|
||||
dollar_arg_stack[dollar_arg_stack_index] = (WORD_LIST *)NULL;
|
||||
dispose_words (dollar_arg_stack[--dollar_arg_stack_index].rest);
|
||||
free_saved_dollar_vars (dollar_arg_stack[dollar_arg_stack_index].first_ten);
|
||||
free (dollar_arg_stack[dollar_arg_stack_index].first_ten);
|
||||
|
||||
dollar_arg_stack[dollar_arg_stack_index].first_ten = (char **)NULL;
|
||||
dollar_arg_stack[dollar_arg_stack_index].rest = (WORD_LIST *)NULL;
|
||||
}
|
||||
|
||||
/* Initialize BASH_ARGV and BASH_ARGC after turning on extdebug after the
|
||||
|
||||
Reference in New Issue
Block a user