mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-07 02:32:27 +02:00
commit bash-20080626 snapshot
This commit is contained in:
+328
-80
@@ -1,6 +1,6 @@
|
||||
/* variables.c -- Functions for hacking shell variables. */
|
||||
|
||||
/* Copyright (C) 1987-2007 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1987-2008 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "input.h"
|
||||
#include "hashcmd.h"
|
||||
#include "pathexp.h"
|
||||
#include "alias.h"
|
||||
|
||||
#include "builtins/getopt.h"
|
||||
#include "builtins/common.h"
|
||||
@@ -169,30 +170,31 @@ static void uidset __P((void));
|
||||
static void make_vers_array __P((void));
|
||||
#endif
|
||||
|
||||
static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *null_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *null_array_assign __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
#endif
|
||||
static SHELL_VAR *get_self __P((SHELL_VAR *));
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *init_dynamic_array_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
|
||||
static SHELL_VAR *init_dynamic_assoc_var __P((char *, sh_var_value_func_t *, sh_var_assign_func_t *, int));
|
||||
#endif
|
||||
|
||||
static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *assign_seconds __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
static SHELL_VAR *get_seconds __P((SHELL_VAR *));
|
||||
static SHELL_VAR *init_seconds_var __P((void));
|
||||
|
||||
static int brand __P((void));
|
||||
static void sbrand __P((unsigned long)); /* set bash random number generator. */
|
||||
static void seedrand __P((void)); /* seed generator randomly */
|
||||
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *assign_random __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
static SHELL_VAR *get_random __P((SHELL_VAR *));
|
||||
|
||||
static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *assign_lineno __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
static SHELL_VAR *get_lineno __P((SHELL_VAR *));
|
||||
|
||||
static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *assign_subshell __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
static SHELL_VAR *get_subshell __P((SHELL_VAR *));
|
||||
|
||||
static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
|
||||
@@ -201,13 +203,25 @@ static SHELL_VAR *get_bashpid __P((SHELL_VAR *));
|
||||
static SHELL_VAR *get_histcmd __P((SHELL_VAR *));
|
||||
#endif
|
||||
|
||||
#if defined (READLINE)
|
||||
static SHELL_VAR *get_comp_wordbreaks __P((SHELL_VAR *));
|
||||
static SHELL_VAR *assign_comp_wordbreaks __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
#endif
|
||||
|
||||
#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
|
||||
static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t));
|
||||
static SHELL_VAR *assign_dirstack __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
static SHELL_VAR *get_dirstack __P((SHELL_VAR *));
|
||||
#endif
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *get_groupset __P((SHELL_VAR *));
|
||||
|
||||
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 *));
|
||||
static SHELL_VAR *build_aliasvar __P((SHELL_VAR *));
|
||||
static SHELL_VAR *get_aliasvar __P((SHELL_VAR *));
|
||||
static SHELL_VAR *assign_aliasvar __P((SHELL_VAR *, char *, arrayind_t, char *));
|
||||
#endif
|
||||
|
||||
static SHELL_VAR *get_funcname __P((SHELL_VAR *));
|
||||
@@ -220,6 +234,7 @@ static SHELL_VAR *new_shell_variable __P((const char *));
|
||||
static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *));
|
||||
static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int));
|
||||
|
||||
static void dispose_variable_value __P((SHELL_VAR *));
|
||||
static void free_variable_hash_data __P((PTR_T));
|
||||
|
||||
static VARLIST *vlist_alloc __P((int));
|
||||
@@ -941,6 +956,8 @@ print_assignment (var)
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
print_array_assignment (var, 0);
|
||||
else if (assoc_p (var))
|
||||
print_assoc_assignment (var, 0);
|
||||
#endif /* ARRAY_VARS */
|
||||
else
|
||||
{
|
||||
@@ -1052,21 +1069,32 @@ print_var_function (var)
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define INIT_DYNAMIC_ASSOC_VAR(var, gfunc, afunc) \
|
||||
do \
|
||||
{ \
|
||||
v = make_new_assoc_variable (var); \
|
||||
v->dynamic_value = gfunc; \
|
||||
v->assign_func = afunc; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
static SHELL_VAR *
|
||||
null_assign (self, value, unused)
|
||||
null_assign (self, value, unused, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
return (self);
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
static SHELL_VAR *
|
||||
null_array_assign (self, value, ind)
|
||||
null_array_assign (self, value, ind, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
{
|
||||
return (self);
|
||||
}
|
||||
@@ -1101,8 +1129,25 @@ init_dynamic_array_var (name, getfunc, setfunc, attrs)
|
||||
VSETATTR (v, attrs);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
static SHELL_VAR *
|
||||
init_dynamic_assoc_var (name, getfunc, setfunc, attrs)
|
||||
char *name;
|
||||
sh_var_value_func_t *getfunc;
|
||||
sh_var_assign_func_t *setfunc;
|
||||
int attrs;
|
||||
{
|
||||
SHELL_VAR *v;
|
||||
|
||||
v = find_variable (name);
|
||||
if (v)
|
||||
return (v);
|
||||
INIT_DYNAMIC_ASSOC_VAR (name, getfunc, setfunc);
|
||||
if (attrs)
|
||||
VSETATTR (v, attrs);
|
||||
return v;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The value of $SECONDS. This is the number of seconds since shell
|
||||
invocation, or, the number of seconds since the last assignment + the
|
||||
@@ -1110,10 +1155,11 @@ init_dynamic_array_var (name, getfunc, setfunc, attrs)
|
||||
static intmax_t seconds_value_assigned;
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_seconds (self, value, unused)
|
||||
assign_seconds (self, value, unused, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
if (legal_number (value, &seconds_value_assigned) == 0)
|
||||
seconds_value_assigned = 0;
|
||||
@@ -1205,10 +1251,11 @@ seedrand ()
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_random (self, value, unused)
|
||||
assign_random (self, value, unused, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
sbrand (strtoul (value, (char **)NULL, 10));
|
||||
if (subshell_environment)
|
||||
@@ -1254,10 +1301,11 @@ get_random (var)
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_lineno (var, value, unused)
|
||||
assign_lineno (var, value, unused, key)
|
||||
SHELL_VAR *var;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
intmax_t new_value;
|
||||
|
||||
@@ -1283,10 +1331,11 @@ get_lineno (var)
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_subshell (var, value, unused)
|
||||
assign_subshell (var, value, unused, key)
|
||||
SHELL_VAR *var;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
intmax_t new_value;
|
||||
|
||||
@@ -1329,7 +1378,7 @@ get_bash_command (var)
|
||||
SHELL_VAR *var;
|
||||
{
|
||||
char *p;
|
||||
|
||||
|
||||
if (the_printed_command_except_trap)
|
||||
p = savestring (the_printed_command_except_trap);
|
||||
else
|
||||
@@ -1366,7 +1415,6 @@ get_comp_wordbreaks (var)
|
||||
if (rl_completer_word_break_characters == 0 && bash_readline_initialized == 0)
|
||||
enable_hostname_completion (perform_hostname_completion);
|
||||
|
||||
itrace("get: rl_completer_word_break_characters = `%s'", rl_completer_word_break_characters);
|
||||
var_setvalue (var, rl_completer_word_break_characters);
|
||||
|
||||
return (var);
|
||||
@@ -1375,27 +1423,28 @@ itrace("get: rl_completer_word_break_characters = `%s'", rl_completer_word_break
|
||||
/* When this function returns, rl_completer_word_break_characters points to
|
||||
malloced memory. */
|
||||
static SHELL_VAR *
|
||||
assign_comp_wordbreaks (self, value, unused)
|
||||
assign_comp_wordbreaks (self, value, unused, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t unused;
|
||||
char *key;
|
||||
{
|
||||
if (rl_completer_word_break_characters &&
|
||||
rl_completer_word_break_characters != rl_basic_word_break_characters)
|
||||
free (rl_completer_word_break_characters);
|
||||
|
||||
rl_completer_word_break_characters = savestring (value);
|
||||
itrace("assign: rl_completer_word_break_characters = `%s'", rl_completer_word_break_characters);
|
||||
return self;
|
||||
}
|
||||
#endif /* READLINE */
|
||||
|
||||
#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
|
||||
static SHELL_VAR *
|
||||
assign_dirstack (self, value, ind)
|
||||
assign_dirstack (self, value, ind, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
{
|
||||
set_dirstack_element (ind, 1, value);
|
||||
return self;
|
||||
@@ -1438,6 +1487,112 @@ get_groupset (self)
|
||||
}
|
||||
return (self);
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
build_hashcmd (self)
|
||||
SHELL_VAR *self;
|
||||
{
|
||||
HASH_TABLE *h;
|
||||
int i;
|
||||
char *k, *v;
|
||||
BUCKET_CONTENTS *item;
|
||||
|
||||
h = assoc_cell (self);
|
||||
if (h)
|
||||
assoc_dispose (h);
|
||||
|
||||
if (hashed_filenames == 0 || HASH_ENTRIES (hashed_filenames) == 0)
|
||||
{
|
||||
var_setvalue (self, (char *)NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
h = assoc_create (hashed_filenames->nbuckets);
|
||||
for (i = 0; i < hashed_filenames->nbuckets; i++)
|
||||
{
|
||||
for (item = hash_items (i, hashed_filenames); item; item = item->next)
|
||||
{
|
||||
k = savestring (item->key);
|
||||
v = pathdata(item)->path;
|
||||
assoc_insert (h, k, v);
|
||||
}
|
||||
}
|
||||
|
||||
var_setvalue (self, (char *)h);
|
||||
return self;
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
get_hashcmd (self)
|
||||
SHELL_VAR *self;
|
||||
{
|
||||
build_hashcmd (self);
|
||||
return (self);
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_hashcmd (self, value, ind, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
{
|
||||
phash_insert (key, value, 0, 0);
|
||||
return (build_hashcmd (self));
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
build_aliasvar (self)
|
||||
SHELL_VAR *self;
|
||||
{
|
||||
HASH_TABLE *h;
|
||||
int i;
|
||||
char *k, *v;
|
||||
BUCKET_CONTENTS *item;
|
||||
|
||||
h = assoc_cell (self);
|
||||
if (h)
|
||||
assoc_dispose (h);
|
||||
|
||||
if (aliases == 0 || HASH_ENTRIES (aliases) == 0)
|
||||
{
|
||||
var_setvalue (self, (char *)NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
h = assoc_create (aliases->nbuckets);
|
||||
for (i = 0; i < aliases->nbuckets; i++)
|
||||
{
|
||||
for (item = hash_items (i, aliases); item; item = item->next)
|
||||
{
|
||||
k = savestring (item->key);
|
||||
v = ((alias_t *)(item->data))->value;
|
||||
assoc_insert (h, k, v);
|
||||
}
|
||||
}
|
||||
|
||||
var_setvalue (self, (char *)h);
|
||||
return self;
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
get_aliasvar (self)
|
||||
SHELL_VAR *self;
|
||||
{
|
||||
build_aliasvar (self);
|
||||
return (self);
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
assign_aliasvar (self, value, ind, key)
|
||||
SHELL_VAR *self;
|
||||
char *value;
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
{
|
||||
add_alias (key, value);
|
||||
return (build_aliasvar (self));
|
||||
}
|
||||
#endif /* ARRAY_VARS */
|
||||
|
||||
/* If ARRAY_VARS is not defined, this just returns the name of any
|
||||
@@ -1531,6 +1686,9 @@ initialize_dynamic_variables ()
|
||||
# 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);
|
||||
|
||||
v = init_dynamic_assoc_var ("BASH_CMDS", get_hashcmd, assign_hashcmd, att_nofree);
|
||||
v = init_dynamic_assoc_var ("BASH_ALIASES", get_aliasvar, assign_aliasvar, att_nofree);
|
||||
#endif
|
||||
|
||||
v = init_funcname_var ();
|
||||
@@ -1577,7 +1735,7 @@ var_lookup (name, vcontext)
|
||||
then also search the temporarily built list of exported variables.
|
||||
The lookup order is:
|
||||
temporary_env
|
||||
shell_variables list
|
||||
shell_variables list
|
||||
*/
|
||||
|
||||
SHELL_VAR *
|
||||
@@ -1650,6 +1808,8 @@ get_variable_value (var)
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
return (array_reference (array_cell (var), 0));
|
||||
else if (assoc_p (var))
|
||||
return (assoc_reference (assoc_cell (var), "0"));
|
||||
#endif
|
||||
else
|
||||
return (value_cell (var));
|
||||
@@ -1759,7 +1919,7 @@ make_local_variable (name)
|
||||
inherit its value. Watch to see if this causes problems with
|
||||
things like `x=4 local x'. */
|
||||
if (was_tmpvar)
|
||||
var_setvalue (new_var, savestring (tmp_value));
|
||||
var_setvalue (new_var, savestring (tmp_value));
|
||||
|
||||
new_var->attributes = exported_p (old_var) ? att_exported : 0;
|
||||
}
|
||||
@@ -1775,27 +1935,6 @@ make_local_variable (name)
|
||||
return (new_var);
|
||||
}
|
||||
|
||||
#if defined (ARRAY_VARS)
|
||||
SHELL_VAR *
|
||||
make_local_array_variable (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
ARRAY *array;
|
||||
|
||||
var = make_local_variable (name);
|
||||
if (var == 0 || array_p (var))
|
||||
return var;
|
||||
|
||||
array = array_create ();
|
||||
|
||||
FREE (value_cell(var));
|
||||
var_setarray (var, array);
|
||||
VSETATTR (var, att_array);
|
||||
return var;
|
||||
}
|
||||
#endif /* ARRAY_VARS */
|
||||
|
||||
/* Create a new shell variable with name NAME. */
|
||||
static SHELL_VAR *
|
||||
new_shell_variable (name)
|
||||
@@ -1854,10 +1993,64 @@ make_new_array_variable (name)
|
||||
|
||||
entry = make_new_variable (name, global_variables->table);
|
||||
array = array_create ();
|
||||
|
||||
var_setarray (entry, array);
|
||||
VSETATTR (entry, att_array);
|
||||
return entry;
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
make_local_array_variable (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
ARRAY *array;
|
||||
|
||||
var = make_local_variable (name);
|
||||
if (var == 0 || array_p (var))
|
||||
return var;
|
||||
|
||||
array = array_create ();
|
||||
|
||||
dispose_variable_value (var);
|
||||
var_setarray (var, array);
|
||||
VSETATTR (var, att_array);
|
||||
return var;
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
make_new_assoc_variable (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *entry;
|
||||
HASH_TABLE *hash;
|
||||
|
||||
entry = make_new_variable (name, global_variables->table);
|
||||
hash = assoc_create (0);
|
||||
|
||||
var_setassoc (entry, hash);
|
||||
VSETATTR (entry, att_assoc);
|
||||
return entry;
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
make_local_assoc_variable (name)
|
||||
char *name;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
HASH_TABLE *hash;
|
||||
|
||||
var = make_local_variable (name);
|
||||
if (var == 0 || assoc_p (var))
|
||||
return var;
|
||||
|
||||
dispose_variable_value (var);
|
||||
hash = assoc_create (0);
|
||||
|
||||
var_setassoc (var, hash);
|
||||
VSETATTR (var, att_assoc);
|
||||
return var;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
@@ -1868,7 +2061,7 @@ make_variable_value (var, value, flags)
|
||||
{
|
||||
char *retval, *oval;
|
||||
intmax_t lval, rval;
|
||||
int expok, olen;
|
||||
int expok, olen, op;
|
||||
|
||||
/* If this variable has had its type set to integer (via `declare -i'),
|
||||
then do expression evaluation on it and store the result. The
|
||||
@@ -1897,6 +2090,34 @@ make_variable_value (var, value, flags)
|
||||
rval += lval;
|
||||
retval = itos (rval);
|
||||
}
|
||||
#if defined (CASEMOD_ATTRS)
|
||||
else if (capcase_p (var) || uppercase_p (var) || lowercase_p (var))
|
||||
{
|
||||
if (flags & ASS_APPEND)
|
||||
{
|
||||
oval = get_variable_value (var);
|
||||
if (oval == 0) /* paranoia */
|
||||
oval = "";
|
||||
olen = STRLEN (oval);
|
||||
retval = (char *)xmalloc (olen + (value ? STRLEN (value) : 0) + 1);
|
||||
strcpy (retval, oval);
|
||||
if (value)
|
||||
strcpy (retval+olen, value);
|
||||
}
|
||||
#endif /* CASEMOD_ATTRS */
|
||||
else if (*value)
|
||||
retval = savestring (value);
|
||||
else
|
||||
{
|
||||
retval = (char *)xmalloc (1);
|
||||
retval[0] = '\0';
|
||||
}
|
||||
op = capcase_p (var) ? CASE_CAPITALIZE
|
||||
: (uppercase_p (var) ? CASE_UPPER : CASE_LOWER);
|
||||
oval = sh_modcase (retval, (char *)0, op);
|
||||
free (retval);
|
||||
retval = oval;
|
||||
}
|
||||
else if (value)
|
||||
{
|
||||
if (flags & ASS_APPEND)
|
||||
@@ -1947,9 +2168,9 @@ bind_variable_internal (name, value, table, hflags, aflags)
|
||||
{
|
||||
INVALIDATE_EXPORTSTR (entry);
|
||||
newval = (aflags & ASS_APPEND) ? make_variable_value (entry, value, aflags) : value;
|
||||
entry = (*(entry->assign_func)) (entry, newval, -1);
|
||||
entry = (*(entry->assign_func)) (entry, newval, -1, 0);
|
||||
if (newval != value)
|
||||
free (newval);
|
||||
free (newval);
|
||||
return (entry);
|
||||
}
|
||||
else
|
||||
@@ -1979,6 +2200,11 @@ bind_variable_internal (name, value, table, hflags, aflags)
|
||||
array_insert (array_cell (entry), 0, newval);
|
||||
free (newval);
|
||||
}
|
||||
else if (assoc_p (entry))
|
||||
{
|
||||
assoc_insert (assoc_cell (entry), "0", newval);
|
||||
free (newval);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
@@ -2024,11 +2250,11 @@ bind_variable (name, value, flags)
|
||||
for (vc = shell_variables; vc; vc = vc->down)
|
||||
{
|
||||
if (vc_isfuncenv (vc) || vc_isbltnenv (vc))
|
||||
{
|
||||
v = hash_lookup (name, vc->table);
|
||||
if (v)
|
||||
{
|
||||
v = hash_lookup (name, vc->table);
|
||||
if (v)
|
||||
return (bind_variable_internal (name, value, vc->table, 0, flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
return (bind_variable_internal (name, value, global_variables->table, 0, flags));
|
||||
}
|
||||
@@ -2053,7 +2279,7 @@ bind_variable_value (var, value, aflags)
|
||||
/* If we're appending, we need the old value, so use
|
||||
make_variable_value */
|
||||
t = (aflags & ASS_APPEND) ? make_variable_value (var, value, aflags) : value;
|
||||
(*(var->assign_func)) (var, t, -1);
|
||||
(*(var->assign_func)) (var, t, -1, 0);
|
||||
if (t != value && t)
|
||||
free (t);
|
||||
}
|
||||
@@ -2311,7 +2537,9 @@ copy_variable (var)
|
||||
var_setfunc (copy, copy_command (function_cell (var)));
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
var_setarray (copy, dup_array (array_cell (var)));
|
||||
var_setarray (copy, array_copy (array_cell (var)));
|
||||
else if (assoc_p (var))
|
||||
var_setassoc (copy, assoc_copy (assoc_cell (var)));
|
||||
#endif
|
||||
else if (value_cell (var))
|
||||
var_setvalue (copy, savestring (value_cell (var)));
|
||||
@@ -2336,6 +2564,22 @@ copy_variable (var)
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Dispose of the information attached to VAR. */
|
||||
static void
|
||||
dispose_variable_value (var)
|
||||
SHELL_VAR *var;
|
||||
{
|
||||
if (function_p (var))
|
||||
dispose_command (function_cell (var));
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
array_dispose (array_cell (var));
|
||||
else if (assoc_p (var))
|
||||
assoc_dispose (assoc_cell (var));
|
||||
#endif
|
||||
else
|
||||
FREE (value_cell (var));
|
||||
}
|
||||
|
||||
void
|
||||
dispose_variable (var)
|
||||
SHELL_VAR *var;
|
||||
@@ -2343,14 +2587,8 @@ dispose_variable (var)
|
||||
if (var == 0)
|
||||
return;
|
||||
|
||||
if (function_p (var))
|
||||
dispose_command (function_cell (var));
|
||||
#if defined (ARRAY_VARS)
|
||||
else if (array_p (var))
|
||||
array_dispose (array_cell (var));
|
||||
#endif
|
||||
else
|
||||
FREE (value_cell (var));
|
||||
if (nofree_p (var) == 0)
|
||||
dispose_variable_value (var);
|
||||
|
||||
FREE_EXPORTSTR (var);
|
||||
|
||||
@@ -2459,15 +2697,19 @@ makunbound (name, vc)
|
||||
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 (nofree_p (old_var))
|
||||
var_setvalue (old_var, (char *)NULL);
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (old_var))
|
||||
else if (array_p (old_var))
|
||||
array_dispose (array_cell (old_var));
|
||||
else
|
||||
else if (assoc_p (old_var))
|
||||
assoc_dispose (assoc_cell (old_var));
|
||||
#endif
|
||||
else
|
||||
FREE (value_cell (old_var));
|
||||
/* Reset the attributes. Preserve the export attribute if the variable
|
||||
came from a temporary environment. Make sure it stays local, and
|
||||
make it invisible. */
|
||||
came from a temporary environment. Make sure it stays local, and
|
||||
make it invisible. */
|
||||
old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0;
|
||||
VSETATTR (old_var, att_local);
|
||||
VSETATTR (old_var, att_invisible);
|
||||
@@ -3030,7 +3272,7 @@ dispose_temporary_env (pushf)
|
||||
{
|
||||
hash_flush (temporary_env, pushf);
|
||||
hash_dispose (temporary_env);
|
||||
temporary_env = (HASH_TABLE *)NULL;
|
||||
temporary_env = (HASH_TABLE *)NULL;
|
||||
|
||||
array_needs_making = 1;
|
||||
|
||||
@@ -3142,6 +3384,12 @@ make_env_array_from_var_list (vars)
|
||||
value = array_to_assignment_string (array_cell (var));
|
||||
# else
|
||||
continue; /* XXX array vars cannot yet be exported */
|
||||
# endif
|
||||
else if (assoc_p (var))
|
||||
# if 0
|
||||
value = assoc_to_assignment_string (assoc_cell (var));
|
||||
# else
|
||||
continue; /* XXX associative array vars cannot yet be exported */
|
||||
# endif
|
||||
#endif
|
||||
else
|
||||
@@ -3162,7 +3410,7 @@ make_env_array_from_var_list (vars)
|
||||
|
||||
#if 0 /* not yet */
|
||||
#if defined (ARRAY_VARS)
|
||||
if (array_p (var))
|
||||
if (array_p (var) || assoc_p (var))
|
||||
free (value);
|
||||
#endif
|
||||
#endif
|
||||
@@ -3316,7 +3564,7 @@ maybe_make_export_env ()
|
||||
if (array_needs_making)
|
||||
{
|
||||
if (export_env)
|
||||
strvec_flush (export_env);
|
||||
strvec_flush (export_env);
|
||||
|
||||
/* Make a guess based on how many shell variables and functions we
|
||||
have. Since there will always be array variables, and array
|
||||
@@ -3333,24 +3581,24 @@ maybe_make_export_env ()
|
||||
export_env[export_env_index = 0] = (char *)NULL;
|
||||
|
||||
/* Make a dummy variable context from the temporary_env, stick it on
|
||||
the front of shell_variables, call make_var_export_array on the
|
||||
whole thing to flatten it, and convert the list of SHELL_VAR *s
|
||||
to the form needed by the environment. */
|
||||
the front of shell_variables, call make_var_export_array on the
|
||||
whole thing to flatten it, and convert the list of SHELL_VAR *s
|
||||
to the form needed by the environment. */
|
||||
if (temporary_env)
|
||||
{
|
||||
tcxt = new_var_context ((char *)NULL, 0);
|
||||
tcxt->table = temporary_env;
|
||||
tcxt->down = shell_variables;
|
||||
}
|
||||
{
|
||||
tcxt = new_var_context ((char *)NULL, 0);
|
||||
tcxt->table = temporary_env;
|
||||
tcxt->down = shell_variables;
|
||||
}
|
||||
else
|
||||
tcxt = shell_variables;
|
||||
tcxt = shell_variables;
|
||||
|
||||
temp_array = make_var_export_array (tcxt);
|
||||
if (temp_array)
|
||||
add_temp_array_to_env (temp_array, 0, 0);
|
||||
|
||||
if (tcxt != shell_variables)
|
||||
free (tcxt);
|
||||
free (tcxt);
|
||||
|
||||
#if defined (RESTRICTED_SHELL)
|
||||
/* Restricted shells may not export shell functions. */
|
||||
@@ -3517,7 +3765,7 @@ push_func_var (data)
|
||||
if (shell_variables == global_variables)
|
||||
var->attributes &= ~(att_tempvar|att_propagate);
|
||||
else
|
||||
shell_variables->flags |= VC_HASTMPVAR;
|
||||
shell_variables->flags |= VC_HASTMPVAR;
|
||||
v->attributes |= var->attributes;
|
||||
}
|
||||
else
|
||||
@@ -3564,7 +3812,7 @@ delete_all_contexts (vcxt)
|
||||
{
|
||||
t = v->down;
|
||||
dispose_var_context (v);
|
||||
}
|
||||
}
|
||||
|
||||
delete_all_variables (global_variables->table);
|
||||
shell_variables = global_variables;
|
||||
@@ -3900,7 +4148,7 @@ find_special_var (name)
|
||||
else if (r > 0)
|
||||
/* Can't match any of rest of elements in sorted list. Take this out
|
||||
if it causes problems in certain environments. */
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user