Imported from ../bash-4.0-rc1.tar.gz.
This commit is contained in:
404
arrayfunc.c
404
arrayfunc.c
@@ -1,22 +1,22 @@
|
||||
/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
|
||||
|
||||
/* Copyright (C) 2001-2006 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 2001-2009 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
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 2, or (at your option) any later
|
||||
version.
|
||||
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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
Bash is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "bashintl.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "pathexp.h"
|
||||
|
||||
#include "shmbutil.h"
|
||||
|
||||
@@ -39,13 +40,14 @@ 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 SHELL_VAR *bind_array_var_internal __P((SHELL_VAR *, arrayind_t, char *, char *, int));
|
||||
|
||||
static char *quote_assign __P((const char *));
|
||||
static void quote_array_assignment_chars __P((WORD_LIST *));
|
||||
static char *array_value_internal __P((char *, int, int, int *));
|
||||
|
||||
/* Standard error message to use when encountering an invalid array subscript */
|
||||
char *bash_badsub_errmsg = N_("bad array subscript");
|
||||
const char * const bash_badsub_errmsg = N_("bad array subscript");
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
@@ -84,10 +86,42 @@ convert_var_to_array (var)
|
||||
return var;
|
||||
}
|
||||
|
||||
/* Convert a shell variable to an array variable. The original value is
|
||||
saved as array[0]. */
|
||||
SHELL_VAR *
|
||||
convert_var_to_assoc (var)
|
||||
SHELL_VAR *var;
|
||||
{
|
||||
char *oldval;
|
||||
HASH_TABLE *hash;
|
||||
|
||||
oldval = value_cell (var);
|
||||
hash = assoc_create (0);
|
||||
if (oldval)
|
||||
assoc_insert (hash, "0", oldval);
|
||||
|
||||
FREE (value_cell (var));
|
||||
var_setassoc (var, hash);
|
||||
|
||||
/* these aren't valid anymore */
|
||||
var->dynamic_value = (sh_var_value_func_t *)NULL;
|
||||
var->assign_func = (sh_var_assign_func_t *)NULL;
|
||||
|
||||
INVALIDATE_EXPORTSTR (var);
|
||||
if (exported_p (var))
|
||||
array_needs_making++;
|
||||
|
||||
VSETATTR (var, att_assoc);
|
||||
VUNSETATTR (var, att_invisible);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
static SHELL_VAR *
|
||||
bind_array_var_internal (entry, ind, value, flags)
|
||||
bind_array_var_internal (entry, ind, key, value, flags)
|
||||
SHELL_VAR *entry;
|
||||
arrayind_t ind;
|
||||
char *key;
|
||||
char *value;
|
||||
int flags;
|
||||
{
|
||||
@@ -100,7 +134,10 @@ bind_array_var_internal (entry, ind, value, flags)
|
||||
{
|
||||
dentry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR));
|
||||
dentry->name = savestring (entry->name);
|
||||
newval = array_reference (array_cell (entry), ind);
|
||||
if (assoc_p (entry))
|
||||
newval = assoc_reference (assoc_cell (entry), key);
|
||||
else
|
||||
newval = array_reference (array_cell (entry), ind);
|
||||
if (newval)
|
||||
dentry->value = savestring (newval);
|
||||
else
|
||||
@@ -109,7 +146,7 @@ bind_array_var_internal (entry, ind, value, flags)
|
||||
dentry->value[0] = '\0';
|
||||
}
|
||||
dentry->exportstr = 0;
|
||||
dentry->attributes = entry->attributes & ~(att_array|att_exported);
|
||||
dentry->attributes = entry->attributes & ~(att_array|att_assoc|att_exported);
|
||||
/* Leave the rest of the members uninitialized; the code doesn't look
|
||||
at them. */
|
||||
newval = make_variable_value (dentry, value, flags);
|
||||
@@ -119,7 +156,9 @@ bind_array_var_internal (entry, ind, value, flags)
|
||||
newval = make_variable_value (entry, value, flags);
|
||||
|
||||
if (entry->assign_func)
|
||||
(*entry->assign_func) (entry, newval, ind);
|
||||
(*entry->assign_func) (entry, newval, ind, key);
|
||||
else if (assoc_p (entry))
|
||||
assoc_insert (assoc_cell (entry), key, newval);
|
||||
else
|
||||
array_insert (array_cell (entry), ind, newval);
|
||||
FREE (newval);
|
||||
@@ -157,7 +196,38 @@ bind_array_variable (name, ind, value, flags)
|
||||
entry = convert_var_to_array (entry);
|
||||
|
||||
/* ENTRY is an array variable, and ARRAY points to the value. */
|
||||
return (bind_array_var_internal (entry, ind, value, flags));
|
||||
return (bind_array_var_internal (entry, ind, 0, value, flags));
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
bind_array_element (entry, ind, value, flags)
|
||||
SHELL_VAR *entry;
|
||||
arrayind_t ind;
|
||||
char *value;
|
||||
int flags;
|
||||
{
|
||||
return (bind_array_var_internal (entry, ind, 0, value, flags));
|
||||
}
|
||||
|
||||
SHELL_VAR *
|
||||
bind_assoc_variable (entry, name, key, value, flags)
|
||||
SHELL_VAR *entry;
|
||||
char *name;
|
||||
char *key;
|
||||
char *value;
|
||||
int flags;
|
||||
{
|
||||
SHELL_VAR *dentry;
|
||||
char *newval;
|
||||
|
||||
if (readonly_p (entry) || noassign_p (entry))
|
||||
{
|
||||
if (readonly_p (entry))
|
||||
err_readonly (name);
|
||||
return (entry);
|
||||
}
|
||||
|
||||
return (bind_array_var_internal (entry, 0, key, value, flags));
|
||||
}
|
||||
|
||||
/* Parse NAME, a lhs of an assignment statement of the form v[s], and
|
||||
@@ -167,7 +237,7 @@ assign_array_element (name, value, flags)
|
||||
char *name, *value;
|
||||
int flags;
|
||||
{
|
||||
char *sub, *vname;
|
||||
char *sub, *vname, *akey;
|
||||
arrayind_t ind;
|
||||
int sublen;
|
||||
SHELL_VAR *entry;
|
||||
@@ -184,15 +254,32 @@ assign_array_element (name, value, flags)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
|
||||
ind = array_expand_index (sub, sublen);
|
||||
if (ind < 0)
|
||||
{
|
||||
free (vname);
|
||||
err_badarraysub (name);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
entry = find_variable (vname);
|
||||
|
||||
entry = bind_array_variable (vname, ind, value, flags);
|
||||
if (entry && assoc_p (entry))
|
||||
{
|
||||
sub[sublen-1] = '\0';
|
||||
akey = expand_assignment_string_to_string (sub, 0); /* [ */
|
||||
sub[sublen-1] = ']';
|
||||
if (akey == 0 || *akey == 0)
|
||||
{
|
||||
free (vname);
|
||||
err_badarraysub (name);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
entry = bind_assoc_variable (entry, vname, akey, value, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
ind = array_expand_index (sub, sublen);
|
||||
if (ind < 0)
|
||||
{
|
||||
free (vname);
|
||||
err_badarraysub (name);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
entry = bind_array_variable (vname, ind, value, flags);
|
||||
}
|
||||
|
||||
free (vname);
|
||||
return (entry);
|
||||
@@ -200,27 +287,33 @@ assign_array_element (name, value, flags)
|
||||
|
||||
/* Find the array variable corresponding to NAME. If there is no variable,
|
||||
create a new array variable. If the variable exists but is not an array,
|
||||
convert it to an indexed array. If CHECK_FLAGS is non-zero, an existing
|
||||
convert it to an indexed array. If FLAGS&1 is non-zero, an existing
|
||||
variable is checked for the readonly or noassign attribute in preparation
|
||||
for assignment (e.g., by the `read' builtin). */
|
||||
for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we
|
||||
create an associative array. */
|
||||
SHELL_VAR *
|
||||
find_or_make_array_variable (name, check_flags)
|
||||
find_or_make_array_variable (name, flags)
|
||||
char *name;
|
||||
int check_flags;
|
||||
int flags;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
|
||||
var = find_variable (name);
|
||||
|
||||
if (var == 0)
|
||||
var = make_new_array_variable (name);
|
||||
else if (check_flags && (readonly_p (var) || noassign_p (var)))
|
||||
var = (flags & 2) ? make_new_assoc_variable (name) : make_new_array_variable (name);
|
||||
else if ((flags & 1) && (readonly_p (var) || noassign_p (var)))
|
||||
{
|
||||
if (readonly_p (var))
|
||||
err_readonly (name);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
else if (array_p (var) == 0)
|
||||
else if ((flags & 2) && array_p (var))
|
||||
{
|
||||
report_error (_("%s: cannot convert indexed to associative array"), name);
|
||||
return ((SHELL_VAR *)NULL);
|
||||
}
|
||||
else if (array_p (var) == 0 && assoc_p (var) == 0)
|
||||
var = convert_var_to_array (var);
|
||||
|
||||
return (var);
|
||||
@@ -234,8 +327,13 @@ assign_array_from_string (name, value, flags)
|
||||
int flags;
|
||||
{
|
||||
SHELL_VAR *var;
|
||||
int vflags;
|
||||
|
||||
var = find_or_make_array_variable (name, 1);
|
||||
vflags = 1;
|
||||
if (flags & ASS_MKASSOC)
|
||||
vflags |= 2;
|
||||
|
||||
var = find_or_make_array_variable (name, vflags);
|
||||
if (var == 0)
|
||||
return ((SHELL_VAR *)NULL);
|
||||
|
||||
@@ -259,14 +357,15 @@ assign_array_var_from_word_list (var, list, flags)
|
||||
|
||||
for (l = list; l; l = l->next, i++)
|
||||
if (var->assign_func)
|
||||
(*var->assign_func) (var, l->word->word, i);
|
||||
(*var->assign_func) (var, l->word->word, i, 0);
|
||||
else
|
||||
array_insert (a, i, l->word->word);
|
||||
return var;
|
||||
}
|
||||
|
||||
WORD_LIST *
|
||||
expand_compound_array_assignment (value, flags)
|
||||
expand_compound_array_assignment (var, value, flags)
|
||||
SHELL_VAR *var;
|
||||
char *value;
|
||||
int flags;
|
||||
{
|
||||
@@ -315,18 +414,30 @@ assign_compound_array_list (var, nlist, flags)
|
||||
int flags;
|
||||
{
|
||||
ARRAY *a;
|
||||
HASH_TABLE *h;
|
||||
WORD_LIST *list;
|
||||
char *w, *val, *nval;
|
||||
int len, iflags;
|
||||
arrayind_t ind, last_ind;
|
||||
char *akey;
|
||||
|
||||
a = array_cell (var);
|
||||
a = (var && array_p (var)) ? array_cell (var) : (ARRAY *)0;
|
||||
h = (var && assoc_p (var)) ? assoc_cell (var) : (HASH_TABLE *)0;
|
||||
|
||||
akey = (char *)0;
|
||||
ind = 0;
|
||||
|
||||
/* Now that we are ready to assign values to the array, kill the existing
|
||||
value. */
|
||||
if (a && (flags & ASS_APPEND) == 0)
|
||||
array_flush (a);
|
||||
last_ind = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
|
||||
if ((flags & ASS_APPEND) == 0)
|
||||
{
|
||||
if (array_p (var) && a)
|
||||
array_flush (a);
|
||||
else if (assoc_p (var) && h)
|
||||
assoc_flush (h);
|
||||
}
|
||||
|
||||
last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
|
||||
|
||||
for (list = nlist; list; list = list->next)
|
||||
{
|
||||
@@ -341,9 +452,14 @@ assign_compound_array_list (var, nlist, flags)
|
||||
/* XXX - changes for `+=' */
|
||||
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
|
||||
{
|
||||
if (assoc_p (var))
|
||||
{
|
||||
err_badarraysub (w);
|
||||
continue;
|
||||
}
|
||||
nval = make_variable_value (var, w, flags);
|
||||
if (var->assign_func)
|
||||
(*var->assign_func) (var, nval, last_ind);
|
||||
(*var->assign_func) (var, nval, last_ind, 0);
|
||||
else
|
||||
array_insert (a, last_ind, nval);
|
||||
FREE (nval);
|
||||
@@ -359,17 +475,34 @@ assign_compound_array_list (var, nlist, flags)
|
||||
|
||||
if (ALL_ELEMENT_SUB (w[1]) && len == 2)
|
||||
{
|
||||
report_error (_("%s: cannot assign to non-numeric index"), w);
|
||||
if (assoc_p (var))
|
||||
report_error (_("%s: invalid associative array key"), w);
|
||||
else
|
||||
report_error (_("%s: cannot assign to non-numeric index"), w);
|
||||
continue;
|
||||
}
|
||||
|
||||
ind = array_expand_index (w + 1, len);
|
||||
if (ind < 0)
|
||||
if (array_p (var))
|
||||
{
|
||||
err_badarraysub (w);
|
||||
continue;
|
||||
ind = array_expand_index (w + 1, len);
|
||||
if (ind < 0)
|
||||
{
|
||||
err_badarraysub (w);
|
||||
continue;
|
||||
}
|
||||
|
||||
last_ind = ind;
|
||||
}
|
||||
last_ind = ind;
|
||||
else if (assoc_p (var))
|
||||
{
|
||||
akey = substring (w, 1, len);
|
||||
if (akey == 0 || *akey == 0)
|
||||
{
|
||||
err_badarraysub (w);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */
|
||||
if (w[len + 1] == '+' && w[len + 2] == '=')
|
||||
{
|
||||
@@ -379,6 +512,11 @@ assign_compound_array_list (var, nlist, flags)
|
||||
else
|
||||
val = w + len + 2;
|
||||
}
|
||||
else if (assoc_p (var))
|
||||
{
|
||||
report_error (_("%s: %s: must use subscript when assigning associative array"), var->name, w);
|
||||
continue;
|
||||
}
|
||||
else /* No [ind]=value, just a stray `=' */
|
||||
{
|
||||
ind = last_ind;
|
||||
@@ -387,7 +525,7 @@ assign_compound_array_list (var, nlist, flags)
|
||||
|
||||
if (integer_p (var))
|
||||
this_command_name = (char *)NULL; /* no command name for errors */
|
||||
bind_array_var_internal (var, ind, val, iflags);
|
||||
bind_array_var_internal (var, ind, akey, val, iflags);
|
||||
last_ind++;
|
||||
}
|
||||
}
|
||||
@@ -405,7 +543,7 @@ assign_array_var_from_string (var, value, flags)
|
||||
if (value == 0)
|
||||
return var;
|
||||
|
||||
nlist = expand_compound_array_assignment (value, flags);
|
||||
nlist = expand_compound_array_assignment (var, value, flags);
|
||||
assign_compound_array_list (var, nlist, flags);
|
||||
|
||||
if (nlist)
|
||||
@@ -413,15 +551,44 @@ assign_array_var_from_string (var, value, flags)
|
||||
return (var);
|
||||
}
|
||||
|
||||
/* Quote globbing chars and characters in $IFS before the `=' in an assignment
|
||||
statement (usually a compound array assignment) to protect them from
|
||||
unwanted filename expansion or word splitting. */
|
||||
static char *
|
||||
quote_assign (string)
|
||||
const char *string;
|
||||
{
|
||||
size_t slen;
|
||||
int saw_eq;
|
||||
char *temp, *t;
|
||||
const char *s, *send;
|
||||
DECLARE_MBSTATE;
|
||||
|
||||
slen = strlen (string);
|
||||
send = string + slen;
|
||||
|
||||
t = temp = (char *)xmalloc (slen * 2 + 1);
|
||||
saw_eq = 0;
|
||||
for (s = string; *s; )
|
||||
{
|
||||
if (*s == '=')
|
||||
saw_eq = 1;
|
||||
if (saw_eq == 0 && (glob_char_p (s) || isifs (*s)))
|
||||
*t++ = '\\';
|
||||
|
||||
COPY_CHAR_P (t, s, send);
|
||||
}
|
||||
*t = '\0';
|
||||
return temp;
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
[ind]=value, quote globbing chars and characters in $IFS before the `='. */
|
||||
static void
|
||||
quote_array_assignment_chars (list)
|
||||
WORD_LIST *list;
|
||||
{
|
||||
char *s, *t, *nword;
|
||||
int saw_eq;
|
||||
char *nword;
|
||||
WORD_LIST *l;
|
||||
|
||||
for (l = list; l; l = l->next)
|
||||
@@ -431,17 +598,7 @@ quote_array_assignment_chars (list)
|
||||
/* Don't bother if it doesn't look like [ind]=value */
|
||||
if (l->word->word[0] != '[' || xstrchr (l->word->word, '=') == 0) /* ] */
|
||||
continue;
|
||||
s = nword = (char *)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';
|
||||
nword = quote_assign (l->word->word);
|
||||
free (l->word->word);
|
||||
l->word->word = nword;
|
||||
}
|
||||
@@ -496,7 +653,7 @@ skipsubscript (s, i)
|
||||
c = s[i];
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
break;
|
||||
else if (c == '[')
|
||||
count++;
|
||||
else if (c == ']')
|
||||
@@ -516,6 +673,7 @@ unbind_array_element (var, sub)
|
||||
{
|
||||
int len;
|
||||
arrayind_t ind;
|
||||
char *akey;
|
||||
ARRAY_ELEMENT *ae;
|
||||
|
||||
len = skipsubscript (sub, 0);
|
||||
@@ -531,15 +689,30 @@ unbind_array_element (var, sub)
|
||||
unbind_variable (var->name);
|
||||
return (0);
|
||||
}
|
||||
ind = array_expand_index (sub, len+1);
|
||||
if (ind < 0)
|
||||
|
||||
if (assoc_p (var))
|
||||
{
|
||||
builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
|
||||
return -1;
|
||||
akey = expand_assignment_string_to_string (sub, 0); /* [ */
|
||||
if (akey == 0 || *akey == 0)
|
||||
{
|
||||
builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
|
||||
return -1;
|
||||
}
|
||||
assoc_remove (assoc_cell (var), akey);
|
||||
}
|
||||
ae = array_remove (array_cell (var), ind);
|
||||
if (ae)
|
||||
array_dispose_element (ae);
|
||||
else
|
||||
{
|
||||
ind = array_expand_index (sub, len+1);
|
||||
if (ind < 0)
|
||||
{
|
||||
builtin_error ("[%s]: %s", sub, _(bash_badsub_errmsg));
|
||||
return -1;
|
||||
}
|
||||
ae = array_remove (array_cell (var), ind);
|
||||
if (ae)
|
||||
array_dispose_element (ae);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,6 +736,26 @@ print_array_assignment (var, quoted)
|
||||
}
|
||||
}
|
||||
|
||||
/* Format and output an associative array assignment in compound form
|
||||
VAR=(VALUES), suitable for re-use as input. */
|
||||
void
|
||||
print_assoc_assignment (var, quoted)
|
||||
SHELL_VAR *var;
|
||||
int quoted;
|
||||
{
|
||||
char *vstr;
|
||||
|
||||
vstr = assoc_to_assign (assoc_cell (var), quoted);
|
||||
|
||||
if (vstr == 0)
|
||||
printf ("%s=%s\n", var->name, quoted ? "'()'" : "()");
|
||||
else
|
||||
{
|
||||
printf ("%s=%s\n", var->name, vstr);
|
||||
free (vstr);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Utility functions to manage arrays and their contents for expansion */
|
||||
@@ -693,8 +886,8 @@ array_variable_part (s, subp, lenp)
|
||||
/* Return a string containing the elements in the array and subscript
|
||||
described by S. If the subscript is * or @, obeys quoting rules akin
|
||||
to the expansion of $* and $@ including double quoting. If RTYPE
|
||||
is non-null it gets 1 if the array reference is name[@] or name[*]
|
||||
and 0 otherwise. */
|
||||
is non-null it gets 1 if the array reference is name[*], 2 if the
|
||||
reference is name[@], and 0 otherwise. */
|
||||
static char *
|
||||
array_value_internal (s, quoted, allow_all, rtype)
|
||||
char *s;
|
||||
@@ -702,6 +895,7 @@ array_value_internal (s, quoted, allow_all, rtype)
|
||||
{
|
||||
int len;
|
||||
arrayind_t ind;
|
||||
char *akey;
|
||||
char *retval, *t, *temp;
|
||||
WORD_LIST *l;
|
||||
SHELL_VAR *var;
|
||||
@@ -730,8 +924,14 @@ array_value_internal (s, quoted, allow_all, rtype)
|
||||
}
|
||||
else if (var == 0 || value_cell (var) == 0)
|
||||
return ((char *)NULL);
|
||||
else if (array_p (var) == 0)
|
||||
else if (array_p (var) == 0 && assoc_p (var) == 0)
|
||||
l = add_string_to_list (value_cell (var), (WORD_LIST *)NULL);
|
||||
else if (assoc_p (var))
|
||||
{
|
||||
l = assoc_to_word_list (assoc_cell (var));
|
||||
if (l == (WORD_LIST *)NULL)
|
||||
return ((char *)NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
l = array_to_word_list (array_cell (var));
|
||||
@@ -754,24 +954,40 @@ array_value_internal (s, quoted, allow_all, rtype)
|
||||
{
|
||||
if (rtype)
|
||||
*rtype = 0;
|
||||
ind = array_expand_index (t, len);
|
||||
if (ind < 0)
|
||||
if (var == 0 || array_p (var) || assoc_p (var) == 0)
|
||||
{
|
||||
if (var)
|
||||
err_badarraysub (var->name);
|
||||
else
|
||||
ind = array_expand_index (t, len);
|
||||
if (ind < 0)
|
||||
{
|
||||
t[-1] = '\0';
|
||||
err_badarraysub (s);
|
||||
t[-1] = '['; /* ] */
|
||||
index_error:
|
||||
if (var)
|
||||
err_badarraysub (var->name);
|
||||
else
|
||||
{
|
||||
t[-1] = '\0';
|
||||
err_badarraysub (s);
|
||||
t[-1] = '['; /* ] */
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
return ((char *)NULL);
|
||||
}
|
||||
else if (assoc_p (var))
|
||||
{
|
||||
t[len - 1] = '\0';
|
||||
akey = expand_assignment_string_to_string (t, 0); /* [ */
|
||||
t[len - 1] = ']';
|
||||
if (akey == 0 || *akey == 0)
|
||||
goto index_error;
|
||||
}
|
||||
|
||||
if (var == 0)
|
||||
return ((char *)NULL);
|
||||
if (array_p (var) == 0)
|
||||
if (array_p (var) == 0 && assoc_p (var) == 0)
|
||||
return (ind == 0 ? value_cell (var) : (char *)NULL);
|
||||
retval = array_reference (array_cell (var), ind);
|
||||
else if (assoc_p (var))
|
||||
retval = assoc_reference (assoc_cell (var), akey);
|
||||
else
|
||||
retval = array_reference (array_cell (var), ind);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@@ -815,14 +1031,14 @@ array_keys (s, quoted)
|
||||
if (var == 0 || ALL_ELEMENT_SUB (t[0]) == 0 || t[1] != ']')
|
||||
return (char *)NULL;
|
||||
|
||||
if (array_p (var) == 0)
|
||||
if (array_p (var) == 0 && assoc_p (var) == 0)
|
||||
l = add_string_to_list ("0", (WORD_LIST *)NULL);
|
||||
else if (assoc_p (var))
|
||||
l = assoc_keys_to_word_list (assoc_cell (var));
|
||||
else
|
||||
{
|
||||
l = array_keys_to_word_list (array_cell (var));
|
||||
if (l == (WORD_LIST *)NULL)
|
||||
return ((char *) NULL);
|
||||
}
|
||||
l = array_keys_to_word_list (array_cell (var));
|
||||
if (l == (WORD_LIST *)NULL)
|
||||
return ((char *) NULL);
|
||||
|
||||
if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user