summaryrefslogtreecommitdiff
path: root/arrayfunc.c
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2018-11-23 15:32:57 -0500
committerChet Ramey <chet.ramey@case.edu>2018-11-23 15:32:57 -0500
commit2ae59c1134a75d5778997b7202b15b0586283042 (patch)
tree6a0fa496d41b222f5f69e3640d84932fb7a84778 /arrayfunc.c
parent2f5dfe5a18b4670eb4cea32c1c76295eb70a8865 (diff)
downloadbash-5.0-beta2.tar.gz
bash-5.0-beta2 releasebash-5.0-beta2
Diffstat (limited to 'arrayfunc.c')
-rw-r--r--arrayfunc.c48
1 files changed, 34 insertions, 14 deletions
diff --git a/arrayfunc.c b/arrayfunc.c
index e3700dd3..e4ae34d0 100644
--- a/arrayfunc.c
+++ b/arrayfunc.c
@@ -283,7 +283,7 @@ assign_array_element (name, value, flags)
int flags;
{
char *sub, *vname;
- int sublen;
+ int sublen, isassoc;
SHELL_VAR *entry;
vname = array_variable_name (name, (flags & ASS_NOEXPAND) != 0, &sub, &sublen);
@@ -291,14 +291,16 @@ assign_array_element (name, value, flags)
if (vname == 0)
return ((SHELL_VAR *)NULL);
- if ((ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']') || (sublen <= 1))
+ entry = find_variable (vname);
+ isassoc = entry && assoc_p (entry);
+
+ if (((isassoc == 0 || (flags & ASS_NOEXPAND) == 0) && (ALL_ELEMENT_SUB (sub[0]) && sub[1] == ']')) || (sublen <= 1))
{
free (vname);
err_badarraysub (name);
return ((SHELL_VAR *)NULL);
}
- entry = find_variable (vname);
entry = assign_array_element_internal (entry, name, vname, sub, sublen, value, flags);
free (vname);
@@ -777,7 +779,7 @@ unbind_array_element (var, sub, flags)
char *akey;
ARRAY_ELEMENT *ae;
- len = skipsubscript (sub, 0, (flags&1) || (var && assoc_p(var)));
+ len = skipsubscript (sub, 0, (flags&1) || (var && assoc_p(var))); /* XXX */
if (sub[len] != ']' || len == 0)
{
builtin_error ("%s[%s: %s", var->name, sub, _(bash_badsub_errmsg));
@@ -888,31 +890,43 @@ print_assoc_assignment (var, quoted)
/***********************************************************************/
/* Return 1 if NAME is a properly-formed array reference v[sub]. */
+
+/* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
int
valid_array_reference (name, flags)
const char *name;
int flags;
{
char *t;
- int r, len;
+ int r, len, isassoc;
+ SHELL_VAR *entry;
t = mbschr (name, '['); /* ] */
+ isassoc = 0;
if (t)
{
*t = '\0';
r = legal_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 = '[';
if (r == 0)
return 0;
- /* Check for a properly-terminated non-null subscript. */
- len = skipsubscript (t, 0, flags);
- if (t[len] != ']' || len == 1)
- return 0;
- if (t[len+1] != '\0')
+
+ if (isassoc && ((flags & (VA_NOEXPAND|VA_ONEWORD)) == (VA_NOEXPAND|VA_ONEWORD)))
+ len = strlen (t) - 1;
+ else if (isassoc)
+ len = skipsubscript (t, 0, flags&VA_NOEXPAND); /* VA_NOEXPAND must be 1 */
+ else
+ /* Check for a properly-terminated non-null subscript. */
+ len = skipsubscript (t, 0, 0); /* arithmetic expression */
+
+ if (t[len] != ']' || len == 1 || t[len+1] != '\0')
return 0;
-#if 1
+
+#if 0
/* Could check and allow subscripts consisting only of whitespace for
- existing associative arrays. */
+ existing associative arrays, using isassoc */
for (r = 1; r < len; r++)
if (whitespace (t[r]) == 0)
return 1;
@@ -940,7 +954,7 @@ array_expand_index (var, s, len, flags)
exp = (char *)xmalloc (len);
strncpy (exp, s, len - 1);
exp[len - 1] = '\0';
-#if 0 /* XXX - not yet -- maybe bash-5.0 */
+#if 0 /* XXX - not yet -- maybe bash-5.1 */
if ((flags & AV_NOEXPAND) == 0)
t = expand_arith_string (exp, Q_DOUBLE_QUOTES|Q_ARITH|Q_ARRAYSUB); /* XXX - Q_ARRAYSUB for future use */
else
@@ -1093,6 +1107,8 @@ array_value_internal (s, quoted, flags, rtype, indp)
}
else if (var == 0 || value_cell (var) == 0) /* XXX - check for invisible_p(var) ? */
return ((char *)NULL);
+ else if (invisible_p (var))
+ return ((char *)NULL);
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))
@@ -1117,7 +1133,6 @@ array_value_internal (s, quoted, flags, rtype, indp)
free (temp);
}
else /* ${name[@]} or unquoted ${name[*]} */
- /* XXX - bash-4.4/bash-5.0 test AV_ASSIGNRHS and pass PF_ASSIGNRHS */
retval = string_list_dollar_at (l, quoted, (flags & AV_ASSIGNRHS) ? PF_ASSIGNRHS : 0);
dispose_words (l);
@@ -1165,6 +1180,11 @@ array_value_internal (s, quoted, flags, rtype, indp)
FREE (akey);
return ((char *)NULL);
}
+ else if (invisible_p (var))
+ {
+ FREE (akey);
+ return ((char *)NULL);
+ }
if (array_p (var) == 0 && assoc_p (var) == 0)
return (ind == 0 ? value_cell (var) : (char *)NULL);
else if (assoc_p (var))