1 /* arrayfunc.c -- High-level array functions used by other parts of the shell. */
3 /* Copyright (C) 2001-2023 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Bash is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23 #if defined (ARRAY_VARS)
25 #if defined (HAVE_UNISTD_H)
33 #include "execute_cmd.h"
37 #if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
38 # include <mbstr.h> /* mbschr */
41 #include "builtins/common.h"
48 /* This variable means to not expand associative or indexed array subscripts
49 more than once, when performing variable expansion. */
50 int array_expand_once
= 0;
52 static SHELL_VAR
*bind_array_var_internal (SHELL_VAR
*, arrayind_t
, char *, const char *, int);
53 static SHELL_VAR
*assign_array_element_internal (SHELL_VAR
*, const char *, char *, char *, int, const char *, int, array_eltstate_t
*);
55 static void assign_assoc_from_kvlist (SHELL_VAR
*, WORD_LIST
*, HASH_TABLE
*, int);
57 static char *quote_assign (const char *);
58 static void quote_array_assignment_chars (WORD_LIST
*);
59 static char *quote_compound_array_word (char *, int);
60 static char *array_value_internal (const char *, int, int, array_eltstate_t
*);
62 /* Standard error message to use when encountering an invalid array subscript */
63 const char * const bash_badsub_errmsg
= N_("bad array subscript");
65 /* **************************************************************** */
67 /* Functions to manipulate array variables and perform assignments */
69 /* **************************************************************** */
71 /* Convert a shell variable to an array variable. The original value is
74 convert_var_to_array (SHELL_VAR
*var
)
79 oldval
= value_cell (var
);
80 array
= array_create ();
82 array_insert (array
, 0, oldval
);
84 FREE (value_cell (var
));
85 var_setarray (var
, array
);
87 /* these aren't valid anymore */
88 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
89 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
91 INVALIDATE_EXPORTSTR (var
);
95 VSETATTR (var
, att_array
);
97 VUNSETATTR (var
, att_invisible
);
99 /* Make sure it's not marked as an associative array any more */
100 VUNSETATTR (var
, att_assoc
);
102 /* Since namerefs can't be array variables, turn off nameref attribute */
103 VUNSETATTR (var
, att_nameref
);
108 /* Convert a shell variable to an array variable. The original value is
109 saved as array[0]. */
111 convert_var_to_assoc (SHELL_VAR
*var
)
116 oldval
= value_cell (var
);
117 hash
= assoc_create (0);
119 assoc_insert (hash
, savestring ("0"), oldval
);
121 FREE (value_cell (var
));
122 var_setassoc (var
, hash
);
124 /* these aren't valid anymore */
125 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
126 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
128 INVALIDATE_EXPORTSTR (var
);
129 if (exported_p (var
))
130 array_needs_making
++;
132 VSETATTR (var
, att_assoc
);
134 VUNSETATTR (var
, att_invisible
);
136 /* Make sure it's not marked as an indexed array any more */
137 VUNSETATTR (var
, att_array
);
139 /* Since namerefs can't be array variables, turn off nameref attribute */
140 VUNSETATTR (var
, att_nameref
);
145 /* Copy the array (ARRAY *) or assoc (HASH_TABLE *) from variable V1 to V2,
148 arrayvar_copyval (SHELL_VAR
*v1
, SHELL_VAR
*v2
)
150 FREE (value_cell (v2
));
151 VUNSETATTR (v2
, (att_array
| att_assoc
));
154 var_setarray (v2
, array_copy (array_cell (v1
)));
155 VSETATTR (v2
, att_array
);
157 else if (assoc_p (v1
))
159 var_setassoc (v2
, assoc_copy (assoc_cell (v1
)));
160 VSETATTR (v2
, att_assoc
);
166 make_array_variable_value (SHELL_VAR
*entry
, arrayind_t ind
, const char *key
, const char *value
, int flags
)
171 /* If we're appending, we need the old value of the array reference, so
172 fake out make_variable_value with a dummy SHELL_VAR */
173 if (flags
& ASS_APPEND
)
175 dentry
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
176 dentry
->name
= savestring (entry
->name
);
178 newval
= assoc_reference (assoc_cell (entry
), key
);
180 newval
= array_reference (array_cell (entry
), ind
);
182 dentry
->value
= savestring (newval
);
185 dentry
->value
= (char *)xmalloc (1);
186 dentry
->value
[0] = '\0';
188 dentry
->exportstr
= 0;
189 dentry
->attributes
= entry
->attributes
& ~(att_array
|att_assoc
|att_exported
);
190 /* Leave the rest of the members uninitialized; the code doesn't look
192 newval
= make_variable_value (dentry
, value
, flags
);
193 dispose_variable (dentry
);
196 newval
= make_variable_value (entry
, value
, flags
);
201 /* Assign HASH[KEY]=VALUE according to FLAGS. ENTRY is an associative array
202 variable; HASH is the hash table to assign into. HASH may or may not be
203 the hash table associated with ENTRY; if it's not, the caller takes care
205 XXX - make sure that any dynamic associative array variables recreate the
206 hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */
208 bind_assoc_var_internal (SHELL_VAR
*entry
, HASH_TABLE
*hash
, char *key
, const char *value
, int flags
)
212 /* Use the existing array contents to expand the value */
213 newval
= make_array_variable_value (entry
, 0, key
, value
, flags
);
215 if (entry
->assign_func
)
217 (*entry
->assign_func
) (entry
, newval
, 0, key
);
221 assoc_insert (hash
, key
, newval
);
225 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
227 /* check mark_modified_variables if we ever want to export array vars */
231 /* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every
232 assignment to an associative array; see assign_compound_array_list below. */
234 bind_array_var_internal (SHELL_VAR
*entry
, arrayind_t ind
, char *key
, const char *value
, int flags
)
238 newval
= make_array_variable_value (entry
, ind
, key
, value
, flags
);
240 if (entry
->assign_func
)
241 (*entry
->assign_func
) (entry
, newval
, ind
, key
);
242 else if (assoc_p (entry
))
243 assoc_insert (assoc_cell (entry
), key
, newval
);
245 array_insert (array_cell (entry
), ind
, newval
);
248 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
250 /* check mark_modified_variables if we ever want to export array vars */
254 /* Perform an array assignment name[ind]=value. If NAME already exists and
255 is not an array, and IND is 0, perform name=value instead. If NAME exists
256 and is not an array, and IND is not 0, convert it into an array with the
257 existing value as name[0].
259 If NAME does not exist, just create an array variable, no matter what
260 IND's value may be. */
262 bind_array_variable (const char *name
, arrayind_t ind
, const char *value
, int flags
)
266 entry
= find_shell_variable (name
);
268 if (entry
== (SHELL_VAR
*) 0)
270 /* Is NAME a nameref variable that points to an unset variable? */
271 entry
= find_variable_nameref_for_create (name
, 0);
272 if (entry
== INVALID_NAMEREF_VALUE
)
273 return ((SHELL_VAR
*)0);
274 if (entry
&& nameref_p (entry
))
275 entry
= make_new_array_variable (nameref_cell (entry
));
277 if (entry
== (SHELL_VAR
*) 0)
278 entry
= make_new_array_variable (name
);
279 else if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
281 if (readonly_p (entry
))
285 else if (array_p (entry
) == 0)
286 entry
= convert_var_to_array (entry
);
288 /* ENTRY is an array variable, and ARRAY points to the value. */
289 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
293 bind_array_element (SHELL_VAR
*entry
, arrayind_t ind
, char *value
, int flags
)
295 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
299 bind_assoc_variable (SHELL_VAR
*entry
, const char *name
, char *key
, const char *value
, int flags
)
301 if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
303 if (readonly_p (entry
))
308 return (bind_assoc_var_internal (entry
, assoc_cell (entry
), key
, value
, flags
));
312 init_eltstate (array_eltstate_t
*estatep
)
316 estatep
->type
= ARRAY_INVALID
;
317 estatep
->subtype
= 0;
318 estatep
->key
= estatep
->value
= 0;
319 estatep
->ind
= INTMAX_MIN
;
324 flush_eltstate (array_eltstate_t
*estatep
)
330 /* Parse NAME, a lhs of an assignment statement of the form v[s], and
331 assign VALUE to that array element by calling bind_array_variable().
332 Flags are ASS_ assignment flags */
334 assign_array_element (const char *name
, const char *value
, int flags
, array_eltstate_t
*estatep
)
337 int sublen
, isassoc
, avflags
;
340 avflags
= convert_assign_flags_to_arrayval_flags (flags
);
341 vname
= array_variable_name (name
, avflags
, &sub
, &sublen
);
344 return ((SHELL_VAR
*)NULL
);
346 entry
= find_variable (vname
);
347 isassoc
= entry
&& assoc_p (entry
);
349 /* We don't allow assignment to `*' or `@' associative array keys if the
350 caller hasn't told us the subscript has already been expanded
351 (ASS_NOEXPAND). If the caller has explicitly told us it's ok
352 (ASS_ALLOWALLSUB) we allow it. */
353 if (((isassoc
== 0 || (flags
& (ASS_NOEXPAND
|ASS_ALLOWALLSUB
)) == 0) &&
354 (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == ']')) ||
356 (sub
[sublen
] != '\0')) /* sanity check */
359 err_badarraysub (name
);
360 return ((SHELL_VAR
*)NULL
);
363 entry
= assign_array_element_internal (entry
, name
, vname
, sub
, sublen
, value
, flags
, estatep
);
366 if (entry
&& exported_p (entry
))
368 INVALIDATE_EXPORTSTR (entry
);
369 array_needs_making
= 1;
377 /* Assign VALUE to the index computed from SUB of length SUBLEN of array
378 VNAME. NAME is the complete variable reference. FLAGS are ASS_ assignment
379 flags. ENTRY is the SHELL_VAR corresponding to VNAME. The caller
380 initializes ESTATEP, and we set it to the values we compute. */
382 assign_array_element_internal (SHELL_VAR
*entry
, const char *name
, char *vname
,
383 char *sub
, int sublen
, const char *value
,
384 int flags
, array_eltstate_t
*estatep
)
390 /* rely on the caller to initialize estatep */
392 if (entry
&& assoc_p (entry
))
394 sub
[sublen
-1] = '\0';
395 if ((flags
& ASS_NOEXPAND
) == 0)
396 akey
= expand_subscript_string (sub
, 0); /* [ */
398 akey
= savestring (sub
);
400 if (akey
== 0 || *akey
== 0)
402 err_badarraysub (name
);
404 return ((SHELL_VAR
*)NULL
);
407 nkey
= savestring (akey
); /* assoc_insert/assoc_replace frees akey */
408 entry
= bind_assoc_variable (entry
, vname
, akey
, value
, flags
);
411 estatep
->type
= ARRAY_ASSOC
;
413 estatep
->value
= entry
? assoc_reference (assoc_cell (entry
), nkey
) : 0;
418 /* convert ASS_ flags to AV_FLAGS here */
421 avflags
= convert_assign_flags_to_arrayval_flags (flags
);
422 ind
= array_expand_index (entry
, sub
, sublen
, avflags
);
423 /* negative subscripts to indexed arrays count back from end */
424 if (entry
&& ind
< 0)
425 ind
= (array_p (entry
) ? array_max_index (array_cell (entry
)) : 0) + 1 + ind
;
428 err_badarraysub (name
);
429 return ((SHELL_VAR
*)NULL
);
431 entry
= bind_array_variable (vname
, ind
, value
, flags
);
434 estatep
->type
= ARRAY_INDEXED
;
436 estatep
->value
= entry
? array_reference (array_cell (entry
), ind
) : 0;
443 /* Find the array variable corresponding to NAME. If there is no variable,
444 create a new array variable. If the variable exists but is not an array,
445 convert it to an indexed array. If FLAGS&1 is non-zero, an existing
446 variable is checked for the readonly or noassign attribute in preparation
447 for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we
448 create an associative array. If FLAGS&4 is non-zero, we return noassign
449 variables instead of NULL because the caller wants to handle them. */
451 find_or_make_array_variable (const char *name
, int flags
)
455 var
= find_variable (name
);
458 /* See if we have a nameref pointing to a variable that hasn't been
460 var
= find_variable_last_nameref (name
, 1);
461 if (var
&& nameref_p (var
) && invisible_p (var
))
463 internal_warning (_("%s: removing nameref attribute"), name
);
464 VUNSETATTR (var
, att_nameref
);
466 if (var
&& nameref_p (var
))
468 if (valid_nameref_value (nameref_cell (var
), 2) == 0)
470 sh_invalidid (nameref_cell (var
));
471 return ((SHELL_VAR
*)NULL
);
473 var
= (flags
& 2) ? make_new_assoc_variable (nameref_cell (var
)) : make_new_array_variable (nameref_cell (var
));
478 var
= (flags
& 2) ? make_new_assoc_variable (name
) : make_new_array_variable (name
);
479 else if ((flags
& 1) && (readonly_p (var
) || noassign_p (var
)))
481 if (readonly_p (var
))
483 if ((flags
& 4) && noassign_p (var
))
485 return ((SHELL_VAR
*)NULL
);
487 else if ((flags
& 2) && array_p (var
))
489 set_exit_status (EXECUTION_FAILURE
);
490 report_error (_("%s: cannot convert indexed to associative array"), name
);
491 return ((SHELL_VAR
*)NULL
);
494 var
= assoc_p (var
) ? var
: convert_var_to_assoc (var
);
495 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
496 var
= convert_var_to_array (var
);
501 /* Perform a compound assignment statement for array NAME, where VALUE is
502 the text between the parens: NAME=( VALUE ) */
504 assign_array_from_string (const char *name
, char *value
, int flags
)
510 if (flags
& ASS_MKASSOC
)
512 vflags
|= 4; /* we want to handle noassign variables ourselves */
514 var
= find_or_make_array_variable (name
, vflags
);
515 if (var
== 0 || noassign_p (var
))
518 return (assign_array_var_from_string (var
, value
, flags
));
521 /* Sequentially assign the indices of indexed array variable VAR from the
524 assign_array_var_from_word_list (SHELL_VAR
*var
, WORD_LIST
*list
, int flags
)
526 register arrayind_t i
;
527 register WORD_LIST
*l
;
530 a
= array_cell (var
);
531 i
= (flags
& ASS_APPEND
) ? array_max_index (a
) + 1 : 0;
533 for (l
= list
; l
; l
= l
->next
, i
++)
535 if (a
&& i
< 0) /* overflow */
540 report_error ("%s[%s]: %s", var
->name
, num
, bash_badsub_errmsg
);
542 return (var
); /* XXX */
545 bind_array_var_internal (var
, i
, 0, l
->word
->word
, flags
& ~ASS_APPEND
);
548 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
554 expand_compound_array_assignment (SHELL_VAR
*var
, char *value
, int flags
)
556 WORD_LIST
*list
, *nlist
;
560 /* This condition is true when invoked from the declare builtin with a
562 declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")' */
563 if (*value
== '(') /*)*/
566 val
= extract_array_assignment_list (value
, &ni
);
568 return (WORD_LIST
*)NULL
;
573 /* Expand the value string into a list of words, performing all the
574 shell expansions including pathname generation and word splitting. */
575 /* First we split the string on whitespace, using the shell parser
576 (ksh93 seems to do this). */
577 /* XXX - this needs a rethink, maybe use split_at_delims */
578 list
= parse_string_to_word_list (val
, 1, "array assign");
580 /* If the parser has quoted CTLESC and CTNLNUL with CTLESC in unquoted
581 words, we need to remove those here because the code below assumes
582 they are there because they exist in the original word. */
583 /* XXX - if we rethink parse_string_to_word_list above, change this. */
584 for (nlist
= list
; nlist
; nlist
= nlist
->next
)
585 if ((nlist
->word
->flags
& W_QUOTED
) == 0)
586 remove_quoted_escapes (nlist
->word
->word
);
588 /* Note that we defer expansion of the assignment statements for associative
589 arrays here, so we don't have to scan the subscript and find the ending
590 bracket twice. See the caller below. */
591 if (var
&& assoc_p (var
))
598 /* If we're using [subscript]=value, we need to quote each [ and ] to
599 prevent unwanted filename expansion. This doesn't need to be done
600 for associative array expansion, since that uses a different expansion
601 function (see assign_compound_array_list below). */
603 quote_array_assignment_chars (list
);
605 /* Now that we've split it, perform the shell expansions on each
607 nlist
= list
? expand_words_no_vars (list
) : (WORD_LIST
*)NULL
;
609 dispose_words (list
);
617 #if ASSOC_KVPAIR_ASSIGNMENT
618 /* If non-zero, we split the words in kv-pair compound array assignments in
619 addition to performing the other expansions. */
620 int split_kvpair_assignments
= 0;
622 /* We have a set of key-value pairs that should be expanded and split
623 (because they are not assignment statements). They are not expanded
624 and split in expand_compound_array_assignment because assoc_p (var)
625 is true. We defer the expansion until now. */
627 assign_assoc_from_kvlist (SHELL_VAR
*var
, WORD_LIST
*nlist
, HASH_TABLE
*h
, int flags
)
629 WORD_LIST
*list
, *explist
;
630 char *akey
, *aval
, *k
, *v
;
632 explist
= split_kvpair_assignments
? expand_words_no_vars (nlist
) : nlist
;
633 for (list
= explist
; list
; list
= list
->next
)
635 k
= list
->word
->word
;
636 v
= list
->next
? list
->next
->word
->word
: 0;
641 akey
= split_kvpair_assignments
? savestring (k
) : expand_subscript_string (k
, 0);
642 if (akey
== 0 || *akey
== 0)
649 aval
= split_kvpair_assignments
? savestring (v
) : expand_assignment_string_to_string (v
, 0);
652 aval
= (char *)xmalloc (1);
653 aval
[0] = '\0'; /* like do_assignment_internal */
656 bind_assoc_var_internal (var
, h
, akey
, aval
, flags
);
661 if (explist
!= nlist
)
662 dispose_words (explist
);
665 /* Return non-zero if L appears to be a key-value pair associative array
666 compound assignment. */
668 kvpair_assignment_p (WORD_LIST
*l
)
670 return (l
&& (l
->word
->flags
& W_ASSIGNMENT
) == 0 && l
->word
->word
[0] != '['); /*]*/
674 expand_and_quote_kvpair_word (const char *w
)
678 t
= w
? expand_subscript_string (w
, 0) : 0;
679 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
680 r
= sh_single_quote (s
? s
: "");
688 /* Callers ensure that VAR is not NULL. Associative array assignments have not
689 been expanded when this is called, or have been expanded once and single-
690 quoted, so we don't have to scan through an unquoted expanded subscript to
691 find the ending bracket; indexed array assignments have been expanded and
692 possibly single-quoted to prevent further expansion.
694 If this is an associative array, we perform the assignments into NHASH and
695 set NHASH to be the value of VAR after processing the assignments in NLIST */
697 assign_compound_array_list (SHELL_VAR
*var
, WORD_LIST
*nlist
, int flags
)
700 HASH_TABLE
*h
, *nhash
;
702 char *w
, *val
, *nval
, *savecmd
;
703 int len
, iflags
, free_val
, any_failed
;
704 arrayind_t ind
, last_ind
;
707 a
= (var
&& array_p (var
)) ? array_cell (var
) : (ARRAY
*)0;
708 nhash
= h
= (var
&& assoc_p (var
)) ? assoc_cell (var
) : (HASH_TABLE
*)0;
715 /* Now that we are ready to assign values to the array, kill the existing
717 if ((flags
& ASS_APPEND
) == 0)
719 if (a
&& array_p (var
))
721 else if (h
&& assoc_p (var
))
722 nhash
= assoc_create (h
->nbuckets
);
725 #if ASSOC_KVPAIR_ASSIGNMENT
726 if (assoc_p (var
) && kvpair_assignment_p (nlist
))
728 iflags
= flags
& ~ASS_APPEND
;
729 assign_assoc_from_kvlist (var
, nlist
, nhash
, iflags
);
730 if (nhash
&& nhash
!= h
)
732 h
= assoc_cell (var
);
733 var_setassoc (var
, nhash
);
736 return 1; /* XXX - check return value */
740 last_ind
= (a
&& (flags
& ASS_APPEND
)) ? array_max_index (a
) + 1 : 0;
742 for (list
= nlist
; list
; list
= list
->next
)
744 /* Don't allow var+=(values) to make assignments in VALUES append to
745 existing values by default. */
746 iflags
= flags
& ~ASS_APPEND
;
747 w
= list
->word
->word
;
749 /* We have a word of the form [ind]=value */
750 if ((list
->word
->flags
& W_ASSIGNMENT
) && w
[0] == '[')
752 /* Don't have to handle embedded quotes specially any more, since
753 associative array subscripts have not been expanded yet (see
755 len
= skipsubscript (w
, 0, 0);
757 /* XXX - changes for `+=' */
758 if (w
[len
] != ']' || (w
[len
+1] != '=' && (w
[len
+1] != '+' || w
[len
+2] != '=')))
760 if (assoc_p (var
) || last_ind
< 0)
766 nval
= make_variable_value (var
, w
, flags
);
767 if (var
->assign_func
)
768 (*var
->assign_func
) (var
, nval
, last_ind
, 0);
770 array_insert (a
, last_ind
, nval
);
783 if (ALL_ELEMENT_SUB (w
[1]) && len
== 2 && array_p (var
))
785 set_exit_status (EXECUTION_FAILURE
);
786 report_error (_("%s: cannot assign to non-numeric index"), w
);
795 /* convert ASS_ FLAGS to AV_ flags here */
796 avflags
= convert_assign_flags_to_arrayval_flags (flags
);
797 ind
= array_expand_index (var
, w
+ 1, len
, avflags
);
798 /* negative subscripts to indexed arrays count back from end */
800 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
810 else if (assoc_p (var
))
812 /* This is not performed above, see expand_compound_array_assignment */
814 akey
= expand_subscript_string (w
+1, 0);
816 /* And we need to expand the value also, see below */
817 if (akey
== 0 || *akey
== 0)
826 /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */
827 if (w
[len
+ 1] == '+' && w
[len
+ 2] == '=')
829 iflags
|= ASS_APPEND
;
835 else if (assoc_p (var
))
837 set_exit_status (EXECUTION_FAILURE
);
838 report_error (_("%s: %s: must use subscript when assigning associative array"), var
->name
, w
);
842 else /* No [ind]=value, just a stray `=' */
848 if (array_p (var
) && ind
< 0) /* overflow */
853 report_error ("%s[%s]: %s", var
->name
, num
, bash_badsub_errmsg
);
859 /* See above; we need to expand the value here */
862 val
= expand_assignment_string_to_string (val
, 0);
865 val
= (char *)xmalloc (1);
866 val
[0] = '\0'; /* like do_assignment_internal */
871 savecmd
= this_command_name
;
873 this_command_name
= 0; /* no command name for errors */
875 bind_assoc_var_internal (var
, nhash
, akey
, val
, iflags
);
877 bind_array_var_internal (var
, ind
, akey
, val
, iflags
);
879 this_command_name
= savecmd
;
885 if (assoc_p (var
) && nhash
&& nhash
!= h
)
887 h
= assoc_cell (var
);
888 var_setassoc (var
, nhash
);
893 if (var
&& exported_p (var
))
895 INVALIDATE_EXPORTSTR (var
);
896 array_needs_making
= 1;
900 return (any_failed
? 0 : 1);
903 /* Perform a compound array assignment: VAR->name=( VALUE ). The
904 VALUE has already had the parentheses stripped. FLAGS are ASS_
907 assign_array_var_from_string (SHELL_VAR
*var
, char *value
, int flags
)
915 nlist
= expand_compound_array_assignment (var
, value
, flags
);
916 /* This is were we set ASS_NOEXPAND and ASS_ONEWORD if we need to, since
917 expand_compound_array_assignment performs word expansions. Honors
918 array_expand_once; allows @ and * as associative array keys. */
919 aflags
= flags
| (array_expand_once
? ASS_NOEXPAND
: 0) | ASS_ALLOWALLSUB
;
920 r
= assign_compound_array_list (var
, nlist
, aflags
);
923 dispose_words (nlist
);
926 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
928 return (r
== 0 ? (SHELL_VAR
*)0 : var
);
931 /* Quote globbing chars and characters in $IFS before the `=' in an assignment
932 statement (usually a compound array assignment) to protect them from
933 unwanted filename expansion or word splitting. */
935 quote_assign (const char *string
)
939 char *temp
, *t
, *subs
;
940 const char *s
, *send
;
944 slen
= strlen (string
);
945 send
= string
+ slen
;
947 t
= temp
= (char *)xmalloc (slen
* 2 + 1);
949 for (s
= string
; *s
; )
953 if (saw_eq
== 0 && *s
== '[') /* looks like a subscript */
956 se
= skipsubscript (string
, ss
, 0);
957 subs
= substring (s
, ss
, se
);
967 if (saw_eq
== 0 && (glob_char_p (s
) || isifs (*s
)))
970 COPY_CHAR_P (t
, s
, send
);
976 /* Take a word W of the form [IND]=VALUE and transform it to ['IND']='VALUE'
977 to prevent further expansion. This is called for compound assignments to
978 indexed arrays. W has already undergone word expansions. If W has no [IND]=,
979 just single-quote and return it. */
981 quote_compound_array_word (char *w
, int type
)
983 char *nword
, *sub
, *value
, *t
;
987 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
988 ind
= skipsubscript (w
, 0, 0);
989 if (w
[ind
] != RBRACK
)
990 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
994 t
= (strchr (w
+1, CTLESC
)) ? quote_escapes (w
+1) : w
+1;
995 sub
= sh_single_quote (t
);
1000 nword
= xmalloc (wlen
* 4 + 5); /* wlen*4 is max single quoted length */
1003 memcpy (nword
+1, sub
, i
);
1005 i
++; /* accommodate the opening LBRACK */
1006 nword
[i
++] = w
[ind
++]; /* RBRACK */
1008 nword
[i
++] = w
[ind
++];
1009 nword
[i
++] = w
[ind
++];
1010 t
= (strchr (w
+ind
, CTLESC
)) ? quote_escapes (w
+ind
) : w
+ind
;
1011 value
= sh_single_quote (t
);
1014 strcpy (nword
+ i
, value
);
1020 /* Expand the key and value in W, which is of the form [KEY]=VALUE, and
1021 reconstruct W with the expanded and single-quoted version:
1022 ['expanded-key']='expanded-value'. If there is no [KEY]=, single-quote the
1023 word and return it. Very similar to previous function, but does not assume
1024 W has already been expanded, and expands the KEY and VALUE separately.
1025 Used for compound assignments to associative arrays that are arguments to
1026 declaration builtins (declare -A a=( list )). */
1028 expand_and_quote_assoc_word (char *w
, int type
)
1030 char *nword
, *key
, *value
, *s
, *t
;
1034 return (sh_single_quote (w
)); /* XXX - quote_escapes */
1035 ind
= skipsubscript (w
, 0, 0);
1036 if (w
[ind
] != RBRACK
)
1037 return (sh_single_quote (w
)); /* XXX - quote_escapes */
1040 t
= expand_subscript_string (w
+1, 0);
1041 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
1042 key
= sh_single_quote (s
? s
: "");
1048 wlen
= STRLEN (key
);
1049 nword
= xmalloc (wlen
+ 5);
1051 memcpy (nword
+1, key
, wlen
);
1052 i
= wlen
+ 1; /* accommodate the opening LBRACK */
1054 nword
[i
++] = w
[ind
++]; /* RBRACK */
1056 nword
[i
++] = w
[ind
++];
1057 nword
[i
++] = w
[ind
++];
1059 t
= expand_assignment_string_to_string (w
+ind
, 0);
1060 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
1061 value
= sh_single_quote (s
? s
: "");
1065 nword
= xrealloc (nword
, wlen
+ 5 + STRLEN (value
));
1066 strcpy (nword
+ i
, value
);
1074 /* For each word in a compound array assignment, if the word looks like
1075 [ind]=value, single-quote ind and value, but leave the brackets and
1076 the = sign (and any `+') alone. If it's not an assignment, just single-
1077 quote the word. This is used for indexed arrays. */
1079 quote_compound_array_list (WORD_LIST
*list
, int type
)
1084 for (l
= list
; l
; l
= l
->next
)
1086 if (l
->word
== 0 || l
->word
->word
== 0)
1087 continue; /* should not happen, but just in case... */
1088 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1090 s
= (strchr (l
->word
->word
, CTLESC
)) ? quote_escapes (l
->word
->word
) : l
->word
->word
;
1091 t
= sh_single_quote (s
);
1092 if (s
!= l
->word
->word
)
1096 t
= quote_compound_array_word (l
->word
->word
, type
);
1097 free (l
->word
->word
);
1102 /* For each word in a compound array assignment, if the word looks like
1103 [ind]=value, quote globbing chars and characters in $IFS before the `='. */
1105 quote_array_assignment_chars (WORD_LIST
*list
)
1110 for (l
= list
; l
; l
= l
->next
)
1112 if (l
->word
== 0 || l
->word
->word
== 0 || l
->word
->word
[0] == '\0')
1113 continue; /* should not happen, but just in case... */
1114 /* Don't bother if it hasn't been recognized as an assignment or
1115 doesn't look like [ind]=value */
1116 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1118 if (l
->word
->word
[0] != '[' || mbschr (l
->word
->word
, '=') == 0) /* ] */
1121 nword
= quote_assign (l
->word
->word
);
1122 free (l
->word
->word
);
1123 l
->word
->word
= nword
;
1124 l
->word
->flags
|= W_NOGLOB
; /* XXX - W_NOSPLIT also? */
1128 /* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
1130 /* This function is called with SUB pointing to just after the beginning
1131 `[' of an array subscript and removes the array element to which SUB
1132 expands from array VAR. A subscript of `*' or `@' unsets the array. */
1133 /* If FLAGS&1 (VA_NOEXPAND) we don't expand the subscript; we just use it
1134 as-is. If FLAGS&VA_ONEWORD, we don't try to use skipsubscript to parse
1135 the subscript, we just assume the subscript ends with a close bracket,
1136 if one is present, and use what's inside the brackets. */
1138 unbind_array_element (SHELL_VAR
*var
, char *sub
, int flags
)
1145 /* Assume that the caller (unset_builtin) passes us a null-terminated SUB,
1146 so we don't have to use VA_ONEWORD or parse the subscript again with
1149 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1151 if (array_p (var
) || assoc_p (var
))
1153 if (flags
& VA_ALLOWALL
)
1155 unbind_variable (var
->name
); /* XXX -- {array,assoc}_flush ? */
1158 /* otherwise we fall through and try to unset element `@' or `*' */
1161 return -2; /* don't allow this to unset scalar variables */
1166 akey
= (flags
& VA_NOEXPAND
) ? sub
: expand_subscript_string (sub
, 0);
1167 if (akey
== 0 || *akey
== 0)
1169 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1173 assoc_remove (assoc_cell (var
), akey
);
1177 else if (array_p (var
))
1179 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1181 /* We can go several ways here:
1182 1) remove the array (backwards compatible)
1183 2) empty the array (new behavior)
1184 3) do nothing; treat the `@' or `*' as an expression and throw
1188 if (shell_compatibility_level
<= 51)
1190 unbind_variable (name_cell (var
));
1193 else /* Behavior 2 */
1195 array_flush (array_cell (var
));
1198 /* Fall through for behavior 3 */
1201 avflags
= convert_validarray_flags_to_arrayval_flags (flags
);
1202 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, avflags
);
1203 /* negative subscripts to indexed arrays count back from end */
1205 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1208 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1211 ae
= array_remove (array_cell (var
), ind
);
1213 array_dispose_element (ae
);
1215 else /* array_p (var) == 0 && assoc_p (var) == 0 */
1217 akey
= this_command_name
;
1218 avflags
= convert_validarray_flags_to_arrayval_flags (flags
);
1219 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, avflags
);
1220 this_command_name
= akey
;
1223 unbind_variable (var
->name
);
1227 return -2; /* any subscript other than 0 is invalid with scalar variables */
1233 /* Format and output an array assignment in compound form VAR=(VALUES),
1234 suitable for re-use as input. */
1236 print_array_assignment (SHELL_VAR
*var
, int quoted
)
1240 vstr
= array_to_assign (array_cell (var
), quoted
);
1243 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1246 printf ("%s=%s\n", var
->name
, vstr
);
1251 /* Format and output an associative array assignment in compound form
1252 VAR=(VALUES), suitable for re-use as input. */
1254 print_assoc_assignment (SHELL_VAR
*var
, int quoted
)
1258 vstr
= assoc_to_assign (assoc_cell (var
), quoted
);
1261 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1264 printf ("%s=%s\n", var
->name
, vstr
);
1269 /***********************************************************************/
1271 /* Utility functions to manage arrays and their contents for expansion */
1273 /***********************************************************************/
1275 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1277 /* When NAME is a properly-formed array reference and a non-null argument SUBP
1278 is supplied, '[' and ']' that enclose the subscript are replaced by '\0',
1279 and the pointer to the subscript in NAME is assigned to *SUBP, so that NAME
1280 and SUBP can be later used as the array name and the subscript,
1281 respectively. When SUBP is the null pointer, the original string NAME will
1283 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1285 tokenize_array_reference (const char *name
, int flags
, char **subp
)
1288 int r
, len
, isassoc
, ssflags
;
1291 t
= mbschr (name
, '['); /* ] */
1296 r
= valid_identifier (name
);
1297 if (flags
& VA_NOEXPAND
) /* Don't waste a lookup if we don't need one */
1298 isassoc
= (entry
= find_variable (name
)) && assoc_p (entry
);
1304 if (isassoc
&& ((flags
& (VA_NOEXPAND
|VA_ONEWORD
)) == (VA_NOEXPAND
|VA_ONEWORD
)))
1305 len
= strlen (t
) - 1;
1308 if (flags
& VA_NOEXPAND
)
1310 len
= skipsubscript (t
, 0, ssflags
);
1313 /* Check for a properly-terminated non-null subscript. */
1314 len
= skipsubscript (t
, 0, 0); /* arithmetic expression */
1316 if (t
[len
] != ']' || len
== 1 || t
[len
+1] != '\0')
1320 /* Could check and allow subscripts consisting only of whitespace for
1321 existing associative arrays, using isassoc */
1322 for (r
= 1; r
< len
; r
++)
1323 if (whitespace (t
[r
]) == 0)
1326 return 0; /* Fail if the subscript contains only whitespaces. */
1331 t
[0] = t
[len
] = '\0';
1335 /* This allows blank subscripts */
1341 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1343 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1345 valid_array_reference (const char *name
, int flags
)
1347 return tokenize_array_reference (name
, flags
, (char **)NULL
);
1350 /* Expand the array index beginning at S and extending LEN characters. FLAGS
1351 are AV_ flags saying how to compute the array value. */
1353 array_expand_index (SHELL_VAR
*var
, const char *s
, int len
, int flags
)
1355 char *exp
, *t
, *savecmd
;
1359 exp
= (char *)xmalloc (len
);
1360 strncpy (exp
, s
, len
- 1);
1361 exp
[len
- 1] = '\0';
1362 #if 1 /* TAG: bash-5.3 */
1364 if (shell_compatibility_level
<= 52 || (flags
& AV_NOEXPAND
) == 0)
1366 if ((flags
& AV_NOEXPAND
) == 0)
1368 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1372 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1374 savecmd
= this_command_name
;
1375 this_command_name
= (char *)NULL
;
1376 eflag
= (shell_compatibility_level
> 51) ? 0 : EXP_EXPANDED
;
1377 val
= evalexp (t
, eflag
, &expok
); /* XXX - was 0 but we expanded exp already */
1378 this_command_name
= savecmd
;
1384 set_exit_status (EXECUTION_FAILURE
);
1386 if (no_longjmp_on_fatal_error
)
1388 top_level_cleanup ();
1389 jump_to_top_level (DISCARD
);
1394 /* Return the name of the variable specified by S without any subscript.
1395 If SUBP is non-null, return a pointer to the start of the subscript
1396 in *SUBP. If LENP is non-null, the length of the subscript is returned
1397 in *LENP. This returns newly-allocated memory. */
1399 array_variable_name (const char *s
, int flags
, char **subp
, int *lenp
)
1402 int ind
, ni
, ssflags
;
1404 t
= mbschr (s
, '[');
1411 return ((char *)NULL
);
1414 if ((flags
& (AV_NOEXPAND
|AV_ONEWORD
)) == (AV_NOEXPAND
|AV_ONEWORD
))
1415 ni
= strlen (s
) - 1;
1419 if (flags
& AV_NOEXPAND
)
1421 ni
= skipsubscript (s
, ind
, ssflags
);
1423 if (ni
<= ind
+ 1 || s
[ni
] != ']')
1425 err_badarraysub (s
);
1430 return ((char *)NULL
);
1434 ret
= savestring (s
);
1445 /* Return the variable specified by S without any subscript. If SUBP is
1446 non-null, return a pointer to the start of the subscript in *SUBP.
1447 If LENP is non-null, the length of the subscript is returned in *LENP. */
1449 array_variable_part (const char *s
, int flags
, char **subp
, int *lenp
)
1454 t
= array_variable_name (s
, flags
, subp
, lenp
);
1456 return ((SHELL_VAR
*)NULL
);
1457 var
= find_variable (t
); /* XXX - handle namerefs here? */
1460 return var
; /* now return invisible variables; caller must handle */
1463 #define INDEX_ERROR() \
1467 err_badarraysub (var->name); \
1471 err_badarraysub (s); \
1472 t[-1] = '['; /* ] */\
1474 return ((char *)NULL); \
1478 /* Return a string containing the elements in the array and subscript
1479 described by S. If the subscript is * or @, obeys quoting rules akin
1480 to the expansion of $* and $@ including double quoting. If RTYPE
1481 is non-null it gets 1 if the array reference is name[*], 2 if the
1482 reference is name[@], and 0 otherwise. */
1484 array_value_internal (const char *s
, int quoted
, int flags
, array_eltstate_t
*estatep
)
1486 int len
, isassoc
, subtype
;
1489 char *retval
, *t
, *temp
;
1493 var
= array_variable_part (s
, flags
, &t
, &len
); /* XXX */
1495 /* Expand the index, even if the variable doesn't exist, in case side
1496 effects are needed, like ${w[i++]} where w is unset. */
1499 return (char *)NULL
;
1503 return ((char *)NULL
); /* error message already printed */
1505 isassoc
= var
&& assoc_p (var
);
1510 estatep
->value
= (char *)NULL
;
1512 /* Backwards compatibility: we only change the behavior of A[@] and A[*]
1513 for associative arrays, and the caller has to request it. */
1514 if ((isassoc
== 0 || (flags
& AV_ATSTARKEYS
) == 0) && ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
1517 estatep
->subtype
= (t
[0] == '*') ? 1 : 2;
1518 if ((flags
& AV_ALLOWALL
) == 0)
1520 err_badarraysub (s
);
1521 return ((char *)NULL
);
1523 else if (var
== 0 || value_cell (var
) == 0)
1524 return ((char *)NULL
);
1525 else if (invisible_p (var
))
1526 return ((char *)NULL
);
1527 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
1530 estatep
->type
= ARRAY_SCALAR
;
1531 l
= add_string_to_list (value_cell (var
), (WORD_LIST
*)NULL
);
1533 else if (assoc_p (var
))
1536 estatep
->type
= ARRAY_ASSOC
;
1537 l
= assoc_to_word_list (assoc_cell (var
));
1538 if (l
== (WORD_LIST
*)NULL
)
1539 return ((char *)NULL
);
1544 estatep
->type
= ARRAY_INDEXED
;
1545 l
= array_to_word_list (array_cell (var
));
1546 if (l
== (WORD_LIST
*)NULL
)
1547 return ((char *) NULL
);
1550 /* Caller of array_value takes care of inspecting estatep->subtype and
1551 duplicating retval if subtype == 0, so this is not a memory leak */
1552 if (t
[0] == '*' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1554 temp
= string_list_dollar_star (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1555 retval
= quote_string (temp
);
1558 else /* ${name[@]} or unquoted ${name[*]} */
1559 retval
= string_list_dollar_at (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1566 estatep
->subtype
= 0;
1567 if (var
== 0 || array_p (var
) || assoc_p (var
) == 0)
1569 if ((flags
& AV_USEIND
) == 0 || estatep
== 0)
1571 ind
= array_expand_index (var
, t
, len
, flags
);
1574 /* negative subscripts to indexed arrays count back from end */
1575 if (var
&& array_p (var
))
1576 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1583 else if (estatep
&& (flags
& AV_USEIND
))
1586 estatep
->type
= array_p (var
) ? ARRAY_INDEXED
: ARRAY_SCALAR
;
1588 else if (assoc_p (var
))
1592 estatep
->type
= ARRAY_ASSOC
;
1593 if ((flags
& AV_USEIND
) && estatep
&& estatep
->key
)
1594 akey
= savestring (estatep
->key
);
1595 else if ((flags
& AV_NOEXPAND
) == 0)
1596 akey
= expand_subscript_string (t
, 0); /* [ */
1598 akey
= savestring (t
);
1600 if (akey
== 0 || *akey
== 0)
1607 if (var
== 0 || value_cell (var
) == 0)
1610 return ((char *)NULL
);
1612 else if (invisible_p (var
))
1615 return ((char *)NULL
);
1617 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1618 retval
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
1619 else if (assoc_p (var
))
1621 retval
= assoc_reference (assoc_cell (var
), akey
);
1622 if (estatep
&& estatep
->key
&& (flags
& AV_USEIND
))
1623 free (akey
); /* duplicated estatep->key */
1625 estatep
->key
= akey
; /* XXX - caller must manage */
1626 else /* not saving it anywhere */
1630 retval
= array_reference (array_cell (var
), ind
);
1633 estatep
->value
= retval
;
1639 /* Return a string containing the elements described by the array and
1640 subscript contained in S, obeying quoting for subscripts * and @. */
1642 array_value (const char *s
, int quoted
, int flags
, array_eltstate_t
*estatep
)
1646 retval
= array_value_internal (s
, quoted
, flags
|AV_ALLOWALL
, estatep
);
1650 /* Return the value of the array indexing expression S as a single string.
1651 If (FLAGS & AV_ALLOWALL) is 0, do not allow `@' and `*' subscripts. This
1652 is used by other parts of the shell such as the arithmetic expression
1653 evaluator in expr.c. */
1655 get_array_value (const char *s
, int flags
, array_eltstate_t
*estatep
)
1659 retval
= array_value_internal (s
, 0, flags
, estatep
);
1664 array_keys (const char *s
, int quoted
, int pflags
)
1667 char *retval
, *t
, *temp
;
1671 var
= array_variable_part (s
, 0, &t
, &len
);
1674 if (var
== 0 || ALL_ELEMENT_SUB (t
[0]) == 0 || t
[1] != ']')
1675 return (char *)NULL
;
1677 if (var_isset (var
) == 0 || invisible_p (var
))
1678 return (char *)NULL
;
1680 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1681 l
= add_string_to_list ("0", (WORD_LIST
*)NULL
);
1682 else if (assoc_p (var
))
1683 l
= assoc_keys_to_word_list (assoc_cell (var
));
1685 l
= array_keys_to_word_list (array_cell (var
));
1686 if (l
== (WORD_LIST
*)NULL
)
1687 return ((char *) NULL
);
1689 retval
= string_list_pos_params (t
[0], l
, quoted
, pflags
);
1694 #endif /* ARRAY_VARS */