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 array subscripts more than
49 once, when performing variable expansion. */
50 int assoc_expand_once
= 0;
52 /* Ditto for indexed array subscripts -- currently unused */
53 int array_expand_once
= 0;
55 static SHELL_VAR
*bind_array_var_internal (SHELL_VAR
*, arrayind_t
, char *, const char *, int);
56 static SHELL_VAR
*assign_array_element_internal (SHELL_VAR
*, const char *, char *, char *, int, const char *, int, array_eltstate_t
*);
58 static void assign_assoc_from_kvlist (SHELL_VAR
*, WORD_LIST
*, HASH_TABLE
*, int);
60 static char *quote_assign (const char *);
61 static void quote_array_assignment_chars (WORD_LIST
*);
62 static char *quote_compound_array_word (char *, int);
63 static char *array_value_internal (const char *, int, int, array_eltstate_t
*);
65 /* Standard error message to use when encountering an invalid array subscript */
66 const char * const bash_badsub_errmsg
= N_("bad array subscript");
68 /* **************************************************************** */
70 /* Functions to manipulate array variables and perform assignments */
72 /* **************************************************************** */
74 /* Convert a shell variable to an array variable. The original value is
77 convert_var_to_array (SHELL_VAR
*var
)
82 oldval
= value_cell (var
);
83 array
= array_create ();
85 array_insert (array
, 0, oldval
);
87 FREE (value_cell (var
));
88 var_setarray (var
, array
);
90 /* these aren't valid anymore */
91 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
92 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
94 INVALIDATE_EXPORTSTR (var
);
98 VSETATTR (var
, att_array
);
100 VUNSETATTR (var
, att_invisible
);
102 /* Make sure it's not marked as an associative array any more */
103 VUNSETATTR (var
, att_assoc
);
105 /* Since namerefs can't be array variables, turn off nameref attribute */
106 VUNSETATTR (var
, att_nameref
);
111 /* Convert a shell variable to an array variable. The original value is
112 saved as array[0]. */
114 convert_var_to_assoc (SHELL_VAR
*var
)
119 oldval
= value_cell (var
);
120 hash
= assoc_create (0);
122 assoc_insert (hash
, savestring ("0"), oldval
);
124 FREE (value_cell (var
));
125 var_setassoc (var
, hash
);
127 /* these aren't valid anymore */
128 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
129 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
131 INVALIDATE_EXPORTSTR (var
);
132 if (exported_p (var
))
133 array_needs_making
++;
135 VSETATTR (var
, att_assoc
);
137 VUNSETATTR (var
, att_invisible
);
139 /* Make sure it's not marked as an indexed array any more */
140 VUNSETATTR (var
, att_array
);
142 /* Since namerefs can't be array variables, turn off nameref attribute */
143 VUNSETATTR (var
, att_nameref
);
149 make_array_variable_value (SHELL_VAR
*entry
, arrayind_t ind
, const char *key
, const char *value
, int flags
)
154 /* If we're appending, we need the old value of the array reference, so
155 fake out make_variable_value with a dummy SHELL_VAR */
156 if (flags
& ASS_APPEND
)
158 dentry
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
159 dentry
->name
= savestring (entry
->name
);
161 newval
= assoc_reference (assoc_cell (entry
), key
);
163 newval
= array_reference (array_cell (entry
), ind
);
165 dentry
->value
= savestring (newval
);
168 dentry
->value
= (char *)xmalloc (1);
169 dentry
->value
[0] = '\0';
171 dentry
->exportstr
= 0;
172 dentry
->attributes
= entry
->attributes
& ~(att_array
|att_assoc
|att_exported
);
173 /* Leave the rest of the members uninitialized; the code doesn't look
175 newval
= make_variable_value (dentry
, value
, flags
);
176 dispose_variable (dentry
);
179 newval
= make_variable_value (entry
, value
, flags
);
184 /* Assign HASH[KEY]=VALUE according to FLAGS. ENTRY is an associative array
185 variable; HASH is the hash table to assign into. HASH may or may not be
186 the hash table associated with ENTRY; if it's not, the caller takes care
188 XXX - make sure that any dynamic associative array variables recreate the
189 hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */
191 bind_assoc_var_internal (SHELL_VAR
*entry
, HASH_TABLE
*hash
, char *key
, const char *value
, int flags
)
195 /* Use the existing array contents to expand the value */
196 newval
= make_array_variable_value (entry
, 0, key
, value
, flags
);
198 if (entry
->assign_func
)
199 (*entry
->assign_func
) (entry
, newval
, 0, key
);
201 assoc_insert (hash
, key
, newval
);
205 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
207 /* check mark_modified_variables if we ever want to export array vars */
211 /* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every
212 assignment to an associative array; see assign_compound_array_list below. */
214 bind_array_var_internal (SHELL_VAR
*entry
, arrayind_t ind
, char *key
, const char *value
, int flags
)
218 newval
= make_array_variable_value (entry
, ind
, key
, value
, flags
);
220 if (entry
->assign_func
)
221 (*entry
->assign_func
) (entry
, newval
, ind
, key
);
222 else if (assoc_p (entry
))
223 assoc_insert (assoc_cell (entry
), key
, newval
);
225 array_insert (array_cell (entry
), ind
, newval
);
228 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
230 /* check mark_modified_variables if we ever want to export array vars */
234 /* Perform an array assignment name[ind]=value. If NAME already exists and
235 is not an array, and IND is 0, perform name=value instead. If NAME exists
236 and is not an array, and IND is not 0, convert it into an array with the
237 existing value as name[0].
239 If NAME does not exist, just create an array variable, no matter what
240 IND's value may be. */
242 bind_array_variable (const char *name
, arrayind_t ind
, const char *value
, int flags
)
246 entry
= find_shell_variable (name
);
248 if (entry
== (SHELL_VAR
*) 0)
250 /* Is NAME a nameref variable that points to an unset variable? */
251 entry
= find_variable_nameref_for_create (name
, 0);
252 if (entry
== INVALID_NAMEREF_VALUE
)
253 return ((SHELL_VAR
*)0);
254 if (entry
&& nameref_p (entry
))
255 entry
= make_new_array_variable (nameref_cell (entry
));
257 if (entry
== (SHELL_VAR
*) 0)
258 entry
= make_new_array_variable (name
);
259 else if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
261 if (readonly_p (entry
))
265 else if (array_p (entry
) == 0)
266 entry
= convert_var_to_array (entry
);
268 /* ENTRY is an array variable, and ARRAY points to the value. */
269 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
273 bind_array_element (SHELL_VAR
*entry
, arrayind_t ind
, char *value
, int flags
)
275 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
279 bind_assoc_variable (SHELL_VAR
*entry
, const char *name
, char *key
, const char *value
, int flags
)
281 if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
283 if (readonly_p (entry
))
288 return (bind_assoc_var_internal (entry
, assoc_cell (entry
), key
, value
, flags
));
292 init_eltstate (array_eltstate_t
*estatep
)
296 estatep
->type
= ARRAY_INVALID
;
297 estatep
->subtype
= 0;
298 estatep
->key
= estatep
->value
= 0;
299 estatep
->ind
= INTMAX_MIN
;
304 flush_eltstate (array_eltstate_t
*estatep
)
310 /* Parse NAME, a lhs of an assignment statement of the form v[s], and
311 assign VALUE to that array element by calling bind_array_variable().
312 Flags are ASS_ assignment flags */
314 assign_array_element (const char *name
, const char *value
, int flags
, array_eltstate_t
*estatep
)
317 int sublen
, isassoc
, avflags
;
321 if (flags
& ASS_NOEXPAND
)
322 avflags
|= AV_NOEXPAND
;
323 if (flags
& ASS_ONEWORD
)
324 avflags
|= AV_ONEWORD
;
325 vname
= array_variable_name (name
, avflags
, &sub
, &sublen
);
328 return ((SHELL_VAR
*)NULL
);
330 entry
= find_variable (vname
);
331 isassoc
= entry
&& assoc_p (entry
);
333 /* We don't allow assignment to `*' or `@' associative array keys if the
334 caller hasn't told us the subscript has already been expanded
335 (ASS_NOEXPAND). If the caller has explicitly told us it's ok
336 (ASS_ALLOWALLSUB) we allow it. */
337 if (((isassoc
== 0 || (flags
& (ASS_NOEXPAND
|ASS_ALLOWALLSUB
)) == 0) &&
338 (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == ']')) ||
340 (sub
[sublen
] != '\0')) /* sanity check */
343 err_badarraysub (name
);
344 return ((SHELL_VAR
*)NULL
);
347 entry
= assign_array_element_internal (entry
, name
, vname
, sub
, sublen
, value
, flags
, estatep
);
350 if (entry
&& exported_p (entry
))
352 INVALIDATE_EXPORTSTR (entry
);
353 array_needs_making
= 1;
362 assign_array_element_internal (SHELL_VAR
*entry
, const char *name
, char *vname
,
363 char *sub
, int sublen
, const char *value
,
364 int flags
, array_eltstate_t
*estatep
)
370 /* rely on the caller to initialize estatep */
372 if (entry
&& assoc_p (entry
))
374 sub
[sublen
-1] = '\0';
375 if ((flags
& ASS_NOEXPAND
) == 0)
376 akey
= expand_subscript_string (sub
, 0); /* [ */
378 akey
= savestring (sub
);
380 if (akey
== 0 || *akey
== 0)
382 err_badarraysub (name
);
384 return ((SHELL_VAR
*)NULL
);
387 nkey
= savestring (akey
); /* assoc_insert/assoc_replace frees akey */
388 entry
= bind_assoc_variable (entry
, vname
, akey
, value
, flags
);
391 estatep
->type
= ARRAY_ASSOC
;
393 estatep
->value
= entry
? assoc_reference (assoc_cell (entry
), nkey
) : 0;
398 ind
= array_expand_index (entry
, sub
, sublen
, 0);
399 /* negative subscripts to indexed arrays count back from end */
400 if (entry
&& ind
< 0)
401 ind
= (array_p (entry
) ? array_max_index (array_cell (entry
)) : 0) + 1 + ind
;
404 err_badarraysub (name
);
405 return ((SHELL_VAR
*)NULL
);
407 entry
= bind_array_variable (vname
, ind
, value
, flags
);
410 estatep
->type
= ARRAY_INDEXED
;
412 estatep
->value
= entry
? array_reference (array_cell (entry
), ind
) : 0;
419 /* Find the array variable corresponding to NAME. If there is no variable,
420 create a new array variable. If the variable exists but is not an array,
421 convert it to an indexed array. If FLAGS&1 is non-zero, an existing
422 variable is checked for the readonly or noassign attribute in preparation
423 for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we
424 create an associative array. */
426 find_or_make_array_variable (const char *name
, int flags
)
430 var
= find_variable (name
);
433 /* See if we have a nameref pointing to a variable that hasn't been
435 var
= find_variable_last_nameref (name
, 1);
436 if (var
&& nameref_p (var
) && invisible_p (var
))
438 internal_warning (_("%s: removing nameref attribute"), name
);
439 VUNSETATTR (var
, att_nameref
);
441 if (var
&& nameref_p (var
))
443 if (valid_nameref_value (nameref_cell (var
), 2) == 0)
445 sh_invalidid (nameref_cell (var
));
446 return ((SHELL_VAR
*)NULL
);
448 var
= (flags
& 2) ? make_new_assoc_variable (nameref_cell (var
)) : make_new_array_variable (nameref_cell (var
));
453 var
= (flags
& 2) ? make_new_assoc_variable (name
) : make_new_array_variable (name
);
454 else if ((flags
& 1) && (readonly_p (var
) || noassign_p (var
)))
456 if (readonly_p (var
))
458 return ((SHELL_VAR
*)NULL
);
460 else if ((flags
& 2) && array_p (var
))
462 set_exit_status (EXECUTION_FAILURE
);
463 report_error (_("%s: cannot convert indexed to associative array"), name
);
464 return ((SHELL_VAR
*)NULL
);
467 var
= assoc_p (var
) ? var
: convert_var_to_assoc (var
);
468 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
469 var
= convert_var_to_array (var
);
474 /* Perform a compound assignment statement for array NAME, where VALUE is
475 the text between the parens: NAME=( VALUE ) */
477 assign_array_from_string (const char *name
, char *value
, int flags
)
483 if (flags
& ASS_MKASSOC
)
486 var
= find_or_make_array_variable (name
, vflags
);
488 return ((SHELL_VAR
*)NULL
);
490 return (assign_array_var_from_string (var
, value
, flags
));
493 /* Sequentially assign the indices of indexed array variable VAR from the
496 assign_array_var_from_word_list (SHELL_VAR
*var
, WORD_LIST
*list
, int flags
)
498 register arrayind_t i
;
499 register WORD_LIST
*l
;
502 a
= array_cell (var
);
503 i
= (flags
& ASS_APPEND
) ? array_max_index (a
) + 1 : 0;
505 for (l
= list
; l
; l
= l
->next
, i
++)
506 bind_array_var_internal (var
, i
, 0, l
->word
->word
, flags
& ~ASS_APPEND
);
508 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
514 expand_compound_array_assignment (SHELL_VAR
*var
, char *value
, int flags
)
516 WORD_LIST
*list
, *nlist
;
520 /* This condition is true when invoked from the declare builtin with a
522 declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")' */
523 if (*value
== '(') /*)*/
526 val
= extract_array_assignment_list (value
, &ni
);
528 return (WORD_LIST
*)NULL
;
533 /* Expand the value string into a list of words, performing all the
534 shell expansions including pathname generation and word splitting. */
535 /* First we split the string on whitespace, using the shell parser
536 (ksh93 seems to do this). */
537 /* XXX - this needs a rethink, maybe use split_at_delims */
538 list
= parse_string_to_word_list (val
, 1, "array assign");
540 /* If the parser has quoted CTLESC and CTNLNUL with CTLESC in unquoted
541 words, we need to remove those here because the code below assumes
542 they are there because they exist in the original word. */
543 /* XXX - if we rethink parse_string_to_word_list above, change this. */
544 for (nlist
= list
; nlist
; nlist
= nlist
->next
)
545 if ((nlist
->word
->flags
& W_QUOTED
) == 0)
546 remove_quoted_escapes (nlist
->word
->word
);
548 /* Note that we defer expansion of the assignment statements for associative
549 arrays here, so we don't have to scan the subscript and find the ending
550 bracket twice. See the caller below. */
551 if (var
&& assoc_p (var
))
558 /* If we're using [subscript]=value, we need to quote each [ and ] to
559 prevent unwanted filename expansion. This doesn't need to be done
560 for associative array expansion, since that uses a different expansion
561 function (see assign_compound_array_list below). */
563 quote_array_assignment_chars (list
);
565 /* Now that we've split it, perform the shell expansions on each
567 nlist
= list
? expand_words_no_vars (list
) : (WORD_LIST
*)NULL
;
569 dispose_words (list
);
577 #if ASSOC_KVPAIR_ASSIGNMENT
578 /* If non-zero, we split the words in kv-pair compound array assignments in
579 addition to performing the other expansions. */
580 int split_kvpair_assignments
= 0;
582 /* We have a set of key-value pairs that should be expanded and split
583 (because they are not assignment statements). They are not expanded
584 and split in expand_compound_array_assignment because assoc_p (var)
585 is true. We defer the expansion until now. */
587 assign_assoc_from_kvlist (SHELL_VAR
*var
, WORD_LIST
*nlist
, HASH_TABLE
*h
, int flags
)
589 WORD_LIST
*list
, *explist
;
590 char *akey
, *aval
, *k
, *v
;
592 explist
= split_kvpair_assignments
? expand_words_no_vars (nlist
) : nlist
;
593 for (list
= explist
; list
; list
= list
->next
)
595 k
= list
->word
->word
;
596 v
= list
->next
? list
->next
->word
->word
: 0;
601 akey
= split_kvpair_assignments
? savestring (k
) : expand_subscript_string (k
, 0);
602 if (akey
== 0 || *akey
== 0)
609 aval
= split_kvpair_assignments
? savestring (v
) : expand_assignment_string_to_string (v
, 0);
612 aval
= (char *)xmalloc (1);
613 aval
[0] = '\0'; /* like do_assignment_internal */
616 bind_assoc_var_internal (var
, h
, akey
, aval
, flags
);
621 if (explist
!= nlist
)
622 dispose_words (explist
);
625 /* Return non-zero if L appears to be a key-value pair associative array
626 compound assignment. */
628 kvpair_assignment_p (WORD_LIST
*l
)
630 return (l
&& (l
->word
->flags
& W_ASSIGNMENT
) == 0 && l
->word
->word
[0] != '['); /*]*/
634 expand_and_quote_kvpair_word (const char *w
)
638 t
= w
? expand_subscript_string (w
, 0) : 0;
639 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
640 r
= sh_single_quote (s
? s
: "");
648 /* Callers ensure that VAR is not NULL. Associative array assignments have not
649 been expanded when this is called, or have been expanded once and single-
650 quoted, so we don't have to scan through an unquoted expanded subscript to
651 find the ending bracket; indexed array assignments have been expanded and
652 possibly single-quoted to prevent further expansion.
654 If this is an associative array, we perform the assignments into NHASH and
655 set NHASH to be the value of VAR after processing the assignments in NLIST */
657 assign_compound_array_list (SHELL_VAR
*var
, WORD_LIST
*nlist
, int flags
)
660 HASH_TABLE
*h
, *nhash
;
662 char *w
, *val
, *nval
, *savecmd
;
663 int len
, iflags
, free_val
;
664 arrayind_t ind
, last_ind
;
667 a
= (var
&& array_p (var
)) ? array_cell (var
) : (ARRAY
*)0;
668 nhash
= h
= (var
&& assoc_p (var
)) ? assoc_cell (var
) : (HASH_TABLE
*)0;
673 /* Now that we are ready to assign values to the array, kill the existing
675 if ((flags
& ASS_APPEND
) == 0)
677 if (a
&& array_p (var
))
679 else if (h
&& assoc_p (var
))
680 nhash
= assoc_create (h
->nbuckets
);
683 last_ind
= (a
&& (flags
& ASS_APPEND
)) ? array_max_index (a
) + 1 : 0;
685 #if ASSOC_KVPAIR_ASSIGNMENT
686 if (assoc_p (var
) && kvpair_assignment_p (nlist
))
688 iflags
= flags
& ~ASS_APPEND
;
689 assign_assoc_from_kvlist (var
, nlist
, nhash
, iflags
);
690 if (nhash
&& nhash
!= h
)
692 h
= assoc_cell (var
);
693 var_setassoc (var
, nhash
);
700 for (list
= nlist
; list
; list
= list
->next
)
702 /* Don't allow var+=(values) to make assignments in VALUES append to
703 existing values by default. */
704 iflags
= flags
& ~ASS_APPEND
;
705 w
= list
->word
->word
;
707 /* We have a word of the form [ind]=value */
708 if ((list
->word
->flags
& W_ASSIGNMENT
) && w
[0] == '[')
710 /* Don't have to handle embedded quotes specially any more, since
711 associative array subscripts have not been expanded yet (see
713 len
= skipsubscript (w
, 0, 0);
715 /* XXX - changes for `+=' */
716 if (w
[len
] != ']' || (w
[len
+1] != '=' && (w
[len
+1] != '+' || w
[len
+2] != '=')))
723 nval
= make_variable_value (var
, w
, flags
);
724 if (var
->assign_func
)
725 (*var
->assign_func
) (var
, nval
, last_ind
, 0);
727 array_insert (a
, last_ind
, nval
);
739 if (ALL_ELEMENT_SUB (w
[1]) && len
== 2 && array_p (var
))
741 set_exit_status (EXECUTION_FAILURE
);
742 report_error (_("%s: cannot assign to non-numeric index"), w
);
748 ind
= array_expand_index (var
, w
+ 1, len
, 0);
749 /* negative subscripts to indexed arrays count back from end */
751 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
760 else if (assoc_p (var
))
762 /* This is not performed above, see expand_compound_array_assignment */
764 akey
= expand_subscript_string (w
+1, 0);
766 /* And we need to expand the value also, see below */
767 if (akey
== 0 || *akey
== 0)
775 /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */
776 if (w
[len
+ 1] == '+' && w
[len
+ 2] == '=')
778 iflags
|= ASS_APPEND
;
784 else if (assoc_p (var
))
786 set_exit_status (EXECUTION_FAILURE
);
787 report_error (_("%s: %s: must use subscript when assigning associative array"), var
->name
, w
);
790 else /* No [ind]=value, just a stray `=' */
797 /* See above; we need to expand the value here */
800 val
= expand_assignment_string_to_string (val
, 0);
803 val
= (char *)xmalloc (1);
804 val
[0] = '\0'; /* like do_assignment_internal */
809 savecmd
= this_command_name
;
811 this_command_name
= 0; /* no command name for errors */
813 bind_assoc_var_internal (var
, nhash
, akey
, val
, iflags
);
815 bind_array_var_internal (var
, ind
, akey
, val
, iflags
);
817 this_command_name
= savecmd
;
823 if (assoc_p (var
) && nhash
&& nhash
!= h
)
825 h
= assoc_cell (var
);
826 var_setassoc (var
, nhash
);
831 /* Perform a compound array assignment: VAR->name=( VALUE ). The
832 VALUE has already had the parentheses stripped. */
834 assign_array_var_from_string (SHELL_VAR
*var
, char *value
, int flags
)
841 nlist
= expand_compound_array_assignment (var
, value
, flags
);
842 assign_compound_array_list (var
, nlist
, flags
);
845 dispose_words (nlist
);
848 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
853 /* Quote globbing chars and characters in $IFS before the `=' in an assignment
854 statement (usually a compound array assignment) to protect them from
855 unwanted filename expansion or word splitting. */
857 quote_assign (const char *string
)
861 char *temp
, *t
, *subs
;
862 const char *s
, *send
;
866 slen
= strlen (string
);
867 send
= string
+ slen
;
869 t
= temp
= (char *)xmalloc (slen
* 2 + 1);
871 for (s
= string
; *s
; )
875 if (saw_eq
== 0 && *s
== '[') /* looks like a subscript */
878 se
= skipsubscript (string
, ss
, 0);
879 subs
= substring (s
, ss
, se
);
889 if (saw_eq
== 0 && (glob_char_p (s
) || isifs (*s
)))
892 COPY_CHAR_P (t
, s
, send
);
898 /* Take a word W of the form [IND]=VALUE and transform it to ['IND']='VALUE'
899 to prevent further expansion. This is called for compound assignments to
900 indexed arrays. W has already undergone word expansions. If W has no [IND]=,
901 just single-quote and return it. */
903 quote_compound_array_word (char *w
, int type
)
905 char *nword
, *sub
, *value
, *t
;
909 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
910 ind
= skipsubscript (w
, 0, 0);
911 if (w
[ind
] != RBRACK
)
912 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
916 t
= (strchr (w
+1, CTLESC
)) ? quote_escapes (w
+1) : w
+1;
917 sub
= sh_single_quote (t
);
922 nword
= xmalloc (wlen
* 4 + 5); /* wlen*4 is max single quoted length */
925 memcpy (nword
+1, sub
, i
);
927 i
++; /* accommodate the opening LBRACK */
928 nword
[i
++] = w
[ind
++]; /* RBRACK */
930 nword
[i
++] = w
[ind
++];
931 nword
[i
++] = w
[ind
++];
932 t
= (strchr (w
+ind
, CTLESC
)) ? quote_escapes (w
+ind
) : w
+ind
;
933 value
= sh_single_quote (t
);
936 strcpy (nword
+ i
, value
);
941 /* Expand the key and value in W, which is of the form [KEY]=VALUE, and
942 reconstruct W with the expanded and single-quoted version:
943 ['expanded-key']='expanded-value'. If there is no [KEY]=, single-quote the
944 word and return it. Very similar to previous function, but does not assume
945 W has already been expanded, and expands the KEY and VALUE separately.
946 Used for compound assignments to associative arrays that are arguments to
947 declaration builtins (declare -A a=( list )). */
949 expand_and_quote_assoc_word (char *w
, int type
)
951 char *nword
, *key
, *value
, *s
, *t
;
955 return (sh_single_quote (w
)); /* XXX - quote_escapes */
956 ind
= skipsubscript (w
, 0, 0);
957 if (w
[ind
] != RBRACK
)
958 return (sh_single_quote (w
)); /* XXX - quote_escapes */
961 t
= expand_subscript_string (w
+1, 0);
962 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
963 key
= sh_single_quote (s
? s
: "");
970 nword
= xmalloc (wlen
+ 5);
972 memcpy (nword
+1, key
, wlen
);
973 i
= wlen
+ 1; /* accommodate the opening LBRACK */
975 nword
[i
++] = w
[ind
++]; /* RBRACK */
977 nword
[i
++] = w
[ind
++];
978 nword
[i
++] = w
[ind
++];
981 t
= expand_assignment_string_to_string (w
+ind
, 0);
982 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
983 value
= sh_single_quote (s
? s
: "");
987 nword
= xrealloc (nword
, wlen
+ 5 + STRLEN (value
));
988 strcpy (nword
+ i
, value
);
996 /* For each word in a compound array assignment, if the word looks like
997 [ind]=value, single-quote ind and value, but leave the brackets and
998 the = sign (and any `+') alone. If it's not an assignment, just single-
999 quote the word. This is used for indexed arrays. */
1001 quote_compound_array_list (WORD_LIST
*list
, int type
)
1006 for (l
= list
; l
; l
= l
->next
)
1008 if (l
->word
== 0 || l
->word
->word
== 0)
1009 continue; /* should not happen, but just in case... */
1010 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1012 s
= (strchr (l
->word
->word
, CTLESC
)) ? quote_escapes (l
->word
->word
) : l
->word
->word
;
1013 t
= sh_single_quote (s
);
1014 if (s
!= l
->word
->word
)
1018 t
= quote_compound_array_word (l
->word
->word
, type
);
1019 free (l
->word
->word
);
1024 /* For each word in a compound array assignment, if the word looks like
1025 [ind]=value, quote globbing chars and characters in $IFS before the `='. */
1027 quote_array_assignment_chars (WORD_LIST
*list
)
1032 for (l
= list
; l
; l
= l
->next
)
1034 if (l
->word
== 0 || l
->word
->word
== 0 || l
->word
->word
[0] == '\0')
1035 continue; /* should not happen, but just in case... */
1036 /* Don't bother if it hasn't been recognized as an assignment or
1037 doesn't look like [ind]=value */
1038 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1040 if (l
->word
->word
[0] != '[' || mbschr (l
->word
->word
, '=') == 0) /* ] */
1043 nword
= quote_assign (l
->word
->word
);
1044 free (l
->word
->word
);
1045 l
->word
->word
= nword
;
1046 l
->word
->flags
|= W_NOGLOB
; /* XXX - W_NOSPLIT also? */
1050 /* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
1052 /* This function is called with SUB pointing to just after the beginning
1053 `[' of an array subscript and removes the array element to which SUB
1054 expands from array VAR. A subscript of `*' or `@' unsets the array. */
1055 /* If FLAGS&1 (VA_NOEXPAND) we don't expand the subscript; we just use it
1056 as-is. If FLAGS&VA_ONEWORD, we don't try to use skipsubscript to parse
1057 the subscript, we just assume the subscript ends with a close bracket,
1058 if one is present, and use what's inside the brackets. */
1060 unbind_array_element (SHELL_VAR
*var
, char *sub
, int flags
)
1066 /* Assume that the caller (unset_builtin) passes us a null-terminated SUB,
1067 so we don't have to use VA_ONEWORD or parse the subscript again with
1070 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1072 if (array_p (var
) || assoc_p (var
))
1074 if (flags
& VA_ALLOWALL
)
1076 unbind_variable (var
->name
); /* XXX -- {array,assoc}_flush ? */
1079 /* otherwise we fall through and try to unset element `@' or `*' */
1082 return -2; /* don't allow this to unset scalar variables */
1087 akey
= (flags
& VA_NOEXPAND
) ? sub
: expand_subscript_string (sub
, 0);
1088 if (akey
== 0 || *akey
== 0)
1090 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1094 assoc_remove (assoc_cell (var
), akey
);
1098 else if (array_p (var
))
1100 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1102 /* We can go several ways here:
1103 1) remove the array (backwards compatible)
1104 2) empty the array (new behavior)
1105 3) do nothing; treat the `@' or `*' as an expression and throw
1109 if (shell_compatibility_level
<= 51)
1111 unbind_variable (name_cell (var
));
1114 else /* Behavior 2 */
1116 array_flush (array_cell (var
));
1119 /* Fall through for behavior 3 */
1121 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, 0);
1122 /* negative subscripts to indexed arrays count back from end */
1124 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1127 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1130 ae
= array_remove (array_cell (var
), ind
);
1132 array_dispose_element (ae
);
1134 else /* array_p (var) == 0 && assoc_p (var) == 0 */
1136 akey
= this_command_name
;
1137 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, 0);
1138 this_command_name
= akey
;
1141 unbind_variable (var
->name
);
1145 return -2; /* any subscript other than 0 is invalid with scalar variables */
1151 /* Format and output an array assignment in compound form VAR=(VALUES),
1152 suitable for re-use as input. */
1154 print_array_assignment (SHELL_VAR
*var
, int quoted
)
1158 vstr
= array_to_assign (array_cell (var
), quoted
);
1161 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1164 printf ("%s=%s\n", var
->name
, vstr
);
1169 /* Format and output an associative array assignment in compound form
1170 VAR=(VALUES), suitable for re-use as input. */
1172 print_assoc_assignment (SHELL_VAR
*var
, int quoted
)
1176 vstr
= assoc_to_assign (assoc_cell (var
), quoted
);
1179 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1182 printf ("%s=%s\n", var
->name
, vstr
);
1187 /***********************************************************************/
1189 /* Utility functions to manage arrays and their contents for expansion */
1191 /***********************************************************************/
1193 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1195 /* When NAME is a properly-formed array reference and a non-null argument SUBP
1196 is supplied, '[' and ']' that enclose the subscript are replaced by '\0',
1197 and the pointer to the subscript in NAME is assigned to *SUBP, so that NAME
1198 and SUBP can be later used as the array name and the subscript,
1199 respectively. When SUBP is the null pointer, the original string NAME will
1201 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1203 tokenize_array_reference (const char *name
, int flags
, char **subp
)
1206 int r
, len
, isassoc
, ssflags
;
1209 t
= mbschr (name
, '['); /* ] */
1214 r
= legal_identifier (name
);
1215 if (flags
& VA_NOEXPAND
) /* Don't waste a lookup if we don't need one */
1216 isassoc
= (entry
= find_variable (name
)) && assoc_p (entry
);
1222 if (isassoc
&& ((flags
& (VA_NOEXPAND
|VA_ONEWORD
)) == (VA_NOEXPAND
|VA_ONEWORD
)))
1223 len
= strlen (t
) - 1;
1226 if (flags
& VA_NOEXPAND
)
1228 len
= skipsubscript (t
, 0, ssflags
);
1231 /* Check for a properly-terminated non-null subscript. */
1232 len
= skipsubscript (t
, 0, 0); /* arithmetic expression */
1234 if (t
[len
] != ']' || len
== 1 || t
[len
+1] != '\0')
1238 /* Could check and allow subscripts consisting only of whitespace for
1239 existing associative arrays, using isassoc */
1240 for (r
= 1; r
< len
; r
++)
1241 if (whitespace (t
[r
]) == 0)
1244 return 0; /* Fail if the subscript contains only whitespaces. */
1249 t
[0] = t
[len
] = '\0';
1253 /* This allows blank subscripts */
1259 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1261 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1263 valid_array_reference (const char *name
, int flags
)
1265 return tokenize_array_reference (name
, flags
, (char **)NULL
);
1268 /* Expand the array index beginning at S and extending LEN characters. */
1270 array_expand_index (SHELL_VAR
*var
, const char *s
, int len
, int flags
)
1272 char *exp
, *t
, *savecmd
;
1276 exp
= (char *)xmalloc (len
);
1277 strncpy (exp
, s
, len
- 1);
1278 exp
[len
- 1] = '\0';
1279 #if 0 /* TAG: maybe bash-5.2 */
1280 if ((flags
& AV_NOEXPAND
) == 0)
1281 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1285 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1287 savecmd
= this_command_name
;
1288 this_command_name
= (char *)NULL
;
1289 eflag
= (shell_compatibility_level
> 51) ? 0 : EXP_EXPANDED
;
1290 val
= evalexp (t
, eflag
, &expok
); /* XXX - was 0 but we expanded exp already */
1291 this_command_name
= savecmd
;
1297 set_exit_status (EXECUTION_FAILURE
);
1299 if (no_longjmp_on_fatal_error
)
1301 top_level_cleanup ();
1302 jump_to_top_level (DISCARD
);
1307 /* Return the name of the variable specified by S without any subscript.
1308 If SUBP is non-null, return a pointer to the start of the subscript
1309 in *SUBP. If LENP is non-null, the length of the subscript is returned
1310 in *LENP. This returns newly-allocated memory. */
1312 array_variable_name (const char *s
, int flags
, char **subp
, int *lenp
)
1315 int ind
, ni
, ssflags
;
1317 t
= mbschr (s
, '[');
1324 return ((char *)NULL
);
1327 if ((flags
& (AV_NOEXPAND
|AV_ONEWORD
)) == (AV_NOEXPAND
|AV_ONEWORD
))
1328 ni
= strlen (s
) - 1;
1332 if (flags
& AV_NOEXPAND
)
1334 ni
= skipsubscript (s
, ind
, ssflags
);
1336 if (ni
<= ind
+ 1 || s
[ni
] != ']')
1338 err_badarraysub (s
);
1343 return ((char *)NULL
);
1347 ret
= savestring (s
);
1358 /* Return the variable specified by S without any subscript. If SUBP is
1359 non-null, return a pointer to the start of the subscript in *SUBP.
1360 If LENP is non-null, the length of the subscript is returned in *LENP. */
1362 array_variable_part (const char *s
, int flags
, char **subp
, int *lenp
)
1367 t
= array_variable_name (s
, flags
, subp
, lenp
);
1369 return ((SHELL_VAR
*)NULL
);
1370 var
= find_variable (t
); /* XXX - handle namerefs here? */
1373 return var
; /* now return invisible variables; caller must handle */
1376 #define INDEX_ERROR() \
1380 err_badarraysub (var->name); \
1384 err_badarraysub (s); \
1385 t[-1] = '['; /* ] */\
1387 return ((char *)NULL); \
1391 /* Return a string containing the elements in the array and subscript
1392 described by S. If the subscript is * or @, obeys quoting rules akin
1393 to the expansion of $* and $@ including double quoting. If RTYPE
1394 is non-null it gets 1 if the array reference is name[*], 2 if the
1395 reference is name[@], and 0 otherwise. */
1397 array_value_internal (const char *s
, int quoted
, int flags
, array_eltstate_t
*estatep
)
1399 int len
, isassoc
, subtype
;
1402 char *retval
, *t
, *temp
;
1406 var
= array_variable_part (s
, flags
, &t
, &len
); /* XXX */
1408 /* Expand the index, even if the variable doesn't exist, in case side
1409 effects are needed, like ${w[i++]} where w is unset. */
1412 return (char *)NULL
;
1416 return ((char *)NULL
); /* error message already printed */
1418 isassoc
= var
&& assoc_p (var
);
1423 estatep
->value
= (char *)NULL
;
1425 /* Backwards compatibility: we only change the behavior of A[@] and A[*]
1426 for associative arrays, and the caller has to request it. */
1427 if ((isassoc
== 0 || (flags
& AV_ATSTARKEYS
) == 0) && ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
1430 estatep
->subtype
= (t
[0] == '*') ? 1 : 2;
1431 if ((flags
& AV_ALLOWALL
) == 0)
1433 err_badarraysub (s
);
1434 return ((char *)NULL
);
1436 else if (var
== 0 || value_cell (var
) == 0)
1437 return ((char *)NULL
);
1438 else if (invisible_p (var
))
1439 return ((char *)NULL
);
1440 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
1443 estatep
->type
= ARRAY_SCALAR
;
1444 l
= add_string_to_list (value_cell (var
), (WORD_LIST
*)NULL
);
1446 else if (assoc_p (var
))
1449 estatep
->type
= ARRAY_ASSOC
;
1450 l
= assoc_to_word_list (assoc_cell (var
));
1451 if (l
== (WORD_LIST
*)NULL
)
1452 return ((char *)NULL
);
1457 estatep
->type
= ARRAY_INDEXED
;
1458 l
= array_to_word_list (array_cell (var
));
1459 if (l
== (WORD_LIST
*)NULL
)
1460 return ((char *) NULL
);
1463 /* Caller of array_value takes care of inspecting estatep->subtype and
1464 duplicating retval if subtype == 0, so this is not a memory leak */
1465 if (t
[0] == '*' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1467 temp
= string_list_dollar_star (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1468 retval
= quote_string (temp
);
1471 else /* ${name[@]} or unquoted ${name[*]} */
1472 retval
= string_list_dollar_at (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1479 estatep
->subtype
= 0;
1480 if (var
== 0 || array_p (var
) || assoc_p (var
) == 0)
1482 if ((flags
& AV_USEIND
) == 0 || estatep
== 0)
1484 ind
= array_expand_index (var
, t
, len
, flags
);
1487 /* negative subscripts to indexed arrays count back from end */
1488 if (var
&& array_p (var
))
1489 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1496 else if (estatep
&& (flags
& AV_USEIND
))
1499 estatep
->type
= array_p (var
) ? ARRAY_INDEXED
: ARRAY_SCALAR
;
1501 else if (assoc_p (var
))
1505 estatep
->type
= ARRAY_ASSOC
;
1506 if ((flags
& AV_USEIND
) && estatep
&& estatep
->key
)
1507 akey
= savestring (estatep
->key
);
1508 else if ((flags
& AV_NOEXPAND
) == 0)
1509 akey
= expand_subscript_string (t
, 0); /* [ */
1511 akey
= savestring (t
);
1513 if (akey
== 0 || *akey
== 0)
1520 if (var
== 0 || value_cell (var
) == 0)
1523 return ((char *)NULL
);
1525 else if (invisible_p (var
))
1528 return ((char *)NULL
);
1530 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1531 retval
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
1532 else if (assoc_p (var
))
1534 retval
= assoc_reference (assoc_cell (var
), akey
);
1535 if (estatep
&& estatep
->key
&& (flags
& AV_USEIND
))
1536 free (akey
); /* duplicated estatep->key */
1538 estatep
->key
= akey
; /* XXX - caller must manage */
1539 else /* not saving it anywhere */
1543 retval
= array_reference (array_cell (var
), ind
);
1546 estatep
->value
= retval
;
1552 /* Return a string containing the elements described by the array and
1553 subscript contained in S, obeying quoting for subscripts * and @. */
1555 array_value (const char *s
, int quoted
, int flags
, array_eltstate_t
*estatep
)
1559 retval
= array_value_internal (s
, quoted
, flags
|AV_ALLOWALL
, estatep
);
1563 /* Return the value of the array indexing expression S as a single string.
1564 If (FLAGS & AV_ALLOWALL) is 0, do not allow `@' and `*' subscripts. This
1565 is used by other parts of the shell such as the arithmetic expression
1566 evaluator in expr.c. */
1568 get_array_value (const char *s
, int flags
, array_eltstate_t
*estatep
)
1572 retval
= array_value_internal (s
, 0, flags
, estatep
);
1577 array_keys (const char *s
, int quoted
, int pflags
)
1580 char *retval
, *t
, *temp
;
1584 var
= array_variable_part (s
, 0, &t
, &len
);
1587 if (var
== 0 || ALL_ELEMENT_SUB (t
[0]) == 0 || t
[1] != ']')
1588 return (char *)NULL
;
1590 if (var_isset (var
) == 0 || invisible_p (var
))
1591 return (char *)NULL
;
1593 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1594 l
= add_string_to_list ("0", (WORD_LIST
*)NULL
);
1595 else if (assoc_p (var
))
1596 l
= assoc_keys_to_word_list (assoc_cell (var
));
1598 l
= array_keys_to_word_list (array_cell (var
));
1599 if (l
== (WORD_LIST
*)NULL
)
1600 return ((char *) NULL
);
1602 retval
= string_list_pos_params (t
[0], l
, quoted
, pflags
);
1607 #endif /* ARRAY_VARS */