X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=arrayfunc.c;h=3bdd54f507080a81a0fdb715e801032ef20d22f7;hb=95732b497d12c98613bb3c5db16b61f377501a59;hp=0d644b121f6cecaadd1d603c21a2cf07acca1e0f;hpb=eb87367179effbe5f430236db8259006d71438b7;p=platform%2Fupstream%2Fbash.git 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);