1 /* subst.c -- The part of the shell that does parameter, command, arithmetic,
2 and globbing substitutions. */
4 /* ``Have a little faith, there's magic in the night. You ain't a
5 beauty, but, hey, you're alright.'' */
7 /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
48 #include "execute_cmd.h"
52 #include "mailcheck.h"
56 #include "builtins/getopt.h"
57 #include "builtins/common.h"
59 #include "builtins/builtext.h"
61 #include <tilde/tilde.h>
62 #include <glob/strmatch.h>
68 /* The size that strings change by. */
69 #define DEFAULT_INITIAL_ARRAY_SIZE 112
70 #define DEFAULT_ARRAY_SIZE 128
76 #define VT_ARRAYMEMBER 3
79 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
81 /* Flags for quoted_strchr */
82 #define ST_BACKSL 0x01
83 #define ST_CTLESC 0x02
84 #define ST_SQUOTE 0x04 /* unused yet */
85 #define ST_DQUOTE 0x08 /* unused yet */
87 /* Flags for the `pflags' argument to param_expand() */
88 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
89 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
90 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
92 /* These defs make it easier to use the editor. */
98 #if defined (HANDLE_MULTIBYTE)
103 /* Evaluates to 1 if C is one of the shell's special parameters whose length
104 can be taken, but is also one of the special expansion characters. */
105 #define VALID_SPECIAL_LENGTH_PARAM(c) \
106 ((c) == '-' || (c) == '?' || (c) == '#')
108 /* Evaluates to 1 if C is one of the shell's special parameters for which an
109 indirect variable reference may be made. */
110 #define VALID_INDIR_PARAM(c) \
111 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
113 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
114 in ${parameter[:]OPword}. */
115 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
117 /* Evaluates to 1 if this is one of the shell's special variables. */
118 #define SPECIAL_VAR(name, wi) \
119 ((DIGIT (*name) && all_digits (name)) || \
120 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
121 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
123 /* An expansion function that takes a string and a quoted flag and returns
124 a WORD_LIST *. Used as the type of the third argument to
125 expand_string_if_necessary(). */
126 typedef WORD_LIST *EXPFUNC __P((char *, int));
128 /* Process ID of the last command executed within command substitution. */
129 pid_t last_command_subst_pid = NO_PID;
130 pid_t current_command_subst_pid = NO_PID;
132 /* Variables used to keep track of the characters in IFS. */
135 unsigned char ifs_cmap[UCHAR_MAX + 1];
137 #if defined (HANDLE_MULTIBYTE)
138 unsigned char ifs_firstc[MB_LEN_MAX];
139 size_t ifs_firstc_len;
141 unsigned char ifs_firstc;
144 /* Sentinel to tell when we are performing variable assignments preceding a
145 command name and putting them into the environment. Used to make sure
146 we use the temporary environment when looking up variable values. */
147 int assigning_in_environment;
149 /* Used to hold a list of variable assignments preceding a command. Global
150 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
151 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
152 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
154 /* Extern functions and variables from different files. */
155 extern int last_command_exit_value, last_command_exit_signal;
156 extern int subshell_environment, line_number;
157 extern int subshell_level, parse_and_execute_level, sourcelevel;
158 extern int eof_encountered;
159 extern int return_catch_flag, return_catch_value;
160 extern pid_t dollar_dollar_pid;
161 extern int posixly_correct;
162 extern char *this_command_name;
163 extern struct fd_bitmap *current_fds_to_close;
164 extern int wordexp_only;
165 extern int expanding_redir;
166 extern int tempenv_assign_error;
168 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
169 extern wchar_t *wcsdup __P((const wchar_t *));
172 /* Non-zero means to allow unmatched globbed filenames to expand to
174 int allow_null_glob_expansion;
176 /* Non-zero means to throw an error when globbing fails to match anything. */
177 int fail_glob_expansion;
180 /* Variables to keep track of which words in an expanded word list (the
181 output of expand_word_list_internal) are the result of globbing
182 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
183 (CURRENTLY UNUSED). */
184 char *glob_argv_flags;
185 static int glob_argv_flags_size;
188 static WORD_LIST expand_word_error, expand_word_fatal;
189 static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
190 static char expand_param_error, expand_param_fatal;
191 static char extract_string_error, extract_string_fatal;
193 /* Tell the expansion functions to not longjmp back to top_level on fatal
194 errors. Enabled when doing completion and prompt string expansion. */
195 static int no_longjmp_on_fatal_error = 0;
197 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
198 $* on $IFS, primarily when doing assignment statements. */
199 static int expand_no_split_dollar_star = 0;
201 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
202 without any leading variable assignments. */
203 static WORD_LIST *garglist = (WORD_LIST *)NULL;
205 static char *quoted_substring __P((char *, int, int));
206 static int quoted_strlen __P((char *));
207 static char *quoted_strchr __P((char *, int, int));
209 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
210 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
211 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
212 static WORD_LIST *expand_string_internal __P((char *, int));
213 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
214 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
216 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
217 static char *make_quoted_char __P((int));
218 static WORD_LIST *quote_list __P((WORD_LIST *));
220 static int unquoted_substring __P((char *, char *));
221 static int unquoted_member __P((int, char *));
223 #if defined (ARRAY_VARS)
224 static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
226 static int do_assignment_internal __P((const WORD_DESC *, int));
228 static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
229 static char *string_extract __P((char *, int *, char *, int));
230 static char *string_extract_double_quoted __P((char *, int *, int));
231 static inline char *string_extract_single_quoted __P((char *, int *));
232 static inline int skip_single_quoted __P((const char *, size_t, int));
233 static int skip_double_quoted __P((char *, size_t, int));
234 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
235 static char *extract_dollar_brace_string __P((char *, int *, int, int));
236 static int skip_matched_pair __P((const char *, int, int, int, int));
238 static char *pos_params __P((char *, int, int, int));
240 static unsigned char *mb_getcharlens __P((char *, int));
242 static char *remove_upattern __P((char *, char *, int));
243 #if defined (HANDLE_MULTIBYTE)
244 static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
246 static char *remove_pattern __P((char *, char *, int));
248 static int match_upattern __P((char *, char *, int, char **, char **));
249 #if defined (HANDLE_MULTIBYTE)
250 static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
252 static int match_pattern __P((char *, char *, int, char **, char **));
253 static int getpatspec __P((int, char *));
254 static char *getpattern __P((char *, int, int));
255 static char *variable_remove_pattern __P((char *, char *, int, int));
256 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
257 static char *parameter_list_remove_pattern __P((int, char *, int, int));
259 static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
261 static char *parameter_brace_remove_pattern __P((char *, char *, int, char *, int, int, int));
263 static char *process_substitute __P((char *, int));
265 static char *read_comsub __P((int, int, int *));
268 static arrayind_t array_length_reference __P((char *));
271 static int valid_brace_expansion_word __P((char *, int));
272 static int chk_atstar __P((char *, int, int *, int *));
273 static int chk_arithsub __P((const char *, int));
275 static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int, arrayind_t *));
276 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
277 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
278 static void parameter_brace_expand_error __P((char *, char *));
280 static int valid_length_expression __P((char *));
281 static intmax_t parameter_brace_expand_length __P((char *));
283 static char *skiparith __P((char *, int));
284 static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
285 static int get_var_and_type __P((char *, char *, arrayind_t, int, int, SHELL_VAR **, char **));
286 static char *mb_substring __P((char *, int, int));
287 static char *parameter_brace_substring __P((char *, char *, int, char *, int, int));
289 static int shouldexp_replacement __P((char *));
291 static char *pos_params_pat_subst __P((char *, char *, char *, int));
293 static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int));
295 static char *pos_params_casemod __P((char *, char *, int, int));
296 static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int));
298 static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
299 static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
301 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
303 static WORD_LIST *word_list_split __P((WORD_LIST *));
305 static void exp_jump_to_top_level __P((int));
307 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
308 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
309 #ifdef BRACE_EXPANSION
310 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
312 #if defined (ARRAY_VARS)
313 static int make_internal_declare __P((char *, char *));
315 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
316 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
318 /* **************************************************************** */
320 /* Utility Functions */
322 /* **************************************************************** */
326 dump_word_flags (flags)
332 fprintf (stderr, "%d -> ", f);
333 if (f & W_ASSIGNASSOC)
336 fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
341 fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
346 fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
351 fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
353 if (f & W_HASQUOTEDNULL)
355 f &= ~W_HASQUOTEDNULL;
356 fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
361 fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
366 fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
368 if (f & W_COMPASSIGN)
371 fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
376 fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
381 fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
386 fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
391 fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
396 fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
398 if (f & W_DOLLARSTAR)
401 fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
406 fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
411 fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
416 fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
421 fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
426 fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
431 fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
433 if (f & W_ASSIGNMENT)
436 fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
441 fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
446 fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
448 fprintf (stderr, "\n");
453 #ifdef INCLUDE_UNUSED
455 quoted_substring (string, start, end)
460 register char *result, *s, *r;
464 /* Move to string[start], skipping quoted characters. */
465 for (s = string, l = 0; *s && l < start; )
477 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
479 /* Copy LEN characters, including quote characters. */
481 for (l = 0; l < len; s++)
495 #ifdef INCLUDE_UNUSED
496 /* Return the length of S, skipping over quoted characters */
520 /* Find the first occurrence of character C in string S, obeying shell
521 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
522 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
523 escaped with CTLESC are skipped. */
525 quoted_strchr (s, c, flags)
533 if (((flags & ST_BACKSL) && *p == '\\')
534 || ((flags & ST_CTLESC) && *p == CTLESC))
538 return ((char *)NULL);
544 return ((char *)NULL);
547 /* Return 1 if CHARACTER appears in an unquoted portion of
548 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
550 unquoted_member (character, string)
558 slen = strlen (string);
560 while (c = string[sindex])
568 ADVANCE_CHAR (string, slen, sindex);
574 ADVANCE_CHAR (string, slen, sindex);
578 sindex = skip_single_quoted (string, slen, ++sindex);
582 sindex = skip_double_quoted (string, slen, ++sindex);
589 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
591 unquoted_substring (substr, string)
592 char *substr, *string;
595 int sindex, c, sublen;
598 if (substr == 0 || *substr == '\0')
601 slen = strlen (string);
602 sublen = strlen (substr);
603 for (sindex = 0; c = string[sindex]; )
605 if (STREQN (string + sindex, substr, sublen))
613 ADVANCE_CHAR (string, slen, sindex);
617 sindex = skip_single_quoted (string, slen, ++sindex);
621 sindex = skip_double_quoted (string, slen, ++sindex);
625 ADVANCE_CHAR (string, slen, sindex);
632 /* Most of the substitutions must be done in parallel. In order
633 to avoid using tons of unclear goto's, I have some functions
634 for manipulating malloc'ed strings. They all take INDX, a
635 pointer to an integer which is the offset into the string
636 where manipulation is taking place. They also take SIZE, a
637 pointer to an integer which is the current length of the
638 character array for this string. */
640 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
641 of space allocated to TARGET. SOURCE can be NULL, in which
642 case nothing happens. Gets rid of SOURCE by freeing it.
643 Returns TARGET in case the location has changed. */
645 sub_append_string (source, target, indx, size)
646 char *source, *target;
653 srclen = STRLEN (source);
654 if (srclen >= (int)(*size - *indx))
657 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
658 target = (char *)xrealloc (target, (*size = n));
661 FASTCOPY (source, target + *indx, srclen);
663 target[*indx] = '\0';
672 /* Append the textual representation of NUMBER to TARGET.
673 INDX and SIZE are as in SUB_APPEND_STRING. */
675 sub_append_number (number, target, indx, size)
682 temp = itos (number);
683 return (sub_append_string (temp, target, indx, size));
687 /* Extract a substring from STRING, starting at SINDEX and ending with
688 one of the characters in CHARLIST. Don't make the ending character
689 part of the string. Leave SINDEX pointing at the ending character.
690 Understand about backslashes in the string. If (flags & SX_VARNAME)
691 is non-zero, and array variables have been compiled into the shell,
692 everything between a `[' and a corresponding `]' is skipped over.
693 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
694 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
695 contain a closing character from CHARLIST. */
697 string_extract (string, sindex, charlist, flags)
709 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
712 while (c = string[i])
721 #if defined (ARRAY_VARS)
722 else if ((flags & SX_VARNAME) && c == '[')
725 /* If this is an array subscript, skip over it and continue. */
726 ni = skipsubscript (string, i, 0);
727 if (string[ni] == ']')
731 else if (MEMBER (c, charlist))
737 ADVANCE_CHAR (string, slen, i);
740 /* If we had to have a matching delimiter and didn't find one, return an
741 error and let the caller deal with it. */
742 if ((flags & SX_REQMATCH) && found == 0)
745 return (&extract_string_error);
748 temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
754 /* Extract the contents of STRING as if it is enclosed in double quotes.
755 SINDEX, when passed in, is the offset of the character immediately
756 following the opening double quote; on exit, SINDEX is left pointing after
757 the closing double quote. If STRIPDQ is non-zero, unquoted double
758 quotes are stripped and the string is terminated by a null byte.
759 Backslashes between the embedded double quotes are processed. If STRIPDQ
760 is zero, an unquoted `"' terminates the string. */
762 string_extract_double_quoted (string, sindex, stripdq)
764 int *sindex, stripdq;
770 char *temp, *ret; /* The new string we return. */
771 int pass_next, backquote, si; /* State variables for the machine. */
775 slen = strlen (string + *sindex) + *sindex;
776 send = string + slen;
778 pass_next = backquote = dquote = 0;
779 temp = (char *)xmalloc (1 + slen - *sindex);
783 while (c = string[i])
785 /* Process a character that was quoted by a backslash. */
788 /* XXX - take another look at this in light of Interp 221 */
791 ``The backslash shall retain its special meaning as an escape
792 character only when followed by one of the characters:
795 If STRIPDQ is zero, we handle the double quotes here and let
796 expand_word_internal handle the rest. If STRIPDQ is non-zero,
797 we have already been through one round of backslash stripping,
798 and want to strip these backslashes only if DQUOTE is non-zero,
799 indicating that we are inside an embedded double-quoted string. */
801 /* If we are in an embedded quoted string, then don't strip
802 backslashes before characters for which the backslash
803 retains its special meaning, but remove backslashes in
804 front of other characters. If we are not in an
805 embedded quoted string, don't strip backslashes at all.
806 This mess is necessary because the string was already
807 surrounded by double quotes (and sh has some really weird
809 The returned string will be run through expansion as if
810 it were double-quoted. */
811 if ((stripdq == 0 && c != '"') ||
812 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
817 COPY_CHAR_I (temp, j, string, send, i);
821 /* A backslash protects the next character. The code just above
822 handles preserving the backslash in front of any character but
831 /* Inside backquotes, ``the portion of the quoted string from the
832 initial backquote and the characters up to the next backquote
833 that is not preceded by a backslash, having escape characters
834 removed, defines that command''. */
852 /* Pass everything between `$(' and the matching `)' or a quoted
853 ${ ... } pair through according to the Posix.2 specification. */
854 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
859 if (string[i + 1] == LPAREN)
860 ret = extract_command_subst (string, &si, 0);
862 ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, 0);
865 temp[j++] = string[i + 1];
867 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
869 if (ret == 0 && no_longjmp_on_fatal_error)
872 ret = string + i + 2;
875 for (t = 0; ret[t]; t++, j++)
877 temp[j] = string[si];
892 /* Add any character but a double quote to the quoted string we're
895 goto add_one_character;
909 /* Point to after the closing quote. */
917 /* This should really be another option to string_extract_double_quoted. */
919 skip_double_quoted (string, slen, sind)
926 int pass_next, backquote, si;
929 pass_next = backquote = 0;
931 while (c = string[i])
936 ADVANCE_CHAR (string, slen, i);
949 ADVANCE_CHAR (string, slen, i);
958 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
961 if (string[i + 1] == LPAREN)
962 ret = extract_command_subst (string, &si, SX_NOALLOC);
964 ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, SX_NOALLOC);
971 ADVANCE_CHAR (string, slen, i);
984 /* Extract the contents of STRING as if it is enclosed in single quotes.
985 SINDEX, when passed in, is the offset of the character immediately
986 following the opening single quote; on exit, SINDEX is left pointing after
987 the closing single quote. */
989 string_extract_single_quoted (string, sindex)
998 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
999 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
1001 while (string[i] && string[i] != '\'')
1002 ADVANCE_CHAR (string, slen, i);
1004 t = substring (string, *sindex, i);
1014 skip_single_quoted (string, slen, sind)
1023 while (string[c] && string[c] != '\'')
1024 ADVANCE_CHAR (string, slen, c);
1031 /* Just like string_extract, but doesn't hack backslashes or any of
1032 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1034 string_extract_verbatim (string, slen, sindex, charlist, flags)
1042 #if defined (HANDLE_MULTIBYTE)
1050 if (charlist[0] == '\'' && charlist[1] == '\0')
1052 temp = string_extract_single_quoted (string, sindex);
1053 --*sindex; /* leave *sindex at separator character */
1059 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1060 this only if MB_CUR_MAX > 1. */
1061 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
1063 #if defined (HANDLE_MULTIBYTE)
1064 clen = strlen (charlist);
1067 while (c = string[i])
1069 #if defined (HANDLE_MULTIBYTE)
1072 if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
1077 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1078 through, to protect the CTLNULs from later calls to
1079 remove_quoted_nulls. */
1080 else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
1086 #if defined (HANDLE_MULTIBYTE)
1087 mblength = MBLEN (string + i, slen - i);
1091 mblength = mbtowc (&wc, string + i, slen - i);
1092 if (MB_INVALIDCH (mblength))
1094 if (MEMBER (c, charlist))
1102 len = mbstowcs (wcharlist, charlist, 0);
1105 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
1106 mbstowcs (wcharlist, charlist, len + 1);
1109 if (wcschr (wcharlist, wc))
1115 if (MEMBER (c, charlist))
1118 ADVANCE_CHAR (string, slen, i);
1121 #if defined (HANDLE_MULTIBYTE)
1125 temp = substring (string, *sindex, i);
1131 /* Extract the $( construct in STRING, and return a new string.
1132 Start extracting at (SINDEX) as if we had just seen "$(".
1133 Make (SINDEX) get the position of the matching ")". )
1134 XFLAGS is additional flags to pass to other extraction functions. */
1136 extract_command_subst (string, sindex, xflags)
1141 if (string[*sindex] == LPAREN)
1142 return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
1145 xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
1146 return (xparse_dolparen (string, string+*sindex, sindex, xflags));
1150 /* Extract the $[ construct in STRING, and return a new string. (])
1151 Start extracting at (SINDEX) as if we had just seen "$[".
1152 Make (SINDEX) get the position of the matching "]". */
1154 extract_arithmetic_subst (string, sindex)
1158 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
1161 #if defined (PROCESS_SUBSTITUTION)
1162 /* Extract the <( or >( construct in STRING, and return a new string.
1163 Start extracting at (SINDEX) as if we had just seen "<(".
1164 Make (SINDEX) get the position of the matching ")". */ /*))*/
1166 extract_process_subst (string, starter, sindex)
1171 return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
1173 #endif /* PROCESS_SUBSTITUTION */
1175 #if defined (ARRAY_VARS)
1176 /* This can be fooled by unquoted right parens in the passed string. If
1177 each caller verifies that the last character in STRING is a right paren,
1178 we don't even need to call extract_delimited_string. */
1180 extract_array_assignment_list (string, sindex)
1187 slen = strlen (string); /* ( */
1188 if (string[slen - 1] == ')')
1190 ret = substring (string, *sindex, slen - 1);
1198 /* Extract and create a new string from the contents of STRING, a
1199 character string delimited with OPENER and CLOSER. SINDEX is
1200 the address of an int describing the current offset in STRING;
1201 it should point to just after the first OPENER found. On exit,
1202 SINDEX gets the position of the last character of the matching CLOSER.
1203 If OPENER is more than a single character, ALT_OPENER, if non-null,
1204 contains a character string that can also match CLOSER and thus
1205 needs to be skipped. */
1207 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
1210 char *opener, *alt_opener, *closer;
1216 int pass_character, nesting_level, in_comment;
1217 int len_closer, len_opener, len_alt_opener;
1220 slen = strlen (string + *sindex) + *sindex;
1221 len_opener = STRLEN (opener);
1222 len_alt_opener = STRLEN (alt_opener);
1223 len_closer = STRLEN (closer);
1225 pass_character = in_comment = 0;
1230 while (nesting_level)
1241 ADVANCE_CHAR (string, slen, i);
1245 if (pass_character) /* previous char was backslash */
1248 ADVANCE_CHAR (string, slen, i);
1252 /* Not exactly right yet; should handle shell metacharacters and
1253 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1254 if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
1257 ADVANCE_CHAR (string, slen, i);
1261 if (c == CTLESC || c == '\\')
1268 /* Process a nested command substitution, but only if we're parsing an
1269 arithmetic substitution. */
1270 if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
1273 t = extract_command_subst (string, &si, flags|SX_NOALLOC);
1278 /* Process a nested OPENER. */
1279 if (STREQN (string + i, opener, len_opener))
1281 si = i + len_opener;
1282 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
1287 /* Process a nested ALT_OPENER */
1288 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1290 si = i + len_alt_opener;
1291 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
1296 /* If the current substring terminates the delimited string, decrement
1297 the nesting level. */
1298 if (STREQN (string + i, closer, len_closer))
1300 i += len_closer - 1; /* move to last byte of the closer */
1302 if (nesting_level == 0)
1306 /* Pass old-style command substitution through verbatim. */
1310 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1315 /* Pass single-quoted and double-quoted strings through verbatim. */
1316 if (c == '\'' || c == '"')
1319 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1320 : skip_double_quoted (string, slen, si);
1324 /* move past this character, which was not special. */
1325 ADVANCE_CHAR (string, slen, i);
1328 if (c == 0 && nesting_level)
1330 if (no_longjmp_on_fatal_error == 0)
1332 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1333 last_command_exit_value = EXECUTION_FAILURE;
1334 exp_jump_to_top_level (DISCARD);
1339 return (char *)NULL;
1343 si = i - *sindex - len_closer + 1;
1344 if (flags & SX_NOALLOC)
1345 result = (char *)NULL;
1348 result = (char *)xmalloc (1 + si);
1349 strncpy (result, string + *sindex, si);
1357 /* Extract a parameter expansion expression within ${ and } from STRING.
1358 Obey the Posix.2 rules for finding the ending `}': count braces while
1359 skipping over enclosed quoted strings and command substitutions.
1360 SINDEX is the address of an int describing the current offset in STRING;
1361 it should point to just after the first `{' found. On exit, SINDEX
1362 gets the position of the matching `}'. QUOTED is non-zero if this
1363 occurs inside double quotes. */
1364 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1366 extract_dollar_brace_string (string, sindex, quoted, flags)
1368 int *sindex, quoted, flags;
1372 int pass_character, nesting_level, si, dolbrace_state;
1378 slen = strlen (string + *sindex) + *sindex;
1380 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1381 parse_matched_pair() */
1383 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1384 dolbrace_state = (flags & SX_POSIXEXP) ? DOLBRACE_QUOTE : DOLBRACE_PARAM;
1387 while (c = string[i])
1392 ADVANCE_CHAR (string, slen, i);
1396 /* CTLESCs and backslashes quote the next character. */
1397 if (c == CTLESC || c == '\\')
1404 if (string[i] == '$' && string[i+1] == LBRACE)
1414 if (nesting_level == 0)
1420 /* Pass the contents of old-style command substitutions through
1425 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1430 /* Pass the contents of new-style command substitutions and
1431 arithmetic substitutions through verbatim. */
1432 if (string[i] == '$' && string[i+1] == LPAREN)
1435 t = extract_command_subst (string, &si, flags|SX_NOALLOC);
1441 /* Pass the contents of single-quoted and double-quoted strings
1442 through verbatim. */
1443 if (c == '\'' || c == '"')
1446 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1447 : skip_double_quoted (string, slen, si);
1448 /* skip_XXX_quoted leaves index one past close quote */
1451 #else /* XXX - bash-4.2 */
1452 /* Pass the contents of double-quoted strings through verbatim. */
1456 i = skip_double_quoted (string, slen, si);
1457 /* skip_XXX_quoted leaves index one past close quote */
1463 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1464 if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE)
1465 ADVANCE_CHAR (string, slen, i);
1469 i = skip_single_quoted (string, slen, si);
1476 /* move past this character, which was not special. */
1477 ADVANCE_CHAR (string, slen, i);
1479 /* This logic must agree with parse.y:parse_matched_pair, since they
1480 share the same defines. */
1481 if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1)
1482 dolbrace_state = DOLBRACE_QUOTE;
1483 else if (dolbrace_state == DOLBRACE_PARAM && c == '#' && (i - *sindex) > 1)
1484 dolbrace_state = DOLBRACE_QUOTE;
1485 else if (dolbrace_state == DOLBRACE_PARAM && c == '/' && (i - *sindex) > 1)
1486 dolbrace_state = DOLBRACE_QUOTE;
1487 else if (dolbrace_state == DOLBRACE_PARAM && c == '^' && (i - *sindex) > 1)
1488 dolbrace_state = DOLBRACE_QUOTE;
1489 else if (dolbrace_state == DOLBRACE_PARAM && c == ',' && (i - *sindex) > 1)
1490 dolbrace_state = DOLBRACE_QUOTE;
1491 else if (dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", c) != 0)
1492 dolbrace_state = DOLBRACE_OP;
1493 else if (dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", c) == 0)
1494 dolbrace_state = DOLBRACE_WORD;
1497 if (c == 0 && nesting_level)
1499 if (no_longjmp_on_fatal_error == 0)
1501 report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1502 last_command_exit_value = EXECUTION_FAILURE;
1503 exp_jump_to_top_level (DISCARD);
1508 return ((char *)NULL);
1512 result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1518 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1519 STRING, and returns a pointer to it. */
1521 de_backslash (string)
1524 register size_t slen;
1525 register int i, j, prev_i;
1528 slen = strlen (string);
1531 /* Loop copying string[i] to string[j], i >= j. */
1534 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1535 string[i + 1] == '$'))
1538 ADVANCE_CHAR (string, slen, i);
1540 do string[j++] = string[prev_i++]; while (prev_i < i);
1551 /* Replace instances of \! in a string with !. */
1553 unquote_bang (string)
1557 register char *temp;
1559 temp = (char *)xmalloc (1 + strlen (string));
1561 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1563 if (string[i] == '\\' && string[i + 1] == '!')
1569 strcpy (string, temp);
1574 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1576 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1577 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1578 matched pairs of quotes or backquotes, or skip word expansions; it is
1579 intended to be used after expansion has been performed and during final
1580 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1582 skip_matched_pair (string, start, open, close, flags)
1584 int start, open, close, flags;
1586 int i, pass_next, backq, si, c, count;
1591 slen = strlen (string + start) + start;
1592 no_longjmp_on_fatal_error = 1;
1594 i = start + 1; /* skip over leading bracket */
1596 pass_next = backq = 0;
1597 ss = (char *)string;
1598 while (c = string[i])
1605 ADVANCE_CHAR (string, slen, i);
1618 ADVANCE_CHAR (string, slen, i);
1621 else if ((flags & 1) == 0 && c == '`')
1627 else if ((flags & 1) == 0 && c == open)
1633 else if (c == close)
1641 else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
1643 i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
1644 : skip_double_quoted (ss, slen, ++i);
1645 /* no increment, the skip functions increment past the closing quote. */
1647 else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1650 if (string[si] == '\0')
1653 if (string[i+1] == LPAREN)
1654 temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1656 temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
1658 if (string[i] == '\0') /* don't increment i past EOS in loop */
1664 ADVANCE_CHAR (string, slen, i);
1670 #if defined (ARRAY_VARS)
1672 skipsubscript (string, start, flags)
1676 return (skip_matched_pair (string, start, '[', ']', flags));
1680 /* Skip characters in STRING until we find a character in DELIMS, and return
1681 the index of that character. START is the index into string at which we
1682 begin. This is similar in spirit to strpbrk, but it returns an index into
1683 STRING and takes a starting index. This little piece of code knows quite
1684 a lot of shell syntax. It's very similar to skip_double_quoted and other
1685 functions of that ilk. */
1687 skip_to_delim (string, start, delims, flags)
1693 int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
1698 slen = strlen (string + start) + start;
1699 if (flags & SD_NOJMP)
1700 no_longjmp_on_fatal_error = 1;
1701 invert = (flags & SD_INVERT);
1702 skipcmd = (flags & SD_NOSKIPCMD) == 0;
1705 pass_next = backq = 0;
1706 while (c = string[i])
1708 /* If this is non-zero, we should not let quote characters be delimiters
1709 and the current character is a single or double quote. We should not
1710 test whether or not it's a delimiter until after we skip single- or
1711 double-quoted strings. */
1712 skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
1718 ADVANCE_CHAR (string, slen, i);
1731 ADVANCE_CHAR (string, slen, i);
1740 else if (skipquote == 0 && invert == 0 && member (c, delims))
1742 else if (c == '\'' || c == '"')
1744 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1745 : skip_double_quoted (string, slen, ++i);
1746 /* no increment, the skip functions increment past the closing quote. */
1748 else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
1751 if (string[si] == '\0')
1754 if (string[i+1] == LPAREN)
1755 temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1757 temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
1759 if (string[i] == '\0') /* don't increment i past EOS in loop */
1764 #if defined (PROCESS_SUBSTITUTION)
1765 else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
1768 if (string[si] == '\0')
1770 temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
1772 if (string[i] == '\0')
1777 #endif /* PROCESS_SUBSTITUTION */
1778 else if ((skipquote || invert) && (member (c, delims) == 0))
1781 ADVANCE_CHAR (string, slen, i);
1787 #if defined (READLINE)
1788 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1789 an unclosed quoted string), or if the character at EINDEX is quoted
1790 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1791 single and double-quoted string parsing functions should not return an
1792 error if there are unclosed quotes or braces. The characters that this
1793 recognizes need to be the same as the contents of
1794 rl_completer_quote_characters. */
1797 char_is_quoted (string, eindex)
1801 int i, pass_next, c;
1805 slen = strlen (string);
1806 no_longjmp_on_fatal_error = 1;
1815 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1817 ADVANCE_CHAR (string, slen, i);
1826 else if (c == '\'' || c == '"')
1828 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1829 : skip_double_quoted (string, slen, ++i);
1832 /* no increment, the skip_xxx functions go one past end */
1835 ADVANCE_CHAR (string, slen, i);
1842 unclosed_pair (string, eindex, openstr)
1847 int i, pass_next, openc, olen;
1851 slen = strlen (string);
1852 olen = strlen (openstr);
1853 i = pass_next = openc = 0;
1859 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1861 ADVANCE_CHAR (string, slen, i);
1864 else if (string[i] == '\\')
1870 else if (STREQN (string + i, openstr, olen))
1875 else if (string[i] == '\'' || string[i] == '"')
1877 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1878 : skip_double_quoted (string, slen, i);
1883 ADVANCE_CHAR (string, slen, i);
1888 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1889 individual words. If DELIMS is NULL, the current value of $IFS is used
1890 to split the string, and the function follows the shell field splitting
1891 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1892 gets the number of words in the returned list. CWP, if non-NULL, gets
1893 the index of the word containing SENTINEL. Non-whitespace chars in
1894 DELIMS delimit separate fields. */
1896 split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
1900 int sentinel, flags;
1903 int ts, te, i, nw, cw, ifs_split, dflags;
1904 char *token, *d, *d2;
1905 WORD_LIST *ret, *tl;
1907 if (string == 0 || *string == '\0')
1913 return ((WORD_LIST *)NULL);
1916 d = (delims == 0) ? ifs_value : delims;
1917 ifs_split = delims == 0;
1919 /* Make d2 the non-whitespace characters in delims */
1924 #if defined (HANDLE_MULTIBYTE)
1925 size_t mblength = 1;
1929 slength = strlen (delims);
1930 d2 = (char *)xmalloc (slength + 1);
1934 #if defined (HANDLE_MULTIBYTE)
1935 mbstate_t state_bak;
1937 mblength = MBRLEN (delims + i, slength, &state);
1938 if (MB_INVALIDCH (mblength))
1940 else if (mblength > 1)
1942 memcpy (d2 + ts, delims + i, mblength);
1945 slength -= mblength;
1949 if (whitespace (delims[i]) == 0)
1950 d2[ts++] = delims[i];
1958 ret = (WORD_LIST *)NULL;
1960 /* Remove sequences of whitespace characters at the start of the string, as
1961 long as those characters are delimiters. */
1962 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1964 if (string[i] == '\0')
1970 dflags = flags|SD_NOJMP;
1973 te = skip_to_delim (string, ts, d, dflags);
1975 /* If we have a non-whitespace delimiter character, use it to make a
1976 separate field. This is just about what $IFS splitting does and
1977 is closer to the behavior of the shell parser. */
1978 if (ts == te && d2 && member (string[ts], d2))
1981 /* If we're using IFS splitting, the non-whitespace delimiter char
1982 and any additional IFS whitespace delimits a field. */
1984 while (member (string[te], d) && spctabnl (string[te]))
1987 while (member (string[te], d2))
1991 token = substring (string, ts, te);
1993 ret = add_string_to_list (token, ret);
1997 if (sentinel >= ts && sentinel <= te)
2000 /* If the cursor is at whitespace just before word start, set the
2001 sentinel word to the current word. */
2002 if (cwp && cw == -1 && sentinel == ts-1)
2005 /* If the cursor is at whitespace between two words, make a new, empty
2006 word, add it before (well, after, since the list is in reverse order)
2007 the word we just added, and set the current word to that one. */
2008 if (cwp && cw == -1 && sentinel < ts)
2010 tl = make_word_list (make_word (""), ret->next);
2016 if (string[te] == 0)
2020 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
2029 /* Special case for SENTINEL at the end of STRING. If we haven't found
2030 the word containing SENTINEL yet, and the index we're looking for is at
2031 the end of STRING (or past the end of the previously-found token,
2032 possible if the end of the line is composed solely of IFS whitespace)
2033 add an additional null argument and set the current word pointer to that. */
2034 if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
2036 if (whitespace (string[sentinel - 1]))
2039 ret = add_string_to_list (token, ret);
2050 return (REVERSE_LIST (ret, WORD_LIST *));
2052 #endif /* READLINE */
2056 /* Extract the name of the variable to bind to from the assignment string. */
2058 assignment_name (string)
2064 offset = assignment (string, 0);
2066 return (char *)NULL;
2067 temp = substring (string, 0, offset);
2072 /* **************************************************************** */
2074 /* Functions to convert strings to WORD_LISTs and vice versa */
2076 /* **************************************************************** */
2078 /* Return a single string of all the words in LIST. SEP is the separator
2079 to put between individual elements of LIST in the output string. */
2081 string_list_internal (list, sep)
2085 register WORD_LIST *t;
2087 int word_len, sep_len, result_size;
2090 return ((char *)NULL);
2092 /* Short-circuit quickly if we don't need to separate anything. */
2093 if (list->next == 0)
2094 return (savestring (list->word->word));
2096 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2097 sep_len = STRLEN (sep);
2100 for (t = list; t; t = t->next)
2103 result_size += sep_len;
2104 result_size += strlen (t->word->word);
2107 r = result = (char *)xmalloc (result_size + 1);
2109 for (t = list; t; t = t->next)
2111 if (t != list && sep_len)
2115 FASTCOPY (sep, r, sep_len);
2122 word_len = strlen (t->word->word);
2123 FASTCOPY (t->word->word, r, word_len);
2131 /* Return a single string of all the words present in LIST, separating
2132 each word with a space. */
2137 return (string_list_internal (list, " "));
2140 /* An external interface that can be used by the rest of the shell to
2141 obtain a string containing the first character in $IFS. Handles all
2142 the multibyte complications. If LENP is non-null, it is set to the
2143 length of the returned string. */
2145 ifs_firstchar (lenp)
2151 ret = xmalloc (MB_LEN_MAX + 1);
2152 #if defined (HANDLE_MULTIBYTE)
2153 if (ifs_firstc_len == 1)
2155 ret[0] = ifs_firstc[0];
2157 len = ret[0] ? 1 : 0;
2161 memcpy (ret, ifs_firstc, ifs_firstc_len);
2162 ret[len = ifs_firstc_len] = '\0';
2165 ret[0] = ifs_firstc;
2167 len = ret[0] ? 0 : 1;
2176 /* Return a single string of all the words present in LIST, obeying the
2177 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2178 expansion [of $*] appears within a double quoted string, it expands
2179 to a single field with the value of each parameter separated by the
2180 first character of the IFS variable, or by a <space> if IFS is unset." */
2182 string_list_dollar_star (list)
2186 #if defined (HANDLE_MULTIBYTE)
2187 # if defined (__GNUC__)
2188 char sep[MB_CUR_MAX + 1];
2196 #if defined (HANDLE_MULTIBYTE)
2197 # if !defined (__GNUC__)
2198 sep = (char *)xmalloc (MB_CUR_MAX + 1);
2199 # endif /* !__GNUC__ */
2200 if (ifs_firstc_len == 1)
2202 sep[0] = ifs_firstc[0];
2207 memcpy (sep, ifs_firstc, ifs_firstc_len);
2208 sep[ifs_firstc_len] = '\0';
2211 sep[0] = ifs_firstc;
2215 ret = string_list_internal (list, sep);
2216 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2222 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2223 is non-zero, the $@ appears within double quotes, and we should quote
2224 the list before converting it into a string. If IFS is unset, and the
2225 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2226 in the words in the list, because the default value of $IFS is
2227 <space><tab><newline>, IFS characters in the words in the list should
2228 also be split. If IFS is null, and the word is not quoted, we need
2229 to quote the words in the list to preserve the positional parameters
2232 string_list_dollar_at (list, quoted)
2237 #if defined (HANDLE_MULTIBYTE)
2238 # if defined (__GNUC__)
2239 char sep[MB_CUR_MAX + 1];
2242 # endif /* !__GNUC__ */
2248 /* XXX this could just be ifs = ifs_value; */
2249 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
2251 #if defined (HANDLE_MULTIBYTE)
2252 # if !defined (__GNUC__)
2253 sep = (char *)xmalloc (MB_CUR_MAX + 1);
2254 # endif /* !__GNUC__ */
2257 if (ifs_firstc_len == 1)
2259 sep[0] = ifs_firstc[0];
2264 memcpy (sep, ifs_firstc, ifs_firstc_len);
2265 sep[ifs_firstc_len] = '\0';
2274 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
2278 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2279 it now that quote_escapes quotes spaces */
2281 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
2283 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
2286 : list_quote_escapes (list);
2288 ret = string_list_internal (tlist, sep);
2289 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2295 /* Turn the positional paramters into a string, understanding quoting and
2296 the various subtleties of using the first character of $IFS as the
2297 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2298 string_list as appropriate. */
2300 string_list_pos_params (pchar, list, quoted)
2308 if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
2310 tlist = quote_list (list);
2311 word_list_remove_quoted_nulls (tlist);
2312 ret = string_list_dollar_star (tlist);
2314 else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
2316 tlist = quote_list (list);
2317 word_list_remove_quoted_nulls (tlist);
2318 ret = string_list (tlist);
2320 else if (pchar == '*')
2322 /* Even when unquoted, string_list_dollar_star does the right thing
2323 making sure that the first character of $IFS is used as the
2325 ret = string_list_dollar_star (list);
2327 else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
2328 /* We use string_list_dollar_at, but only if the string is quoted, since
2329 that quotes the escapes if it's not, which we don't want. We could
2330 use string_list (the old code did), but that doesn't do the right
2331 thing if the first character of $IFS is not a space. We use
2332 string_list_dollar_star if the string is unquoted so we make sure that
2333 the elements of $@ are separated by the first character of $IFS for
2335 ret = string_list_dollar_at (list, quoted);
2336 else if (pchar == '@')
2337 ret = string_list_dollar_star (list);
2339 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
2344 /* Return the list of words present in STRING. Separate the string into
2345 words at any of the characters found in SEPARATORS. If QUOTED is
2346 non-zero then word in the list will have its quoted flag set, otherwise
2347 the quoted flag is left as make_word () deemed fit.
2349 This obeys the P1003.2 word splitting semantics. If `separators' is
2350 exactly <space><tab><newline>, then the splitting algorithm is that of
2351 the Bourne shell, which treats any sequence of characters from `separators'
2352 as a delimiter. If IFS is unset, which results in `separators' being set
2353 to "", no splitting occurs. If separators has some other value, the
2354 following rules are applied (`IFS white space' means zero or more
2355 occurrences of <space>, <tab>, or <newline>, as long as those characters
2356 are in `separators'):
2358 1) IFS white space is ignored at the start and the end of the
2360 2) Each occurrence of a character in `separators' that is not
2361 IFS white space, along with any adjacent occurrences of
2362 IFS white space delimits a field.
2363 3) Any nonzero-length sequence of IFS white space delimits a field.
2366 /* BEWARE! list_string strips null arguments. Don't call it twice and
2367 expect to have "" preserved! */
2369 /* This performs word splitting and quoted null character removal on
2372 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2373 : (c) == (separators)[0]) \
2377 list_string (string, separators, quoted)
2378 register char *string, *separators;
2383 char *current_word, *s;
2384 int sindex, sh_style_split, whitesep, xflags;
2387 if (!string || !*string)
2388 return ((WORD_LIST *)NULL);
2390 sh_style_split = separators && separators[0] == ' ' &&
2391 separators[1] == '\t' &&
2392 separators[2] == '\n' &&
2393 separators[3] == '\0';
2394 for (xflags = 0, s = ifs_value; s && *s; s++)
2396 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2397 else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2401 /* Remove sequences of whitespace at the beginning of STRING, as
2402 long as those characters appear in IFS. Do not do this if
2403 STRING is quoted or if there are no separator characters. */
2404 if (!quoted || !separators || !*separators)
2406 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
2409 return ((WORD_LIST *)NULL);
2414 /* OK, now STRING points to a word that does not begin with white space.
2415 The splitting algorithm is:
2416 extract a word, stopping at a separator
2417 skip sequences of spc, tab, or nl as long as they are separators
2418 This obeys the field splitting rules in Posix.2. */
2419 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
2420 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
2422 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2423 unless multibyte chars are possible. */
2424 current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
2425 if (current_word == 0)
2428 /* If we have a quoted empty string, add a quoted null argument. We
2429 want to preserve the quoted null character iff this is a quoted
2430 empty string; otherwise the quoted null characters are removed
2432 if (QUOTED_NULL (current_word))
2434 t = alloc_word_desc ();
2435 t->word = make_quoted_char ('\0');
2436 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2437 result = make_word_list (t, result);
2439 else if (current_word[0] != '\0')
2441 /* If we have something, then add it regardless. However,
2442 perform quoted null character removal on the current word. */
2443 remove_quoted_nulls (current_word);
2444 result = add_string_to_list (current_word, result);
2445 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
2446 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
2447 result->word->flags |= W_QUOTED;
2450 /* If we're not doing sequences of separators in the traditional
2451 Bourne shell style, then add a quoted null argument. */
2452 else if (!sh_style_split && !spctabnl (string[sindex]))
2454 t = alloc_word_desc ();
2455 t->word = make_quoted_char ('\0');
2456 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2457 result = make_word_list (t, result);
2460 free (current_word);
2462 /* Note whether or not the separator is IFS whitespace, used later. */
2463 whitesep = string[sindex] && spctabnl (string[sindex]);
2465 /* Move past the current separator character. */
2469 ADVANCE_CHAR (string, slen, sindex);
2472 /* Now skip sequences of space, tab, or newline characters if they are
2473 in the list of separators. */
2474 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
2477 /* If the first separator was IFS whitespace and the current character
2478 is a non-whitespace IFS character, it should be part of the current
2479 field delimiter, not a separate delimiter that would result in an
2480 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2481 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
2484 /* An IFS character that is not IFS white space, along with any
2485 adjacent IFS white space, shall delimit a field. (SUSv3) */
2486 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
2490 return (REVERSE_LIST (result, WORD_LIST *));
2493 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2494 ENDPTR is set to the first character after the word. This is used by
2495 the `read' builtin. This is never called with SEPARATORS != $IFS;
2496 it should be simplified.
2498 XXX - this function is very similar to list_string; they should be
2501 get_word_from_string (stringp, separators, endptr)
2502 char **stringp, *separators, **endptr;
2506 int sindex, sh_style_split, whitesep, xflags;
2509 if (!stringp || !*stringp || !**stringp)
2510 return ((char *)NULL);
2512 sh_style_split = separators && separators[0] == ' ' &&
2513 separators[1] == '\t' &&
2514 separators[2] == '\n' &&
2515 separators[3] == '\0';
2516 for (xflags = 0, s = ifs_value; s && *s; s++)
2518 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2519 if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2525 /* Remove sequences of whitespace at the beginning of STRING, as
2526 long as those characters appear in IFS. */
2527 if (sh_style_split || !separators || !*separators)
2529 for (; *s && spctabnl (*s) && isifs (*s); s++);
2531 /* If the string is nothing but whitespace, update it and return. */
2537 return ((char *)NULL);
2541 /* OK, S points to a word that does not begin with white space.
2542 Now extract a word, stopping at a separator, save a pointer to
2543 the first character after the word, then skip sequences of spc,
2544 tab, or nl as long as they are separators.
2546 This obeys the field splitting rules in Posix.2. */
2548 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2549 unless multibyte chars are possible. */
2550 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
2551 current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
2553 /* Set ENDPTR to the first character after the end of the word. */
2555 *endptr = s + sindex;
2557 /* Note whether or not the separator is IFS whitespace, used later. */
2558 whitesep = s[sindex] && spctabnl (s[sindex]);
2560 /* Move past the current separator character. */
2564 ADVANCE_CHAR (s, slen, sindex);
2567 /* Now skip sequences of space, tab, or newline characters if they are
2568 in the list of separators. */
2569 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2572 /* If the first separator was IFS whitespace and the current character is
2573 a non-whitespace IFS character, it should be part of the current field
2574 delimiter, not a separate delimiter that would result in an empty field.
2575 Look at POSIX.2, 3.6.5, (3)(b). */
2576 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
2579 /* An IFS character that is not IFS white space, along with any adjacent
2580 IFS white space, shall delimit a field. */
2581 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2585 /* Update STRING to point to the next field. */
2586 *stringp = s + sindex;
2587 return (current_word);
2590 /* Remove IFS white space at the end of STRING. Start at the end
2591 of the string and walk backwards until the beginning of the string
2592 or we find a character that's not IFS white space and not CTLESC.
2593 Only let CTLESC escape a white space character if SAW_ESCAPE is
2596 strip_trailing_ifs_whitespace (string, separators, saw_escape)
2597 char *string, *separators;
2602 s = string + STRLEN (string) - 1;
2603 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
2604 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
2612 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2613 backslashes, single and double quotes. */
2615 list_string_with_quotes (string)
2621 int c, i, tokstart, len;
2623 for (s = string; s && *s && spctabnl (*s); s++)
2625 if (s == 0 || *s == 0)
2626 return ((WORD_LIST *)NULL);
2630 list = (WORD_LIST *)NULL;
2641 i = skip_single_quoted (s, s_len, ++i);
2643 i = skip_double_quoted (s, s_len, ++i);
2644 else if (c == 0 || spctabnl (c))
2646 /* We have found the end of a token. Make a word out of it and
2647 add it to the word list. */
2648 token = substring (s, tokstart, i);
2649 list = add_string_to_list (token, list);
2651 while (spctabnl (s[i]))
2659 i++; /* normal character */
2661 return (REVERSE_LIST (list, WORD_LIST *));
2665 /********************************************************/
2667 /* Functions to perform assignment statements */
2669 /********************************************************/
2671 #if defined (ARRAY_VARS)
2673 do_compound_assignment (name, value, flags)
2678 int mklocal, mkassoc;
2681 mklocal = flags & ASS_MKLOCAL;
2682 mkassoc = flags & ASS_MKASSOC;
2684 if (mklocal && variable_context)
2686 v = find_variable (name);
2687 list = expand_compound_array_assignment (v, value, flags);
2689 v = make_local_assoc_variable (name);
2690 else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
2691 v = make_local_array_variable (name);
2692 assign_compound_array_list (v, list, flags);
2695 v = assign_array_from_string (name, value, flags);
2701 /* Given STRING, an assignment string, get the value of the right side
2702 of the `=', and bind it to the left side. If EXPAND is true, then
2703 perform parameter expansion, command substitution, and arithmetic
2704 expansion on the right-hand side. Perform tilde expansion in any
2705 case. Do not perform word splitting on the result of expansion. */
2707 do_assignment_internal (word, expand)
2708 const WORD_DESC *word;
2711 int offset, appendop, assign_list, aflags, retval;
2712 char *name, *value, *temp;
2714 #if defined (ARRAY_VARS)
2720 if (word == 0 || word->word == 0)
2723 appendop = assign_list = aflags = 0;
2724 string = word->word;
2725 offset = assignment (string, 0);
2726 name = savestring (string);
2727 value = (char *)NULL;
2729 if (name[offset] == '=')
2731 if (name[offset - 1] == '+')
2734 name[offset - 1] = '\0';
2737 name[offset] = 0; /* might need this set later */
2738 temp = name + offset + 1;
2740 #if defined (ARRAY_VARS)
2741 if (expand && (word->flags & W_COMPASSIGN))
2743 assign_list = ni = 1;
2744 value = extract_array_assignment_list (temp, &ni);
2748 if (expand && temp[0])
2749 value = expand_string_if_necessary (temp, 0, expand_string_assignment);
2751 value = savestring (temp);
2756 value = (char *)xmalloc (1);
2760 if (echo_command_at_execute)
2763 name[offset - 1] = '+';
2764 xtrace_print_assignment (name, value, assign_list, 1);
2766 name[offset - 1] = '\0';
2769 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2772 aflags |= ASS_APPEND;
2774 #if defined (ARRAY_VARS)
2775 if (t = mbschr (name, '[')) /*]*/
2779 report_error (_("%s: cannot assign list to array member"), name);
2782 entry = assign_array_element (name, value, aflags);
2786 else if (assign_list)
2788 if (word->flags & W_ASSIGNARG)
2789 aflags |= ASS_MKLOCAL;
2790 if (word->flags & W_ASSIGNASSOC)
2791 aflags |= ASS_MKASSOC;
2792 entry = do_compound_assignment (name, value, aflags);
2795 #endif /* ARRAY_VARS */
2796 entry = bind_variable (name, value, aflags);
2798 stupidly_hack_special_variables (name);
2801 /* Return 1 if the assignment seems to have been performed correctly. */
2802 if (entry == 0 || readonly_p (entry))
2803 retval = 0; /* assignment failure */
2804 else if (noassign_p (entry))
2806 last_command_exit_value = EXECUTION_FAILURE;
2807 retval = 1; /* error status, but not assignment failure */
2812 if (entry && retval != 0 && noassign_p (entry) == 0)
2813 VUNSETATTR (entry, att_invisible);
2815 ASSIGN_RETURN (retval);
2818 VUNSETATTR (entry, att_invisible);
2820 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
2824 /* Perform the assignment statement in STRING, and expand the
2825 right side by doing tilde, command and parameter expansion. */
2827 do_assignment (string)
2832 td.flags = W_ASSIGNMENT;
2835 return do_assignment_internal (&td, 1);
2839 do_word_assignment (word)
2842 return do_assignment_internal (word, 1);
2845 /* Given STRING, an assignment string, get the value of the right side
2846 of the `=', and bind it to the left side. Do not perform any word
2847 expansions on the right hand side. */
2849 do_assignment_no_expand (string)
2854 td.flags = W_ASSIGNMENT;
2857 return (do_assignment_internal (&td, 0));
2860 /***************************************************
2862 * Functions to manage the positional parameters *
2864 ***************************************************/
2866 /* Return the word list that corresponds to `$*'. */
2868 list_rest_of_args ()
2870 register WORD_LIST *list, *args;
2873 /* Break out of the loop as soon as one of the dollar variables is null. */
2874 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2875 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2877 for (args = rest_of_args; args; args = args->next)
2878 list = make_word_list (make_bare_word (args->word->word), list);
2880 return (REVERSE_LIST (list, WORD_LIST *));
2886 register WORD_LIST *list;
2889 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2891 for (list = rest_of_args; list; list = list->next)
2896 /* Return the value of a positional parameter. This handles values > 10. */
2898 get_dollar_var_value (ind)
2905 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2906 else /* We want something like ${11} */
2909 for (p = rest_of_args; p && ind--; p = p->next)
2911 temp = p ? savestring (p->word->word) : (char *)NULL;
2916 /* Make a single large string out of the dollar digit variables,
2917 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2918 case of "$*" with respect to IFS. */
2920 string_rest_of_args (dollar_star)
2923 register WORD_LIST *list;
2926 list = list_rest_of_args ();
2927 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2928 dispose_words (list);
2932 /* Return a string containing the positional parameters from START to
2933 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2934 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2935 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2936 no quoting chars are added. */
2938 pos_params (string, start, end, quoted)
2940 int start, end, quoted;
2942 WORD_LIST *save, *params, *h, *t;
2946 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2948 return ((char *)NULL);
2950 save = params = list_rest_of_args ();
2952 return ((char *)NULL);
2954 if (start == 0) /* handle ${@:0[:x]} specially */
2956 t = make_word_list (make_word (dollar_vars[0]), params);
2960 for (i = start ? 1 : 0; params && i < start; i++)
2961 params = params->next;
2963 return ((char *)NULL);
2964 for (h = t = params; params && i < end; i++)
2967 params = params->next;
2970 t->next = (WORD_LIST *)NULL;
2972 ret = string_list_pos_params (string[0], h, quoted);
2977 dispose_words (save);
2981 /******************************************************************/
2983 /* Functions to expand strings to strings or WORD_LISTs */
2985 /******************************************************************/
2987 #if defined (PROCESS_SUBSTITUTION)
2988 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2990 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2993 /* If there are any characters in STRING that require full expansion,
2994 then call FUNC to expand STRING; otherwise just perform quote
2995 removal if necessary. This returns a new string. */
2997 expand_string_if_necessary (string, quoted, func)
3008 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3009 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
3013 if (EXP_CHAR (string[i]))
3015 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
3017 ADVANCE_CHAR (string, slen, i);
3022 list = (*func) (string, quoted);
3025 ret = string_list (list);
3026 dispose_words (list);
3031 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
3032 ret = string_quote_removal (string, quoted);
3034 ret = savestring (string);
3039 static inline char *
3040 expand_string_to_string_internal (string, quoted, func)
3048 if (string == 0 || *string == '\0')
3049 return ((char *)NULL);
3051 list = (*func) (string, quoted);
3054 ret = string_list (list);
3055 dispose_words (list);
3064 expand_string_to_string (string, quoted)
3068 return (expand_string_to_string_internal (string, quoted, expand_string));
3072 expand_string_unsplit_to_string (string, quoted)
3076 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
3080 expand_assignment_string_to_string (string, quoted)
3084 return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
3088 expand_arith_string (string, quoted)
3092 return (expand_string_if_necessary (string, quoted, expand_string));
3095 #if defined (COND_COMMAND)
3096 /* Just remove backslashes in STRING. Returns a new string. */
3098 remove_backslashes (string)
3103 r = ret = (char *)xmalloc (strlen (string) + 1);
3104 for (s = string; s && *s; )
3116 /* This needs better error handling. */
3117 /* Expand W for use as an argument to a unary or binary operator in a
3118 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3119 to the != or == operator, and should be treated as a pattern. In
3120 this case, we quote the string specially for the globbing code. If
3121 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3122 be quoted appropriately for regcomp/regexec. The caller is responsible
3123 for removing the backslashes if the unquoted word is needed later. */
3125 cond_expand_word (w, special)
3133 if (w->word == 0 || w->word[0] == '\0')
3134 return ((char *)NULL);
3136 w->flags |= W_NOSPLIT2;
3137 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
3143 r = string_list (l);
3147 qflags = QGLOB_CVTNULL;
3149 qflags |= QGLOB_REGEXP;
3150 p = string_list (l);
3151 r = quote_string_for_globbing (p, qflags);
3163 /* Call expand_word_internal to expand W and handle error returns.
3164 A convenience function for functions that don't want to handle
3165 any errors or free any memory before aborting. */
3167 call_expand_word_internal (w, q, i, c, e)
3173 result = expand_word_internal (w, q, i, c, e);
3174 if (result == &expand_word_error || result == &expand_word_fatal)
3176 /* By convention, each time this error is returned, w->word has
3177 already been freed (it sometimes may not be in the fatal case,
3178 but that doesn't result in a memory leak because we're going
3179 to exit in most cases). */
3180 w->word = (char *)NULL;
3181 last_command_exit_value = EXECUTION_FAILURE;
3182 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
3189 /* Perform parameter expansion, command substitution, and arithmetic
3190 expansion on STRING, as if it were a word. Leave the result quoted. */
3192 expand_string_internal (string, quoted)
3199 if (string == 0 || *string == 0)
3200 return ((WORD_LIST *)NULL);
3203 td.word = savestring (string);
3205 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3211 /* Expand STRING by performing parameter expansion, command substitution,
3212 and arithmetic expansion. Dequote the resulting WORD_LIST before
3213 returning it, but do not perform word splitting. The call to
3214 remove_quoted_nulls () is in here because word splitting normally
3215 takes care of quote removal. */
3217 expand_string_unsplit (string, quoted)
3223 if (string == 0 || *string == '\0')
3224 return ((WORD_LIST *)NULL);
3226 expand_no_split_dollar_star = 1;
3227 value = expand_string_internal (string, quoted);
3228 expand_no_split_dollar_star = 0;
3234 remove_quoted_nulls (value->word->word);
3235 value->word->flags &= ~W_HASQUOTEDNULL;
3237 dequote_list (value);
3242 /* Expand the rhs of an assignment statement */
3244 expand_string_assignment (string, quoted)
3251 if (string == 0 || *string == '\0')
3252 return ((WORD_LIST *)NULL);
3254 expand_no_split_dollar_star = 1;
3256 td.flags = W_ASSIGNRHS;
3257 td.word = savestring (string);
3258 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3261 expand_no_split_dollar_star = 0;
3267 remove_quoted_nulls (value->word->word);
3268 value->word->flags &= ~W_HASQUOTEDNULL;
3270 dequote_list (value);
3276 /* Expand one of the PS? prompt strings. This is a sort of combination of
3277 expand_string_unsplit and expand_string_internal, but returns the
3278 passed string when an error occurs. Might want to trap other calls
3279 to jump_to_top_level here so we don't endlessly loop. */
3281 expand_prompt_string (string, quoted, wflags)
3289 if (string == 0 || *string == 0)
3290 return ((WORD_LIST *)NULL);
3293 td.word = savestring (string);
3295 no_longjmp_on_fatal_error = 1;
3296 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3297 no_longjmp_on_fatal_error = 0;
3299 if (value == &expand_word_error || value == &expand_word_fatal)
3301 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
3309 remove_quoted_nulls (value->word->word);
3310 value->word->flags &= ~W_HASQUOTEDNULL;
3312 dequote_list (value);
3317 /* Expand STRING just as if you were expanding a word, but do not dequote
3318 the resultant WORD_LIST. This is called only from within this file,
3319 and is used to correctly preserve quoted characters when expanding
3320 things like ${1+"$@"}. This does parameter expansion, command
3321 substitution, arithmetic expansion, and word splitting. */
3323 expand_string_leave_quoted (string, quoted)
3330 if (string == 0 || *string == '\0')
3331 return ((WORD_LIST *)NULL);
3333 tlist = expand_string_internal (string, quoted);
3337 tresult = word_list_split (tlist);
3338 dispose_words (tlist);
3341 return ((WORD_LIST *)NULL);
3344 /* This does not perform word splitting or dequote the WORD_LIST
3347 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
3349 int quoted, *dollar_at_p, *has_dollar_at;
3354 if (string == 0 || *string == '\0')
3355 return (WORD_LIST *)NULL;
3359 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
3363 /* Expand STRING just as if you were expanding a word. This also returns
3364 a list of words. Note that filename globbing is *NOT* done for word
3365 or string expansion, just when the shell is expanding a command. This
3366 does parameter expansion, command substitution, arithmetic expansion,
3367 and word splitting. Dequote the resultant WORD_LIST before returning. */
3369 expand_string (string, quoted)
3375 if (string == 0 || *string == '\0')
3376 return ((WORD_LIST *)NULL);
3378 result = expand_string_leave_quoted (string, quoted);
3379 return (result ? dequote_list (result) : result);
3382 /***************************************************
3384 * Functions to handle quoting chars *
3386 ***************************************************/
3390 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3391 The parser passes CTLNUL as CTLESC CTLNUL. */
3393 /* Quote escape characters in string s, but no other characters. This is
3394 used to protect CTLESC and CTLNUL in variable values from the rest of
3395 the word expansion process after the variable is expanded (word splitting
3396 and filename generation). If IFS is null, we quote spaces as well, just
3397 in case we split on spaces later (in the case of unquoted $@, we will
3398 eventually attempt to split the entire word on spaces). Corresponding
3399 code exists in dequote_escapes. Even if we don't end up splitting on
3400 spaces, quoting spaces is not a problem. This should never be called on
3401 a string that is quoted with single or double quotes or part of a here
3402 document (effectively double-quoted). */
3404 quote_escapes (string)
3407 register char *s, *t;
3409 char *result, *send;
3410 int quote_spaces, skip_ctlesc, skip_ctlnul;
3413 slen = strlen (string);
3414 send = string + slen;
3416 quote_spaces = (ifs_value && *ifs_value == 0);
3418 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
3419 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
3421 t = result = (char *)xmalloc ((slen * 2) + 1);
3426 if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
3428 COPY_CHAR_P (t, s, send);
3435 list_quote_escapes (list)
3438 register WORD_LIST *w;
3441 for (w = list; w; w = w->next)
3444 w->word->word = quote_escapes (t);
3450 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3452 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3453 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3454 data stream pass through properly.
3456 We need to remove doubled CTLESC characters inside quoted strings before
3457 quoting the entire string, so we do not double the number of CTLESC
3460 Also used by parts of the pattern substitution code. */
3462 dequote_escapes (string)
3465 register char *s, *t, *s1;
3467 char *result, *send;
3474 slen = strlen (string);
3475 send = string + slen;
3477 t = result = (char *)xmalloc (slen + 1);
3479 if (strchr (string, CTLESC) == 0)
3480 return (strcpy (result, string));
3482 quote_spaces = (ifs_value && *ifs_value == 0);
3487 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
3493 COPY_CHAR_P (t, s, send);
3499 /* Return a new string with the quoted representation of character C.
3500 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3501 set in any resultant WORD_DESC where this value is the word. */
3503 make_quoted_char (c)
3508 temp = (char *)xmalloc (3);
3523 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3524 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3525 this value is the word. */
3527 quote_string (string)
3532 char *result, *send;
3536 result = (char *)xmalloc (2);
3544 slen = strlen (string);
3545 send = string + slen;
3547 result = (char *)xmalloc ((slen * 2) + 1);
3549 for (t = result; string < send; )
3552 COPY_CHAR_P (t, string, send);
3559 /* De-quote quoted characters in STRING. */
3561 dequote_string (string)
3564 register char *s, *t;
3566 char *result, *send;
3569 slen = strlen (string);
3571 t = result = (char *)xmalloc (slen + 1);
3573 if (QUOTED_NULL (string))
3579 /* If no character in the string can be quoted, don't bother examining
3580 each character. Just return a copy of the string passed to us. */
3581 if (strchr (string, CTLESC) == NULL)
3582 return (strcpy (result, string));
3584 send = string + slen;
3594 COPY_CHAR_P (t, s, send);
3601 /* Quote the entire WORD_LIST list. */
3606 register WORD_LIST *w;
3609 for (w = list; w; w = w->next)
3612 w->word->word = quote_string (t);
3614 w->word->flags |= W_HASQUOTEDNULL; /* XXX - turn on W_HASQUOTEDNULL here? */
3615 w->word->flags |= W_QUOTED;
3621 /* De-quote quoted characters in each word in LIST. */
3627 register WORD_LIST *tlist;
3629 for (tlist = list; tlist; tlist = tlist->next)
3631 s = dequote_string (tlist->word->word);
3632 if (QUOTED_NULL (tlist->word->word))
3633 tlist->word->flags &= ~W_HASQUOTEDNULL;
3634 free (tlist->word->word);
3635 tlist->word->word = s;
3640 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3643 remove_quoted_escapes (string)
3650 t = dequote_escapes (string);
3658 /* Perform quoted null character removal on STRING. We don't allow any
3659 quoted null characters in the middle or at the ends of strings because
3660 of how expand_word_internal works. remove_quoted_nulls () turns
3661 STRING into an empty string iff it only consists of a quoted null,
3662 and removes all unquoted CTLNUL characters. */
3664 remove_quoted_nulls (string)
3667 register size_t slen;
3668 register int i, j, prev_i;
3671 if (strchr (string, CTLNUL) == 0) /* XXX */
3672 return string; /* XXX */
3674 slen = strlen (string);
3679 if (string[i] == CTLESC)
3681 /* Old code had j++, but we cannot assume that i == j at this
3682 point -- what if a CTLNUL has already been removed from the
3683 string? We don't want to drop the CTLESC or recopy characters
3684 that we've already copied down. */
3685 i++; string[j++] = CTLESC;
3689 else if (string[i] == CTLNUL)
3693 ADVANCE_CHAR (string, slen, i);
3696 do string[j++] = string[prev_i++]; while (prev_i < i);
3706 /* Perform quoted null character removal on each element of LIST.
3707 This modifies LIST. */
3709 word_list_remove_quoted_nulls (list)
3712 register WORD_LIST *t;
3714 for (t = list; t; t = t->next)
3716 remove_quoted_nulls (t->word->word);
3717 t->word->flags &= ~W_HASQUOTEDNULL;
3721 /* **************************************************************** */
3723 /* Functions for Matching and Removing Patterns */
3725 /* **************************************************************** */
3727 #if defined (HANDLE_MULTIBYTE)
3728 #if 0 /* Currently unused */
3729 static unsigned char *
3730 mb_getcharlens (string, len)
3734 int i, offset, last;
3741 ret = (unsigned char *)xmalloc (len);
3742 memset (ret, 0, len);
3743 while (string[last])
3745 ADVANCE_CHAR (string, len, offset);
3746 ret[last] = offset - last;
3754 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3755 can have one of 4 values:
3756 RP_LONG_LEFT remove longest matching portion at start of PARAM
3757 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3758 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3759 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3762 #define RP_LONG_LEFT 1
3763 #define RP_SHORT_LEFT 2
3764 #define RP_LONG_RIGHT 3
3765 #define RP_SHORT_RIGHT 4
3767 /* Returns its first argument if nothing matched; new memory otherwise */
3769 remove_upattern (param, pattern, op)
3770 char *param, *pattern;
3775 register char *p, *ret, c;
3777 len = STRLEN (param);
3782 case RP_LONG_LEFT: /* remove longest match at start */
3783 for (p = end; p >= param; p--)
3786 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3789 return (savestring (p));
3796 case RP_SHORT_LEFT: /* remove shortest match at start */
3797 for (p = param; p <= end; p++)
3800 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3803 return (savestring (p));
3809 case RP_LONG_RIGHT: /* remove longest match at end */
3810 for (p = param; p <= end; p++)
3812 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3815 ret = savestring (param);
3822 case RP_SHORT_RIGHT: /* remove shortest match at end */
3823 for (p = end; p >= param; p--)
3825 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3828 ret = savestring (param);
3836 return (param); /* no match, return original string */
3839 #if defined (HANDLE_MULTIBYTE)
3840 /* Returns its first argument if nothing matched; new memory otherwise */
3842 remove_wpattern (wparam, wstrlen, wpattern, op)
3853 case RP_LONG_LEFT: /* remove longest match at start */
3854 for (n = wstrlen; n >= 0; n--)
3856 wc = wparam[n]; wparam[n] = L'\0';
3857 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3860 return (wcsdup (wparam + n));
3866 case RP_SHORT_LEFT: /* remove shortest match at start */
3867 for (n = 0; n <= wstrlen; n++)
3869 wc = wparam[n]; wparam[n] = L'\0';
3870 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3873 return (wcsdup (wparam + n));
3879 case RP_LONG_RIGHT: /* remove longest match at end */
3880 for (n = 0; n <= wstrlen; n++)
3882 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3884 wc = wparam[n]; wparam[n] = L'\0';
3885 ret = wcsdup (wparam);
3892 case RP_SHORT_RIGHT: /* remove shortest match at end */
3893 for (n = wstrlen; n >= 0; n--)
3895 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3897 wc = wparam[n]; wparam[n] = L'\0';
3898 ret = wcsdup (wparam);
3906 return (wparam); /* no match, return original string */
3908 #endif /* HANDLE_MULTIBYTE */
3911 remove_pattern (param, pattern, op)
3912 char *param, *pattern;
3919 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3920 return (savestring (param));
3922 #if defined (HANDLE_MULTIBYTE)
3925 wchar_t *ret, *oret;
3927 wchar_t *wparam, *wpattern;
3930 n = xdupmbstowcs (&wpattern, NULL, pattern);
3931 if (n == (size_t)-1)
3933 xret = remove_upattern (param, pattern, op);
3934 return ((xret == param) ? savestring (param) : xret);
3936 n = xdupmbstowcs (&wparam, NULL, param);
3937 if (n == (size_t)-1)
3940 xret = remove_upattern (param, pattern, op);
3941 return ((xret == param) ? savestring (param) : xret);
3943 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3944 /* Don't bother to convert wparam back to multibyte string if nothing
3945 matched; just return copy of original string */
3950 return (savestring (param));
3957 xret = (char *)xmalloc (n + 1);
3958 memset (&ps, '\0', sizeof (mbstate_t));
3959 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3960 xret[n] = '\0'; /* just to make sure */
3967 xret = remove_upattern (param, pattern, op);
3968 return ((xret == param) ? savestring (param) : xret);
3972 /* Match PAT anywhere in STRING and return the match boundaries.
3973 This returns 1 in case of a successful match, 0 otherwise. SP
3974 and EP are pointers into the string where the match begins and
3975 ends, respectively. MTYPE controls what kind of match is attempted.
3976 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3977 of the string, respectively. The longest match is returned. */
3979 match_upattern (string, pat, mtype, sp, ep)
3985 register char *p, *p1, *npat;
3988 /* If the pattern doesn't match anywhere in the string, go ahead and
3989 short-circuit right away. A minor optimization, saves a bunch of
3990 unnecessary calls to strmatch (up to N calls for a string of N
3991 characters) if the match is unsuccessful. To preserve the semantics
3992 of the substring matches below, we make sure that the pattern has
3993 `*' as first and last character, making a new pattern if necessary. */
3994 /* XXX - check this later if I ever implement `**' with special meaning,
3995 since this will potentially result in `**' at the beginning or end */
3997 if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
3999 p = npat = (char *)xmalloc (len + 3);
4001 if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
4005 if (p1[-1] != '*' || p[-2] == '\\')
4011 c = strmatch (npat, string, FNMATCH_EXTFLAG);
4014 if (c == FNM_NOMATCH)
4017 len = STRLEN (string);
4020 mlen = umatchlen (pat, len);
4025 for (p = string; p <= end; p++)
4027 if (match_pattern_char (pat, p))
4030 for (p1 = end; p1 >= p; p1--)
4032 p1 = (mlen == -1) ? end : p + mlen;
4033 /* extra -1 to handle case of p1 == end */
4034 if (p1 - p + mlen - 1 > len)
4036 for ( ; p1 >= p; p1--)
4039 c = *p1; *p1 = '\0';
4040 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
4049 /* If MLEN != -1, we have a fixed length pattern. */
4060 if (match_pattern_char (pat, string) == 0)
4064 for (p = end; p >= string; p--)
4066 for (p = (mlen == -1) ? end : string + mlen; p >= string; p--)
4070 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
4079 /* If MLEN != -1, we have a fixed length pattern. */
4089 for (p = string; p <= end; p++)
4091 for (p = end - ((mlen == -1) ? len : mlen); p <= end; p++)
4094 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
4101 /* If MLEN != -1, we have a fixed length pattern. */
4113 #if defined (HANDLE_MULTIBYTE)
4114 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4115 This returns 1 in case of a successful match, 0 otherwise. Wide
4116 character version. */
4118 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
4126 wchar_t wc, *wp, *nwpat, *wp1;
4131 /* If the pattern doesn't match anywhere in the string, go ahead and
4132 short-circuit right away. A minor optimization, saves a bunch of
4133 unnecessary calls to strmatch (up to N calls for a string of N
4134 characters) if the match is unsuccessful. To preserve the semantics
4135 of the substring matches below, we make sure that the pattern has
4136 `*' as first and last character, making a new pattern if necessary. */
4137 len = wcslen (wpat);
4138 if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
4140 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
4142 if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
4144 while (*wp1 != L'\0')
4146 if (wp1[-1] != L'*' || wp1[-2] == L'\\')
4152 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
4155 if (len == FNM_NOMATCH)
4158 mlen = wmatchlen (wpat, wstrlen);
4159 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4163 for (n = 0; n <= wstrlen; n++)
4165 if (match_pattern_wchar (wpat, wstring + n))
4168 for (n1 = wstrlen; n1 >= n; n1--)
4170 n1 = (mlen == -1) ? wstrlen : n + mlen;
4174 for ( ; n1 >= n; n1--)
4177 wc = wstring[n1]; wstring[n1] = L'\0';
4178 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
4187 /* If MLEN != -1, we have a fixed length pattern. */
4198 if (match_pattern_wchar (wpat, wstring) == 0)
4202 for (n = wstrlen; n >= 0; n--)
4204 for (n = (mlen == -1) ? wstrlen : mlen; n >= 0; n--)
4207 wc = wstring[n]; wstring[n] = L'\0';
4208 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
4217 /* If MLEN != -1, we have a fixed length pattern. */
4227 for (n = 0; n <= wstrlen; n++)
4229 for (n = wstrlen - ((mlen == -1) ? wstrlen : mlen); n <= wstrlen; n++)
4232 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
4235 *ep = indices[wstrlen];
4239 /* If MLEN != -1, we have a fixed length pattern. */
4250 #endif /* HANDLE_MULTIBYTE */
4253 match_pattern (string, pat, mtype, sp, ep)
4258 #if defined (HANDLE_MULTIBYTE)
4261 wchar_t *wstring, *wpat;
4265 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
4268 #if defined (HANDLE_MULTIBYTE)
4271 n = xdupmbstowcs (&wpat, NULL, pat);
4272 if (n == (size_t)-1)
4273 return (match_upattern (string, pat, mtype, sp, ep));
4274 n = xdupmbstowcs (&wstring, &indices, string);
4275 if (n == (size_t)-1)
4278 return (match_upattern (string, pat, mtype, sp, ep));
4280 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
4290 return (match_upattern (string, pat, mtype, sp, ep));
4294 getpatspec (c, value)
4299 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
4301 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
4304 /* Posix.2 says that the WORD should be run through tilde expansion,
4305 parameter expansion, command substitution and arithmetic expansion.
4306 This leaves the result quoted, so quote_string_for_globbing () has
4307 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4308 it means that the entire expression was enclosed in double quotes.
4309 This means that quoting characters in the pattern do not make any
4310 special pattern characters quoted. For example, the `*' in the
4311 following retains its special meaning: "${foo#'*'}". */
4313 getpattern (value, quoted, expandpat)
4315 int quoted, expandpat;
4322 /* There is a problem here: how to handle single or double quotes in the
4323 pattern string when the whole expression is between double quotes?
4324 POSIX.2 says that enclosing double quotes do not cause the pattern to
4325 be quoted, but does that leave us a problem with @ and array[@] and their
4326 expansions inside a pattern? */
4328 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
4331 pat = string_extract_double_quoted (tword, &i, 1);
4337 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4339 l = *value ? expand_string_for_rhs (value,
4340 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
4341 (int *)NULL, (int *)NULL)
4343 pat = string_list (l);
4347 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
4355 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4356 or ${name#[#]value}. */
4358 variable_remove_pattern (value, pattern, patspec, quoted)
4359 char *value, *pattern;
4360 int patspec, quoted;
4364 tword = remove_pattern (value, pattern, patspec);
4371 list_remove_pattern (list, pattern, patspec, itype, quoted)
4374 int patspec, itype, quoted;
4380 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
4382 tword = remove_pattern (l->word->word, pattern, patspec);
4383 w = alloc_word_desc ();
4384 w->word = tword ? tword : savestring ("");
4385 new = make_word_list (w, new);
4388 l = REVERSE_LIST (new, WORD_LIST *);
4389 tword = string_list_pos_params (itype, l, quoted);
4396 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
4399 int patspec, quoted;
4404 list = list_rest_of_args ();
4406 return ((char *)NULL);
4407 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4408 dispose_words (list);
4412 #if defined (ARRAY_VARS)
4414 array_remove_pattern (var, pattern, patspec, varname, quoted)
4418 char *varname; /* so we can figure out how it's indexed */
4428 /* compute itype from varname here */
4429 v = array_variable_part (varname, &ret, 0);
4432 a = (v && array_p (v)) ? array_cell (v) : 0;
4433 h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
4435 list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
4437 return ((char *)NULL);
4438 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4439 dispose_words (list);
4443 #endif /* ARRAY_VARS */
4446 parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flags)
4447 char *varname, *value;
4450 int rtype, quoted, flags;
4452 int vtype, patspec, starsub;
4453 char *temp1, *val, *pattern;
4457 return ((char *)NULL);
4459 this_command_name = varname;
4461 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
4463 return ((char *)NULL);
4465 starsub = vtype & VT_STARSUB;
4466 vtype &= ~VT_STARSUB;
4468 patspec = getpatspec (rtype, patstr);
4469 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
4472 /* Need to pass getpattern newly-allocated memory in case of expansion --
4473 the expansion code will free the passed string on an error. */
4474 temp1 = savestring (patstr);
4475 pattern = getpattern (temp1, quoted, 1);
4478 temp1 = (char *)NULL; /* shut up gcc */
4482 case VT_ARRAYMEMBER:
4483 temp1 = remove_pattern (val, pattern, patspec);
4484 if (vtype == VT_VARIABLE)
4488 val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4489 ? quote_string (temp1)
4490 : quote_escapes (temp1);
4495 #if defined (ARRAY_VARS)
4497 temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
4498 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4500 val = quote_escapes (temp1);
4507 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
4508 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4510 val = quote_escapes (temp1);
4521 /*******************************************
4523 * Functions to expand WORD_DESCs *
4525 *******************************************/
4527 /* Expand WORD, performing word splitting on the result. This does
4528 parameter expansion, command substitution, arithmetic expansion,
4529 word splitting, and quote removal. */
4532 expand_word (word, quoted)
4536 WORD_LIST *result, *tresult;
4538 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4539 result = word_list_split (tresult);
4540 dispose_words (tresult);
4541 return (result ? dequote_list (result) : result);
4544 /* Expand WORD, but do not perform word splitting on the result. This
4545 does parameter expansion, command substitution, arithmetic expansion,
4546 and quote removal. */
4548 expand_word_unsplit (word, quoted)
4554 expand_no_split_dollar_star = 1;
4555 #if defined (HANDLE_MULTIBYTE)
4556 if (ifs_firstc[0] == 0)
4558 if (ifs_firstc == 0)
4560 word->flags |= W_NOSPLIT;
4561 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4562 expand_no_split_dollar_star = 0;
4564 return (result ? dequote_list (result) : result);
4567 /* Perform shell expansions on WORD, but do not perform word splitting or
4568 quote removal on the result. Virtually identical to expand_word_unsplit;
4569 could be combined if implementations don't diverge. */
4571 expand_word_leave_quoted (word, quoted)
4577 expand_no_split_dollar_star = 1;
4578 #if defined (HANDLE_MULTIBYTE)
4579 if (ifs_firstc[0] == 0)
4581 if (ifs_firstc == 0)
4583 word->flags |= W_NOSPLIT;
4584 word->flags |= W_NOSPLIT2;
4585 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4586 expand_no_split_dollar_star = 0;
4591 #if defined (PROCESS_SUBSTITUTION)
4593 /*****************************************************************/
4595 /* Hacking Process Substitution */
4597 /*****************************************************************/
4599 #if !defined (HAVE_DEV_FD)
4600 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4601 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4602 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4603 list. NFIFO is a count of the number of FIFOs in the list. */
4604 #define FIFO_INCR 20
4611 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
4613 static int fifo_list_size;
4616 copy_fifo_list (sizep)
4621 return (char *)NULL;
4625 add_fifo_list (pathname)
4628 if (nfifo >= fifo_list_size - 1)
4630 fifo_list_size += FIFO_INCR;
4631 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
4632 fifo_list_size * sizeof (struct temp_fifo));
4635 fifo_list[nfifo].file = savestring (pathname);
4643 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4645 unlink (fifo_list[i].file);
4646 free (fifo_list[i].file);
4647 fifo_list[i].file = (char *)NULL;
4648 fifo_list[i].proc = -1;
4660 for (i = saved = 0; i < nfifo; i++)
4662 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4664 unlink (fifo_list[i].file);
4665 free (fifo_list[i].file);
4666 fifo_list[i].file = (char *)NULL;
4667 fifo_list[i].proc = -1;
4673 /* If we didn't remove some of the FIFOs, compact the list. */
4676 for (i = j = 0; i < nfifo; i++)
4677 if (fifo_list[i].file)
4679 fifo_list[j].file = fifo_list[i].file;
4680 fifo_list[j].proc = fifo_list[i].proc;
4689 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4690 from some point in the past, and close all open FIFOs in fifo_list
4691 that are not marked as active in LIST. If LIST is NULL, close
4692 everything in fifo_list. LSIZE is the number of elements in LIST, in
4693 case it's larger than fifo_list_size (size of fifo_list). */
4695 close_new_fifos (list, lsize)
4703 unlink_fifo_list ();
4707 for (i = 0; i < lsize; i++)
4708 if (list[i] == 0 && i < fifo_list_size && fifo_list[i].proc != -1)
4711 for (i = lsize; i < fifo_list_size; i++)
4732 tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
4733 if (mkfifo (tname, 0600) < 0)
4736 return ((char *)NULL);
4739 add_fifo_list (tname);
4743 #else /* HAVE_DEV_FD */
4745 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4746 has open to children. NFDS is a count of the number of bits currently
4747 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4749 static char *dev_fd_list = (char *)NULL;
4751 static int totfds; /* The highest possible number of open files. */
4754 copy_fifo_list (sizep)
4759 if (nfds == 0 || totfds == 0)
4763 return (char *)NULL;
4768 ret = (char *)xmalloc (totfds);
4769 return (memcpy (ret, dev_fd_list, totfds));
4776 if (dev_fd_list == 0 || fd >= totfds)
4781 totfds = getdtablesize ();
4782 if (totfds < 0 || totfds > 256)
4787 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
4788 memset (dev_fd_list + ofds, '\0', totfds - ofds);
4791 dev_fd_list[fd] = 1;
4798 return 0; /* used for cleanup; not needed with /dev/fd */
4811 if (dev_fd_list[fd])
4814 dev_fd_list[fd] = 0;
4827 for (i = 0; nfds && i < totfds; i++)
4833 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4834 the past, and close all open fds in dev_fd_list that are not marked
4835 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4836 LSIZE is the number of elements in LIST, in case it's larger than
4837 totfds (size of dev_fd_list). */
4839 close_new_fifos (list, lsize)
4847 unlink_fifo_list ();
4851 for (i = 0; i < lsize; i++)
4852 if (list[i] == 0 && i < totfds && dev_fd_list[i])
4855 for (i = lsize; i < totfds; i++)
4859 #if defined (NOTDEF)
4860 print_dev_fd_list ()
4864 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
4867 for (i = 0; i < totfds; i++)
4870 fprintf (stderr, " %d", i);
4872 fprintf (stderr, "\n");
4877 make_dev_fd_filename (fd)
4880 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
4882 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
4884 strcpy (ret, DEV_FD_PREFIX);
4885 p = inttostr (fd, intbuf, sizeof (intbuf));
4886 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
4892 #endif /* HAVE_DEV_FD */
4894 /* Return a filename that will open a connection to the process defined by
4895 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4896 a filename in /dev/fd corresponding to a descriptor that is one of the
4897 ends of the pipe. If not defined, we use named pipes on systems that have
4898 them. Systems without /dev/fd and named pipes are out of luck.
4900 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4901 use the read end of the pipe and dup that file descriptor to fd 0 in
4902 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4903 writing or use the write end of the pipe in the child, and dup that
4904 file descriptor to fd 1 in the child. The parent does the opposite. */
4907 process_substitute (string, open_for_read_in_child)
4909 int open_for_read_in_child;
4914 #if defined (HAVE_DEV_FD)
4915 int parent_pipe_fd, child_pipe_fd;
4917 #endif /* HAVE_DEV_FD */
4918 #if defined (JOB_CONTROL)
4919 pid_t old_pipeline_pgrp;
4922 if (!string || !*string || wordexp_only)
4923 return ((char *)NULL);
4925 #if !defined (HAVE_DEV_FD)
4926 pathname = make_named_pipe ();
4927 #else /* HAVE_DEV_FD */
4928 if (pipe (fildes) < 0)
4930 sys_error (_("cannot make pipe for process substitution"));
4931 return ((char *)NULL);
4933 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4934 the pipe in the parent, otherwise the read end. */
4935 parent_pipe_fd = fildes[open_for_read_in_child];
4936 child_pipe_fd = fildes[1 - open_for_read_in_child];
4937 /* Move the parent end of the pipe to some high file descriptor, to
4938 avoid clashes with FDs used by the script. */
4939 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
4941 pathname = make_dev_fd_filename (parent_pipe_fd);
4942 #endif /* HAVE_DEV_FD */
4946 sys_error (_("cannot make pipe for process substitution"));
4947 return ((char *)NULL);
4950 old_pid = last_made_pid;
4952 #if defined (JOB_CONTROL)
4953 old_pipeline_pgrp = pipeline_pgrp;
4954 pipeline_pgrp = shell_pgrp;
4956 #endif /* JOB_CONTROL */
4958 pid = make_child ((char *)NULL, 1);
4961 reset_terminating_signals (); /* XXX */
4962 free_pushed_string_input ();
4963 /* Cancel traps, in trap.c. */
4964 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
4965 setup_async_signals ();
4966 subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
4969 #if defined (JOB_CONTROL)
4970 set_sigchld_handler ();
4971 stop_making_children ();
4972 /* XXX - should we only do this in the parent? (as in command subst) */
4973 pipeline_pgrp = old_pipeline_pgrp;
4974 #endif /* JOB_CONTROL */
4978 sys_error (_("cannot make child for process substitution"));
4980 #if defined (HAVE_DEV_FD)
4981 close (parent_pipe_fd);
4982 close (child_pipe_fd);
4983 #endif /* HAVE_DEV_FD */
4984 return ((char *)NULL);
4989 #if defined (JOB_CONTROL)
4990 restore_pipeline (1);
4993 #if !defined (HAVE_DEV_FD)
4994 fifo_list[nfifo-1].proc = pid;
4997 last_made_pid = old_pid;
4999 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5001 #endif /* JOB_CONTROL && PGRP_PIPE */
5003 #if defined (HAVE_DEV_FD)
5004 close (child_pipe_fd);
5005 #endif /* HAVE_DEV_FD */
5010 set_sigint_handler ();
5012 #if defined (JOB_CONTROL)
5013 set_job_control (0);
5014 #endif /* JOB_CONTROL */
5016 #if !defined (HAVE_DEV_FD)
5017 /* Open the named pipe in the child. */
5018 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
5021 /* Two separate strings for ease of translation. */
5022 if (open_for_read_in_child)
5023 sys_error (_("cannot open named pipe %s for reading"), pathname);
5025 sys_error (_("cannot open named pipe %s for writing"), pathname);
5029 if (open_for_read_in_child)
5031 if (sh_unset_nodelay_mode (fd) < 0)
5033 sys_error (_("cannot reset nodelay mode for fd %d"), fd);
5037 #else /* HAVE_DEV_FD */
5039 #endif /* HAVE_DEV_FD */
5041 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
5043 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
5044 open_for_read_in_child ? 0 : 1);
5048 if (fd != (open_for_read_in_child ? 0 : 1))
5051 /* Need to close any files that this process has open to pipes inherited
5053 if (current_fds_to_close)
5055 close_fd_bitmap (current_fds_to_close);
5056 current_fds_to_close = (struct fd_bitmap *)NULL;
5059 #if defined (HAVE_DEV_FD)
5060 /* Make sure we close the parent's end of the pipe and clear the slot
5061 in the fd list so it is not closed later, if reallocated by, for
5062 instance, pipe(2). */
5063 close (parent_pipe_fd);
5064 dev_fd_list[parent_pipe_fd] = 0;
5065 #endif /* HAVE_DEV_FD */
5067 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
5069 #if !defined (HAVE_DEV_FD)
5070 /* Make sure we close the named pipe in the child before we exit. */
5071 close (open_for_read_in_child ? 0 : 1);
5072 #endif /* !HAVE_DEV_FD */
5077 #endif /* PROCESS_SUBSTITUTION */
5079 /***********************************/
5081 /* Command Substitution */
5083 /***********************************/
5086 read_comsub (fd, quoted, rflag)
5090 char *istring, buf[128], *bufp, *s;
5091 int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
5094 istring = (char *)NULL;
5095 istring_index = istring_size = bufn = tflag = 0;
5097 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
5098 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
5101 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
5104 /* Read the output of the command through the pipe. This may need to be
5105 changed to understand multibyte characters in the future. */
5112 bufn = zread (fd, buf, sizeof (buf));
5122 internal_warning ("read_comsub: ignored null byte in input");
5127 /* Add the character to ISTRING, possibly after resizing it. */
5128 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
5130 /* This is essentially quote_string inline */
5131 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
5132 istring[istring_index++] = CTLESC;
5133 /* Escape CTLESC and CTLNUL in the output to protect those characters
5134 from the rest of the word expansions (word splitting and globbing.)
5135 This is essentially quote_escapes inline. */
5136 else if (skip_ctlesc == 0 && c == CTLESC)
5138 tflag |= W_HASCTLESC;
5139 istring[istring_index++] = CTLESC;
5141 else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
5142 istring[istring_index++] = CTLESC;
5144 istring[istring_index++] = c;
5147 #if defined (__CYGWIN__)
5148 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
5151 istring[istring_index - 1] = '\n';
5158 istring[istring_index] = '\0';
5160 /* If we read no output, just return now and save ourselves some
5162 if (istring_index == 0)
5167 return (char *)NULL;
5170 /* Strip trailing newlines from the output of the command. */
5171 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5173 while (istring_index > 0)
5175 if (istring[istring_index - 1] == '\n')
5179 /* If the newline was quoted, remove the quoting char. */
5180 if (istring[istring_index - 1] == CTLESC)
5186 istring[istring_index] = '\0';
5189 strip_trailing (istring, istring_index - 1, 1);
5196 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5197 contained string possibly quoted. */
5199 command_substitute (string, quoted)
5203 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
5205 int result, fildes[2], function_value, pflags, rc, tflag;
5208 istring = (char *)NULL;
5210 /* Don't fork () if there is no need to. In the case of no command to
5211 run, just return NULL. */
5212 if (!string || !*string || (string[0] == '\n' && !string[1]))
5213 return ((WORD_DESC *)NULL);
5215 if (wordexp_only && read_but_dont_execute)
5217 last_command_exit_value = EX_WEXPCOMSUB;
5218 jump_to_top_level (EXITPROG);
5221 /* We're making the assumption here that the command substitution will
5222 eventually run a command from the file system. Since we'll run
5223 maybe_make_export_env in this subshell before executing that command,
5224 the parent shell and any other shells it starts will have to remake
5225 the environment. If we make it before we fork, other shells won't
5226 have to. Don't bother if we have any temporary variable assignments,
5227 though, because the export environment will be remade after this
5228 command completes anyway, but do it if all the words to be expanded
5229 are variable assignments. */
5230 if (subst_assign_varlist == 0 || garglist == 0)
5231 maybe_make_export_env (); /* XXX */
5233 /* Flags to pass to parse_and_execute() */
5234 pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
5236 /* Pipe the output of executing STRING into the current shell. */
5237 if (pipe (fildes) < 0)
5239 sys_error (_("cannot make pipe for command substitution"));
5243 old_pid = last_made_pid;
5244 #if defined (JOB_CONTROL)
5245 old_pipeline_pgrp = pipeline_pgrp;
5246 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5247 if ((subshell_environment & SUBSHELL_PIPE) == 0)
5248 pipeline_pgrp = shell_pgrp;
5249 cleanup_the_pipeline ();
5250 #endif /* JOB_CONTROL */
5252 old_async_pid = last_asynchronous_pid;
5253 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
5254 last_asynchronous_pid = old_async_pid;
5258 /* Reset the signal handlers in the child, but don't free the
5259 trap strings. Set a flag noting that we have to free the
5260 trap strings if we run trap to change a signal disposition. */
5261 reset_signal_handlers ();
5262 subshell_environment |= SUBSHELL_RESETTRAP;
5265 #if defined (JOB_CONTROL)
5266 /* XXX DO THIS ONLY IN PARENT ? XXX */
5267 set_sigchld_handler ();
5268 stop_making_children ();
5270 pipeline_pgrp = old_pipeline_pgrp;
5272 stop_making_children ();
5273 #endif /* JOB_CONTROL */
5277 sys_error (_("cannot make child for command substitution"));
5283 return ((WORD_DESC *)NULL);
5288 set_sigint_handler (); /* XXX */
5290 free_pushed_string_input ();
5292 if (dup2 (fildes[1], 1) < 0)
5294 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5295 exit (EXECUTION_FAILURE);
5298 /* If standard output is closed in the parent shell
5299 (such as after `exec >&-'), file descriptor 1 will be
5300 the lowest available file descriptor, and end up in
5301 fildes[0]. This can happen for stdin and stderr as well,
5302 but stdout is more important -- it will cause no output
5303 to be generated from this command. */
5304 if ((fildes[1] != fileno (stdin)) &&
5305 (fildes[1] != fileno (stdout)) &&
5306 (fildes[1] != fileno (stderr)))
5309 if ((fildes[0] != fileno (stdin)) &&
5310 (fildes[0] != fileno (stdout)) &&
5311 (fildes[0] != fileno (stderr)))
5314 /* The currently executing shell is not interactive. */
5317 /* This is a subshell environment. */
5318 subshell_environment |= SUBSHELL_COMSUB;
5320 /* When not in POSIX mode, command substitution does not inherit
5322 if (posixly_correct == 0)
5323 exit_immediately_on_error = 0;
5325 remove_quoted_escapes (string);
5327 startup_state = 2; /* see if we can avoid a fork */
5328 /* Give command substitution a place to jump back to on failure,
5329 so we don't go back up to main (). */
5330 result = setjmp (top_level);
5332 /* If we're running a command substitution inside a shell function,
5333 trap `return' so we don't return from the function in the subshell
5334 and go off to never-never land. */
5335 if (result == 0 && return_catch_flag)
5336 function_value = setjmp (return_catch);
5340 if (result == ERREXIT)
5341 rc = last_command_exit_value;
5342 else if (result == EXITPROG)
5343 rc = last_command_exit_value;
5345 rc = EXECUTION_FAILURE;
5346 else if (function_value)
5347 rc = return_catch_value;
5351 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
5355 last_command_exit_value = rc;
5356 rc = run_exit_trap ();
5357 #if defined (PROCESS_SUBSTITUTION)
5358 unlink_fifo_list ();
5364 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5366 #endif /* JOB_CONTROL && PGRP_PIPE */
5371 istring = read_comsub (fildes[0], quoted, &tflag);
5375 current_command_subst_pid = pid;
5376 last_command_exit_value = wait_for (pid);
5377 last_command_subst_pid = pid;
5378 last_made_pid = old_pid;
5380 #if defined (JOB_CONTROL)
5381 /* If last_command_exit_value > 128, then the substituted command
5382 was terminated by a signal. If that signal was SIGINT, then send
5383 SIGINT to ourselves. This will break out of loops, for instance. */
5384 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
5385 kill (getpid (), SIGINT);
5387 /* wait_for gives the terminal back to shell_pgrp. If some other
5388 process group should have it, give it away to that group here.
5389 pipeline_pgrp is non-zero only while we are constructing a
5390 pipline, so what we are concerned about is whether or not that
5391 pipeline was started in the background. A pipeline started in
5392 the background should never get the tty back here. */
5393 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
5394 give_terminal_to (pipeline_pgrp, 0);
5395 #endif /* JOB_CONTROL */
5397 ret = alloc_word_desc ();
5398 ret->word = istring;
5405 /********************************************************
5407 * Utility functions for parameter expansion *
5409 ********************************************************/
5411 #if defined (ARRAY_VARS)
5414 array_length_reference (s)
5425 var = array_variable_part (s, &t, &len);
5427 /* If unbound variables should generate an error, report one and return
5429 if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
5433 last_command_exit_value = EXECUTION_FAILURE;
5441 /* We support a couple of expansions for variables that are not arrays.
5442 We'll return the length of the value for v[0], and 1 for v[@] or
5443 v[*]. Return 0 for everything else. */
5445 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
5446 h = assoc_p (var) ? assoc_cell (var) : (HASH_TABLE *)NULL;
5448 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
5451 return (h ? assoc_num_elements (h) : 0);
5452 else if (array_p (var))
5453 return (array ? array_num_elements (array) : 0);
5455 return (var_isset (var) ? 1 : 0);
5461 akey = expand_assignment_string_to_string (t, 0); /* [ */
5463 if (akey == 0 || *akey == 0)
5465 err_badarraysub (t);
5468 t = assoc_reference (assoc_cell (var), akey);
5472 ind = array_expand_index (t, len);
5475 err_badarraysub (t);
5479 t = array_reference (array, ind);
5481 t = (ind == 0) ? value_cell (var) : (char *)NULL;
5484 len = MB_STRLEN (t);
5487 #endif /* ARRAY_VARS */
5490 valid_brace_expansion_word (name, var_is_special)
5494 if (DIGIT (*name) && all_digits (name))
5496 else if (var_is_special)
5498 #if defined (ARRAY_VARS)
5499 else if (valid_array_reference (name))
5501 #endif /* ARRAY_VARS */
5502 else if (legal_identifier (name))
5509 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
5512 int *quoted_dollar_atp, *contains_dollar_at;
5518 if (quoted_dollar_atp)
5519 *quoted_dollar_atp = 0;
5520 if (contains_dollar_at)
5521 *contains_dollar_at = 0;
5525 /* check for $@ and $* */
5526 if (name[0] == '@' && name[1] == 0)
5528 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5529 *quoted_dollar_atp = 1;
5530 if (contains_dollar_at)
5531 *contains_dollar_at = 1;
5534 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
5536 if (contains_dollar_at)
5537 *contains_dollar_at = 1;
5541 /* Now check for ${array[@]} and ${array[*]} */
5542 #if defined (ARRAY_VARS)
5543 else if (valid_array_reference (name))
5545 temp1 = mbschr (name, '[');
5546 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
5548 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5549 *quoted_dollar_atp = 1;
5550 if (contains_dollar_at)
5551 *contains_dollar_at = 1;
5554 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5555 which should result in separate words even when IFS is unset. */
5556 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
5558 if (contains_dollar_at)
5559 *contains_dollar_at = 1;
5567 /* Parameter expand NAME, and return a new string which is the expansion,
5568 or NULL if there was no expansion.
5569 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5570 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5571 NAME was found inside of a double-quoted expression. */
5573 parameter_brace_expand_word (name, var_is_special, quoted, pflags, indp)
5575 int var_is_special, quoted, pflags;
5592 /* Handle multiple digit arguments, as in ${11}. */
5593 if (legal_number (name, &arg_index))
5595 tt = get_dollar_var_value (arg_index);
5597 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5599 : quote_escapes (tt);
5601 temp = (char *)NULL;
5604 else if (var_is_special) /* ${@} */
5607 tt = (char *)xmalloc (2 + strlen (name));
5608 tt[sindex = 0] = '$';
5609 strcpy (tt + 1, name);
5611 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
5612 (int *)NULL, (int *)NULL, pflags);
5615 #if defined (ARRAY_VARS)
5616 else if (valid_array_reference (name))
5618 temp = array_value (name, quoted, 0, &atype, &ind);
5619 if (atype == 0 && temp)
5621 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5622 ? quote_string (temp)
5623 : quote_escapes (temp);
5624 rflags |= W_ARRAYIND;
5628 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5629 rflags |= W_HASQUOTEDNULL;
5632 else if (var = find_variable (name))
5634 if (var_isset (var) && invisible_p (var) == 0)
5636 #if defined (ARRAY_VARS)
5638 temp = assoc_reference (assoc_cell (var), "0");
5639 else if (array_p (var))
5640 temp = array_reference (array_cell (var), 0);
5642 temp = value_cell (var);
5644 temp = value_cell (var);
5648 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5649 ? quote_string (temp)
5650 : quote_escapes (temp);
5653 temp = (char *)NULL;
5656 temp = (char *)NULL;
5660 ret = alloc_word_desc ();
5662 ret->flags |= rflags;
5667 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5668 value of the variable whose name is the value of NAME. */
5670 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
5672 int var_is_special, quoted;
5673 int *quoted_dollar_atp, *contains_dollar_at;
5678 w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND, 0);
5680 /* Have to dequote here if necessary */
5683 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5684 ? dequote_string (t)
5685 : dequote_escapes (t);
5689 dispose_word_desc (w);
5691 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
5693 return (WORD_DESC *)NULL;
5695 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0, 0);
5701 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5702 depending on the value of C, the separating character. C can be one of
5703 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5704 between double quotes. */
5706 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
5708 int c, quoted, *qdollaratp, *hasdollarat;
5712 char *t, *t1, *temp;
5715 /* If the entire expression is between double quotes, we want to treat
5716 the value as a double-quoted string, with the exception that we strip
5717 embedded unescaped double quotes (for sh backwards compatibility). */
5718 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
5721 temp = string_extract_double_quoted (value, &hasdol, 1);
5726 w = alloc_word_desc ();
5728 /* XXX was 0 not quoted */
5729 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
5732 *hasdollarat = hasdol || (l && l->next);
5737 /* The expansion of TEMP returned something. We need to treat things
5738 slightly differently if HASDOL is non-zero. If we have "$@", the
5739 individual words have already been quoted. We need to turn them
5740 into a string with the words separated by the first character of
5741 $IFS without any additional quoting, so string_list_dollar_at won't
5742 do the right thing. We use string_list_dollar_star instead. */
5743 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
5745 /* If l->next is not null, we know that TEMP contained "$@", since that
5746 is the only expansion that creates more than one word. */
5747 if (qdollaratp && ((hasdol && quoted) || l->next))
5751 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
5753 /* The brace expansion occurred between double quotes and there was
5754 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5755 it does not expand to anything. In this case, we want to return
5756 a quoted empty string. */
5757 temp = make_quoted_char ('\0');
5758 w->flags |= W_HASQUOTEDNULL;
5761 temp = (char *)NULL;
5763 if (c == '-' || c == '+')
5770 t = temp ? savestring (temp) : savestring ("");
5771 t1 = dequote_string (t);
5773 #if defined (ARRAY_VARS)
5774 if (valid_array_reference (name))
5775 assign_array_element (name, t1, 0);
5777 #endif /* ARRAY_VARS */
5778 bind_variable (name, t1, 0);
5780 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5787 /* Deal with the right hand side of a ${name:?value} expansion in the case
5788 that NAME is null or not set. If VALUE is non-null it is expanded and
5789 used as the error message to print, otherwise a standard message is
5792 parameter_brace_expand_error (name, value)
5798 if (value && *value)
5800 l = expand_string (value, 0);
5801 temp = string_list (l);
5802 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
5807 report_error (_("%s: parameter null or not set"), name);
5809 /* Free the data we have allocated during this expansion, since we
5810 are about to longjmp out. */
5815 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5818 valid_length_expression (name)
5821 return (name[1] == '\0' || /* ${#} */
5822 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
5823 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
5824 #if defined (ARRAY_VARS)
5825 valid_array_reference (name + 1) || /* ${#a[7]} */
5827 legal_identifier (name + 1)); /* ${#PS1} */
5830 #if defined (HANDLE_MULTIBYTE)
5836 mbstate_t mbs, mbsbak;
5839 memset (&mbs, 0, sizeof (mbs));
5841 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
5843 if (MB_INVALIDCH(clen))
5845 clen = 1; /* assume single byte */
5858 /* Handle the parameter brace expansion that requires us to return the
5859 length of a parameter. */
5861 parameter_brace_expand_length (name)
5865 intmax_t number, arg_index;
5867 #if defined (ARRAY_VARS)
5871 if (name[1] == '\0') /* ${#} */
5872 number = number_of_args ();
5873 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
5874 number = number_of_args ();
5875 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
5877 /* Take the lengths of some of the shell's special parameters. */
5881 t = which_set_flags ();
5884 t = itos (last_command_exit_value);
5887 t = itos (dollar_dollar_pid);
5890 if (last_asynchronous_pid == NO_PID)
5893 t = itos (last_asynchronous_pid);
5896 t = itos (number_of_args ());
5899 number = STRLEN (t);
5902 #if defined (ARRAY_VARS)
5903 else if (valid_array_reference (name + 1))
5904 number = array_length_reference (name + 1);
5905 #endif /* ARRAY_VARS */
5910 if (legal_number (name + 1, &arg_index)) /* ${#1} */
5912 t = get_dollar_var_value (arg_index);
5913 number = MB_STRLEN (t);
5916 #if defined (ARRAY_VARS)
5917 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
5920 t = assoc_reference (assoc_cell (var), "0");
5922 t = array_reference (array_cell (var), 0);
5923 number = MB_STRLEN (t);
5928 newname = savestring (name);
5930 list = expand_string (newname, Q_DOUBLE_QUOTES);
5931 t = list ? string_list (list) : (char *)NULL;
5934 dispose_words (list);
5936 number = MB_STRLEN (t);
5944 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5945 so we do some ad-hoc parsing of an arithmetic expression to find
5946 the first DELIM, instead of using strchr(3). Two rules:
5947 1. If the substring contains a `(', read until closing `)'.
5948 2. If the substring contains a `?', read past one `:' for each `?'.
5952 skiparith (substr, delim)
5957 int skipcol, pcount, i;
5960 sublen = strlen (substr);
5961 i = skipcol = pcount = 0;
5964 /* Balance parens */
5965 if (substr[i] == LPAREN)
5971 if (substr[i] == RPAREN && pcount)
5979 ADVANCE_CHAR (substr, sublen, i);
5983 /* Skip one `:' for each `?' */
5984 if (substr[i] == ':' && skipcol)
5990 if (substr[i] == delim)
5992 if (substr[i] == '?')
5998 ADVANCE_CHAR (substr, sublen, i);
6001 return (substr + i);
6004 /* Verify and limit the start and end of the desired substring. If
6005 VTYPE == 0, a regular shell variable is being used; if it is 1,
6006 then the positional parameters are being used; if it is 2, then
6007 VALUE is really a pointer to an array variable that should be used.
6008 Return value is 1 if both values were OK, 0 if there was a problem
6009 with an invalid expression, or -1 if the values were out of range. */
6011 verify_substring_values (v, value, substr, vtype, e1p, e2p)
6013 char *value, *substr;
6015 intmax_t *e1p, *e2p;
6017 char *t, *temp1, *temp2;
6020 #if defined (ARRAY_VARS)
6025 /* duplicate behavior of strchr(3) */
6026 t = skiparith (substr, ':');
6027 if (*t && *t == ':')
6032 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
6033 *e1p = evalexp (temp1, &expok);
6038 len = -1; /* paranoia */
6042 case VT_ARRAYMEMBER:
6043 len = MB_STRLEN (value);
6046 len = number_of_args () + 1;
6048 len++; /* add one arg if counting from $0 */
6050 #if defined (ARRAY_VARS)
6052 /* For arrays, the first value deals with array indices. Negative
6053 offsets count from one past the array's maximum index. Associative
6054 arrays treat the number of elements as the maximum index. */
6058 len = assoc_num_elements (h) + (*e1p < 0);
6063 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
6069 if (len == -1) /* paranoia */
6072 if (*e1p < 0) /* negative offsets count from end */
6075 if (*e1p > len || *e1p < 0)
6078 #if defined (ARRAY_VARS)
6079 /* For arrays, the second offset deals with the number of elements. */
6080 if (vtype == VT_ARRAYVAR)
6081 len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
6087 temp2 = savestring (t);
6088 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
6091 *e2p = evalexp (temp1, &expok);
6095 if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
6097 internal_error (_("%s: substring expression < 0"), t);
6100 #if defined (ARRAY_VARS)
6101 /* In order to deal with sparse arrays, push the intelligence about how
6102 to deal with the number of elements desired down to the array-
6103 specific functions. */
6104 if (vtype != VT_ARRAYVAR)
6110 if (*e2p < 0 || *e2p < *e1p)
6112 internal_error (_("%s: substring expression < 0"), t);
6117 *e2p += *e1p; /* want E2 chars starting at E1 */
6128 /* Return the type of variable specified by VARNAME (simple variable,
6129 positional param, or array variable). Also return the value specified
6130 by VARNAME (value of a variable or a reference to an array element).
6131 QUOTED is the standard description of quoting state, using Q_* defines.
6132 FLAGS is currently a set of flags to pass to array_value. If IND is
6133 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6134 passed to array_value so the array index is not computed again.
6135 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6136 characters in the value are quoted with CTLESC and takes appropriate
6137 steps. For convenience, *VALP is set to the dequoted VALUE. */
6139 get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
6140 char *varname, *value;
6148 #if defined (ARRAY_VARS)
6153 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6154 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
6155 if (vtype == VT_POSPARMS && varname[0] == '*')
6156 vtype |= VT_STARSUB;
6157 *varp = (SHELL_VAR *)NULL;
6159 #if defined (ARRAY_VARS)
6160 if (valid_array_reference (varname))
6162 v = array_variable_part (varname, &temp, (int *)0);
6163 /* If we want to signal array_value to use an already-computed index,
6164 set LIND to that index */
6165 lind = (ind != INTMAX_MIN && (flags & AV_USEIND)) ? ind : 0;
6166 if (v && (array_p (v) || assoc_p (v)))
6168 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
6170 /* Callers have to differentiate betwen indexed and associative */
6171 vtype = VT_ARRAYVAR;
6173 vtype |= VT_STARSUB;
6174 *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
6178 vtype = VT_ARRAYMEMBER;
6179 *valp = array_value (varname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
6183 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
6185 vtype = VT_VARIABLE;
6187 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6188 *valp = dequote_string (value);
6190 *valp = dequote_escapes (value);
6194 vtype = VT_ARRAYMEMBER;
6196 *valp = array_value (varname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
6199 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
6201 vtype = VT_ARRAYMEMBER;
6203 *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
6208 if (value && vtype == VT_VARIABLE)
6210 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6211 *valp = dequote_string (value);
6213 *valp = dequote_escapes (value);
6222 /******************************************************/
6224 /* Functions to extract substrings of variable values */
6226 /******************************************************/
6228 #if defined (HANDLE_MULTIBYTE)
6229 /* Character-oriented rather than strictly byte-oriented substrings. S and
6230 E, rather being strict indices into STRING, indicate character (possibly
6231 multibyte character) positions that require calculation.
6232 Used by the ${param:offset[:length]} expansion. */
6234 mb_substring (string, s, e)
6239 int start, stop, i, slen;
6243 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6244 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
6247 while (string[start] && i--)
6248 ADVANCE_CHAR (string, slen, start);
6251 while (string[stop] && i--)
6252 ADVANCE_CHAR (string, slen, stop);
6253 tt = substring (string, start, stop);
6258 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6259 is `@', use the positional parameters; otherwise, use the value of
6260 VARNAME. If VARNAME is an array variable, use the array elements. */
6263 parameter_brace_substring (varname, value, ind, substr, quoted, flags)
6264 char *varname, *value;
6270 int vtype, r, starsub;
6271 char *temp, *val, *tt, *oname;
6275 return ((char *)NULL);
6277 oname = this_command_name;
6278 this_command_name = varname;
6280 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6283 this_command_name = oname;
6284 return ((char *)NULL);
6287 starsub = vtype & VT_STARSUB;
6288 vtype &= ~VT_STARSUB;
6290 r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
6291 this_command_name = oname;
6293 return ((r == 0) ? &expand_param_error : (char *)NULL);
6298 case VT_ARRAYMEMBER:
6299 #if defined (HANDLE_MULTIBYTE)
6301 tt = mb_substring (val, e1, e2);
6304 tt = substring (val, e1, e2);
6306 if (vtype == VT_VARIABLE)
6308 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6309 temp = quote_string (tt);
6311 temp = tt ? quote_escapes (tt) : (char *)NULL;
6315 tt = pos_params (varname, e1, e2, quoted);
6316 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
6318 temp = tt ? quote_escapes (tt) : (char *)NULL;
6324 #if defined (ARRAY_VARS)
6327 /* we convert to list and take first e2 elements starting at e1th
6328 element -- officially undefined for now */
6329 temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
6331 /* We want E2 to be the number of elements desired (arrays can be sparse,
6332 so verify_substring_values just returns the numbers specified and we
6333 rely on array_subrange to understand how to deal with them). */
6334 temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
6335 /* array_subrange now calls array_quote_escapes as appropriate, so the
6336 caller no longer needs to. */
6340 temp = (char *)NULL;
6346 /****************************************************************/
6348 /* Functions to perform pattern substitution on variable values */
6350 /****************************************************************/
6353 shouldexp_replacement (s)
6358 for (p = s; p && *p; p++)
6369 pat_subst (string, pat, rep, mflags)
6370 char *string, *pat, *rep;
6373 char *ret, *s, *e, *str, *rstr, *mstr;
6374 int rsize, rptr, l, replen, mtype, rxpand, rslen, mlen;
6377 return (savestring (""));
6379 mtype = mflags & MATCH_TYPEMASK;
6381 #if 0 /* bash-4.2 ? */
6382 rxpand = (rep && *rep) ? shouldexp_replacement (rep) : 0;
6388 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6389 * with REP and return the result.
6390 * 2. A null pattern with mtype == MATCH_END means to append REP to
6391 * STRING and return the result.
6392 * These don't understand or process `&' in the replacement string.
6394 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
6396 replen = STRLEN (rep);
6397 l = STRLEN (string);
6398 ret = (char *)xmalloc (replen + l + 2);
6400 strcpy (ret, string);
6401 else if (mtype == MATCH_BEG)
6404 strcpy (ret + replen, string);
6408 strcpy (ret, string);
6409 strcpy (ret + l, rep);
6414 ret = (char *)xmalloc (rsize = 64);
6417 for (replen = STRLEN (rep), rptr = 0, str = string;;)
6419 if (match_pattern (str, pat, mtype, &s, &e) == 0)
6427 mstr = xmalloc (mlen + 1);
6428 for (x = 0; x < mlen; x++)
6431 rstr = strcreplace (rep, '&', mstr, 0);
6432 rslen = strlen (rstr);
6440 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64);
6442 /* OK, now copy the leading unmatched portion of the string (from
6443 str to s) to ret starting at rptr (the current offset). Then copy
6444 the replacement string at ret + rptr + (s - str). Increment
6445 rptr (if necessary) and str and go on. */
6448 strncpy (ret + rptr, str, l);
6453 strncpy (ret + rptr, rstr, rslen);
6456 str = e; /* e == end of match */
6461 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
6466 /* On a zero-length match, make sure we copy one character, since
6467 we increment one character to avoid infinite recursion. */
6468 RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
6469 ret[rptr++] = *str++;
6470 e++; /* avoid infinite recursion on zero-length match */
6474 /* Now copy the unmatched portion of the input string */
6477 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
6478 strcpy (ret + rptr, str);
6486 /* Do pattern match and replacement on the positional parameters. */
6488 pos_params_pat_subst (string, pat, rep, mflags)
6489 char *string, *pat, *rep;
6492 WORD_LIST *save, *params;
6497 save = params = list_rest_of_args ();
6499 return ((char *)NULL);
6501 for ( ; params; params = params->next)
6503 ret = pat_subst (params->word->word, pat, rep, mflags);
6504 w = alloc_word_desc ();
6505 w->word = ret ? ret : savestring ("");
6506 dispose_word (params->word);
6510 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
6511 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
6514 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
6515 ret = string_list_dollar_star (quote_list (save));
6516 else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
6517 ret = string_list_dollar_star (save);
6518 else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
6519 ret = string_list_dollar_at (save, qflags);
6521 ret = string_list_dollar_star (save);
6523 ret = string_list_pos_params (pchar, save, qflags);
6526 dispose_words (save);
6531 /* Perform pattern substitution on VALUE, which is the expansion of
6532 VARNAME. PATSUB is an expression supplying the pattern to match
6533 and the string to substitute. QUOTED is a flags word containing
6534 the type of quoting currently in effect. */
6536 parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
6537 char *varname, *value;
6542 int vtype, mflags, starsub, delim;
6543 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
6547 return ((char *)NULL);
6549 this_command_name = varname;
6551 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6553 return ((char *)NULL);
6555 starsub = vtype & VT_STARSUB;
6556 vtype &= ~VT_STARSUB;
6559 if (patsub && *patsub == '/')
6561 mflags |= MATCH_GLOBREP;
6565 /* Malloc this because expand_string_if_necessary or one of the expansion
6566 functions in its call chain may free it on a substitution error. */
6567 lpatsub = savestring (patsub);
6569 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6570 mflags |= MATCH_QUOTED;
6573 mflags |= MATCH_STARSUB;
6575 /* If the pattern starts with a `/', make sure we skip over it when looking
6576 for the replacement delimiter. */
6578 if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
6583 delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
6584 if (lpatsub[delim] == '/')
6587 rep = lpatsub + delim + 1;
6593 if (rep && *rep == '\0')
6596 /* Perform the same expansions on the pattern as performed by the
6597 pattern removal expansions. */
6598 pat = getpattern (lpatsub, quoted, 1);
6602 if ((mflags & MATCH_QUOTED) == 0)
6603 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
6605 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
6608 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6609 pattern. This is an extension. Make sure we don't anchor the pattern
6610 at the beginning or end of the string if we're doing global replacement,
6613 if (mflags & MATCH_GLOBREP)
6614 mflags |= MATCH_ANY;
6615 else if (pat && pat[0] == '#')
6617 mflags |= MATCH_BEG;
6620 else if (pat && pat[0] == '%')
6622 mflags |= MATCH_END;
6626 mflags |= MATCH_ANY;
6628 /* OK, we now want to substitute REP for PAT in VAL. If
6629 flags & MATCH_GLOBREP is non-zero, the substitution is done
6630 everywhere, otherwise only the first occurrence of PAT is
6631 replaced. The pattern matching code doesn't understand
6632 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6633 values passed in (VT_VARIABLE) so the pattern substitution
6634 code works right. We need to requote special chars after
6635 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6636 other cases if QUOTED == 0, since the posparams and arrays
6637 indexed by * or @ do special things when QUOTED != 0. */
6642 case VT_ARRAYMEMBER:
6643 temp = pat_subst (val, p, rep, mflags);
6644 if (vtype == VT_VARIABLE)
6648 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6654 temp = pos_params_pat_subst (val, p, rep, mflags);
6655 if (temp && (mflags & MATCH_QUOTED) == 0)
6657 tt = quote_escapes (temp);
6662 #if defined (ARRAY_VARS)
6664 temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
6665 : array_patsub (array_cell (v), p, rep, mflags);
6666 /* Don't call quote_escapes anymore; array_patsub calls
6667 array_quote_escapes as appropriate before adding the
6668 space separators; ditto for assoc_patsub. */
6680 /****************************************************************/
6682 /* Functions to perform case modification on variable values */
6684 /****************************************************************/
6686 /* Do case modification on the positional parameters. */
6689 pos_params_modcase (string, pat, modop, mflags)
6694 WORD_LIST *save, *params;
6699 save = params = list_rest_of_args ();
6701 return ((char *)NULL);
6703 for ( ; params; params = params->next)
6705 ret = sh_modcase (params->word->word, pat, modop);
6706 w = alloc_word_desc ();
6707 w->word = ret ? ret : savestring ("");
6708 dispose_word (params->word);
6712 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
6713 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
6715 ret = string_list_pos_params (pchar, save, qflags);
6716 dispose_words (save);
6721 /* Perform case modification on VALUE, which is the expansion of
6722 VARNAME. MODSPEC is an expression supplying the type of modification
6723 to perform. QUOTED is a flags word containing the type of quoting
6724 currently in effect. */
6726 parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
6727 char *varname, *value;
6732 int vtype, starsub, modop, mflags, x;
6733 char *val, *temp, *pat, *p, *lpat, *tt;
6737 return ((char *)NULL);
6739 this_command_name = varname;
6741 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6743 return ((char *)NULL);
6745 starsub = vtype & VT_STARSUB;
6746 vtype &= ~VT_STARSUB;
6750 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6751 mflags |= MATCH_QUOTED;
6753 mflags |= MATCH_STARSUB;
6758 x = p && p[0] == modspec;
6759 modop = x ? CASE_UPPER : CASE_UPFIRST;
6762 else if (modspec == ',')
6764 x = p && p[0] == modspec;
6765 modop = x ? CASE_LOWER : CASE_LOWFIRST;
6768 else if (modspec == '~')
6770 x = p && p[0] == modspec;
6771 modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
6775 lpat = p ? savestring (p) : 0;
6776 /* Perform the same expansions on the pattern as performed by the
6777 pattern removal expansions. FOR LATER */
6778 pat = lpat ? getpattern (lpat, quoted, 1) : 0;
6780 /* OK, now we do the case modification. */
6784 case VT_ARRAYMEMBER:
6785 temp = sh_modcase (val, pat, modop);
6786 if (vtype == VT_VARIABLE)
6790 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6797 temp = pos_params_modcase (val, pat, modop, mflags);
6798 if (temp && (mflags & MATCH_QUOTED) == 0)
6800 tt = quote_escapes (temp);
6806 #if defined (ARRAY_VARS)
6808 temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
6809 : array_modcase (array_cell (v), pat, modop, mflags);
6810 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6811 as appropriate before adding the space separators; ditto for
6823 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6824 any occur, this must be a nested command substitution, so return 0.
6825 Otherwise, return 1. A valid arithmetic expression must always have a
6826 ( before a matching ), so any cases where there are more right parens
6827 means that this must not be an arithmetic expression, though the parser
6828 will not accept it without a balanced total number of parens. */
6830 chk_arithsub (s, len)
6842 else if (s[i] == RPAREN)
6852 ADVANCE_CHAR (s, len, i);
6858 ADVANCE_CHAR (s, len, i);
6862 i = skip_single_quoted (s, len, ++i);
6866 i = skip_double_quoted ((char *)s, len, ++i);
6871 return (count == 0);
6874 /****************************************************************/
6876 /* Functions to perform parameter expansion on a string */
6878 /****************************************************************/
6880 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6882 parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
6884 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
6886 int check_nullness, var_is_set, var_is_null, var_is_special;
6887 int want_substring, want_indir, want_patsub, want_casemod;
6888 char *name, *value, *temp, *temp1;
6889 WORD_DESC *tdesc, *ret;
6890 int t_index, sindex, c, tflag, modspec;
6894 temp = temp1 = value = (char *)NULL;
6895 var_is_set = var_is_null = var_is_special = check_nullness = 0;
6896 want_substring = want_indir = want_patsub = want_casemod = 0;
6900 /* ${#var} doesn't have any of the other parameter expansions on it. */
6901 if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */
6902 name = string_extract (string, &t_index, "}", SX_VARNAME);
6904 #if defined (CASEMOD_EXPANSIONS)
6905 /* To enable case-toggling expansions using the `~' operator character
6906 change the 1 to 0. */
6907 # if defined (CASEMOD_CAPCASE)
6908 name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
6910 name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
6911 # endif /* CASEMOD_CAPCASE */
6913 name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
6914 #endif /* CASEMOD_EXPANSIONS */
6921 /* If the name really consists of a special variable, then make sure
6922 that we have the entire name. We don't allow indirect references
6923 to special variables except `#', `?', `@' and `*'. */
6924 if ((sindex == t_index &&
6925 (string[t_index] == '-' ||
6926 string[t_index] == '?' ||
6927 string[t_index] == '#')) ||
6928 (sindex == t_index - 1 && string[sindex] == '!' &&
6929 (string[t_index] == '#' ||
6930 string[t_index] == '?' ||
6931 string[t_index] == '@' ||
6932 string[t_index] == '*')))
6936 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
6937 name = (char *)xmalloc (3 + (strlen (temp1)));
6938 *name = string[sindex];
6939 if (string[sindex] == '!')
6941 /* indirect reference of $#, $?, $@, or $* */
6942 name[1] = string[sindex + 1];
6943 strcpy (name + 2, temp1);
6946 strcpy (name + 1, temp1);
6951 /* Find out what character ended the variable name. Then
6952 do the appropriate thing. */
6953 if (c = string[sindex])
6956 /* If c is followed by one of the valid parameter expansion
6957 characters, move past it as normal. If not, assume that
6958 a substring specification is being given, and do not move
6960 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
6963 if (c = string[sindex])
6966 else if (c == ':' && string[sindex] != RBRACE)
6968 else if (c == '/' && string[sindex] != RBRACE)
6970 #if defined (CASEMOD_EXPANSIONS)
6971 else if (c == '^' || c == ',' || c == '~')
6978 /* Catch the valid and invalid brace expressions that made it through the
6980 /* ${#-} is a valid expansion and means to take the length of $-.
6981 Similarly for ${#?} and ${##}... */
6982 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6983 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
6985 name = (char *)xrealloc (name, 3);
6988 c = string[sindex++];
6991 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6992 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6993 member (c, "%:=+/") && string[sindex] == RBRACE)
6995 temp = (char *)NULL;
6996 goto bad_substitution;
6999 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7000 either a variable name, one of the positional parameters or a special
7001 variable that expands to one of the positional parameters. */
7002 want_indir = *name == '!' &&
7003 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
7004 || VALID_INDIR_PARAM (name[1]));
7006 /* Determine the value of this variable. */
7008 /* Check for special variables, directly referenced. */
7009 if (SPECIAL_VAR (name, want_indir))
7012 /* Check for special expansion things, like the length of a parameter */
7013 if (*name == '#' && name[1])
7015 /* If we are not pointing at the character just after the
7016 closing brace, then we haven't gotten all of the name.
7017 Since it begins with a special character, this is a bad
7018 substitution. Also check NAME for validity before trying
7020 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
7022 temp = (char *)NULL;
7023 goto bad_substitution;
7026 number = parameter_brace_expand_length (name);
7031 return (&expand_wdesc_error);
7034 ret = alloc_word_desc ();
7035 ret->word = itos (number);
7040 /* ${@} is identical to $@. */
7041 if (name[0] == '@' && name[1] == '\0')
7043 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7044 *quoted_dollar_atp = 1;
7046 if (contains_dollar_at)
7047 *contains_dollar_at = 1;
7050 /* Process ${!PREFIX*} expansion. */
7051 if (want_indir && string[sindex - 1] == RBRACE &&
7052 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
7053 legal_variable_starter ((unsigned char) name[1]))
7058 temp1 = savestring (name + 1);
7059 number = strlen (temp1);
7060 temp1[number - 1] = '\0';
7061 x = all_variables_matching_prefix (temp1);
7062 xlist = strvec_to_word_list (x, 0, 0);
7063 if (string[sindex - 2] == '*')
7064 temp = string_list_dollar_star (xlist);
7067 temp = string_list_dollar_at (xlist, quoted);
7068 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7069 *quoted_dollar_atp = 1;
7070 if (contains_dollar_at)
7071 *contains_dollar_at = 1;
7074 dispose_words (xlist);
7078 ret = alloc_word_desc ();
7083 #if defined (ARRAY_VARS)
7084 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7085 if (want_indir && string[sindex - 1] == RBRACE &&
7086 string[sindex - 2] == ']' && valid_array_reference (name+1))
7090 temp1 = savestring (name + 1);
7091 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
7093 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
7095 temp = array_keys (temp1, quoted); /* handles assoc vars too */
7098 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7099 *quoted_dollar_atp = 1;
7100 if (contains_dollar_at)
7101 *contains_dollar_at = 1;
7107 ret = alloc_word_desc ();
7114 #endif /* ARRAY_VARS */
7116 /* Make sure that NAME is valid before trying to go on. */
7117 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
7118 var_is_special) == 0)
7120 temp = (char *)NULL;
7121 goto bad_substitution;
7125 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
7127 tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&PF_NOSPLIT2), &ind);
7132 tflag = tdesc->flags;
7133 dispose_word_desc (tdesc);
7138 #if defined (ARRAY_VARS)
7139 if (valid_array_reference (name))
7140 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
7143 var_is_set = temp != (char *)0;
7144 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
7146 /* Get the rest of the stuff inside the braces. */
7147 if (c && c != RBRACE)
7149 /* Extract the contents of the ${ ... } expansion
7150 according to the Posix.2 rules. */
7151 value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#') ? SX_POSIXEXP : 0);
7152 if (string[sindex] == RBRACE)
7155 goto bad_substitution;
7158 value = (char *)NULL;
7162 /* If this is a substring spec, process it and add the result. */
7165 temp1 = parameter_brace_substring (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7170 if (temp1 == &expand_param_error)
7171 return (&expand_wdesc_error);
7172 else if (temp1 == &expand_param_fatal)
7173 return (&expand_wdesc_fatal);
7175 ret = alloc_word_desc ();
7177 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7178 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7181 else if (want_patsub)
7183 temp1 = parameter_brace_patsub (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7188 if (temp1 == &expand_param_error)
7189 return (&expand_wdesc_error);
7190 else if (temp1 == &expand_param_fatal)
7191 return (&expand_wdesc_fatal);
7193 ret = alloc_word_desc ();
7195 ret = alloc_word_desc ();
7197 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7198 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7201 #if defined (CASEMOD_EXPANSIONS)
7202 else if (want_casemod)
7204 temp1 = parameter_brace_casemod (name, temp, ind, modspec, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7209 if (temp1 == &expand_param_error)
7210 return (&expand_wdesc_error);
7211 else if (temp1 == &expand_param_fatal)
7212 return (&expand_wdesc_fatal);
7214 ret = alloc_word_desc ();
7216 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7217 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7222 /* Do the right thing based on which character ended the variable name. */
7228 report_error (_("%s: bad substitution"), string ? string : "??");
7232 return &expand_wdesc_error;
7235 if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
7237 last_command_exit_value = EXECUTION_FAILURE;
7238 err_unboundvar (name);
7242 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7246 case '#': /* ${param#[#]pattern} */
7247 case '%': /* ${param%[%]pattern} */
7248 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
7253 temp1 = parameter_brace_remove_pattern (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7258 ret = alloc_word_desc ();
7260 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7261 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7268 if (var_is_set && var_is_null == 0)
7270 /* If the operator is `+', we don't want the value of the named
7271 variable for anything, just the value of the right hand side. */
7274 /* XXX -- if we're double-quoted and the named variable is "$@",
7275 we want to turn off any special handling of "$@" --
7276 we're not using it, so whatever is on the rhs applies. */
7277 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7278 *quoted_dollar_atp = 0;
7279 if (contains_dollar_at)
7280 *contains_dollar_at = 0;
7285 /* From Posix discussion on austin-group list. Issue 221
7286 requires that backslashes escaping `}' inside
7287 double-quoted ${...} be removed. */
7288 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7289 quoted |= Q_DOLBRACE;
7290 ret = parameter_brace_expand_rhs (name, value, c,
7293 contains_dollar_at);
7294 /* XXX - fix up later, esp. noting presence of
7295 W_HASQUOTEDNULL in ret->flags */
7299 temp = (char *)NULL;
7305 /* Otherwise do nothing; just use the value in TEMP. */
7307 else /* VAR not set or VAR is NULL. */
7310 temp = (char *)NULL;
7311 if (c == '=' && var_is_special)
7313 report_error (_("$%s: cannot assign in this way"), name);
7316 return &expand_wdesc_error;
7320 parameter_brace_expand_error (name, value);
7321 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7325 /* XXX -- if we're double-quoted and the named variable is "$@",
7326 we want to turn off any special handling of "$@" --
7327 we're not using it, so whatever is on the rhs applies. */
7328 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7329 *quoted_dollar_atp = 0;
7330 if (contains_dollar_at)
7331 *contains_dollar_at = 0;
7333 /* From Posix discussion on austin-group list. Issue 221 requires
7334 that backslashes escaping `}' inside double-quoted ${...} be
7336 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7337 quoted |= Q_DOLBRACE;
7338 ret = parameter_brace_expand_rhs (name, value, c, quoted,
7340 contains_dollar_at);
7341 /* XXX - fix up later, esp. noting presence of
7342 W_HASQUOTEDNULL in tdesc->flags */
7353 ret = alloc_word_desc ();
7360 /* Expand a single ${xxx} expansion. The braces are optional. When
7361 the braces are used, parameter_brace_expand() does the work,
7362 possibly calling param_expand recursively. */
7364 param_expand (string, sindex, quoted, expanded_something,
7365 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
7368 int *sindex, quoted, *expanded_something, *contains_dollar_at;
7369 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
7371 char *temp, *temp1, uerror[3];
7372 int zindex, t_index, expok;
7377 WORD_DESC *tdesc, *ret;
7381 c = string[++zindex];
7383 temp = (char *)NULL;
7384 ret = tdesc = (WORD_DESC *)NULL;
7387 /* Do simple cases first. Switch on what follows '$'. */
7401 temp1 = dollar_vars[TODIGIT (c)];
7402 if (unbound_vars_is_error && temp1 == (char *)NULL)
7407 last_command_exit_value = EXECUTION_FAILURE;
7408 err_unboundvar (uerror);
7409 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7412 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7413 ? quote_string (temp1)
7414 : quote_escapes (temp1);
7416 temp = (char *)NULL;
7420 /* $$ -- pid of the invoking shell. */
7422 temp = itos (dollar_dollar_pid);
7425 /* $# -- number of positional parameters. */
7427 temp = itos (number_of_args ());
7430 /* $? -- return value of the last synchronous command. */
7432 temp = itos (last_command_exit_value);
7435 /* $- -- flags supplied to the shell on invocation or by `set'. */
7437 temp = which_set_flags ();
7440 /* $! -- Pid of the last asynchronous command. */
7442 /* If no asynchronous pids have been created, expand to nothing.
7443 If `set -u' has been executed, and no async processes have
7444 been created, this is an expansion error. */
7445 if (last_asynchronous_pid == NO_PID)
7447 if (expanded_something)
7448 *expanded_something = 0;
7449 temp = (char *)NULL;
7450 if (unbound_vars_is_error)
7455 last_command_exit_value = EXECUTION_FAILURE;
7456 err_unboundvar (uerror);
7457 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7461 temp = itos (last_asynchronous_pid);
7464 /* The only difference between this and $@ is when the arg is quoted. */
7465 case '*': /* `$*' */
7466 list = list_rest_of_args ();
7469 /* According to austin-group posix proposal by Geoff Clare in
7470 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7472 "The shell shall write a message to standard error and
7473 immediately exit when it tries to expand an unset parameter
7474 other than the '@' and '*' special parameters."
7477 if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
7482 last_command_exit_value = EXECUTION_FAILURE;
7483 err_unboundvar (uerror);
7484 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7488 /* If there are no command-line arguments, this should just
7489 disappear if there are other characters in the expansion,
7490 even if it's quoted. */
7491 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
7492 temp = (char *)NULL;
7493 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
7495 /* If we have "$*" we want to make a string of the positional
7496 parameters, separated by the first character of $IFS, and
7497 quote the whole string, including the separators. If IFS
7498 is unset, the parameters are separated by ' '; if $IFS is
7499 null, the parameters are concatenated. */
7500 temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
7501 temp1 = quote_string (temp);
7503 tflag |= W_HASQUOTEDNULL;
7509 /* We check whether or not we're eventually going to split $* here,
7510 for example when IFS is empty and we are processing the rhs of
7511 an assignment statement. In that case, we don't separate the
7512 arguments at all. Otherwise, if the $* is not quoted it is
7515 # if defined (HANDLE_MULTIBYTE)
7516 if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
7518 if (expand_no_split_dollar_star && ifs_firstc == 0)
7520 temp = string_list_dollar_star (list);
7522 temp = string_list_dollar_at (list, quoted);
7524 temp = string_list_dollar_at (list, quoted);
7526 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
7527 *contains_dollar_at = 1;
7530 dispose_words (list);
7533 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7534 means that we have to turn quoting off after we split into
7535 the individually quoted arguments so that the final split
7536 on the first character of $IFS is still done. */
7537 case '@': /* `$@' */
7538 list = list_rest_of_args ();
7541 /* According to austin-group posix proposal by Geoff Clare in
7542 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7544 "The shell shall write a message to standard error and
7545 immediately exit when it tries to expand an unset parameter
7546 other than the '@' and '*' special parameters."
7549 if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
7554 last_command_exit_value = EXECUTION_FAILURE;
7555 err_unboundvar (uerror);
7556 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7560 /* We want to flag the fact that we saw this. We can't turn
7561 off quoting entirely, because other characters in the
7562 string might need it (consider "\"$@\""), but we need some
7563 way to signal that the final split on the first character
7564 of $IFS should be done, even though QUOTED is 1. */
7565 /* XXX - should this test include Q_PATQUOTE? */
7566 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7567 *quoted_dollar_at_p = 1;
7568 if (contains_dollar_at)
7569 *contains_dollar_at = 1;
7572 if (pflags & PF_NOSPLIT2)
7573 temp = string_list_internal (quoted ? quote_list (list) : list, " ");
7576 /* We want to separate the positional parameters with the first
7577 character of $IFS in case $IFS is something other than a space.
7578 We also want to make sure that splitting is done no matter what --
7579 according to POSIX.2, this expands to a list of the positional
7580 parameters no matter what IFS is set to. */
7581 temp = string_list_dollar_at (list, quoted);
7583 dispose_words (list);
7587 tdesc = parameter_brace_expand (string, &zindex, quoted, pflags,
7589 contains_dollar_at);
7591 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
7593 temp = tdesc ? tdesc->word : (char *)0;
7596 /* Quoted nulls should be removed if there is anything else
7598 /* Note that we saw the quoted null so we can add one back at
7599 the end of this function if there are no other characters
7600 in the string, discard TEMP, and go on. The exception to
7601 this is when we have "${@}" and $1 is '', since $@ needs
7602 special handling. */
7603 if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
7605 if (had_quoted_null_p)
7606 *had_quoted_null_p = 1;
7607 if (*quoted_dollar_at_p == 0)
7610 tdesc->word = temp = (char *)NULL;
7618 /* Do command or arithmetic substitution. */
7620 /* We have to extract the contents of this paren substitution. */
7621 t_index = zindex + 1;
7622 temp = extract_command_subst (string, &t_index, 0);
7625 /* For Posix.2-style `$(( ))' arithmetic substitution,
7626 extract the expression and pass it to the evaluator. */
7627 if (temp && *temp == LPAREN)
7631 temp2 = savestring (temp1);
7632 t_index = strlen (temp2) - 1;
7634 if (temp2[t_index] != RPAREN)
7640 /* Cut off ending `)' */
7641 temp2[t_index] = '\0';
7643 if (chk_arithsub (temp2, t_index) == 0)
7647 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7652 /* Expand variables found inside the expression. */
7653 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
7657 /* No error messages. */
7658 this_command_name = (char *)NULL;
7659 number = evalexp (temp1, &expok);
7664 if (interactive_shell == 0 && posixly_correct)
7666 last_command_exit_value = EXECUTION_FAILURE;
7667 return (&expand_wdesc_fatal);
7670 return (&expand_wdesc_error);
7672 temp = itos (number);
7677 if (pflags & PF_NOCOMSUB)
7678 /* we need zindex+1 because string[zindex] == RPAREN */
7679 temp1 = substring (string, *sindex, zindex+1);
7682 tdesc = command_substitute (temp, quoted);
7683 temp1 = tdesc ? tdesc->word : (char *)NULL;
7685 dispose_word_desc (tdesc);
7691 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7692 away in a future bash release. */
7694 /* Extract the contents of this arithmetic substitution. */
7695 t_index = zindex + 1;
7696 temp = extract_arithmetic_subst (string, &t_index);
7700 temp = savestring (string);
7701 if (expanded_something)
7702 *expanded_something = 0;
7706 /* Do initial variable expansion. */
7707 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
7712 /* Find the variable in VARIABLE_LIST. */
7713 temp = (char *)NULL;
7715 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
7717 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
7719 /* If this isn't a variable name, then just output the `$'. */
7720 if (temp1 == 0 || *temp1 == '\0')
7723 temp = (char *)xmalloc (2);
7726 if (expanded_something)
7727 *expanded_something = 0;
7731 /* If the variable exists, return its value cell. */
7732 var = find_variable (temp1);
7734 if (var && invisible_p (var) == 0 && var_isset (var))
7736 #if defined (ARRAY_VARS)
7737 if (assoc_p (var) || array_p (var))
7739 temp = array_p (var) ? array_reference (array_cell (var), 0)
7740 : assoc_reference (assoc_cell (var), "0");
7742 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7743 ? quote_string (temp)
7744 : quote_escapes (temp);
7745 else if (unbound_vars_is_error)
7746 goto unbound_variable;
7751 temp = value_cell (var);
7753 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7754 ? quote_string (temp)
7755 : quote_escapes (temp);
7763 temp = (char *)NULL;
7766 if (unbound_vars_is_error)
7768 last_command_exit_value = EXECUTION_FAILURE;
7769 err_unboundvar (temp1);
7778 last_command_exit_value = EXECUTION_FAILURE;
7779 return ((unbound_vars_is_error && interactive_shell == 0)
7780 ? &expand_wdesc_fatal
7781 : &expand_wdesc_error);
7792 ret = alloc_word_desc ();
7793 ret->flags = tflag; /* XXX */
7799 /* Make a word list which is the result of parameter and variable
7800 expansion, command substitution, arithmetic substitution, and
7801 quote removal of WORD. Return a pointer to a WORD_LIST which is
7802 the result of the expansion. If WORD contains a null word, the
7803 word list returned is also null.
7805 QUOTED contains flag values defined in shell.h.
7807 ISEXP is used to tell expand_word_internal that the word should be
7808 treated as the result of an expansion. This has implications for
7809 how IFS characters in the word are treated.
7811 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7812 they point to an integer value which receives information about expansion.
7813 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7814 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7817 This only does word splitting in the case of $@ expansion. In that
7818 case, we split on ' '. */
7820 /* Values for the local variable quoted_state. */
7822 #define PARTIALLY_QUOTED 1
7823 #define WHOLLY_QUOTED 2
7826 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
7829 int *contains_dollar_at;
7830 int *expanded_something;
7835 /* The intermediate string that we build while expanding. */
7838 /* The current size of the above object. */
7841 /* Index into ISTRING. */
7844 /* Temporary string storage. */
7847 /* The text of WORD. */
7848 register char *string;
7850 /* The size of STRING. */
7853 /* The index into STRING. */
7856 /* This gets 1 if we see a $@ while quoted. */
7857 int quoted_dollar_at;
7859 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7860 whether WORD contains no quoting characters, a partially quoted
7861 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7865 int had_quoted_null;
7868 int pflags; /* flags passed to param_expand */
7870 int assignoff; /* If assignment, offset of `=' */
7872 register unsigned char c; /* Current character. */
7873 int t_index; /* For calls to string_extract_xxx. */
7879 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
7880 istring[istring_index = 0] = '\0';
7881 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
7882 quoted_state = UNQUOTED;
7884 string = word->word;
7886 goto finished_with_string;
7887 /* Don't need the string length for the SADD... and COPY_ macros unless
7888 multibyte characters are possible. */
7889 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
7891 if (contains_dollar_at)
7892 *contains_dollar_at = 0;
7896 /* Begin the expansion. */
7902 /* Case on toplevel character. */
7906 goto finished_with_string;
7910 #if HANDLE_MULTIBYTE
7911 if (MB_CUR_MAX > 1 && string[sindex])
7913 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
7918 temp = (char *)xmalloc (3);
7920 temp[1] = c = string[sindex];
7931 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
7937 #if defined (PROCESS_SUBSTITUTION)
7938 /* Process substitution. */
7942 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
7944 sindex--; /* add_character: label increments sindex */
7948 t_index = sindex + 1; /* skip past both '<' and LPAREN */
7950 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
7953 /* If the process substitution specification is `<()', we want to
7954 open the pipe for writing in the child and produce output; if
7955 it is `>()', we want to open the pipe for reading in the child
7956 and consume input. */
7957 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
7961 goto dollar_add_string;
7963 #endif /* PROCESS_SUBSTITUTION */
7966 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7967 which are not assignment statements are not expanded. If the
7968 shell isn't in posix mode, though, we perform tilde expansion
7969 on `likely candidate' unquoted assignment statements (flags
7970 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7971 contains an unquoted :~ or =~. Something to think about: we
7972 now have a flag that says to perform tilde expansion on arguments
7973 to `assignment builtins' like declare and export that look like
7974 assignment statements. We now do tilde expansion on such words
7975 even in POSIX mode. */
7976 if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
7978 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
7979 goto add_ifs_character;
7983 /* If we're not in posix mode or forcing assignment-statement tilde
7984 expansion, note where the `=' appears in the word and prepare to
7985 do tilde expansion following the first `='. */
7986 if ((word->flags & W_ASSIGNMENT) &&
7987 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
7988 assignoff == -1 && sindex > 0)
7990 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */
7991 word->flags |= W_ITILDE;
7993 else if ((word->flags & W_ASSIGNMENT) &&
7994 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
7995 string[sindex+1] == '~')
7996 word->flags |= W_ITILDE;
7998 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
7999 goto add_ifs_character;
8004 if (word->flags & W_NOTILDE)
8006 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8007 goto add_ifs_character;
8012 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
8013 string[sindex+1] == '~')
8014 word->flags |= W_ITILDE;
8016 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8017 goto add_ifs_character;
8022 /* If the word isn't supposed to be tilde expanded, or we're not
8023 at the start of a word or after an unquoted : or = in an
8024 assignment statement, we don't do tilde expansion. */
8025 if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
8026 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
8027 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8029 word->flags &= ~W_ITILDE;
8030 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
8031 goto add_ifs_character;
8036 if (word->flags & W_ASSIGNRHS)
8038 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
8043 temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
8045 word->flags &= ~W_ITILDE;
8047 if (temp && *temp && t_index > 0)
8049 temp1 = bash_tilde_expand (temp, tflag);
8050 if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
8054 goto add_character; /* tilde expansion failed */
8059 goto add_quoted_string; /* XXX was add_string */
8068 if (expanded_something)
8069 *expanded_something = 1;
8072 pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
8073 if (word->flags & W_NOSPLIT2)
8074 pflags |= PF_NOSPLIT2;
8075 tword = param_expand (string, &sindex, quoted, expanded_something,
8076 &has_dollar_at, "ed_dollar_at,
8077 &had_quoted_null, pflags);
8079 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
8083 return ((tword == &expand_wdesc_error) ? &expand_word_error
8084 : &expand_word_fatal);
8086 if (contains_dollar_at && has_dollar_at)
8087 *contains_dollar_at = 1;
8089 if (tword && (tword->flags & W_HASQUOTEDNULL))
8090 had_quoted_null = 1;
8093 dispose_word_desc (tword);
8098 case '`': /* Backquoted command substitution. */
8102 temp = string_extract (string, &sindex, "`", SX_REQMATCH);
8103 /* The test of sindex against t_index is to allow bare instances of
8104 ` to pass through, for backwards compatibility. */
8105 if (temp == &extract_string_error || temp == &extract_string_fatal)
8107 if (sindex - 1 == t_index)
8112 report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
8115 return ((temp == &extract_string_error) ? &expand_word_error
8116 : &expand_word_fatal);
8119 if (expanded_something)
8120 *expanded_something = 1;
8122 if (word->flags & W_NOCOMSUB)
8123 /* sindex + 1 because string[sindex] == '`' */
8124 temp1 = substring (string, t_index, sindex + 1);
8127 de_backslash (temp);
8128 tword = command_substitute (temp, quoted);
8129 temp1 = tword ? tword->word : (char *)NULL;
8131 dispose_word_desc (tword);
8135 goto dollar_add_string;
8139 if (string[sindex + 1] == '\n')
8145 c = string[++sindex];
8147 if (quoted & Q_HERE_DOCUMENT)
8149 else if (quoted & Q_DOUBLE_QUOTES)
8154 /* From Posix discussion on austin-group list: Backslash escaping
8155 a } in ${...} is removed. Issue 0000221 */
8156 if ((quoted & Q_DOLBRACE) && c == RBRACE)
8158 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
8160 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
8162 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
8167 sindex--; /* add_character: label increments sindex */
8172 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
8177 /* BEFORE jumping here, we need to increment sindex if appropriate */
8178 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
8179 DEFAULT_ARRAY_SIZE);
8180 istring[istring_index++] = twochars[0];
8181 istring[istring_index++] = twochars[1];
8182 istring[istring_index] = '\0';
8188 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
8190 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8195 temp = string_extract_double_quoted (string, &sindex, 0);
8197 /* If the quotes surrounded the entire string, then the
8198 whole word was quoted. */
8199 quoted_state = (t_index == 1 && string[sindex] == '\0')
8205 tword = alloc_word_desc ();
8208 temp = (char *)NULL;
8211 /* Need to get W_HASQUOTEDNULL flag through this function. */
8212 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
8214 if (list == &expand_word_error || list == &expand_word_fatal)
8218 /* expand_word_internal has already freed temp_word->word
8219 for us because of the way it prints error messages. */
8220 tword->word = (char *)NULL;
8221 dispose_word (tword);
8225 dispose_word (tword);
8227 /* "$@" (a double-quoted dollar-at) expands into nothing,
8228 not even a NULL word, when there are no positional
8230 if (list == 0 && has_dollar_at)
8236 /* If we get "$@", we know we have expanded something, so we
8237 need to remember it for the final split on $IFS. This is
8238 a special case; it's the only case where a quoted string
8239 can expand into more than one word. It's going to come back
8240 from the above call to expand_word_internal as a list with
8241 a single word, in which all characters are quoted and
8242 separated by blanks. What we want to do is to turn it back
8243 into a list for the next piece of code. */
8245 dequote_list (list);
8247 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
8248 had_quoted_null = 1;
8253 if (contains_dollar_at)
8254 *contains_dollar_at = 1;
8255 if (expanded_something)
8256 *expanded_something = 1;
8261 /* What we have is "". This is a minor optimization. */
8263 list = (WORD_LIST *)NULL;
8266 /* The code above *might* return a list (consider the case of "$@",
8267 where it returns "$1", "$2", etc.). We can't throw away the
8268 rest of the list, and we have to make sure each word gets added
8269 as quoted. We test on tresult->next: if it is non-NULL, we
8270 quote the whole list, save it to a string with string_list, and
8271 add that string. We don't need to quote the results of this
8272 (and it would be wrong, since that would quote the separators
8273 as well), so we go directly to add_string. */
8279 if (quoted_dollar_at && word->flags & W_NOSPLIT2)
8280 temp = string_list_internal (quote_list (list), " ");
8283 /* Testing quoted_dollar_at makes sure that "$@" is
8284 split correctly when $IFS does not contain a space. */
8285 temp = quoted_dollar_at
8286 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
8287 : string_list (quote_list (list));
8288 dispose_words (list);
8293 temp = savestring (list->word->word);
8294 tflag = list->word->flags;
8295 dispose_words (list);
8297 /* If the string is not a quoted null string, we want
8298 to remove any embedded unquoted CTLNUL characters.
8299 We do not want to turn quoted null strings back into
8300 the empty string, though. We do this because we
8301 want to remove any quoted nulls from expansions that
8302 contain other characters. For example, if we have
8303 x"$*"y or "x$*y" and there are no positional parameters,
8304 the $* should expand into nothing. */
8305 /* We use the W_HASQUOTEDNULL flag to differentiate the
8306 cases: a quoted null character as above and when
8307 CTLNUL is contained in the (non-null) expansion
8308 of some variable. We use the had_quoted_null flag to
8309 pass the value through this function to its caller. */
8310 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
8311 remove_quoted_nulls (temp); /* XXX */
8315 temp = (char *)NULL;
8318 /* We do not want to add quoted nulls to strings that are only
8319 partially quoted; we can throw them away. */
8320 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
8329 temp = quote_string (temp);
8337 sindex--; /* add_character: label increments sindex */
8345 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
8347 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8352 temp = string_extract_single_quoted (string, &sindex);
8354 /* If the entire STRING was surrounded by single quotes,
8355 then the string is wholly quoted. */
8356 quoted_state = (t_index == 1 && string[sindex] == '\0')
8360 /* If all we had was '', it is a null expansion. */
8364 temp = (char *)NULL;
8367 remove_quoted_escapes (temp); /* ??? */
8369 /* We do not want to add quoted nulls to strings that are only
8370 partially quoted; such nulls are discarded. */
8371 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
8374 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8378 sindex--; /* add_character: label increments sindex */
8382 goto add_quoted_string;
8387 /* This is the fix for " $@ " */
8389 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
8391 if (string[sindex]) /* from old goto dollar_add_string */
8400 #if HANDLE_MULTIBYTE
8406 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
8411 twochars[0] = CTLESC;
8418 SADD_MBCHAR (temp, string, sindex, string_size);
8421 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
8422 DEFAULT_ARRAY_SIZE);
8423 istring[istring_index++] = c;
8424 istring[istring_index] = '\0';
8426 /* Next character. */
8431 finished_with_string:
8432 /* OK, we're ready to return. If we have a quoted string, and
8433 quoted_dollar_at is not set, we do no splitting at all; otherwise
8434 we split on ' '. The routines that call this will handle what to
8435 do if nothing has been expanded. */
8437 /* Partially and wholly quoted strings which expand to the empty
8438 string are retained as an empty arguments. Unquoted strings
8439 which expand to the empty string are discarded. The single
8440 exception is the case of expanding "$@" when there are no
8441 positional parameters. In that case, we discard the expansion. */
8443 /* Because of how the code that handles "" and '' in partially
8444 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8445 if we saw quoting characters, but the expansion was empty.
8446 "" and '' are tossed away before we get to this point when
8447 processing partially quoted strings. This makes "" and $xxx""
8448 equivalent when xxx is unset. We also look to see whether we
8449 saw a quoted null from a ${} expansion and add one back if we
8452 /* If we expand to nothing and there were no single or double quotes
8453 in the word, we throw it away. Otherwise, we return a NULL word.
8454 The single exception is for $@ surrounded by double quotes when
8455 there are no positional parameters. In that case, we also throw
8458 if (*istring == '\0')
8460 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
8462 istring[0] = CTLNUL;
8464 tword = make_bare_word (istring);
8465 tword->flags |= W_HASQUOTEDNULL; /* XXX */
8466 list = make_word_list (tword, (WORD_LIST *)NULL);
8467 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8468 tword->flags |= W_QUOTED;
8470 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8471 and a double-quoted "$@" appears anywhere in it, then the entire
8473 else if (quoted_state == UNQUOTED || quoted_dollar_at)
8474 list = (WORD_LIST *)NULL;
8478 tword = make_bare_word (istring);
8479 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8480 tword->flags |= W_QUOTED;
8481 list = make_word_list (tword, (WORD_LIST *)NULL);
8485 list = (WORD_LIST *)NULL;
8488 else if (word->flags & W_NOSPLIT)
8490 tword = make_bare_word (istring);
8491 if (word->flags & W_ASSIGNMENT)
8492 tword->flags |= W_ASSIGNMENT; /* XXX */
8493 if (word->flags & W_COMPASSIGN)
8494 tword->flags |= W_COMPASSIGN; /* XXX */
8495 if (word->flags & W_NOGLOB)
8496 tword->flags |= W_NOGLOB; /* XXX */
8497 if (word->flags & W_NOEXPAND)
8498 tword->flags |= W_NOEXPAND; /* XXX */
8499 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8500 tword->flags |= W_QUOTED;
8501 if (had_quoted_null)
8502 tword->flags |= W_HASQUOTEDNULL;
8503 list = make_word_list (tword, (WORD_LIST *)NULL);
8509 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
8511 /* If we have $@, we need to split the results no matter what. If
8512 IFS is unset or NULL, string_list_dollar_at has separated the
8513 positional parameters with a space, so we split on space (we have
8514 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8515 string_list_dollar_at has separated the positional parameters
8516 with the first character of $IFS, so we split on $IFS. */
8517 if (has_dollar_at && ifs_chars)
8518 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
8521 tword = make_bare_word (istring);
8522 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
8523 tword->flags |= W_QUOTED;
8524 if (word->flags & W_ASSIGNMENT)
8525 tword->flags |= W_ASSIGNMENT;
8526 if (word->flags & W_COMPASSIGN)
8527 tword->flags |= W_COMPASSIGN;
8528 if (word->flags & W_NOGLOB)
8529 tword->flags |= W_NOGLOB;
8530 if (word->flags & W_NOEXPAND)
8531 tword->flags |= W_NOEXPAND;
8532 if (had_quoted_null)
8533 tword->flags |= W_HASQUOTEDNULL; /* XXX */
8534 list = make_word_list (tword, (WORD_LIST *)NULL);
8542 /* **************************************************************** */
8544 /* Functions for Quote Removal */
8546 /* **************************************************************** */
8548 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8549 backslash quoting rules for within double quotes or a here document. */
8551 string_quote_removal (string, quoted)
8556 char *r, *result_string, *temp, *send;
8557 int sindex, tindex, dquote;
8561 /* The result can be no longer than the original string. */
8562 slen = strlen (string);
8563 send = string + slen;
8565 r = result_string = (char *)xmalloc (slen + 1);
8567 for (dquote = sindex = 0; c = string[sindex];)
8572 c = string[++sindex];
8578 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
8583 SCOPY_CHAR_M (r, string, send, sindex);
8587 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
8593 tindex = sindex + 1;
8594 temp = string_extract_single_quoted (string, &tindex);
8605 dquote = 1 - dquote;
8611 return (result_string);
8616 /* Perform quote removal on word WORD. This allocates and returns a new
8619 word_quote_removal (word, quoted)
8626 t = string_quote_removal (word->word, quoted);
8627 w = alloc_word_desc ();
8628 w->word = t ? t : savestring ("");
8632 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8633 the members of the list are treated as if they are surrounded by
8634 double quotes. Return a new list, or NULL if LIST is NULL. */
8636 word_list_quote_removal (list, quoted)
8640 WORD_LIST *result, *t, *tresult, *e;
8642 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8644 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
8646 result = (WORD_LIST *) list_append (result, tresult);
8649 result = e = tresult;
8662 /*******************************************
8664 * Functions to perform word splitting *
8666 *******************************************/
8676 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
8678 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8679 handle multibyte chars in IFS */
8680 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
8681 for (t = ifs_value ; t && *t; t++)
8687 #if defined (HANDLE_MULTIBYTE)
8690 ifs_firstc[0] = '\0';
8696 ifs_len = strnlen (ifs_value, MB_CUR_MAX);
8697 ifs_firstc_len = MBLEN (ifs_value, ifs_len);
8698 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
8700 ifs_firstc[0] = ifs_value[0];
8701 ifs_firstc[1] = '\0';
8705 memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
8708 ifs_firstc = ifs_value ? *ifs_value : 0;
8718 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8719 is not quoted. list_string () performs quote removal for us, even if we
8720 don't do any splitting. */
8722 word_split (w, ifs_chars)
8732 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
8733 result = list_string (w->word, xifs, w->flags & W_QUOTED);
8736 result = (WORD_LIST *)NULL;
8741 /* Perform word splitting on LIST and return the RESULT. It is possible
8742 to return (WORD_LIST *)NULL. */
8744 word_list_split (list)
8747 WORD_LIST *result, *t, *tresult, *e;
8749 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8751 tresult = word_split (t->word, ifs_value);
8753 result = e = tresult;
8764 /**************************************************
8766 * Functions to expand an entire WORD_LIST *
8768 **************************************************/
8770 /* Do any word-expansion-specific cleanup and jump to top_level */
8772 exp_jump_to_top_level (v)
8775 set_pipestatus_from_exit (last_command_exit_value);
8777 /* Cleanup code goes here. */
8778 expand_no_split_dollar_star = 0; /* XXX */
8779 expanding_redir = 0;
8780 assigning_in_environment = 0;
8782 if (parse_and_execute_level == 0)
8783 top_level_cleanup (); /* from sig.c */
8785 jump_to_top_level (v);
8788 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8789 ELIST, and set ELIST to the new list. */
8790 #define PREPEND_LIST(nlist, elist) \
8791 do { nlist->next = elist; elist = nlist; } while (0)
8793 /* Separate out any initial variable assignments from TLIST. If set -k has
8794 been executed, remove all assignment statements from TLIST. Initial
8795 variable assignments and other environment assignments are placed
8796 on SUBST_ASSIGN_VARLIST. */
8798 separate_out_assignments (tlist)
8801 register WORD_LIST *vp, *lp;
8804 return ((WORD_LIST *)NULL);
8806 if (subst_assign_varlist)
8807 dispose_words (subst_assign_varlist); /* Clean up after previous error */
8809 subst_assign_varlist = (WORD_LIST *)NULL;
8812 /* Separate out variable assignments at the start of the command.
8813 Loop invariant: vp->next == lp
8815 lp = list of words left after assignment statements skipped
8816 tlist = original list of words
8818 while (lp && (lp->word->flags & W_ASSIGNMENT))
8824 /* If lp != tlist, we have some initial assignment statements.
8825 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8826 words and TLIST point to the remaining words. */
8829 subst_assign_varlist = tlist;
8830 /* ASSERT(vp->next == lp); */
8831 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
8832 tlist = lp; /* remainder of word list */
8835 /* vp == end of variable list */
8836 /* tlist == remainder of original word list without variable assignments */
8838 /* All the words in tlist were assignment statements */
8839 return ((WORD_LIST *)NULL);
8841 /* ASSERT(tlist != NULL); */
8842 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8844 /* If the -k option is in effect, we need to go through the remaining
8845 words, separate out the assignment words, and place them on
8846 SUBST_ASSIGN_VARLIST. */
8847 if (place_keywords_in_env)
8849 WORD_LIST *tp; /* tp == running pointer into tlist */
8854 /* Loop Invariant: tp->next == lp */
8855 /* Loop postcondition: tlist == word list without assignment statements */
8858 if (lp->word->flags & W_ASSIGNMENT)
8860 /* Found an assignment statement, add this word to end of
8861 subst_assign_varlist (vp). */
8862 if (!subst_assign_varlist)
8863 subst_assign_varlist = vp = lp;
8870 /* Remove the word pointed to by LP from TLIST. */
8871 tp->next = lp->next;
8872 /* ASSERT(vp == lp); */
8873 lp->next = (WORD_LIST *)NULL;
8886 #define WEXP_VARASSIGN 0x001
8887 #define WEXP_BRACEEXP 0x002
8888 #define WEXP_TILDEEXP 0x004
8889 #define WEXP_PARAMEXP 0x008
8890 #define WEXP_PATHEXP 0x010
8892 /* All of the expansions, including variable assignments at the start of
8894 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8896 /* All of the expansions except variable assignments at the start of
8898 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8900 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8901 expansion, command substitution, arithmetic expansion, word splitting, and
8903 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8905 /* Take the list of words in LIST and do the various substitutions. Return
8906 a new list of words which is the expanded list, and without things like
8907 variable assignments. */
8913 return (expand_word_list_internal (list, WEXP_ALL));
8916 /* Same as expand_words (), but doesn't hack variable or environment
8919 expand_words_no_vars (list)
8922 return (expand_word_list_internal (list, WEXP_NOVARS));
8926 expand_words_shellexp (list)
8929 return (expand_word_list_internal (list, WEXP_SHELLEXP));
8933 glob_expand_word_list (tlist, eflags)
8937 char **glob_array, *temp_string;
8938 register int glob_index;
8939 WORD_LIST *glob_list, *output_list, *disposables, *next;
8942 output_list = disposables = (WORD_LIST *)NULL;
8943 glob_array = (char **)NULL;
8946 /* For each word, either globbing is attempted or the word is
8947 added to orig_list. If globbing succeeds, the results are
8948 added to orig_list and the word (tlist) is added to the list
8949 of disposable words. If globbing fails and failed glob
8950 expansions are left unchanged (the shell default), the
8951 original word is added to orig_list. If globbing fails and
8952 failed glob expansions are removed, the original word is
8953 added to the list of disposable words. orig_list ends up
8954 in reverse order and requires a call to REVERSE_LIST to
8955 be set right. After all words are examined, the disposable
8959 /* If the word isn't an assignment and contains an unquoted
8960 pattern matching character, then glob it. */
8961 if ((tlist->word->flags & W_NOGLOB) == 0 &&
8962 unquoted_glob_pattern_p (tlist->word->word))
8964 glob_array = shell_glob_filename (tlist->word->word);
8966 /* Handle error cases.
8967 I don't think we should report errors like "No such file
8968 or directory". However, I would like to report errors
8969 like "Read failed". */
8971 if (glob_array == 0 || GLOB_FAILED (glob_array))
8973 glob_array = (char **)xmalloc (sizeof (char *));
8974 glob_array[0] = (char *)NULL;
8977 /* Dequote the current word in case we have to use it. */
8978 if (glob_array[0] == NULL)
8980 temp_string = dequote_string (tlist->word->word);
8981 free (tlist->word->word);
8982 tlist->word->word = temp_string;
8985 /* Make the array into a word list. */
8986 glob_list = (WORD_LIST *)NULL;
8987 for (glob_index = 0; glob_array[glob_index]; glob_index++)
8989 tword = make_bare_word (glob_array[glob_index]);
8990 tword->flags |= W_GLOBEXP; /* XXX */
8991 glob_list = make_word_list (tword, glob_list);
8996 output_list = (WORD_LIST *)list_append (glob_list, output_list);
8997 PREPEND_LIST (tlist, disposables);
8999 else if (fail_glob_expansion != 0)
9001 report_error (_("no match: %s"), tlist->word->word);
9002 exp_jump_to_top_level (DISCARD);
9004 else if (allow_null_glob_expansion == 0)
9006 /* Failed glob expressions are left unchanged. */
9007 PREPEND_LIST (tlist, output_list);
9011 /* Failed glob expressions are removed. */
9012 PREPEND_LIST (tlist, disposables);
9017 /* Dequote the string. */
9018 temp_string = dequote_string (tlist->word->word);
9019 free (tlist->word->word);
9020 tlist->word->word = temp_string;
9021 PREPEND_LIST (tlist, output_list);
9024 strvec_dispose (glob_array);
9025 glob_array = (char **)NULL;
9031 dispose_words (disposables);
9034 output_list = REVERSE_LIST (output_list, WORD_LIST *);
9036 return (output_list);
9039 #if defined (BRACE_EXPANSION)
9041 brace_expand_word_list (tlist, eflags)
9045 register char **expansions;
9047 WORD_LIST *disposables, *output_list, *next;
9051 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
9055 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
9057 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9058 PREPEND_LIST (tlist, output_list);
9062 /* Only do brace expansion if the word has a brace character. If
9063 not, just add the word list element to BRACES and continue. In
9064 the common case, at least when running shell scripts, this will
9065 degenerate to a bunch of calls to `mbschr', and then what is
9066 basically a reversal of TLIST into BRACES, which is corrected
9067 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9069 if (mbschr (tlist->word->word, LBRACE))
9071 expansions = brace_expand (tlist->word->word);
9073 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
9075 w = make_word (temp_string);
9076 /* If brace expansion didn't change the word, preserve
9077 the flags. We may want to preserve the flags
9078 unconditionally someday -- XXX */
9079 if (STREQ (temp_string, tlist->word->word))
9080 w->flags = tlist->word->flags;
9081 output_list = make_word_list (w, output_list);
9082 free (expansions[eindex]);
9086 /* Add TLIST to the list of words to be freed after brace
9087 expansion has been performed. */
9088 PREPEND_LIST (tlist, disposables);
9091 PREPEND_LIST (tlist, output_list);
9095 dispose_words (disposables);
9098 output_list = REVERSE_LIST (output_list, WORD_LIST *);
9100 return (output_list);
9104 #if defined (ARRAY_VARS)
9105 /* Take WORD, a compound associative array assignment, and internally run
9106 'declare -A w', where W is the variable name portion of WORD. */
9108 make_internal_declare (word, option)
9116 w = make_word (word);
9118 t = assignment (w->word, 0);
9121 wl = make_word_list (w, (WORD_LIST *)NULL);
9122 wl = make_word_list (make_word (option), wl);
9124 return (declare_builtin (wl));
9129 shell_expand_word_list (tlist, eflags)
9133 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
9134 int expanded_something, has_dollar_at;
9137 /* We do tilde expansion all the time. This is what 1003.2 says. */
9138 new_list = (WORD_LIST *)NULL;
9139 for (orig_list = tlist; tlist; tlist = next)
9141 temp_string = tlist->word->word;
9145 #if defined (ARRAY_VARS)
9146 /* If this is a compound array assignment to a builtin that accepts
9147 such assignments (e.g., `declare'), take the assignment and perform
9148 it separately, handling the semantics of declarations inside shell
9149 functions. This avoids the double-evaluation of such arguments,
9150 because `declare' does some evaluation of compound assignments on
9152 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
9156 if (tlist->word->flags & W_ASSIGNASSOC)
9157 make_internal_declare (tlist->word->word, "-A");
9159 t = do_word_assignment (tlist->word);
9162 last_command_exit_value = EXECUTION_FAILURE;
9163 exp_jump_to_top_level (DISCARD);
9166 /* Now transform the word as ksh93 appears to do and go on */
9167 t = assignment (tlist->word->word, 0);
9168 tlist->word->word[t] = '\0';
9169 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
9173 expanded_something = 0;
9174 expanded = expand_word_internal
9175 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
9177 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
9179 /* By convention, each time this error is returned,
9180 tlist->word->word has already been freed. */
9181 tlist->word->word = (char *)NULL;
9183 /* Dispose our copy of the original list. */
9184 dispose_words (orig_list);
9185 /* Dispose the new list we're building. */
9186 dispose_words (new_list);
9188 last_command_exit_value = EXECUTION_FAILURE;
9189 if (expanded == &expand_word_error)
9190 exp_jump_to_top_level (DISCARD);
9192 exp_jump_to_top_level (FORCE_EOF);
9195 /* Don't split words marked W_NOSPLIT. */
9196 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
9198 temp_list = word_list_split (expanded);
9199 dispose_words (expanded);
9203 /* If no parameter expansion, command substitution, process
9204 substitution, or arithmetic substitution took place, then
9205 do not do word splitting. We still have to remove quoted
9206 null characters from the result. */
9207 word_list_remove_quoted_nulls (expanded);
9208 temp_list = expanded;
9211 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
9212 new_list = (WORD_LIST *)list_append (expanded, new_list);
9216 dispose_words (orig_list);
9219 new_list = REVERSE_LIST (new_list, WORD_LIST *);
9224 /* The workhorse for expand_words () and expand_words_no_vars ().
9225 First arg is LIST, a WORD_LIST of words.
9226 Second arg EFLAGS is a flags word controlling which expansions are
9229 This does all of the substitutions: brace expansion, tilde expansion,
9230 parameter expansion, command substitution, arithmetic expansion,
9231 process substitution, word splitting, and pathname expansion, according
9232 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9233 set, or for which no expansion is done, do not undergo word splitting.
9234 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
9236 expand_word_list_internal (list, eflags)
9240 WORD_LIST *new_list, *temp_list;
9244 return ((WORD_LIST *)NULL);
9246 garglist = new_list = copy_word_list (list);
9247 if (eflags & WEXP_VARASSIGN)
9249 garglist = new_list = separate_out_assignments (new_list);
9252 if (subst_assign_varlist)
9254 /* All the words were variable assignments, so they are placed
9255 into the shell's environment. */
9256 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
9258 this_command_name = (char *)NULL; /* no arithmetic errors */
9259 tint = do_word_assignment (temp_list->word);
9260 /* Variable assignment errors in non-interactive shells
9261 running in Posix.2 mode cause the shell to exit. */
9264 last_command_exit_value = EXECUTION_FAILURE;
9265 if (interactive_shell == 0 && posixly_correct)
9266 exp_jump_to_top_level (FORCE_EOF);
9268 exp_jump_to_top_level (DISCARD);
9271 dispose_words (subst_assign_varlist);
9272 subst_assign_varlist = (WORD_LIST *)NULL;
9274 return ((WORD_LIST *)NULL);
9278 /* Begin expanding the words that remain. The expansions take place on
9279 things that aren't really variable assignments. */
9281 #if defined (BRACE_EXPANSION)
9282 /* Do brace expansion on this word if there are any brace characters
9284 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
9285 new_list = brace_expand_word_list (new_list, eflags);
9286 #endif /* BRACE_EXPANSION */
9288 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9289 variable substitution, command substitution, arithmetic expansion,
9290 and word splitting. */
9291 new_list = shell_expand_word_list (new_list, eflags);
9293 /* Okay, we're almost done. Now let's just do some filename
9297 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
9298 /* Glob expand the word list unless globbing has been disabled. */
9299 new_list = glob_expand_word_list (new_list, eflags);
9301 /* Dequote the words, because we're not performing globbing. */
9302 new_list = dequote_list (new_list);
9305 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
9307 sh_wassign_func_t *assign_func;
9309 /* If the remainder of the words expand to nothing, Posix.2 requires
9310 that the variable and environment assignments affect the shell's
9312 assign_func = new_list ? assign_in_env : do_word_assignment;
9313 tempenv_assign_error = 0;
9315 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
9317 this_command_name = (char *)NULL;
9318 assigning_in_environment = (assign_func == assign_in_env);
9319 tint = (*assign_func) (temp_list->word);
9320 assigning_in_environment = 0;
9321 /* Variable assignment errors in non-interactive shells running
9322 in Posix.2 mode cause the shell to exit. */
9325 if (assign_func == do_word_assignment)
9327 last_command_exit_value = EXECUTION_FAILURE;
9328 if (interactive_shell == 0 && posixly_correct)
9329 exp_jump_to_top_level (FORCE_EOF);
9331 exp_jump_to_top_level (DISCARD);
9334 tempenv_assign_error++;
9338 dispose_words (subst_assign_varlist);
9339 subst_assign_varlist = (WORD_LIST *)NULL;
9343 tint = list_length (new_list) + 1;
9344 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
9345 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
9346 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
9347 glob_argv_flags[tint] = '\0';