aboutsummaryrefslogtreecommitdiffstats
path: root/arrayfunc.c
diff options
context:
space:
mode:
authorJari Aalto <jari.aalto@cante.net>2005-12-07 14:08:12 +0000
committerJari Aalto <jari.aalto@cante.net>2009-09-12 16:46:57 +0000
commit95732b497d12c98613bb3c5db16b61f377501a59 (patch)
tree5e1cdf79eb0407e09dca4c0ec29e11442c7d1d15 /arrayfunc.c
parenteb87367179effbe5f430236db8259006d71438b7 (diff)
downloadandroid_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.tar.gz
android_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.tar.bz2
android_external_bash-95732b497d12c98613bb3c5db16b61f377501a59.zip
Imported from ../bash-3.1.tar.gz.
Diffstat (limited to 'arrayfunc.c')
-rw-r--r--arrayfunc.c118
1 files changed, 89 insertions, 29 deletions
diff --git a/arrayfunc.c b/arrayfunc.c
index 0d644b1..3bdd54f 100644
--- a/arrayfunc.c
+++ b/arrayfunc.c
@@ -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);