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

This commit is contained in:
Jari Aalto
2005-12-07 14:08:12 +00:00
parent eb87367179
commit 95732b497d
267 changed files with 24541 additions and 18843 deletions

View File

@@ -1,6 +1,6 @@
/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
/* Copyright (C) 2001-2003 Free Software Foundation, Inc.
/* Copyright (C) 2001-2005 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -37,6 +37,9 @@
extern char *this_command_name;
extern int last_command_exit_value;
extern int array_needs_making;
static SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, int));
static void quote_array_assignment_chars __P((WORD_LIST *));
static char *array_value_internal __P((char *, int, int, int *));
@@ -72,6 +75,8 @@ convert_var_to_array (var)
var->assign_func = (sh_var_assign_func_t *)NULL;
INVALIDATE_EXPORTSTR (var);
if (exported_p (var))
array_needs_making++;
VSETATTR (var, att_array);
VUNSETATTR (var, att_invisible);
@@ -79,6 +84,49 @@ convert_var_to_array (var)
return var;
}
static SHELL_VAR *
bind_array_var_internal (entry, ind, value, flags)
SHELL_VAR *entry;
arrayind_t ind;
char *value;
int flags;
{
SHELL_VAR *dentry;
char *newval;
/* If we're appending, we need the old value of the array reference, so
fake out make_variable_value with a dummy SHELL_VAR */
if (flags & ASS_APPEND)
{
dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
dentry->name = savestring (entry->name);
newval = array_reference (array_cell (entry), ind);
if (newval)
dentry->value = savestring (newval);
else
{
dentry->value = (char *)xmalloc (1);
dentry->value[0] = '\0';
}
dentry->exportstr = 0;
dentry->attributes = entry->attributes & ~(att_array|att_exported);
/* Leave the rest of the members uninitialized; the code doesn't look
at them. */
newval = make_variable_value (dentry, value, flags);
dispose_variable (dentry);
}
else
newval = make_variable_value (entry, value, flags);
if (entry->assign_func)
(*entry->assign_func) (entry, newval, ind);
else
array_insert (array_cell (entry), ind, newval);
FREE (newval);
return (entry);
}
/* Perform an array assignment name[ind]=value. If NAME already exists and
is not an array, and IND is 0, perform name=value instead. If NAME exists
and is not an array, and IND is not 0, convert it into an array with the
@@ -87,13 +135,13 @@ convert_var_to_array (var)
If NAME does not exist, just create an array variable, no matter what
IND's value may be. */
SHELL_VAR *
bind_array_variable (name, ind, value)
bind_array_variable (name, ind, value, flags)
char *name;
arrayind_t ind;
char *value;
int flags;
{
SHELL_VAR *entry;
char *newval;
entry = var_lookup (name, shell_variables);
@@ -109,21 +157,15 @@ bind_array_variable (name, ind, value)
entry = convert_var_to_array (entry);
/* ENTRY is an array variable, and ARRAY points to the value. */
newval = make_variable_value (entry, value);
if (entry->assign_func)
(*entry->assign_func) (entry, newval, ind);
else
array_insert (array_cell (entry), ind, newval);
FREE (newval);
return (entry);
return (bind_array_var_internal (entry, ind, value, flags));
}
/* Parse NAME, a lhs of an assignment statement of the form v[s], and
assign VALUE to that array element by calling bind_array_variable(). */
SHELL_VAR *
assign_array_element (name, value)
assign_array_element (name, value, flags)
char *name, *value;
int flags;
{
char *sub, *vname;
arrayind_t ind;
@@ -150,7 +192,7 @@ assign_array_element (name, value)
return ((SHELL_VAR *)NULL);
}
entry = bind_array_variable (vname, ind, value);
entry = bind_array_variable (vname, ind, value, flags);
free (vname);
return (entry);
@@ -187,8 +229,9 @@ find_or_make_array_variable (name, check_flags)
/* Perform a compound assignment statement for array NAME, where VALUE is
the text between the parens: NAME=( VALUE ) */
SHELL_VAR *
assign_array_from_string (name, value)
assign_array_from_string (name, value, flags)
char *name, *value;
int flags;
{
SHELL_VAR *var;
@@ -196,21 +239,25 @@ assign_array_from_string (name, value)
if (var == 0)
return ((SHELL_VAR *)NULL);
return (assign_array_var_from_string (var, value));
return (assign_array_var_from_string (var, value, flags));
}
/* Sequentially assign the indices of indexed array variable VAR from the
words in LIST. */
SHELL_VAR *
assign_array_var_from_word_list (var, list)
assign_array_var_from_word_list (var, list, flags)
SHELL_VAR *var;
WORD_LIST *list;
int flags;
{
register arrayind_t i;
register WORD_LIST *l;
ARRAY *a;
for (a = array_cell (var), l = list, i = 0; l; l = l->next, i++)
a = array_cell (var);
i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
for (l = list; l; l = l->next, i++)
if (var->assign_func)
(*var->assign_func) (var, l->word->word, i);
else
@@ -221,9 +268,10 @@ assign_array_var_from_word_list (var, list)
/* Perform a compound array assignment: VAR->name=( VALUE ). The
VALUE has already had the parentheses stripped. */
SHELL_VAR *
assign_array_var_from_string (var, value)
assign_array_var_from_string (var, value, flags)
SHELL_VAR *var;
char *value;
int flags;
{
ARRAY *a;
WORD_LIST *list, *nlist;
@@ -271,10 +319,11 @@ assign_array_var_from_string (var, value)
/* Now that we are ready to assign values to the array, kill the existing
value. */
if (a)
if (a && (flags & ASS_APPEND) == 0)
array_flush (a);
last_ind = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
for (last_ind = 0, list = nlist; list; list = list->next)
for (list = nlist; list; list = list->next)
{
w = list->word->word;
@@ -283,9 +332,14 @@ assign_array_var_from_string (var, value)
{
len = skipsubscript (w, 0);
#if 1
/* XXX - changes for `+=' */
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
#else
if (w[len] != ']' || w[len+1] != '=')
#endif
{
nval = make_variable_value (var, w);
nval = make_variable_value (var, w, flags);
if (var->assign_func)
(*var->assign_func) (var, nval, last_ind);
else
@@ -314,7 +368,14 @@ assign_array_var_from_string (var, value)
continue;
}
last_ind = ind;
val = w + len + 2;
/* XXX - changes for `+=' */
if (w[len + 1] == '+' && w[len + 2] == '=')
{
flags |= ASS_APPEND;
val = w + len + 3;
}
else
val = w + len + 2;
}
else /* No [ind]=value, just a stray `=' */
{
@@ -324,12 +385,7 @@ assign_array_var_from_string (var, value)
if (integer_p (var))
this_command_name = (char *)NULL; /* no command name for errors */
nval = make_variable_value (var, val);
if (var->assign_func)
(*var->assign_func) (var, nval, ind);
else
array_insert (a, ind, nval);
FREE (nval);
bind_array_var_internal (var, ind, val, flags);
last_ind++;
}
@@ -536,7 +592,11 @@ array_expand_index (s, len)
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
#if 0
t = expand_string_to_string (exp, 0);
#else
t = expand_string_to_string (exp, Q_DOUBLE_QUOTES);
#endif
this_command_name = (char *)NULL;
val = evalexp (t, &expok);
free (t);
@@ -652,7 +712,7 @@ array_value_internal (s, quoted, allow_all, rtype)
err_badarraysub (s);
return ((char *)NULL);
}
else if (var == 0)
else if (var == 0 || value_cell (var) == 0)
return ((char *)NULL);
else if (array_p (var) == 0)
l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);