Imported from ../bash-2.04.tar.gz.

This commit is contained in:
Jari Aalto 2000-03-17 21:46:59 +00:00
commit bb70624e96
387 changed files with 28522 additions and 9334 deletions

View file

@ -6,7 +6,7 @@
Bash is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
the Free Software Foundation; either version 2, or (at your option)
any later version.
Bash is distributed in the hope that it will be useful, but WITHOUT
@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#include "config.h"
@ -58,6 +58,10 @@
# include <readline/history.h>
#endif /* HISTORY */
#if defined (PROGRAMMABLE_COMPLETION)
# include "pcomplete.h"
#endif
/* Variables used here and defined in other files. */
extern int posixly_correct;
extern int variable_context, line_number;
@ -69,6 +73,7 @@ extern char *shell_name;
extern char *primary_prompt, *secondary_prompt;
extern char *current_host_name;
extern Function *this_shell_builtin;
extern SHELL_VAR *this_shell_function;
extern char *this_command_name;
extern time_t shell_start_time;
@ -175,17 +180,14 @@ initialize_shell_variables (env, privmode)
char_index == strlen (name) */
/* If exported function, define it now. */
if (privmode == 0 && STREQN ("() {", string, 4))
if (privmode == 0 && read_but_dont_execute == 0 && STREQN ("() {", string, 4))
{
string_length = strlen (string);
temp_string = xmalloc (3 + string_length + char_index);
#if 1
strcpy (temp_string, name);
temp_string[char_index] = ' ';
strcpy (temp_string + char_index + 1, string);
#else
sprintf (temp_string, "%s %s", name, string);
#endif
parse_and_execute (temp_string, name, SEVAL_NONINT|SEVAL_NOHIST);
@ -196,14 +198,15 @@ initialize_shell_variables (env, privmode)
if (temp_var = find_function (name))
{
temp_var->attributes |= (att_exported | att_imported);
VSETATTR (temp_var, (att_exported|att_imported));
array_needs_making = 1;
}
else
report_error ("error importing function definition for `%s'", name);
/* ( */
if (name[char_index - 1] == ')' && name[char_index - 2] == '\0')
name[char_index - 2] = '(';
name[char_index - 2] = '('; /* ) */
}
#if defined (ARRAY_VARS)
# if 0
@ -214,7 +217,7 @@ initialize_shell_variables (env, privmode)
temp_string = extract_array_assignment_list (string, &string_length);
temp_var = assign_array_from_string (name, temp_string);
FREE (temp_string);
temp_var->attributes |= (att_exported | att_imported);
VSETATTR (temp_var, (att_exported | att_imported));
array_needs_making = 1;
}
# endif
@ -222,11 +225,17 @@ initialize_shell_variables (env, privmode)
else
{
temp_var = bind_variable (name, string);
temp_var->attributes |= (att_exported | att_imported);
VSETATTR (temp_var, (att_exported | att_imported));
array_needs_making = 1;
}
name[char_index] = '=';
/* temp_var can be NULL if it was an exported function with a syntax
error (a different bug, but it still shouldn't dump core). */
if (temp_var && function_p (temp_var) == 0) /* XXX not yet */
{
CACHE_IMPORTSTR (temp_var, name);
}
}
/* If we got PWD from the environment, update our idea of the current
@ -253,7 +262,7 @@ initialize_shell_variables (env, privmode)
`environment variable' and therefore should be auto-exported.
Make a dummy invisible variable for OLDPWD, and mark it as exported. */
temp_var = bind_variable ("OLDPWD", (char *)NULL);
temp_var->attributes |= (att_exported | att_invisible);
VSETATTR (temp_var, (att_exported | att_invisible));
/* Set up initial value of $_ */
temp_var = bind_variable ("_", dollar_vars[0]);
@ -391,6 +400,13 @@ initialize_shell_variables (env, privmode)
}
#endif /* HISTORY */
temp_var = find_variable ("SSH_CLIENT");
if (temp_var && imported_p (temp_var))
{
VUNSETATTR (temp_var, att_exported);
array_needs_making = 1;
}
/* Get the user's real and effective user ids. */
uidset ();
@ -419,7 +435,7 @@ set_home_var ()
temp_var = find_variable ("HOME");
if (temp_var == 0)
temp_var = bind_variable ("HOME", get_home_dir ());
temp_var->attributes |= att_exported;
VSETATTR (temp_var, att_exported);
}
/* Set $SHELL to the user's login shell if it is not already set. Call
@ -436,7 +452,7 @@ set_shell_var ()
get_current_user_info ();
temp_var = bind_variable ("SHELL", current_user.shell);
}
temp_var->attributes |= att_exported;
VSETATTR (temp_var, att_exported);
}
static char *
@ -555,12 +571,6 @@ adjust_shell_level (change)
static void
initialize_shell_level ()
{
#if 0
SHELL_VAR *temp_var;
temp_var = set_if_not ("SHLVL", "0");
set_auto_export (temp_var);
#endif
adjust_shell_level (1);
}
@ -574,9 +584,9 @@ set_ppid ()
name = inttostr ((int) getppid (), namebuf, sizeof(namebuf));
temp_var = find_variable ("PPID");
if (temp_var)
temp_var->attributes &= ~(att_readonly | att_exported);
VUNSETATTR (temp_var, (att_readonly | att_exported));
temp_var = bind_variable ("PPID", name);
temp_var->attributes |= (att_readonly | att_integer);
VSETATTR (temp_var, (att_readonly | att_integer));
}
static void
@ -588,20 +598,20 @@ uidset ()
b = inttostr (current_user.uid, buff, sizeof (buff));
v = find_variable ("UID");
if (v)
v->attributes &= ~att_readonly;
VUNSETATTR (v, att_readonly);
v = bind_variable ("UID", b);
v->attributes |= (att_readonly | att_integer);
VSETATTR (v, (att_readonly | att_integer));
if (current_user.euid != current_user.uid)
b = inttostr (current_user.euid, buff, sizeof (buff));
v = find_variable ("EUID");
if (v)
v->attributes &= ~att_readonly;
VUNSETATTR (v, att_readonly);
v = bind_variable ("EUID", b);
v->attributes |= (att_readonly | att_integer);
VSETATTR (v, (att_readonly | att_integer));
}
#if defined (ARRAY_VARS)
@ -629,7 +639,7 @@ make_vers_array ()
array_add_element (av, 4, release_status);
array_add_element (av, 5, MACHTYPE);
vv->attributes |= att_readonly;
VSETATTR (vv, att_readonly);
}
#endif /* ARRAY_VARS */
@ -893,6 +903,25 @@ print_array_assignment (var, quoted)
stupidly_hack_special_variables, but I wanted the changes as
localized as possible. */
static SHELL_VAR *
null_assign (self, value)
SHELL_VAR *self;
char *value;
{
return (self);
}
#if defined (ARRAY_VARS)
static SHELL_VAR *
null_array_assign (self, ind, value)
SHELL_VAR *self;
int ind;
char *value;
{
return (self);
}
#endif
/* The value of $SECONDS. This is the number of seconds since shell
invocation, or, the number of seconds since the last assignment + the
value of the last assignment. */
@ -920,7 +949,7 @@ get_seconds (var)
FREE (var->value);
var->attributes |= att_integer;
VSETATTR (var, att_integer);
var->value = p;
return (var);
}
@ -979,7 +1008,7 @@ get_random (var)
FREE (var->value);
var->attributes |= att_integer;
VSETATTR (var, att_integer);
var->value = p;
return (var);
}
@ -1071,42 +1100,74 @@ get_groupset (self)
return (self);
}
#endif /* ARRAY_VARS */
static SHELL_VAR *
get_funcname (self)
SHELL_VAR *self;
{
if (variable_context && this_shell_function)
{
FREE (self->value);
self->value = savestring (this_shell_function->name);
}
return (self);
}
void
make_funcname_visible (on_or_off)
int on_or_off;
{
SHELL_VAR *v;
v = find_variable ("FUNCNAME");
if (v == 0 || v->dynamic_value == 0)
return;
if (on_or_off)
VUNSETATTR (v, att_invisible);
else
VSETATTR (v, att_invisible);
}
#define INIT_DYNAMIC_VAR(var, val, gfunc, afunc) \
do \
{ \
v = bind_variable (var, val); \
v->dynamic_value = gfunc; \
v->assign_func = afunc; \
} while (0)
#define INIT_DYNAMIC_ARRAY_VAR(var, gfunc, afunc) \
do \
{ \
v = make_new_array_variable (var); \
v->dynamic_value = gfunc; \
v->assign_func = afunc; \
} while (0)
static void
initialize_dynamic_variables ()
{
SHELL_VAR *v;
v = bind_variable ("SECONDS", (char *)NULL);
v->dynamic_value = get_seconds;
v->assign_func = assign_seconds;
v = bind_variable ("RANDOM", (char *)NULL);
v->dynamic_value = get_random;
v->assign_func = assign_random;
v = bind_variable ("LINENO", (char *)NULL);
v->dynamic_value = get_lineno;
v->assign_func = assign_lineno;
INIT_DYNAMIC_VAR ("SECONDS", (char *)NULL, get_seconds, assign_seconds);
INIT_DYNAMIC_VAR ("RANDOM", (char *)NULL, get_random, assign_random);
INIT_DYNAMIC_VAR ("LINENO", (char *)NULL, get_lineno, assign_lineno);
#if defined (HISTORY)
v = bind_variable ("HISTCMD", (char *)NULL);
v->dynamic_value = get_histcmd;
v->assign_func = (DYNAMIC_FUNC *)NULL;
INIT_DYNAMIC_VAR ("HISTCMD", (char *)NULL, get_histcmd, (DYNAMIC_FUNC *)NULL);
#endif
#if defined (PUSHD_AND_POPD) && defined (ARRAY_VARS)
v = make_new_array_variable ("DIRSTACK");
v->dynamic_value = get_dirstack;
v->assign_func = assign_dirstack;
INIT_DYNAMIC_ARRAY_VAR ("DIRSTACK", get_dirstack, assign_dirstack);
#endif /* PUSHD_AND_POPD && ARRAY_VARS */
#if defined (ARRAY_VARS)
v = make_new_array_variable ("GROUPS");
v->dynamic_value = get_groupset;
v->assign_func = (DYNAMIC_FUNC *)NULL;
v->attributes |= att_readonly;
INIT_DYNAMIC_ARRAY_VAR ("GROUPS", get_groupset, null_array_assign);
#endif
INIT_DYNAMIC_VAR ("FUNCNAME", (char *)NULL, get_funcname, null_assign);
VSETATTR (v, att_invisible);
}
/* How to get a pointer to the shell variable or function named NAME.
@ -1211,6 +1272,15 @@ make_local_variable (name)
if (old_var && old_var->context == variable_context)
return (old_var);
/* Since this is called only from the local/declare/typeset code, we can
call builtin_error here without worry (of course, it will also work
for anything that sets this_command_name). */
if (old_var && readonly_p (old_var))
{
builtin_error ("%s: readonly variable");
return ((SHELL_VAR *)NULL);
}
elt = remove_hash_item (name, shell_variables);
if (elt)
{
@ -1233,6 +1303,8 @@ make_local_variable (name)
new_var->value = xmalloc (1);
new_var->value[0] = '\0';
CLEAR_EXPORTSTR (new_var);
new_var->dynamic_value = (DYNAMIC_FUNC *)NULL;
new_var->assign_func = (DYNAMIC_FUNC *)NULL;
@ -1244,7 +1316,7 @@ make_local_variable (name)
}
new_var->context = variable_context;
new_var->attributes |= att_local;
VSETATTR (new_var, att_local);
/* XXX */
if (variable_context >= local_variable_stack_size)
@ -1269,11 +1341,13 @@ make_local_array_variable (name)
ARRAY *array;
var = make_local_variable (name);
if (var == 0)
return var;
array = new_array ();
FREE (value_cell(var));
var->value = (char *)array;
var->attributes |= att_array;
VSETATTR (var, att_array);
return var;
}
#endif /* ARRAY_VARS */
@ -1293,6 +1367,7 @@ make_new_variable (name)
entry->attributes = 0;
entry->name = savestring (name);
entry->value = (char *)NULL;
CLEAR_EXPORTSTR (entry);
entry->dynamic_value = (DYNAMIC_FUNC *)NULL;
entry->assign_func = (DYNAMIC_FUNC *)NULL;
@ -1320,7 +1395,7 @@ make_new_array_variable (name)
entry = make_new_variable (name);
array = new_array ();
entry->value = (char *)array;
entry->attributes |= att_array;
VSETATTR (entry, att_array);
return entry;
}
#endif
@ -1383,7 +1458,10 @@ bind_variable (name, value)
#else
else if (entry->assign_func)
#endif
return ((*(entry->assign_func)) (entry, value));
{
INVALIDATE_EXPORTSTR (entry);
return ((*(entry->assign_func)) (entry, value));
}
else
{
if (readonly_p (entry))
@ -1393,10 +1471,13 @@ bind_variable (name, value)
}
/* Variables which are bound are visible. */
entry->attributes &= ~att_invisible;
VUNSETATTR (entry, att_invisible);
newval = make_variable_value (entry, value);
/* Invalidate any cached export string */
INVALIDATE_EXPORTSTR (entry);
#if defined (ARRAY_VARS)
/* XXX -- this bears looking at again -- XXX */
/* If an existing array variable x is being assigned to with x=b or
@ -1419,7 +1500,7 @@ bind_variable (name, value)
}
if (mark_modified_vars)
entry->attributes |= att_exported;
VSETATTR (entry, att_exported);
if (exported_p (entry))
array_needs_making = 1;
@ -1427,6 +1508,67 @@ bind_variable (name, value)
return (entry);
}
/* 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
all modified variables should be exported, mark the variable for export
and note that the export environment needs to be recreated. */
SHELL_VAR *
bind_variable_value (var, value)
SHELL_VAR *var;
char *value;
{
char *t;
VUNSETATTR (var, att_invisible);
t = make_variable_value (var, value);
FREE (var->value);
var->value = t;
INVALIDATE_EXPORTSTR (var);
if (mark_modified_vars)
VSETATTR (var, att_exported);
if (exported_p (var))
array_needs_making = 1;
return (var);
}
/* Bind/create a shell variable with the name LHS to the RHS.
This creates or modifies a variable such that it is an integer.
This used to be in expr.c, but it is here so that all of the
variable binding stuff is localized. Since we don't want any
recursive evaluation from bind_variable() (possible without this code,
since bind_variable() calls the evaluator for variables with the integer
attribute set), we temporarily turn off the integer attribute for each
variable we set here, then turn it back on after binding as necessary. */
SHELL_VAR *
bind_int_variable (lhs, rhs)
char *lhs, *rhs;
{
register SHELL_VAR *v;
int isint;
isint = 0;
v = find_variable (lhs);
if (v)
{
isint = integer_p (v);
VUNSETATTR (v, att_integer);
}
v = bind_variable (lhs, rhs);
if (isint)
VSETATTR (v, att_integer);
return (v);
}
#if defined (ARRAY_VARS)
/* Convert a shell variable to an array variable. The original value is
saved as array[0]. */
@ -1440,10 +1582,14 @@ convert_var_to_array (var)
oldval = value_cell (var);
array = new_array ();
array_add_element (array, 0, oldval);
FREE (value_cell (var));
var->value = (char *)array;
var->attributes |= att_array;
var->attributes &= ~att_invisible;
INVALIDATE_EXPORTSTR (var);
VSETATTR (var, att_array);
VUNSETATTR (var, att_invisible);
return var;
}
@ -1526,6 +1672,40 @@ assign_array_var_from_word_list (var, list)
return var;
}
/* For each word in a compound array assignment, if the word looks like
[ind]=value, quote the `[' and `]' before the `=' to protect them from
unwanted filename expansion. */
static void
quote_array_assignment_chars (list)
WORD_LIST *list;
{
char *s, *t, *nword;
int saw_eq;
WORD_LIST *l;
for (l = list; l; l = l->next)
{
if (l->word == 0 || l->word->word == 0 || l->word->word[0] == '\0')
continue; /* should not happen, but just in case... */
/* Don't bother if it doesn't look like [ind]=value */
if (l->word->word[0] != '[' || strchr (l->word->word, '=') == 0) /* ] */
continue;
s = nword = xmalloc (strlen (l->word->word) * 2 + 1);
saw_eq = 0;
for (t = l->word->word; *t; )
{
if (*t == '=')
saw_eq = 1;
if (saw_eq == 0 && (*t == '[' || *t == ']'))
*s++ = '\\';
*s++ = *t++;
}
*s = '\0';
free (l->word->word);
l->word->word = nword;
}
}
/* Perform a compound array assignment: VAR->name=( VALUE ). The
VALUE has already had the parentheses stripped. */
SHELL_VAR *
@ -1559,13 +1739,15 @@ assign_array_var_from_string (var, value)
/* First we split the string on whitespace, using the shell parser
(ksh93 seems to do this). */
list = parse_string_to_word_list (val, "array assign");
/* If we're using [subscript]=value, we need to quote each [ and ] to
prevent unwanted filename expansion. */
if (list)
quote_array_assignment_chars (list);
/* Now that we've split it, perform the shell expansions on each
word in the list. */
#if 0
nlist = list ? expand_words_shellexp (list) : (WORD_LIST *)NULL;
#else
nlist = list ? expand_words_no_vars (list) : (WORD_LIST *)NULL;
#endif
dispose_words (list);
@ -1660,6 +1842,8 @@ dispose_variable (var)
else
FREE (value_cell (var));
FREE_EXPORTSTR (var);
free (var->name);
if (exported_p (var))
@ -1756,6 +1940,11 @@ makunbound (name, hash_list)
if (old_var && exported_p (old_var))
array_needs_making++;
#if defined (PROGRAMMABLE_COMPLETION)
if (hash_list == shell_functions)
set_itemlist_dirty (&it_functions);
#endif
/* If we're unsetting a local variable and we're still executing inside
the function, just mark the variable as invisible.
kill_all_local_variables will clean it up later. This must be done
@ -1764,7 +1953,8 @@ makunbound (name, hash_list)
to add it back into the correct hash table. */
if (old_var && local_p (old_var) && variable_context == old_var->context)
{
old_var->attributes |= att_invisible;
VSETATTR (old_var, att_invisible);
INVALIDATE_EXPORTSTR (old_var);
new_elt = add_hash_item (savestring (old_var->name), hash_list);
new_elt->data = (char *)old_var;
stupidly_hack_special_variables (old_var->name);
@ -1852,7 +2042,7 @@ kill_all_local_variables ()
{
for (i = 0; var = list[i]; i++)
{
var->attributes &= ~att_local;
VUNSETATTR (var, att_local);
makunbound (var->name, varlist);
}
free (list);
@ -1914,29 +2104,37 @@ bind_function (name, value)
elt = add_hash_item (savestring (name), shell_functions);
elt->data = (char *)new_shell_variable (name);
entry = (SHELL_VAR *)elt->data;
entry = new_shell_variable (name);
entry->dynamic_value = entry->assign_func = (DYNAMIC_FUNC *)NULL;
CLEAR_EXPORTSTR (entry);
/* Functions are always made at the top level. This allows a
function to define another function (like autoload). */
entry->context = 0;
elt->data = (char *)entry;
}
INVALIDATE_EXPORTSTR (entry);
if (entry->value)
dispose_command ((COMMAND *)entry->value);
entry->value = value ? (char *)copy_command (value) : (char *)NULL;
entry->attributes |= att_function;
VSETATTR (entry, att_function);
if (mark_modified_vars)
entry->attributes |= att_exported;
VSETATTR (entry, att_exported);
entry->attributes &= ~att_invisible; /* Just to be sure */
VUNSETATTR (entry, att_invisible); /* Just to be sure */
if (exported_p (entry))
array_needs_making = 1;
#if defined (PROGRAMMABLE_COMPLETION)
set_itemlist_dirty (&it_functions);
#endif
return (entry);
}
@ -1969,6 +2167,8 @@ copy_variable (var)
copy->dynamic_value = var->dynamic_value;
copy->assign_func = var->assign_func;
copy->exportstr = COPY_EXPORTSTR (var);
copy->context = var->context;
/* Don't bother copying previous contexts along with this variable. */
@ -1999,7 +2199,7 @@ set_var_read_only (name)
SHELL_VAR *entry;
FIND_OR_MAKE_VARIABLE (name, entry);
entry->attributes |= att_readonly;
VSETATTR (entry, att_readonly);
}
#ifdef INCLUDE_UNUSED
@ -2013,7 +2213,7 @@ set_func_read_only (name)
entry = find_function (name);
if (entry)
entry->attributes |= att_readonly;
VSETATTR (entry, att_readonly);
}
/* Make the variable associated with NAME be auto-exported.
@ -2102,8 +2302,6 @@ assignment (string)
return (0);
}
#ifdef READLINE
static int
visible_var (var)
SHELL_VAR *var;
@ -2125,19 +2323,17 @@ _visible_names (table)
return (list);
}
SHELL_VAR **
all_visible_variables ()
{
return (_visible_names (shell_variables));
}
SHELL_VAR **
all_visible_functions ()
{
return (_visible_names (shell_functions));
}
#endif /* READLINE */
SHELL_VAR **
all_visible_variables ()
{
return (_visible_names (shell_variables));
}
/* Return non-zero if the variable VAR is visible and exported. Array
variables cannot be exported. */
@ -2148,6 +2344,114 @@ visible_and_exported (var)
return (invisible_p (var) == 0 && exported_p (var));
}
SHELL_VAR **
all_exported_variables ()
{
SHELL_VAR **list;
list = map_over (visible_and_exported, shell_variables);
if (list)
sort_variables (list);
return (list);
}
#if defined (ARRAY_VARS)
/* Return non-zero if the variable VAR is visible and an array. */
static int
visible_array_vars (var)
SHELL_VAR *var;
{
return (invisible_p (var) == 0 && array_p (var));
}
SHELL_VAR **
all_array_variables ()
{
SHELL_VAR **list;
list = map_over (visible_array_vars, shell_variables);
if (list)
sort_variables (list);
return (list);
}
#endif /* ARRAY_VARS */
char **
all_variables_matching_prefix (prefix)
char *prefix;
{
SHELL_VAR **varlist;
char **rlist;
int vind, rind, plen;
plen = STRLEN (prefix);
varlist = all_visible_variables ();
for (vind = 0; varlist && varlist[vind]; vind++)
;
if (varlist == 0 || vind == 0)
return ((char **)NULL);
rlist = alloc_array (vind + 1);
for (vind = rind = 0; varlist[vind]; vind++)
{
if (plen == 0 || STREQN (prefix, varlist[vind]->name, plen))
rlist[rind++] = savestring (varlist[vind]->name);
}
rlist[rind] = (char *)0;
free (varlist);
return rlist;
}
static inline char *
mk_env_string (name, value)
char *name, *value;
{
int name_len, value_len;
char *p;
name_len = strlen (name);
value_len = STRLEN (value);
p = xmalloc (2 + name_len + value_len);
strcpy (p, name);
p[name_len] = '=';
if (value && *value)
strcpy (p + name_len + 1, value);
else
p[name_len + 1] = '\0';
return (p);
}
/* Debugging */
static int
valid_exportstr (v)
SHELL_VAR *v;
{
char *s;
s = v->exportstr;
if (legal_variable_starter (*s) == 0)
{
internal_error ("invalid character %d in exportstr for %s", *s, v->name);
return (0);
}
for (s = v->exportstr + 1; s && *s; s++)
{
if (*s == '=')
break;
if (legal_variable_char (*s) == 0)
{
internal_error ("invalid character %d in exportstr for %s", *s, v->name);
return (0);
}
}
if (*s != '=')
{
internal_error ("no `=' in exportstr for %s", v->name);
return (0);
}
return (1);
}
/* Make an array of assignment statements from the hash table
HASHED_VARS which contains SHELL_VARs. Only visible, exported
variables are eligible. */
@ -2165,11 +2469,32 @@ make_var_array (hashed_vars)
if (vars == 0)
return (char **)NULL;
list = (char **)xmalloc ((1 + array_len ((char **)vars)) * sizeof (char *));
list = alloc_array ((1 + array_len ((char **)vars)));
#define USE_EXPORTSTR (value == var->exportstr)
for (i = 0, list_index = 0; var = vars[i]; i++)
{
if (function_p (var))
if (var->exportstr)
{
#if defined(__CYGWIN__) || defined (__CYGWIN32__)
INVALIDATE_EXPORTSTR (var);
value = value_cell (var);
#else
/* XXX -- this test can go away in the next release, to be replaced
by a simple `value = var->exportstr;', when the exportstr code
is better-tested. Until then, don't do it for cygwin at all,
since that system has some weird environment variables. */
if (valid_exportstr (var))
value = var->exportstr;
else
{
INVALIDATE_EXPORTSTR (var);
value = value_cell (var);
}
#endif
}
else if (function_p (var))
value = named_function_string ((char *)NULL, function_cell (var), 0);
#if defined (ARRAY_VARS)
else if (array_p (var))
@ -2184,19 +2509,23 @@ make_var_array (hashed_vars)
if (value)
{
int name_len, value_len;
char *p;
/* Gee, I'd like to get away with not using savestring() if we're
using the cached exportstr... */
list[list_index] = USE_EXPORTSTR ? savestring (value)
: mk_env_string (var->name, value);
name_len = strlen (var->name);
value_len = strlen (value);
p = list[list_index] = xmalloc (2 + name_len + value_len);
strcpy (p, var->name);
p[name_len] = '=';
strcpy (p + name_len + 1, value);
if (USE_EXPORTSTR == 0 && function_p (var))
{
SAVE_EXPORTSTR (var, list[list_index]);
}
list_index++;
#undef USE_EXPORTSTR
#if 0 /* not yet */
#if defined (ARRAY_VARS)
if (array_p (var))
free (value);
#endif
#endif
}
}
@ -2245,18 +2574,8 @@ assign_in_env (string)
free (temp);
}
nlen = strlen (name);
vlen = value ? strlen (value) : 0;
temp = xmalloc (2 + nlen + vlen);
strcpy (temp, name);
temp[nlen] = '=';
temp[nlen + 1] = '\0';
if (value)
{
if (*value)
strcpy (temp + nlen + 1, value);
free (value);
}
temp = mk_env_string (name, value);
FREE (value);
free (name);
if (temporary_env == 0)
@ -2317,6 +2636,7 @@ find_name_in_env_array (name, array)
temp->prev_context = (SHELL_VAR *)NULL;
temp->dynamic_value = temp->assign_func = (DYNAMIC_FUNC *)NULL;
CLEAR_EXPORTSTR (temp);
return (temp);
}
@ -2427,6 +2747,12 @@ merge_builtin_env ()
merge_env_array (builtin_env);
}
int
any_temporary_variables ()
{
return (temporary_env || function_env);
}
/* Add ENVSTR to the end of the exported environment, EXPORT_ENV. */
#define add_to_export_env(envstr,do_alloc) \
do \
@ -2495,7 +2821,7 @@ maybe_make_export_env ()
variables are not (yet) exported, this will always be big enough
for the exported variables and functions, without any temporary
or function environments. */
new_size = shell_variables->nentries + shell_functions->nentries + 1;
new_size = HASH_ENTRIES (shell_variables) + HASH_ENTRIES (shell_functions) + 1;
if (new_size > export_env_size)
{
export_env_size = new_size;
@ -2688,6 +3014,7 @@ struct name_and_function {
{ "LC_COLLATE", sv_locale },
{ "LC_CTYPE", sv_locale },
{ "LC_MESSAGES", sv_locale },
{ "LC_NUMERIC", sv_locale },
{ "LANG", sv_locale },
#if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
@ -2768,7 +3095,13 @@ void
sv_hostfile (name)
char *name;
{
hostname_list_initialized = 0;
SHELL_VAR *v;
v = find_variable (name);
if (v == 0)
clear_hostname_list ();
else
hostname_list_initialized = 0;
}
#endif /* READLINE */