1 /* arrayfunc.c -- High-level array functions used by other parts of the shell. */
3 /* Copyright (C) 2001-2021 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
PARAMS((SHELL_VAR
*, arrayind_t
, char *, char *, int));
56 static SHELL_VAR
*assign_array_element_internal
PARAMS((SHELL_VAR
*, char *, char *, char *, int, char *, int, array_eltstate_t
*));
58 static void assign_assoc_from_kvlist
PARAMS((SHELL_VAR
*, WORD_LIST
*, HASH_TABLE
*, int));
60 static char *quote_assign
PARAMS((const char *));
61 static void quote_array_assignment_chars
PARAMS((WORD_LIST
*));
62 static char *quote_compound_array_word
PARAMS((char *, int));
63 static char *array_value_internal
PARAMS((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 (var
)
83 oldval
= value_cell (var
);
84 array
= array_create ();
86 array_insert (array
, 0, oldval
);
88 FREE (value_cell (var
));
89 var_setarray (var
, array
);
91 /* these aren't valid anymore */
92 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
93 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
95 INVALIDATE_EXPORTSTR (var
);
99 VSETATTR (var
, att_array
);
101 VUNSETATTR (var
, att_invisible
);
103 /* Make sure it's not marked as an associative array any more */
104 VUNSETATTR (var
, att_assoc
);
106 /* Since namerefs can't be array variables, turn off nameref attribute */
107 VUNSETATTR (var
, att_nameref
);
112 /* Convert a shell variable to an array variable. The original value is
113 saved as array[0]. */
115 convert_var_to_assoc (var
)
121 oldval
= value_cell (var
);
122 hash
= assoc_create (0);
124 assoc_insert (hash
, savestring ("0"), oldval
);
126 FREE (value_cell (var
));
127 var_setassoc (var
, hash
);
129 /* these aren't valid anymore */
130 var
->dynamic_value
= (sh_var_value_func_t
*)NULL
;
131 var
->assign_func
= (sh_var_assign_func_t
*)NULL
;
133 INVALIDATE_EXPORTSTR (var
);
134 if (exported_p (var
))
135 array_needs_making
++;
137 VSETATTR (var
, att_assoc
);
139 VUNSETATTR (var
, att_invisible
);
141 /* Make sure it's not marked as an indexed array any more */
142 VUNSETATTR (var
, att_array
);
144 /* Since namerefs can't be array variables, turn off nameref attribute */
145 VUNSETATTR (var
, att_nameref
);
151 make_array_variable_value (entry
, ind
, key
, value
, flags
)
161 /* If we're appending, we need the old value of the array reference, so
162 fake out make_variable_value with a dummy SHELL_VAR */
163 if (flags
& ASS_APPEND
)
165 dentry
= (SHELL_VAR
*)xmalloc (sizeof (SHELL_VAR
));
166 dentry
->name
= savestring (entry
->name
);
168 newval
= assoc_reference (assoc_cell (entry
), key
);
170 newval
= array_reference (array_cell (entry
), ind
);
172 dentry
->value
= savestring (newval
);
175 dentry
->value
= (char *)xmalloc (1);
176 dentry
->value
[0] = '\0';
178 dentry
->exportstr
= 0;
179 dentry
->attributes
= entry
->attributes
& ~(att_array
|att_assoc
|att_exported
);
180 /* Leave the rest of the members uninitialized; the code doesn't look
182 newval
= make_variable_value (dentry
, value
, flags
);
183 dispose_variable (dentry
);
186 newval
= make_variable_value (entry
, value
, flags
);
191 /* Assign HASH[KEY]=VALUE according to FLAGS. ENTRY is an associative array
192 variable; HASH is the hash table to assign into. HASH may or may not be
193 the hash table associated with ENTRY; if it's not, the caller takes care
195 XXX - make sure that any dynamic associative array variables recreate the
196 hash table on each assignment. BASH_CMDS and BASH_ALIASES already do this */
198 bind_assoc_var_internal (entry
, hash
, key
, value
, flags
)
207 /* Use the existing array contents to expand the value */
208 newval
= make_array_variable_value (entry
, 0, key
, value
, flags
);
210 if (entry
->assign_func
)
211 (*entry
->assign_func
) (entry
, newval
, 0, key
);
213 assoc_insert (hash
, key
, newval
);
217 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
219 /* check mark_modified_variables if we ever want to export array vars */
223 /* Perform ENTRY[IND]=VALUE or ENTRY[KEY]=VALUE. This is not called for every
224 assignment to an associative array; see assign_compound_array_list below. */
226 bind_array_var_internal (entry
, ind
, key
, value
, flags
)
235 newval
= make_array_variable_value (entry
, ind
, key
, value
, flags
);
237 if (entry
->assign_func
)
238 (*entry
->assign_func
) (entry
, newval
, ind
, key
);
239 else if (assoc_p (entry
))
240 assoc_insert (assoc_cell (entry
), key
, newval
);
242 array_insert (array_cell (entry
), ind
, newval
);
245 VUNSETATTR (entry
, att_invisible
); /* no longer invisible */
247 /* check mark_modified_variables if we ever want to export array vars */
251 /* Perform an array assignment name[ind]=value. If NAME already exists and
252 is not an array, and IND is 0, perform name=value instead. If NAME exists
253 and is not an array, and IND is not 0, convert it into an array with the
254 existing value as name[0].
256 If NAME does not exist, just create an array variable, no matter what
257 IND's value may be. */
259 bind_array_variable (name
, ind
, value
, flags
)
267 entry
= find_shell_variable (name
);
269 if (entry
== (SHELL_VAR
*) 0)
271 /* Is NAME a nameref variable that points to an unset variable? */
272 entry
= find_variable_nameref_for_create (name
, 0);
273 if (entry
== INVALID_NAMEREF_VALUE
)
274 return ((SHELL_VAR
*)0);
275 if (entry
&& nameref_p (entry
))
276 entry
= make_new_array_variable (nameref_cell (entry
));
278 if (entry
== (SHELL_VAR
*) 0)
279 entry
= make_new_array_variable (name
);
280 else if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
282 if (readonly_p (entry
))
286 else if (array_p (entry
) == 0)
287 entry
= convert_var_to_array (entry
);
289 /* ENTRY is an array variable, and ARRAY points to the value. */
290 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
294 bind_array_element (entry
, ind
, value
, flags
)
300 return (bind_array_var_internal (entry
, ind
, 0, value
, flags
));
304 bind_assoc_variable (entry
, name
, key
, value
, flags
)
311 if ((readonly_p (entry
) && (flags
&ASS_FORCE
) == 0) || noassign_p (entry
))
313 if (readonly_p (entry
))
318 return (bind_assoc_var_internal (entry
, assoc_cell (entry
), key
, value
, flags
));
322 init_eltstate (array_eltstate_t
*estatep
)
326 estatep
->type
= ARRAY_INVALID
;
327 estatep
->subtype
= 0;
328 estatep
->key
= estatep
->value
= 0;
329 estatep
->ind
= INTMAX_MIN
;
334 flush_eltstate (array_eltstate_t
*estatep
)
340 /* Parse NAME, a lhs of an assignment statement of the form v[s], and
341 assign VALUE to that array element by calling bind_array_variable().
342 Flags are ASS_ assignment flags */
344 assign_array_element (name
, value
, flags
, estatep
)
347 array_eltstate_t
*estatep
;
350 int sublen
, isassoc
, avflags
;
354 if (flags
& ASS_NOEXPAND
)
355 avflags
|= AV_NOEXPAND
;
356 if (flags
& ASS_ONEWORD
)
357 avflags
|= AV_ONEWORD
;
358 vname
= array_variable_name (name
, avflags
, &sub
, &sublen
);
361 return ((SHELL_VAR
*)NULL
);
363 entry
= find_variable (vname
);
364 isassoc
= entry
&& assoc_p (entry
);
366 /* We don't allow assignment to `*' or `@' associative array keys if the
367 caller hasn't told us the subscript has already been expanded
368 (ASS_NOEXPAND). If the caller has explicitly told us it's ok
369 (ASS_ALLOWALLSUB) we allow it. */
370 if (((isassoc
== 0 || (flags
& (ASS_NOEXPAND
|ASS_ALLOWALLSUB
)) == 0) &&
371 (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == ']')) ||
373 (sub
[sublen
] != '\0')) /* sanity check */
376 err_badarraysub (name
);
377 return ((SHELL_VAR
*)NULL
);
380 entry
= assign_array_element_internal (entry
, name
, vname
, sub
, sublen
, value
, flags
, estatep
);
383 if (entry
&& exported_p (entry
))
385 INVALIDATE_EXPORTSTR (entry
);
386 array_needs_making
= 1;
395 assign_array_element_internal (entry
, name
, vname
, sub
, sublen
, value
, flags
, estatep
)
397 char *name
; /* only used for error messages */
403 array_eltstate_t
*estatep
;
409 /* rely on the caller to initialize estatep */
411 if (entry
&& assoc_p (entry
))
413 sub
[sublen
-1] = '\0';
414 if ((flags
& ASS_NOEXPAND
) == 0)
415 akey
= expand_subscript_string (sub
, 0); /* [ */
417 akey
= savestring (sub
);
419 if (akey
== 0 || *akey
== 0)
421 err_badarraysub (name
);
423 return ((SHELL_VAR
*)NULL
);
426 nkey
= savestring (akey
); /* assoc_insert/assoc_replace frees akey */
427 entry
= bind_assoc_variable (entry
, vname
, akey
, value
, flags
);
430 estatep
->type
= ARRAY_ASSOC
;
432 estatep
->value
= entry
? assoc_reference (assoc_cell (entry
), nkey
) : 0;
437 ind
= array_expand_index (entry
, sub
, sublen
, 0);
438 /* negative subscripts to indexed arrays count back from end */
439 if (entry
&& ind
< 0)
440 ind
= (array_p (entry
) ? array_max_index (array_cell (entry
)) : 0) + 1 + ind
;
443 err_badarraysub (name
);
444 return ((SHELL_VAR
*)NULL
);
446 entry
= bind_array_variable (vname
, ind
, value
, flags
);
449 estatep
->type
= ARRAY_INDEXED
;
451 estatep
->value
= entry
? array_reference (array_cell (entry
), ind
) : 0;
458 /* Find the array variable corresponding to NAME. If there is no variable,
459 create a new array variable. If the variable exists but is not an array,
460 convert it to an indexed array. If FLAGS&1 is non-zero, an existing
461 variable is checked for the readonly or noassign attribute in preparation
462 for assignment (e.g., by the `read' builtin). If FLAGS&2 is non-zero, we
463 create an associative array. */
465 find_or_make_array_variable (name
, flags
)
471 var
= find_variable (name
);
474 /* See if we have a nameref pointing to a variable that hasn't been
476 var
= find_variable_last_nameref (name
, 1);
477 if (var
&& nameref_p (var
) && invisible_p (var
))
479 internal_warning (_("%s: removing nameref attribute"), name
);
480 VUNSETATTR (var
, att_nameref
);
482 if (var
&& nameref_p (var
))
484 if (valid_nameref_value (nameref_cell (var
), 2) == 0)
486 sh_invalidid (nameref_cell (var
));
487 return ((SHELL_VAR
*)NULL
);
489 var
= (flags
& 2) ? make_new_assoc_variable (nameref_cell (var
)) : make_new_array_variable (nameref_cell (var
));
494 var
= (flags
& 2) ? make_new_assoc_variable (name
) : make_new_array_variable (name
);
495 else if ((flags
& 1) && (readonly_p (var
) || noassign_p (var
)))
497 if (readonly_p (var
))
499 return ((SHELL_VAR
*)NULL
);
501 else if ((flags
& 2) && array_p (var
))
503 set_exit_status (EXECUTION_FAILURE
);
504 report_error (_("%s: cannot convert indexed to associative array"), name
);
505 return ((SHELL_VAR
*)NULL
);
508 var
= assoc_p (var
) ? var
: convert_var_to_assoc (var
);
509 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
510 var
= convert_var_to_array (var
);
515 /* Perform a compound assignment statement for array NAME, where VALUE is
516 the text between the parens: NAME=( VALUE ) */
518 assign_array_from_string (name
, value
, flags
)
526 if (flags
& ASS_MKASSOC
)
529 var
= find_or_make_array_variable (name
, vflags
);
531 return ((SHELL_VAR
*)NULL
);
533 return (assign_array_var_from_string (var
, value
, flags
));
536 /* Sequentially assign the indices of indexed array variable VAR from the
539 assign_array_var_from_word_list (var
, list
, flags
)
544 register arrayind_t i
;
545 register WORD_LIST
*l
;
548 a
= array_cell (var
);
549 i
= (flags
& ASS_APPEND
) ? array_max_index (a
) + 1 : 0;
551 for (l
= list
; l
; l
= l
->next
, i
++)
552 bind_array_var_internal (var
, i
, 0, l
->word
->word
, flags
& ~ASS_APPEND
);
554 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
560 expand_compound_array_assignment (var
, value
, flags
)
565 WORD_LIST
*list
, *nlist
;
569 /* This condition is true when invoked from the declare builtin with a
571 declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")' */
572 if (*value
== '(') /*)*/
575 val
= extract_array_assignment_list (value
, &ni
);
577 return (WORD_LIST
*)NULL
;
582 /* Expand the value string into a list of words, performing all the
583 shell expansions including pathname generation and word splitting. */
584 /* First we split the string on whitespace, using the shell parser
585 (ksh93 seems to do this). */
586 /* XXX - this needs a rethink, maybe use split_at_delims */
587 list
= parse_string_to_word_list (val
, 1, "array assign");
589 /* If the parser has quoted CTLESC and CTNLNUL with CTLESC in unquoted
590 words, we need to remove those here because the code below assumes
591 they are there because they exist in the original word. */
592 /* XXX - if we rethink parse_string_to_word_list above, change this. */
593 for (nlist
= list
; nlist
; nlist
= nlist
->next
)
594 if ((nlist
->word
->flags
& W_QUOTED
) == 0)
595 remove_quoted_escapes (nlist
->word
->word
);
597 /* Note that we defer expansion of the assignment statements for associative
598 arrays here, so we don't have to scan the subscript and find the ending
599 bracket twice. See the caller below. */
600 if (var
&& assoc_p (var
))
607 /* If we're using [subscript]=value, we need to quote each [ and ] to
608 prevent unwanted filename expansion. This doesn't need to be done
609 for associative array expansion, since that uses a different expansion
610 function (see assign_compound_array_list below). */
612 quote_array_assignment_chars (list
);
614 /* Now that we've split it, perform the shell expansions on each
616 nlist
= list
? expand_words_no_vars (list
) : (WORD_LIST
*)NULL
;
618 dispose_words (list
);
626 #if ASSOC_KVPAIR_ASSIGNMENT
628 assign_assoc_from_kvlist (var
, nlist
, h
, flags
)
635 char *akey
, *aval
, *k
, *v
;
637 for (list
= nlist
; list
; list
= list
->next
)
639 k
= list
->word
->word
;
640 v
= list
->next
? list
->next
->word
->word
: 0;
645 akey
= expand_subscript_string (k
, 0);
646 if (akey
== 0 || *akey
== 0)
653 aval
= expand_subscript_string (v
, 0);
656 aval
= (char *)xmalloc (1);
657 aval
[0] = '\0'; /* like do_assignment_internal */
660 bind_assoc_var_internal (var
, h
, akey
, aval
, flags
);
665 /* Return non-zero if L appears to be a key-value pair associative array
666 compound assignment. */
668 kvpair_assignment_p (l
)
671 return (l
&& (l
->word
->flags
& W_ASSIGNMENT
) == 0 && l
->word
->word
[0] != '['); /*]*/
675 expand_and_quote_kvpair_word (w
)
680 t
= w
? expand_subscript_string (w
, 0) : 0;
681 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
682 r
= sh_single_quote (s
? s
: "");
690 /* Callers ensure that VAR is not NULL. Associative array assignments have not
691 been expanded when this is called, or have been expanded once and single-
692 quoted, so we don't have to scan through an unquoted expanded subscript to
693 find the ending bracket; indexed array assignments have been expanded and
694 possibly single-quoted to prevent further expansion.
696 If this is an associative array, we perform the assignments into NHASH and
697 set NHASH to be the value of VAR after processing the assignments in NLIST */
699 assign_compound_array_list (var
, nlist
, flags
)
705 HASH_TABLE
*h
, *nhash
;
707 char *w
, *val
, *nval
, *savecmd
;
708 int len
, iflags
, free_val
;
709 arrayind_t ind
, last_ind
;
712 a
= (var
&& array_p (var
)) ? array_cell (var
) : (ARRAY
*)0;
713 nhash
= h
= (var
&& assoc_p (var
)) ? assoc_cell (var
) : (HASH_TABLE
*)0;
718 /* Now that we are ready to assign values to the array, kill the existing
720 if ((flags
& ASS_APPEND
) == 0)
722 if (a
&& array_p (var
))
724 else if (h
&& assoc_p (var
))
725 nhash
= assoc_create (h
->nbuckets
);
728 last_ind
= (a
&& (flags
& ASS_APPEND
)) ? array_max_index (a
) + 1 : 0;
730 #if ASSOC_KVPAIR_ASSIGNMENT
731 if (assoc_p (var
) && kvpair_assignment_p (nlist
))
733 iflags
= flags
& ~ASS_APPEND
;
734 assign_assoc_from_kvlist (var
, nlist
, nhash
, iflags
);
735 if (nhash
&& nhash
!= h
)
737 h
= assoc_cell (var
);
738 var_setassoc (var
, nhash
);
745 for (list
= nlist
; list
; list
= list
->next
)
747 /* Don't allow var+=(values) to make assignments in VALUES append to
748 existing values by default. */
749 iflags
= flags
& ~ASS_APPEND
;
750 w
= list
->word
->word
;
752 /* We have a word of the form [ind]=value */
753 if ((list
->word
->flags
& W_ASSIGNMENT
) && w
[0] == '[')
755 /* Don't have to handle embedded quotes specially any more, since
756 associative array subscripts have not been expanded yet (see
758 len
= skipsubscript (w
, 0, 0);
760 /* XXX - changes for `+=' */
761 if (w
[len
] != ']' || (w
[len
+1] != '=' && (w
[len
+1] != '+' || w
[len
+2] != '=')))
768 nval
= make_variable_value (var
, w
, flags
);
769 if (var
->assign_func
)
770 (*var
->assign_func
) (var
, nval
, last_ind
, 0);
772 array_insert (a
, last_ind
, nval
);
784 if (ALL_ELEMENT_SUB (w
[1]) && len
== 2 && array_p (var
))
786 set_exit_status (EXECUTION_FAILURE
);
787 report_error (_("%s: cannot assign to non-numeric index"), w
);
793 ind
= array_expand_index (var
, w
+ 1, len
, 0);
794 /* negative subscripts to indexed arrays count back from end */
796 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
805 else if (assoc_p (var
))
807 /* This is not performed above, see expand_compound_array_assignment */
809 akey
= expand_subscript_string (w
+1, 0);
811 /* And we need to expand the value also, see below */
812 if (akey
== 0 || *akey
== 0)
820 /* XXX - changes for `+=' -- just accept the syntax. ksh93 doesn't do this */
821 if (w
[len
+ 1] == '+' && w
[len
+ 2] == '=')
823 iflags
|= ASS_APPEND
;
829 else if (assoc_p (var
))
831 set_exit_status (EXECUTION_FAILURE
);
832 report_error (_("%s: %s: must use subscript when assigning associative array"), var
->name
, w
);
835 else /* No [ind]=value, just a stray `=' */
842 /* See above; we need to expand the value here */
845 val
= expand_subscript_string (val
, 0);
848 val
= (char *)xmalloc (1);
849 val
[0] = '\0'; /* like do_assignment_internal */
854 savecmd
= this_command_name
;
856 this_command_name
= (char *)NULL
; /* no command name for errors */
858 bind_assoc_var_internal (var
, nhash
, akey
, val
, iflags
);
860 bind_array_var_internal (var
, ind
, akey
, val
, iflags
);
862 this_command_name
= savecmd
;
868 if (assoc_p (var
) && nhash
&& nhash
!= h
)
870 h
= assoc_cell (var
);
871 var_setassoc (var
, nhash
);
876 /* Perform a compound array assignment: VAR->name=( VALUE ). The
877 VALUE has already had the parentheses stripped. */
879 assign_array_var_from_string (var
, value
, flags
)
889 nlist
= expand_compound_array_assignment (var
, value
, flags
);
890 assign_compound_array_list (var
, nlist
, flags
);
893 dispose_words (nlist
);
896 VUNSETATTR (var
, att_invisible
); /* no longer invisible */
901 /* Quote globbing chars and characters in $IFS before the `=' in an assignment
902 statement (usually a compound array assignment) to protect them from
903 unwanted filename expansion or word splitting. */
905 quote_assign (string
)
910 char *temp
, *t
, *subs
;
911 const char *s
, *send
;
915 slen
= strlen (string
);
916 send
= string
+ slen
;
918 t
= temp
= (char *)xmalloc (slen
* 2 + 1);
920 for (s
= string
; *s
; )
924 if (saw_eq
== 0 && *s
== '[') /* looks like a subscript */
927 se
= skipsubscript (string
, ss
, 0);
928 subs
= substring (s
, ss
, se
);
938 if (saw_eq
== 0 && (glob_char_p (s
) || isifs (*s
)))
941 COPY_CHAR_P (t
, s
, send
);
947 /* Take a word W of the form [IND]=VALUE and transform it to ['IND']='VALUE'
948 to prevent further expansion. This is called for compound assignments to
949 indexed arrays. W has already undergone word expansions. If W has no [IND]=,
950 just single-quote and return it. */
952 quote_compound_array_word (w
, type
)
956 char *nword
, *sub
, *value
, *t
;
960 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
961 ind
= skipsubscript (w
, 0, 0);
962 if (w
[ind
] != RBRACK
)
963 return (sh_single_quote (w
)); /* XXX - quote CTLESC */
967 t
= (strchr (w
+1, CTLESC
)) ? quote_escapes (w
+1) : w
+1;
968 sub
= sh_single_quote (t
);
973 nword
= xmalloc (wlen
* 4 + 5); /* wlen*4 is max single quoted length */
976 memcpy (nword
+1, sub
, i
);
978 i
++; /* accommodate the opening LBRACK */
979 nword
[i
++] = w
[ind
++]; /* RBRACK */
981 nword
[i
++] = w
[ind
++];
982 nword
[i
++] = w
[ind
++];
983 t
= (strchr (w
+ind
, CTLESC
)) ? quote_escapes (w
+ind
) : w
+ind
;
984 value
= sh_single_quote (t
);
987 strcpy (nword
+ i
, value
);
992 /* Expand the key and value in W, which is of the form [KEY]=VALUE, and
993 reconstruct W with the expanded and single-quoted version:
994 ['expanded-key']='expanded-value'. If there is no [KEY]=, single-quote the
995 word and return it. Very similar to previous function, but does not assume
996 W has already been expanded, and expands the KEY and VALUE separately.
997 Used for compound assignments to associative arrays that are arguments to
998 declaration builtins (declare -A a=( list )). */
1000 expand_and_quote_assoc_word (w
, type
)
1004 char *nword
, *key
, *value
, *s
, *t
;
1008 return (sh_single_quote (w
)); /* XXX - quote_escapes */
1009 ind
= skipsubscript (w
, 0, 0);
1010 if (w
[ind
] != RBRACK
)
1011 return (sh_single_quote (w
)); /* XXX - quote_escapes */
1014 t
= expand_subscript_string (w
+1, 0);
1015 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
1016 key
= sh_single_quote (s
? s
: "");
1022 wlen
= STRLEN (key
);
1023 nword
= xmalloc (wlen
+ 5);
1025 memcpy (nword
+1, key
, wlen
);
1026 i
= wlen
+ 1; /* accommodate the opening LBRACK */
1028 nword
[i
++] = w
[ind
++]; /* RBRACK */
1030 nword
[i
++] = w
[ind
++];
1031 nword
[i
++] = w
[ind
++];
1033 t
= expand_subscript_string (w
+ind
, 0);
1034 s
= (t
&& strchr (t
, CTLESC
)) ? quote_escapes (t
) : t
;
1035 value
= sh_single_quote (s
? s
: "");
1039 nword
= xrealloc (nword
, wlen
+ 5 + STRLEN (value
));
1040 strcpy (nword
+ i
, value
);
1048 /* For each word in a compound array assignment, if the word looks like
1049 [ind]=value, single-quote ind and value, but leave the brackets and
1050 the = sign (and any `+') alone. If it's not an assignment, just single-
1051 quote the word. This is used for indexed arrays. */
1053 quote_compound_array_list (list
, type
)
1060 for (l
= list
; l
; l
= l
->next
)
1062 if (l
->word
== 0 || l
->word
->word
== 0)
1063 continue; /* should not happen, but just in case... */
1064 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1066 s
= (strchr (l
->word
->word
, CTLESC
)) ? quote_escapes (l
->word
->word
) : l
->word
->word
;
1067 t
= sh_single_quote (s
);
1068 if (s
!= l
->word
->word
)
1072 t
= quote_compound_array_word (l
->word
->word
, type
);
1073 free (l
->word
->word
);
1078 /* For each word in a compound array assignment, if the word looks like
1079 [ind]=value, quote globbing chars and characters in $IFS before the `='. */
1081 quote_array_assignment_chars (list
)
1087 for (l
= list
; l
; l
= l
->next
)
1089 if (l
->word
== 0 || l
->word
->word
== 0 || l
->word
->word
[0] == '\0')
1090 continue; /* should not happen, but just in case... */
1091 /* Don't bother if it hasn't been recognized as an assignment or
1092 doesn't look like [ind]=value */
1093 if ((l
->word
->flags
& W_ASSIGNMENT
) == 0)
1095 if (l
->word
->word
[0] != '[' || mbschr (l
->word
->word
, '=') == 0) /* ] */
1098 nword
= quote_assign (l
->word
->word
);
1099 free (l
->word
->word
);
1100 l
->word
->word
= nword
;
1101 l
->word
->flags
|= W_NOGLOB
; /* XXX - W_NOSPLIT also? */
1105 /* skipsubscript moved to subst.c to use private functions. 2009/02/24. */
1107 /* This function is called with SUB pointing to just after the beginning
1108 `[' of an array subscript and removes the array element to which SUB
1109 expands from array VAR. A subscript of `*' or `@' unsets the array. */
1110 /* If FLAGS&1 (VA_NOEXPAND) we don't expand the subscript; we just use it
1111 as-is. If FLAGS&VA_ONEWORD, we don't try to use skipsubscript to parse
1112 the subscript, we just assume the subscript ends with a close bracket,
1113 if one is present, and use what's inside the brackets. */
1115 unbind_array_element (var
, sub
, flags
)
1124 /* Assume that the caller (unset_builtin) passes us a null-terminated SUB,
1125 so we don't have to use VA_ONEWORD or parse the subscript again with
1128 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1130 if (array_p (var
) || assoc_p (var
))
1132 if (flags
& VA_ALLOWALL
)
1134 unbind_variable (var
->name
); /* XXX -- {array,assoc}_flush ? */
1137 /* otherwise we fall through and try to unset element `@' or `*' */
1140 return -2; /* don't allow this to unset scalar variables */
1145 akey
= (flags
& VA_NOEXPAND
) ? sub
: expand_subscript_string (sub
, 0);
1146 if (akey
== 0 || *akey
== 0)
1148 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1152 assoc_remove (assoc_cell (var
), akey
);
1156 else if (array_p (var
))
1158 if (ALL_ELEMENT_SUB (sub
[0]) && sub
[1] == 0)
1160 /* We can go several ways here:
1161 1) remove the array (backwards compatible)
1162 2) empty the array (new behavior)
1163 3) do nothing; treat the `@' or `*' as an expression and throw
1167 if (shell_compatibility_level
<= 51)
1169 unbind_variable (name_cell (var
));
1172 else /* Behavior 2 */
1174 array_flush (array_cell (var
));
1177 /* Fall through for behavior 3 */
1179 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, 0);
1180 /* negative subscripts to indexed arrays count back from end */
1182 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1185 builtin_error ("[%s]: %s", sub
, _(bash_badsub_errmsg
));
1188 ae
= array_remove (array_cell (var
), ind
);
1190 array_dispose_element (ae
);
1192 else /* array_p (var) == 0 && assoc_p (var) == 0 */
1194 akey
= this_command_name
;
1195 ind
= array_expand_index (var
, sub
, strlen (sub
) + 1, 0);
1196 this_command_name
= akey
;
1199 unbind_variable (var
->name
);
1203 return -2; /* any subscript other than 0 is invalid with scalar variables */
1209 /* Format and output an array assignment in compound form VAR=(VALUES),
1210 suitable for re-use as input. */
1212 print_array_assignment (var
, quoted
)
1218 vstr
= array_to_assign (array_cell (var
), quoted
);
1221 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1224 printf ("%s=%s\n", var
->name
, vstr
);
1229 /* Format and output an associative array assignment in compound form
1230 VAR=(VALUES), suitable for re-use as input. */
1232 print_assoc_assignment (var
, quoted
)
1238 vstr
= assoc_to_assign (assoc_cell (var
), quoted
);
1241 printf ("%s=%s\n", var
->name
, quoted
? "'()'" : "()");
1244 printf ("%s=%s\n", var
->name
, vstr
);
1249 /***********************************************************************/
1251 /* Utility functions to manage arrays and their contents for expansion */
1253 /***********************************************************************/
1255 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1257 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1259 /* When NAME is a properly-formed array reference and a non-null argument SUBP
1260 is supplied, '[' and ']' that enclose the subscript are replaced by '\0',
1261 and the pointer to the subscript in NAME is assigned to *SUBP, so that NAME
1262 and SUBP can be later used as the array name and the subscript,
1263 respectively. When SUBP is the null pointer, the original string NAME will
1265 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1267 tokenize_array_reference (name
, flags
, subp
)
1273 int r
, len
, isassoc
, ssflags
;
1276 t
= mbschr (name
, '['); /* ] */
1281 r
= legal_identifier (name
);
1282 if (flags
& VA_NOEXPAND
) /* Don't waste a lookup if we don't need one */
1283 isassoc
= (entry
= find_variable (name
)) && assoc_p (entry
);
1289 if (isassoc
&& ((flags
& (VA_NOEXPAND
|VA_ONEWORD
)) == (VA_NOEXPAND
|VA_ONEWORD
)))
1290 len
= strlen (t
) - 1;
1293 if (flags
& VA_NOEXPAND
)
1295 len
= skipsubscript (t
, 0, ssflags
);
1298 /* Check for a properly-terminated non-null subscript. */
1299 len
= skipsubscript (t
, 0, 0); /* arithmetic expression */
1301 if (t
[len
] != ']' || len
== 1 || t
[len
+1] != '\0')
1305 /* Could check and allow subscripts consisting only of whitespace for
1306 existing associative arrays, using isassoc */
1307 for (r
= 1; r
< len
; r
++)
1308 if (whitespace (t
[r
]) == 0)
1311 return 0; /* Fail if the subscript contains only whitespaces. */
1316 t
[0] = t
[len
] = '\0';
1320 /* This allows blank subscripts */
1326 /* Return 1 if NAME is a properly-formed array reference v[sub]. */
1328 /* We need to reserve 1 for FLAGS, which we pass to skipsubscript. */
1330 valid_array_reference (name
, flags
)
1334 return tokenize_array_reference ((char *)name
, flags
, (char **)NULL
);
1337 /* Expand the array index beginning at S and extending LEN characters. */
1339 array_expand_index (var
, s
, len
, flags
)
1345 char *exp
, *t
, *savecmd
;
1349 exp
= (char *)xmalloc (len
);
1350 strncpy (exp
, s
, len
- 1);
1351 exp
[len
- 1] = '\0';
1352 #if 0 /* TAG: maybe bash-5.2 */
1353 if ((flags
& AV_NOEXPAND
) == 0)
1354 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1358 t
= expand_arith_string (exp
, Q_DOUBLE_QUOTES
|Q_ARITH
|Q_ARRAYSUB
); /* XXX - Q_ARRAYSUB for future use */
1360 savecmd
= this_command_name
;
1361 this_command_name
= (char *)NULL
;
1362 eflag
= (shell_compatibility_level
> 51) ? 0 : EXP_EXPANDED
;
1363 val
= evalexp (t
, eflag
, &expok
); /* XXX - was 0 but we expanded exp already */
1364 this_command_name
= savecmd
;
1370 set_exit_status (EXECUTION_FAILURE
);
1372 if (no_longjmp_on_fatal_error
)
1374 top_level_cleanup ();
1375 jump_to_top_level (DISCARD
);
1380 /* Return the name of the variable specified by S without any subscript.
1381 If SUBP is non-null, return a pointer to the start of the subscript
1382 in *SUBP. If LENP is non-null, the length of the subscript is returned
1383 in *LENP. This returns newly-allocated memory. */
1385 array_variable_name (s
, flags
, subp
, lenp
)
1392 int ind
, ni
, ssflags
;
1394 t
= mbschr (s
, '[');
1401 return ((char *)NULL
);
1404 if ((flags
& (AV_NOEXPAND
|AV_ONEWORD
)) == (AV_NOEXPAND
|AV_ONEWORD
))
1405 ni
= strlen (s
) - 1;
1409 if (flags
& AV_NOEXPAND
)
1411 ni
= skipsubscript (s
, ind
, ssflags
);
1413 if (ni
<= ind
+ 1 || s
[ni
] != ']')
1415 err_badarraysub (s
);
1420 return ((char *)NULL
);
1424 ret
= savestring (s
);
1435 /* Return the variable specified by S without any subscript. If SUBP is
1436 non-null, return a pointer to the start of the subscript in *SUBP.
1437 If LENP is non-null, the length of the subscript is returned in *LENP. */
1439 array_variable_part (s
, flags
, subp
, lenp
)
1448 t
= array_variable_name (s
, flags
, subp
, lenp
);
1450 return ((SHELL_VAR
*)NULL
);
1451 var
= find_variable (t
); /* XXX - handle namerefs here? */
1454 return var
; /* now return invisible variables; caller must handle */
1457 #define INDEX_ERROR() \
1461 err_badarraysub (var->name); \
1465 err_badarraysub (s); \
1466 t[-1] = '['; /* ] */\
1468 return ((char *)NULL); \
1472 /* Return a string containing the elements in the array and subscript
1473 described by S. If the subscript is * or @, obeys quoting rules akin
1474 to the expansion of $* and $@ including double quoting. If RTYPE
1475 is non-null it gets 1 if the array reference is name[*], 2 if the
1476 reference is name[@], and 0 otherwise. */
1478 array_value_internal (s
, quoted
, flags
, estatep
)
1481 array_eltstate_t
*estatep
;
1483 int len
, isassoc
, subtype
;
1486 char *retval
, *t
, *temp
;
1490 var
= array_variable_part (s
, flags
, &t
, &len
); /* XXX */
1492 /* Expand the index, even if the variable doesn't exist, in case side
1493 effects are needed, like ${w[i++]} where w is unset. */
1496 return (char *)NULL
;
1500 return ((char *)NULL
); /* error message already printed */
1502 isassoc
= var
&& assoc_p (var
);
1507 estatep
->value
= (char *)NULL
;
1509 /* Backwards compatibility: we only change the behavior of A[@] and A[*]
1510 for associative arrays, and the caller has to request it. */
1511 if ((isassoc
== 0 || (flags
& AV_ATSTARKEYS
) == 0) && ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
1514 estatep
->subtype
= (t
[0] == '*') ? 1 : 2;
1515 if ((flags
& AV_ALLOWALL
) == 0)
1517 err_badarraysub (s
);
1518 return ((char *)NULL
);
1520 else if (var
== 0 || value_cell (var
) == 0)
1521 return ((char *)NULL
);
1522 else if (invisible_p (var
))
1523 return ((char *)NULL
);
1524 else if (array_p (var
) == 0 && assoc_p (var
) == 0)
1527 estatep
->type
= ARRAY_SCALAR
;
1528 l
= add_string_to_list (value_cell (var
), (WORD_LIST
*)NULL
);
1530 else if (assoc_p (var
))
1533 estatep
->type
= ARRAY_ASSOC
;
1534 l
= assoc_to_word_list (assoc_cell (var
));
1535 if (l
== (WORD_LIST
*)NULL
)
1536 return ((char *)NULL
);
1541 estatep
->type
= ARRAY_INDEXED
;
1542 l
= array_to_word_list (array_cell (var
));
1543 if (l
== (WORD_LIST
*)NULL
)
1544 return ((char *) NULL
);
1547 /* Caller of array_value takes care of inspecting estatep->subtype and
1548 duplicating retval if subtype == 0, so this is not a memory leak */
1549 if (t
[0] == '*' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1551 temp
= string_list_dollar_star (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1552 retval
= quote_string (temp
);
1555 else /* ${name[@]} or unquoted ${name[*]} */
1556 retval
= string_list_dollar_at (l
, quoted
, (flags
& AV_ASSIGNRHS
) ? PF_ASSIGNRHS
: 0);
1563 estatep
->subtype
= 0;
1564 if (var
== 0 || array_p (var
) || assoc_p (var
) == 0)
1566 if ((flags
& AV_USEIND
) == 0 || estatep
== 0)
1568 ind
= array_expand_index (var
, t
, len
, flags
);
1571 /* negative subscripts to indexed arrays count back from end */
1572 if (var
&& array_p (var
))
1573 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
1580 else if (estatep
&& (flags
& AV_USEIND
))
1583 estatep
->type
= array_p (var
) ? ARRAY_INDEXED
: ARRAY_SCALAR
;
1585 else if (assoc_p (var
))
1589 estatep
->type
= ARRAY_ASSOC
;
1590 if ((flags
& AV_USEIND
) && estatep
&& estatep
->key
)
1591 akey
= savestring (estatep
->key
);
1592 else if ((flags
& AV_NOEXPAND
) == 0)
1593 akey
= expand_subscript_string (t
, 0); /* [ */
1595 akey
= savestring (t
);
1597 if (akey
== 0 || *akey
== 0)
1604 if (var
== 0 || value_cell (var
) == 0)
1607 return ((char *)NULL
);
1609 else if (invisible_p (var
))
1612 return ((char *)NULL
);
1614 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1615 retval
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
1616 else if (assoc_p (var
))
1618 retval
= assoc_reference (assoc_cell (var
), akey
);
1619 if (estatep
&& estatep
->key
&& (flags
& AV_USEIND
))
1620 free (akey
); /* duplicated estatep->key */
1622 estatep
->key
= akey
; /* XXX - caller must manage */
1623 else /* not saving it anywhere */
1627 retval
= array_reference (array_cell (var
), ind
);
1630 estatep
->value
= retval
;
1636 /* Return a string containing the elements described by the array and
1637 subscript contained in S, obeying quoting for subscripts * and @. */
1639 array_value (s
, quoted
, flags
, estatep
)
1642 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 (s
, flags
, estatep
)
1658 array_eltstate_t
*estatep
;
1662 retval
= array_value_internal (s
, 0, flags
, estatep
);
1667 array_keys (s
, quoted
, pflags
)
1672 char *retval
, *t
, *temp
;
1676 var
= array_variable_part (s
, 0, &t
, &len
);
1679 if (var
== 0 || ALL_ELEMENT_SUB (t
[0]) == 0 || t
[1] != ']')
1680 return (char *)NULL
;
1682 if (var_isset (var
) == 0 || invisible_p (var
))
1683 return (char *)NULL
;
1685 if (array_p (var
) == 0 && assoc_p (var
) == 0)
1686 l
= add_string_to_list ("0", (WORD_LIST
*)NULL
);
1687 else if (assoc_p (var
))
1688 l
= assoc_keys_to_word_list (assoc_cell (var
));
1690 l
= array_keys_to_word_list (array_cell (var
));
1691 if (l
== (WORD_LIST
*)NULL
)
1692 return ((char *) NULL
);
1694 retval
= string_list_pos_params (t
[0], l
, quoted
, pflags
);
1699 #endif /* ARRAY_VARS */