/* arrayfunc.c -- High-level array functions used by other parts of the shell. */
-/* Copyright (C) 2001-2021 Free Software Foundation, Inc.
+/* Copyright (C) 2001-2024 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
# define RBRACK ']'
#endif
-/* This variable means to not expand associative array subscripts more than
- once, when performing variable expansion. */
-int assoc_expand_once = 0;
-
-/* Ditto for indexed array subscripts -- currently unused */
+/* This variable means to not expand associative or indexed array subscripts
+ more than once, when performing variable expansion. */
int array_expand_once = 0;
-static SHELL_VAR *bind_array_var_internal PARAMS((SHELL_VAR *, arrayind_t, char *, char *, int));
-static SHELL_VAR *assign_array_element_internal PARAMS((SHELL_VAR *, char *, char *, char *, int, char *, int, array_eltstate_t *));
+static SHELL_VAR *bind_array_var_internal (SHELL_VAR *, arrayind_t, char *, const char *, int);
+static SHELL_VAR *assign_array_element_internal (SHELL_VAR *, const char *, char *, char *, int, const char *, int, array_eltstate_t *);
-static void assign_assoc_from_kvlist PARAMS((SHELL_VAR *, WORD_LIST *, HASH_TABLE *, int));
+static void assign_assoc_from_kvlist (SHELL_VAR *, WORD_LIST *, HASH_TABLE *, int);
-static char *quote_assign PARAMS((const char *));
-static void quote_array_assignment_chars PARAMS((WORD_LIST *));
-static char *quote_compound_array_word PARAMS((char *, int));
-static char *array_value_internal PARAMS((const char *, int, int, array_eltstate_t *));
+static char *quote_assign (const char *);
+static void quote_array_assignment_chars (WORD_LIST *);
+static char *quote_compound_array_word (char *, int);
+static char *array_value_internal (const char *, int, int, array_eltstate_t *);
/* Standard error message to use when encountering an invalid array subscript */
const char * const bash_badsub_errmsg = N_("bad array subscript");
/* Convert a shell variable to an array variable. The original value is
saved as array[0]. */
SHELL_VAR *
-convert_var_to_array (var)
- SHELL_VAR *var;
+convert_var_to_array (SHELL_VAR *var)
{
char *oldval;
ARRAY *array;
/* 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;
+convert_var_to_assoc (SHELL_VAR *var)
{
char *oldval;
HASH_TABLE *hash;
return var;
}
+/* Copy the array (ARRAY *) or assoc (HASH_TABLE *) from variable V1 to V2,
+ and return V2. */
+SHELL_VAR *
+arrayvar_copyval (SHELL_VAR *v1, SHELL_VAR *v2)
+{
+ FREE (value_cell (v2));
+ VUNSETATTR (v2, (att_array | att_assoc));
+ if (array_p (v1))
+ {
+ var_setarray (v2, array_copy (array_cell (v1)));
+ VSETATTR (v2, att_array);
+ }
+ else if (assoc_p (v1))
+ {
+ var_setassoc (v2, assoc_copy (assoc_cell (v1)));
+ VSETATTR (v2, att_assoc);
+ }
+ return v2;
+}
+
char *
-make_array_variable_value (entry, ind, key, value, flags)
- SHELL_VAR *entry;
- arrayind_t ind;
- char *key;
- char *value;
- int flags;
+make_array_variable_value (SHELL_VAR *entry, arrayind_t ind, const char *key, const char *value, int flags)
{
SHELL_VAR *dentry;
char *newval;
XXX - make sure that any dynamic associative array variables recreate the
hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */
static SHELL_VAR *
-bind_assoc_var_internal (entry, hash, key, value, flags)
- SHELL_VAR *entry;
- HASH_TABLE *hash;
- char *key;
- char *value;
- int flags;
+bind_assoc_var_internal (SHELL_VAR *entry, HASH_TABLE *hash, char *key, const char *value, int flags)
{
char *newval;
newval = make_array_variable_value (entry, 0, key, value, flags);
if (entry->assign_func)
- (*entry->assign_func) (entry, newval, 0, key);
+ {
+ (*entry->assign_func) (entry, newval, 0, key);
+ FREE (key);
+ }
else
assoc_insert (hash, key, newval);
/* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every
assignment to an associative array; see assign_compound_array_list below. */
static SHELL_VAR *
-bind_array_var_internal (entry, ind, key, value, flags)
- SHELL_VAR *entry;
- arrayind_t ind;
- char *key;
- char *value;
- int flags;
+bind_array_var_internal (SHELL_VAR *entry, arrayind_t ind, char *key, const char *value, int flags)
{
char *newval;
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, flags)
- char *name;
- arrayind_t ind;
- char *value;
- int flags;
+bind_array_variable (const char *name, arrayind_t ind, const char *value, int flags)
{
SHELL_VAR *entry;
}
SHELL_VAR *
-bind_array_element (entry, ind, value, flags)
- SHELL_VAR *entry;
- arrayind_t ind;
- char *value;
- int flags;
+bind_array_element (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;
+bind_assoc_variable (SHELL_VAR *entry, const char *name, char *key, const char *value, int flags)
{
if ((readonly_p (entry) && (flags&ASS_FORCE) == 0) || noassign_p (entry))
{
assign VALUE to that array element by calling bind_array_variable().
Flags are ASS_ assignment flags */
SHELL_VAR *
-assign_array_element (name, value, flags, estatep)
- char *name, *value;
- int flags;
- array_eltstate_t *estatep;
+assign_array_element (const char *name, const char *value, int flags, array_eltstate_t *estatep)
{
char *sub, *vname;
int sublen, isassoc, avflags;
SHELL_VAR *entry;
- avflags = 0;
- if (flags & ASS_NOEXPAND)
- avflags |= AV_NOEXPAND;
- if (flags & ASS_ONEWORD)
- avflags |= AV_ONEWORD;
+ avflags = convert_assign_flags_to_arrayval_flags (flags);
vname = array_variable_name (name, avflags, &sub, &sublen);
if (vname == 0)
return entry;
}
+/* Assign VALUE to the index computed from SUB of length SUBLEN of array
+ VNAME. NAME is the complete variable reference. FLAGS are ASS_ assignment
+ flags. ENTRY is the SHELL_VAR corresponding to VNAME. The caller
+ initializes ESTATEP, and we set it to the values we compute. */
static SHELL_VAR *
-assign_array_element_internal (entry, name, vname, sub, sublen, value, flags, estatep)
- SHELL_VAR *entry;
- char *name; /* only used for error messages */
- char *vname;
- char *sub;
- int sublen;
- char *value;
- int flags;
- array_eltstate_t *estatep;
+assign_array_element_internal (SHELL_VAR *entry, const char *name, char *vname,
+ char *sub, int sublen, const char *value,
+ int flags, array_eltstate_t *estatep)
{
char *akey, *nkey;
arrayind_t ind;
}
else
{
- ind = array_expand_index (entry, sub, sublen, 0);
+ /* convert ASS_ flags to AV_FLAGS here */
+ int avflags;
+
+ avflags = convert_assign_flags_to_arrayval_flags (flags);
+ ind = array_expand_index (entry, sub, sublen, avflags);
/* negative subscripts to indexed arrays count back from end */
if (entry && ind < 0)
ind = (array_p (entry) ? array_max_index (array_cell (entry)) : 0) + 1 + ind;
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). If FLAGS&2 is non-zero, we
- create an associative array. */
+ create an associative array. If FLAGS&4 is non-zero, we return noassign
+ variables instead of NULL because the caller wants to handle them. */
SHELL_VAR *
-find_or_make_array_variable (name, flags)
- char *name;
- int flags;
+find_or_make_array_variable (const char *name, int flags)
{
SHELL_VAR *var;
{
if (readonly_p (var))
err_readonly (name);
+ if ((flags & 4) && noassign_p (var))
+ return (var);
return ((SHELL_VAR *)NULL);
}
else if ((flags & 2) && array_p (var))
report_error (_("%s: cannot convert indexed to associative array"), name);
return ((SHELL_VAR *)NULL);
}
+ else if (flags & 2)
+ var = assoc_p (var) ? var : convert_var_to_assoc (var);
else if (array_p (var) == 0 && assoc_p (var) == 0)
var = convert_var_to_array (var);
/* 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, flags)
- char *name, *value;
- int flags;
+assign_array_from_string (const char *name, char *value, int flags)
{
SHELL_VAR *var;
int vflags;
vflags = 1;
if (flags & ASS_MKASSOC)
vflags |= 2;
+ vflags |= 4; /* we want to handle noassign variables ourselves */
var = find_or_make_array_variable (name, vflags);
- if (var == 0)
- return ((SHELL_VAR *)NULL);
+ if (var == 0 || noassign_p (var))
+ return (var);
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, flags)
- SHELL_VAR *var;
- WORD_LIST *list;
- int flags;
+assign_array_var_from_word_list (SHELL_VAR *var, WORD_LIST *list, int flags)
{
register arrayind_t i;
register WORD_LIST *l;
i = (flags & ASS_APPEND) ? array_max_index (a) + 1 : 0;
for (l = list; l; l = l->next, i++)
- bind_array_var_internal (var, i, 0, l->word->word, flags & ~ASS_APPEND);
+ {
+ if (a && i < 0) /* overflow */
+ {
+ char *num;
+
+ num = itos (i);
+ report_error ("%s[%s]: %s", var->name, num, bash_badsub_errmsg);
+ free (num);
+ return (var); /* XXX */
+ }
+
+ bind_array_var_internal (var, i, 0, l->word->word, flags & ~ASS_APPEND);
+ }
VUNSETATTR (var, att_invisible); /* no longer invisible */
}
WORD_LIST *
-expand_compound_array_assignment (var, value, flags)
- SHELL_VAR *var;
- char *value;
- int flags;
+expand_compound_array_assignment (SHELL_VAR *var, char *value, int flags)
{
WORD_LIST *list, *nlist;
char *val;
- int ni;
+ size_t ni;
/* This condition is true when invoked from the declare builtin with a
command like
}
#if ASSOC_KVPAIR_ASSIGNMENT
+/* If non-zero, we split the words in kv-pair compound array assignments in
+ addition to performing the other expansions. */
+int split_kvpair_assignments = 0;
+
+/* We have a set of key-value pairs that should be expanded and split
+ (because they are not assignment statements). They are not expanded
+ and split in expand_compound_array_assignment because assoc_p (var)
+ is true. We defer the expansion until now. */
static void
-assign_assoc_from_kvlist (var, nlist, h, flags)
- SHELL_VAR *var;
- WORD_LIST *nlist;
- HASH_TABLE *h;
- int flags;
+assign_assoc_from_kvlist (SHELL_VAR *var, WORD_LIST *nlist, HASH_TABLE *h, int flags)
{
- WORD_LIST *list;
+ WORD_LIST *list, *explist;
char *akey, *aval, *k, *v;
- for (list = nlist; list; list = list->next)
+ explist = split_kvpair_assignments ? expand_words_no_vars (nlist) : nlist;
+ for (list = explist; list; list = list->next)
{
k = list->word->word;
v = list->next ? list->next->word->word : 0;
if (list->next)
list = list->next;
- akey = expand_subscript_string (k, 0);
+ akey = split_kvpair_assignments ? savestring (k) : expand_subscript_string (k, 0);
if (akey == 0 || *akey == 0)
{
err_badarraysub (k);
continue;
}
- aval = expand_subscript_string (v, 0);
+ aval = split_kvpair_assignments ? savestring (v) : expand_assignment_string_to_string (v, 0);
if (aval == 0)
{
aval = (char *)xmalloc (1);
}
bind_assoc_var_internal (var, h, akey, aval, flags);
+
free (aval);
}
+
+ if (explist != nlist)
+ dispose_words (explist);
}
/* Return non-zero if L appears to be a key-value pair associative array
compound assignment. */
int
-kvpair_assignment_p (l)
- WORD_LIST *l;
+kvpair_assignment_p (WORD_LIST *l)
{
return (l && (l->word->flags & W_ASSIGNMENT) == 0 && l->word->word[0] != '['); /*]*/
}
char *
-expand_and_quote_kvpair_word (w)
- char *w;
+expand_and_quote_kvpair_word (const char *w)
{
char *r, *s, *t;
If this is an associative array, we perform the assignments into NHASH and
set NHASH to be the value of VAR after processing the assignments in NLIST */
-void
-assign_compound_array_list (var, nlist, flags)
- SHELL_VAR *var;
- WORD_LIST *nlist;
- int flags;
+int
+assign_compound_array_list (SHELL_VAR *var, WORD_LIST *nlist, int flags)
{
ARRAY *a;
HASH_TABLE *h, *nhash;
WORD_LIST *list;
char *w, *val, *nval, *savecmd;
- int len, iflags, free_val;
+ int len, iflags, free_val, any_failed;
arrayind_t ind, last_ind;
char *akey;
akey = (char *)0;
ind = 0;
+ any_failed = 0;
+
/* Now that we are ready to assign values to the array, kill the existing
value. */
if ((flags & ASS_APPEND) == 0)
nhash = assoc_create (h->nbuckets);
}
- last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
-
#if ASSOC_KVPAIR_ASSIGNMENT
if (assoc_p (var) && kvpair_assignment_p (nlist))
{
var_setassoc (var, nhash);
assoc_dispose (h);
}
- return;
+ return 1; /* XXX - check return value */
}
#endif
+ last_ind = (a && (flags & ASS_APPEND)) ? array_max_index (a) + 1 : 0;
+
for (list = nlist; list; list = list->next)
{
/* Don't allow var+=(values) to make assignments in VALUES append to
/* XXX - changes for `+=' */
if (w[len] != ']' || (w[len+1] != '=' && (w[len+1] != '+' || w[len+2] != '=')))
{
- if (assoc_p (var))
+ if (assoc_p (var) || last_ind < 0)
{
err_badarraysub (w);
- continue;
+ any_failed++;
+ break;
}
nval = make_variable_value (var, w, flags);
if (var->assign_func)
if (len == 1)
{
err_badarraysub (w);
- continue;
+ any_failed++;
+ break;
}
if (ALL_ELEMENT_SUB (w[1]) && len == 2 && array_p (var))
{
set_exit_status (EXECUTION_FAILURE);
report_error (_("%s: cannot assign to non-numeric index"), w);
- continue;
+ any_failed++;
+ break;
}
if (array_p (var))
{
- ind = array_expand_index (var, w + 1, len, 0);
+ int avflags;
+
+ /* convert ASS_ FLAGS to AV_ flags here */
+ avflags = convert_assign_flags_to_arrayval_flags (flags);
+ ind = array_expand_index (var, w + 1, len, avflags);
/* negative subscripts to indexed arrays count back from end */
if (ind < 0)
ind = array_max_index (array_cell (var)) + 1 + ind;
if (ind < 0)
{
err_badarraysub (w);
- continue;
+ any_failed++;
+ break;
}
last_ind = ind;
{
err_badarraysub (w);
FREE (akey);
- continue;
+ any_failed++;
+ break;
}
}
{
set_exit_status (EXECUTION_FAILURE);
report_error (_("%s: %s: must use subscript when assigning associative array"), var->name, w);
- continue;
+ any_failed++;
+ break;
}
else /* No [ind]=value, just a stray `=' */
{
val = w;
}
+ if (array_p (var) && ind < 0) /* overflow */
+ {
+ char *num;
+
+ num = itos (ind);
+ report_error ("%s[%s]: %s", var->name, num, bash_badsub_errmsg);
+ free (num);
+ return 0;
+ }
+
free_val = 0;
/* See above; we need to expand the value here */
if (assoc_p (var))
{
- val = expand_subscript_string (val, 0);
+ val = expand_assignment_string_to_string (val, 0);
if (val == 0)
{
val = (char *)xmalloc (1);
savecmd = this_command_name;
if (integer_p (var))
- this_command_name = (char *)NULL; /* no command name for errors */
+ this_command_name = 0; /* no command name for errors */
if (assoc_p (var))
bind_assoc_var_internal (var, nhash, akey, val, iflags);
else
var_setassoc (var, nhash);
assoc_dispose (h);
}
+
+#if ARRAY_EXPORT
+ if (var && exported_p (var))
+ {
+ INVALIDATE_EXPORTSTR (var);
+ array_needs_making = 1;
+ }
+#endif
+
+ return (any_failed ? 0 : 1);
}
/* Perform a compound array assignment: VAR->name=( VALUE ). The
- VALUE has already had the parentheses stripped. */
+ VALUE has already had the parentheses stripped. FLAGS are ASS_
+ assignment flags. */
SHELL_VAR *
-assign_array_var_from_string (var, value, flags)
- SHELL_VAR *var;
- char *value;
- int flags;
+assign_array_var_from_string (SHELL_VAR *var, char *value, int flags)
{
WORD_LIST *nlist;
+ int aflags, r;
if (value == 0)
return var;
nlist = expand_compound_array_assignment (var, value, flags);
- assign_compound_array_list (var, nlist, flags);
+ /* This is were we set ASS_NOEXPAND and ASS_ONEWORD if we need to, since
+ expand_compound_array_assignment performs word expansions. Honors
+ array_expand_once; allows @ and * as associative array keys. */
+ aflags = flags | (array_expand_once ? ASS_NOEXPAND : 0) | ASS_ALLOWALLSUB;
+ r = assign_compound_array_list (var, nlist, aflags);
if (nlist)
dispose_words (nlist);
if (var)
VUNSETATTR (var, att_invisible); /* no longer invisible */
- return (var);
+ return (r == 0 ? (SHELL_VAR *)0 : 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;
+quote_assign (const char *string)
{
size_t slen;
int saw_eq;
indexed arrays. W has already undergone word expansions. If W has no [IND]=,
just single-quote and return it. */
static char *
-quote_compound_array_word (w, type)
- char *w;
- int type;
+quote_compound_array_word (char *w, int type)
{
char *nword, *sub, *value, *t;
int ind, wlen, i;
if (t != w+ind)
free (t);
strcpy (nword + i, value);
+ free (value);
return nword;
}
Used for compound assignments to associative arrays that are arguments to
declaration builtins (declare -A a=( list )). */
char *
-expand_and_quote_assoc_word (w, type)
- char *w;
- int type;
+expand_and_quote_assoc_word (char *w, int type)
{
char *nword, *key, *value, *s, *t;
int ind, wlen, i;
nword[i++] = w[ind++];
nword[i++] = w[ind++];
- t = expand_subscript_string (w+ind, 0);
+ t = expand_assignment_string_to_string (w+ind, 0);
s = (t && strchr (t, CTLESC)) ? quote_escapes (t) : t;
value = sh_single_quote (s ? s : "");
if (s != t)
the = sign (and any `+') alone. If it's not an assignment, just single-
quote the word. This is used for indexed arrays. */
void
-quote_compound_array_list (list, type)
- WORD_LIST *list;
- int type;
+quote_compound_array_list (WORD_LIST *list, int type)
{
char *s, *t;
WORD_LIST *l;
/* For each word in a compound array assignment, if the word looks like
[ind]=value, quote globbing chars and characters in $IFS before the `='. */
static void
-quote_array_assignment_chars (list)
- WORD_LIST *list;
+quote_array_assignment_chars (WORD_LIST *list)
{
char *nword;
WORD_LIST *l;
the subscript, we just assume the subscript ends with a close bracket,
if one is present, and use what's inside the brackets. */
int
-unbind_array_element (var, sub, flags)
- SHELL_VAR *var;
- char *sub;
- int flags;
+unbind_array_element (SHELL_VAR *var, char *sub, int flags)
{
arrayind_t ind;
char *akey;
ARRAY_ELEMENT *ae;
+ int avflags;
/* Assume that the caller (unset_builtin) passes us a null-terminated SUB,
so we don't have to use VA_ONEWORD or parse the subscript again with
}
/* Fall through for behavior 3 */
}
- ind = array_expand_index (var, sub, strlen (sub) + 1, 0);
+
+ avflags = convert_validarray_flags_to_arrayval_flags (flags);
+ ind = array_expand_index (var, sub, strlen (sub) + 1, avflags);
/* negative subscripts to indexed arrays count back from end */
if (ind < 0)
ind = array_max_index (array_cell (var)) + 1 + ind;
else /* array_p (var) == 0 && assoc_p (var) == 0 */
{
akey = this_command_name;
- ind = array_expand_index (var, sub, strlen (sub) + 1, 0);
+ avflags = convert_validarray_flags_to_arrayval_flags (flags);
+ ind = array_expand_index (var, sub, strlen (sub) + 1, avflags);
this_command_name = akey;
if (ind == 0)
{
/* Format and output an array assignment in compound form VAR=(VALUES),
suitable for re-use as input. */
void
-print_array_assignment (var, quoted)
- SHELL_VAR *var;
- int quoted;
+print_array_assignment (SHELL_VAR *var, int quoted)
{
char *vstr;
/* 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;
+print_assoc_assignment (SHELL_VAR *var, int quoted)
{
char *vstr;
/* Return 1 if NAME is a properly-formed array reference v[sub]. */
-/* Return 1 if NAME is a properly-formed array reference v[sub]. */
-
/* When NAME is a properly-formed array reference and a non-null argument SUBP
is supplied, '[' and ']' that enclose the subscript are replaced by '\0',
and the pointer to the subscript in NAME is assigned to *SUBP, so that NAME
not be modified. */
/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
int
-tokenize_array_reference (name, flags, subp)
- char *name;
- int flags;
- char **subp;
+tokenize_array_reference (const char *name, int flags, char **subp)
{
char *t;
int r, len, isassoc, ssflags;
if (t)
{
*t = '\0';
- r = legal_identifier (name);
+ r = valid_identifier (name);
if (flags & VA_NOEXPAND) /* Don't waste a lookup if we don't need one */
isassoc = (entry = find_variable (name)) && assoc_p (entry);
*t = '[';
/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
int
-valid_array_reference (name, flags)
- const char *name;
- int flags;
+valid_array_reference (const char *name, int flags)
{
- return tokenize_array_reference ((char *)name, flags, (char **)NULL);
+ return tokenize_array_reference (name, flags, (char **)NULL);
}
-/* Expand the array index beginning at S and extending LEN characters. */
+/* Expand the array index beginning at S and extending LEN characters. FLAGS
+ are AV_ flags saying how to compute the array value. */
arrayind_t
-array_expand_index (var, s, len, flags)
- SHELL_VAR *var;
- char *s;
- int len;
- int flags;
+array_expand_index (SHELL_VAR *var, const char *s, int len, int flags)
{
char *exp, *t, *savecmd;
int expok, eflag;
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
-#if 0 /* TAG: maybe bash-5.2 */
+#if 1 /* TAG: bash-5.3 */
+#if 0
+ if (shell_compatibility_level <= 52 || (flags & AV_NOEXPAND) == 0)
+#else
if ((flags & AV_NOEXPAND) == 0)
+#endif
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
else
t = exp;
in *SUBP. If LENP is non-null, the length of the subscript is returned
in *LENP. This returns newly-allocated memory. */
char *
-array_variable_name (s, flags, subp, lenp)
- const char *s;
- int flags;
- char **subp;
- int *lenp;
+array_variable_name (const char *s, int flags, char **subp, int *lenp)
{
char *t, *ret;
int ind, ni, ssflags;
non-null, return a pointer to the start of the subscript in *SUBP.
If LENP is non-null, the length of the subscript is returned in *LENP. */
SHELL_VAR *
-array_variable_part (s, flags, subp, lenp)
- const char *s;
- int flags;
- char **subp;
- int *lenp;
+array_variable_part (const char *s, int flags, char **subp, int *lenp)
{
char *t;
SHELL_VAR *var;
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, flags, estatep)
- const char *s;
- int quoted, flags;
- array_eltstate_t *estatep;
+array_value_internal (const char *s, int quoted, int flags, array_eltstate_t *estatep)
{
int len, isassoc, subtype;
arrayind_t ind;
else
{
if (estatep)
- estatep->type = ARRAY_ASSOC;
+ estatep->type = ARRAY_INDEXED;
l = array_to_word_list (array_cell (var));
if (l == (WORD_LIST *)NULL)
return ((char *) NULL);
/* Return a string containing the elements described by the array and
subscript contained in S, obeying quoting for subscripts * and @. */
char *
-array_value (s, quoted, flags, estatep)
- const char *s;
- int quoted, flags;
- array_eltstate_t *estatep;
+array_value (const char *s, int quoted, int flags, array_eltstate_t *estatep)
{
char *retval;
is used by other parts of the shell such as the arithmetic expression
evaluator in expr.c. */
char *
-get_array_value (s, flags, estatep)
- const char *s;
- int flags;
- array_eltstate_t *estatep;
+get_array_value (const char *s, int flags, array_eltstate_t *estatep)
{
char *retval;
}
char *
-array_keys (s, quoted, pflags)
- char *s;
- int quoted, pflags;
+array_keys (const char *s, int quoted, int pflags)
{
int len;
char *retval, *t, *temp;