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-2012 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"
57 #include "builtins/getopt.h"
58 #include "builtins/common.h"
60 #include "builtins/builtext.h"
62 #include <tilde/tilde.h>
63 #include <glob/strmatch.h>
69 /* The size that strings change by. */
70 #define DEFAULT_INITIAL_ARRAY_SIZE 112
71 #define DEFAULT_ARRAY_SIZE 128
77 #define VT_ARRAYMEMBER 3
80 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
82 /* Flags for quoted_strchr */
83 #define ST_BACKSL 0x01
84 #define ST_CTLESC 0x02
85 #define ST_SQUOTE 0x04 /* unused yet */
86 #define ST_DQUOTE 0x08 /* unused yet */
88 /* Flags for the `pflags' argument to param_expand() */
89 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
91 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
92 #define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */
94 /* These defs make it easier to use the editor. */
100 #if defined (HANDLE_MULTIBYTE)
105 /* Evaluates to 1 if C is one of the shell's special parameters whose length
106 can be taken, but is also one of the special expansion characters. */
107 #define VALID_SPECIAL_LENGTH_PARAM(c) \
108 ((c) == '-' || (c) == '?' || (c) == '#')
110 /* Evaluates to 1 if C is one of the shell's special parameters for which an
111 indirect variable reference may be made. */
112 #define VALID_INDIR_PARAM(c) \
113 ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
115 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
116 in ${parameter[:]OPword}. */
117 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
119 /* Evaluates to 1 if this is one of the shell's special variables. */
120 #define SPECIAL_VAR(name, wi) \
121 ((DIGIT (*name) && all_digits (name)) || \
122 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
123 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
125 /* An expansion function that takes a string and a quoted flag and returns
126 a WORD_LIST *. Used as the type of the third argument to
127 expand_string_if_necessary(). */
128 typedef WORD_LIST *EXPFUNC __P((char *, int));
130 /* Process ID of the last command executed within command substitution. */
131 pid_t last_command_subst_pid = NO_PID;
132 pid_t current_command_subst_pid = NO_PID;
134 /* Variables used to keep track of the characters in IFS. */
137 unsigned char ifs_cmap[UCHAR_MAX + 1];
139 #if defined (HANDLE_MULTIBYTE)
140 unsigned char ifs_firstc[MB_LEN_MAX];
141 size_t ifs_firstc_len;
143 unsigned char ifs_firstc;
146 /* Sentinel to tell when we are performing variable assignments preceding a
147 command name and putting them into the environment. Used to make sure
148 we use the temporary environment when looking up variable values. */
149 int assigning_in_environment;
151 /* Used to hold a list of variable assignments preceding a command. Global
152 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
153 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
154 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
156 /* Extern functions and variables from different files. */
157 extern int last_command_exit_value, last_command_exit_signal;
158 extern int subshell_environment, line_number;
159 extern int subshell_level, parse_and_execute_level, sourcelevel;
160 extern int eof_encountered;
161 extern int return_catch_flag, return_catch_value;
162 extern pid_t dollar_dollar_pid;
163 extern int posixly_correct;
164 extern char *this_command_name;
165 extern struct fd_bitmap *current_fds_to_close;
166 extern int wordexp_only;
167 extern int expanding_redir;
168 extern int tempenv_assign_error;
170 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
171 extern wchar_t *wcsdup __P((const wchar_t *));
174 /* Non-zero means to allow unmatched globbed filenames to expand to
176 int allow_null_glob_expansion;
178 /* Non-zero means to throw an error when globbing fails to match anything. */
179 int fail_glob_expansion;
182 /* Variables to keep track of which words in an expanded word list (the
183 output of expand_word_list_internal) are the result of globbing
184 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
185 (CURRENTLY UNUSED). */
186 char *glob_argv_flags;
187 static int glob_argv_flags_size;
190 static WORD_LIST expand_word_error, expand_word_fatal;
191 static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
192 static char expand_param_error, expand_param_fatal;
193 static char extract_string_error, extract_string_fatal;
195 /* Tell the expansion functions to not longjmp back to top_level on fatal
196 errors. Enabled when doing completion and prompt string expansion. */
197 static int no_longjmp_on_fatal_error = 0;
199 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
200 $* on $IFS, primarily when doing assignment statements. */
201 static int expand_no_split_dollar_star = 0;
203 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
204 without any leading variable assignments. */
205 static WORD_LIST *garglist = (WORD_LIST *)NULL;
207 static char *quoted_substring __P((char *, int, int));
208 static int quoted_strlen __P((char *));
209 static char *quoted_strchr __P((char *, int, int));
211 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
212 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
213 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
214 static WORD_LIST *expand_string_internal __P((char *, int));
215 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
216 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
218 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
219 static char *make_quoted_char __P((int));
220 static WORD_LIST *quote_list __P((WORD_LIST *));
222 static int unquoted_substring __P((char *, char *));
223 static int unquoted_member __P((int, char *));
225 #if defined (ARRAY_VARS)
226 static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
228 static int do_assignment_internal __P((const WORD_DESC *, int));
230 static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
231 static char *string_extract __P((char *, int *, char *, int));
232 static char *string_extract_double_quoted __P((char *, int *, int));
233 static inline char *string_extract_single_quoted __P((char *, int *));
234 static inline int skip_single_quoted __P((const char *, size_t, int));
235 static int skip_double_quoted __P((char *, size_t, int));
236 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
237 static char *extract_dollar_brace_string __P((char *, int *, int, int));
238 static int skip_matched_pair __P((const char *, int, int, int, int));
240 static char *pos_params __P((char *, int, int, int));
242 static unsigned char *mb_getcharlens __P((char *, int));
244 static char *remove_upattern __P((char *, char *, int));
245 #if defined (HANDLE_MULTIBYTE)
246 static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
248 static char *remove_pattern __P((char *, char *, int));
250 static int match_upattern __P((char *, char *, int, char **, char **));
251 #if defined (HANDLE_MULTIBYTE)
252 static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
254 static int match_pattern __P((char *, char *, int, char **, char **));
255 static int getpatspec __P((int, char *));
256 static char *getpattern __P((char *, int, int));
257 static char *variable_remove_pattern __P((char *, char *, int, int));
258 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
259 static char *parameter_list_remove_pattern __P((int, char *, int, int));
261 static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
263 static char *parameter_brace_remove_pattern __P((char *, char *, int, char *, int, int, int));
265 static char *process_substitute __P((char *, int));
267 static char *read_comsub __P((int, int, int *));
270 static arrayind_t array_length_reference __P((char *));
273 static int valid_brace_expansion_word __P((char *, int));
274 static int chk_atstar __P((char *, int, int *, int *));
275 static int chk_arithsub __P((const char *, int));
277 static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int, arrayind_t *));
278 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
279 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
280 static void parameter_brace_expand_error __P((char *, char *));
282 static int valid_length_expression __P((char *));
283 static intmax_t parameter_brace_expand_length __P((char *));
285 static char *skiparith __P((char *, int));
286 static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
287 static int get_var_and_type __P((char *, char *, arrayind_t, int, int, SHELL_VAR **, char **));
288 static char *mb_substring __P((char *, int, int));
289 static char *parameter_brace_substring __P((char *, char *, int, char *, int, int));
291 static int shouldexp_replacement __P((char *));
293 static char *pos_params_pat_subst __P((char *, char *, char *, int));
295 static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int));
297 static char *pos_params_casemod __P((char *, char *, int, int));
298 static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int));
300 static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));
301 static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
303 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
305 static WORD_LIST *word_list_split __P((WORD_LIST *));
307 static void exp_jump_to_top_level __P((int));
309 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
310 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
311 #ifdef BRACE_EXPANSION
312 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
314 #if defined (ARRAY_VARS)
315 static int make_internal_declare __P((char *, char *));
317 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
318 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
320 /* **************************************************************** */
322 /* Utility Functions */
324 /* **************************************************************** */
328 dump_word_flags (flags)
334 fprintf (stderr, "%d -> ", f);
335 if (f & W_ASSIGNASSOC)
338 fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");
343 fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");
348 fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");
353 fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");
355 if (f & W_HASQUOTEDNULL)
357 f &= ~W_HASQUOTEDNULL;
358 fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");
363 fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");
368 fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");
370 if (f & W_ASSNGLOBAL)
373 fprintf (stderr, "W_ASSNGLOBAL%s", f ? "|" : "");
375 if (f & W_COMPASSIGN)
378 fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");
383 fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");
388 fprintf (stderr, "W_ITILDE%s", f ? "|" : "");
393 fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");
398 fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");
403 fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");
405 if (f & W_DOLLARSTAR)
408 fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");
413 fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");
418 fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");
423 fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");
428 fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");
433 fprintf (stderr, "W_NOBRACE%s", f ? "|" : "");
438 fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");
443 fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");
445 if (f & W_ASSIGNMENT)
448 fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");
453 fprintf (stderr, "W_QUOTED%s", f ? "|" : "");
458 fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");
460 fprintf (stderr, "\n");
465 #ifdef INCLUDE_UNUSED
467 quoted_substring (string, start, end)
472 register char *result, *s, *r;
476 /* Move to string[start], skipping quoted characters. */
477 for (s = string, l = 0; *s && l < start; )
489 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
491 /* Copy LEN characters, including quote characters. */
493 for (l = 0; l < len; s++)
507 #ifdef INCLUDE_UNUSED
508 /* Return the length of S, skipping over quoted characters */
532 /* Find the first occurrence of character C in string S, obeying shell
533 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
534 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
535 escaped with CTLESC are skipped. */
537 quoted_strchr (s, c, flags)
545 if (((flags & ST_BACKSL) && *p == '\\')
546 || ((flags & ST_CTLESC) && *p == CTLESC))
550 return ((char *)NULL);
556 return ((char *)NULL);
559 /* Return 1 if CHARACTER appears in an unquoted portion of
560 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
562 unquoted_member (character, string)
570 slen = strlen (string);
572 while (c = string[sindex])
580 ADVANCE_CHAR (string, slen, sindex);
586 ADVANCE_CHAR (string, slen, sindex);
590 sindex = skip_single_quoted (string, slen, ++sindex);
594 sindex = skip_double_quoted (string, slen, ++sindex);
601 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
603 unquoted_substring (substr, string)
604 char *substr, *string;
607 int sindex, c, sublen;
610 if (substr == 0 || *substr == '\0')
613 slen = strlen (string);
614 sublen = strlen (substr);
615 for (sindex = 0; c = string[sindex]; )
617 if (STREQN (string + sindex, substr, sublen))
625 ADVANCE_CHAR (string, slen, sindex);
629 sindex = skip_single_quoted (string, slen, ++sindex);
633 sindex = skip_double_quoted (string, slen, ++sindex);
637 ADVANCE_CHAR (string, slen, sindex);
644 /* Most of the substitutions must be done in parallel. In order
645 to avoid using tons of unclear goto's, I have some functions
646 for manipulating malloc'ed strings. They all take INDX, a
647 pointer to an integer which is the offset into the string
648 where manipulation is taking place. They also take SIZE, a
649 pointer to an integer which is the current length of the
650 character array for this string. */
652 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
653 of space allocated to TARGET. SOURCE can be NULL, in which
654 case nothing happens. Gets rid of SOURCE by freeing it.
655 Returns TARGET in case the location has changed. */
657 sub_append_string (source, target, indx, size)
658 char *source, *target;
665 srclen = STRLEN (source);
666 if (srclen >= (int)(*size - *indx))
669 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
670 target = (char *)xrealloc (target, (*size = n));
673 FASTCOPY (source, target + *indx, srclen);
675 target[*indx] = '\0';
684 /* Append the textual representation of NUMBER to TARGET.
685 INDX and SIZE are as in SUB_APPEND_STRING. */
687 sub_append_number (number, target, indx, size)
694 temp = itos (number);
695 return (sub_append_string (temp, target, indx, size));
699 /* Extract a substring from STRING, starting at SINDEX and ending with
700 one of the characters in CHARLIST. Don't make the ending character
701 part of the string. Leave SINDEX pointing at the ending character.
702 Understand about backslashes in the string. If (flags & SX_VARNAME)
703 is non-zero, and array variables have been compiled into the shell,
704 everything between a `[' and a corresponding `]' is skipped over.
705 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
706 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
707 contain a closing character from CHARLIST. */
709 string_extract (string, sindex, charlist, flags)
721 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
724 while (c = string[i])
733 #if defined (ARRAY_VARS)
734 else if ((flags & SX_VARNAME) && c == '[')
737 /* If this is an array subscript, skip over it and continue. */
738 ni = skipsubscript (string, i, 0);
739 if (string[ni] == ']')
743 else if (MEMBER (c, charlist))
749 ADVANCE_CHAR (string, slen, i);
752 /* If we had to have a matching delimiter and didn't find one, return an
753 error and let the caller deal with it. */
754 if ((flags & SX_REQMATCH) && found == 0)
757 return (&extract_string_error);
760 temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
766 /* Extract the contents of STRING as if it is enclosed in double quotes.
767 SINDEX, when passed in, is the offset of the character immediately
768 following the opening double quote; on exit, SINDEX is left pointing after
769 the closing double quote. If STRIPDQ is non-zero, unquoted double
770 quotes are stripped and the string is terminated by a null byte.
771 Backslashes between the embedded double quotes are processed. If STRIPDQ
772 is zero, an unquoted `"' terminates the string. */
774 string_extract_double_quoted (string, sindex, stripdq)
776 int *sindex, stripdq;
782 char *temp, *ret; /* The new string we return. */
783 int pass_next, backquote, si; /* State variables for the machine. */
787 slen = strlen (string + *sindex) + *sindex;
788 send = string + slen;
790 pass_next = backquote = dquote = 0;
791 temp = (char *)xmalloc (1 + slen - *sindex);
795 while (c = string[i])
797 /* Process a character that was quoted by a backslash. */
800 /* XXX - take another look at this in light of Interp 221 */
803 ``The backslash shall retain its special meaning as an escape
804 character only when followed by one of the characters:
807 If STRIPDQ is zero, we handle the double quotes here and let
808 expand_word_internal handle the rest. If STRIPDQ is non-zero,
809 we have already been through one round of backslash stripping,
810 and want to strip these backslashes only if DQUOTE is non-zero,
811 indicating that we are inside an embedded double-quoted string. */
813 /* If we are in an embedded quoted string, then don't strip
814 backslashes before characters for which the backslash
815 retains its special meaning, but remove backslashes in
816 front of other characters. If we are not in an
817 embedded quoted string, don't strip backslashes at all.
818 This mess is necessary because the string was already
819 surrounded by double quotes (and sh has some really weird
821 The returned string will be run through expansion as if
822 it were double-quoted. */
823 if ((stripdq == 0 && c != '"') ||
824 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
829 COPY_CHAR_I (temp, j, string, send, i);
833 /* A backslash protects the next character. The code just above
834 handles preserving the backslash in front of any character but
843 /* Inside backquotes, ``the portion of the quoted string from the
844 initial backquote and the characters up to the next backquote
845 that is not preceded by a backslash, having escape characters
846 removed, defines that command''. */
864 /* Pass everything between `$(' and the matching `)' or a quoted
865 ${ ... } pair through according to the Posix.2 specification. */
866 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
871 if (string[i + 1] == LPAREN)
872 ret = extract_command_subst (string, &si, 0);
874 ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, 0);
877 temp[j++] = string[i + 1];
879 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
881 if (ret == 0 && no_longjmp_on_fatal_error)
884 ret = string + i + 2;
887 for (t = 0; ret[t]; t++, j++)
889 temp[j] = string[si];
904 /* Add any character but a double quote to the quoted string we're
907 goto add_one_character;
921 /* Point to after the closing quote. */
929 /* This should really be another option to string_extract_double_quoted. */
931 skip_double_quoted (string, slen, sind)
938 int pass_next, backquote, si;
941 pass_next = backquote = 0;
943 while (c = string[i])
948 ADVANCE_CHAR (string, slen, i);
961 ADVANCE_CHAR (string, slen, i);
970 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
973 if (string[i + 1] == LPAREN)
974 ret = extract_command_subst (string, &si, SX_NOALLOC);
976 ret = extract_dollar_brace_string (string, &si, Q_DOUBLE_QUOTES, SX_NOALLOC);
983 ADVANCE_CHAR (string, slen, i);
996 /* Extract the contents of STRING as if it is enclosed in single quotes.
997 SINDEX, when passed in, is the offset of the character immediately
998 following the opening single quote; on exit, SINDEX is left pointing after
999 the closing single quote. */
1000 static inline char *
1001 string_extract_single_quoted (string, sindex)
1010 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1011 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
1013 while (string[i] && string[i] != '\'')
1014 ADVANCE_CHAR (string, slen, i);
1016 t = substring (string, *sindex, i);
1026 skip_single_quoted (string, slen, sind)
1035 while (string[c] && string[c] != '\'')
1036 ADVANCE_CHAR (string, slen, c);
1043 /* Just like string_extract, but doesn't hack backslashes or any of
1044 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1046 string_extract_verbatim (string, slen, sindex, charlist, flags)
1054 #if defined (HANDLE_MULTIBYTE)
1062 if (charlist[0] == '\'' && charlist[1] == '\0')
1064 temp = string_extract_single_quoted (string, sindex);
1065 --*sindex; /* leave *sindex at separator character */
1071 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1072 this only if MB_CUR_MAX > 1. */
1073 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
1075 #if defined (HANDLE_MULTIBYTE)
1076 clen = strlen (charlist);
1079 while (c = string[i])
1081 #if defined (HANDLE_MULTIBYTE)
1084 if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
1089 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1090 through, to protect the CTLNULs from later calls to
1091 remove_quoted_nulls. */
1092 else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
1098 #if defined (HANDLE_MULTIBYTE)
1099 mblength = MBLEN (string + i, slen - i);
1103 mblength = mbtowc (&wc, string + i, slen - i);
1104 if (MB_INVALIDCH (mblength))
1106 if (MEMBER (c, charlist))
1114 len = mbstowcs (wcharlist, charlist, 0);
1117 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
1118 mbstowcs (wcharlist, charlist, len + 1);
1121 if (wcschr (wcharlist, wc))
1127 if (MEMBER (c, charlist))
1130 ADVANCE_CHAR (string, slen, i);
1133 #if defined (HANDLE_MULTIBYTE)
1137 temp = substring (string, *sindex, i);
1143 /* Extract the $( construct in STRING, and return a new string.
1144 Start extracting at (SINDEX) as if we had just seen "$(".
1145 Make (SINDEX) get the position of the matching ")". )
1146 XFLAGS is additional flags to pass to other extraction functions. */
1148 extract_command_subst (string, sindex, xflags)
1153 if (string[*sindex] == LPAREN)
1154 return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
1157 xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
1158 return (xparse_dolparen (string, string+*sindex, sindex, xflags));
1162 /* Extract the $[ 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_arithmetic_subst (string, sindex)
1170 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
1173 #if defined (PROCESS_SUBSTITUTION)
1174 /* Extract the <( or >( construct in STRING, and return a new string.
1175 Start extracting at (SINDEX) as if we had just seen "<(".
1176 Make (SINDEX) get the position of the matching ")". */ /*))*/
1178 extract_process_subst (string, starter, sindex)
1183 return (extract_delimited_string (string, sindex, starter, "(", ")", SX_COMMAND));
1185 #endif /* PROCESS_SUBSTITUTION */
1187 #if defined (ARRAY_VARS)
1188 /* This can be fooled by unquoted right parens in the passed string. If
1189 each caller verifies that the last character in STRING is a right paren,
1190 we don't even need to call extract_delimited_string. */
1192 extract_array_assignment_list (string, sindex)
1199 slen = strlen (string); /* ( */
1200 if (string[slen - 1] == ')')
1202 ret = substring (string, *sindex, slen - 1);
1210 /* Extract and create a new string from the contents of STRING, a
1211 character string delimited with OPENER and CLOSER. SINDEX is
1212 the address of an int describing the current offset in STRING;
1213 it should point to just after the first OPENER found. On exit,
1214 SINDEX gets the position of the last character of the matching CLOSER.
1215 If OPENER is more than a single character, ALT_OPENER, if non-null,
1216 contains a character string that can also match CLOSER and thus
1217 needs to be skipped. */
1219 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
1222 char *opener, *alt_opener, *closer;
1228 int pass_character, nesting_level, in_comment;
1229 int len_closer, len_opener, len_alt_opener;
1232 slen = strlen (string + *sindex) + *sindex;
1233 len_opener = STRLEN (opener);
1234 len_alt_opener = STRLEN (alt_opener);
1235 len_closer = STRLEN (closer);
1237 pass_character = in_comment = 0;
1242 while (nesting_level)
1253 ADVANCE_CHAR (string, slen, i);
1257 if (pass_character) /* previous char was backslash */
1260 ADVANCE_CHAR (string, slen, i);
1264 /* Not exactly right yet; should handle shell metacharacters and
1265 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1266 if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
1269 ADVANCE_CHAR (string, slen, i);
1273 if (c == CTLESC || c == '\\')
1280 /* Process a nested command substitution, but only if we're parsing an
1281 arithmetic substitution. */
1282 if ((flags & SX_COMMAND) && string[i] == '$' && string[i+1] == LPAREN)
1285 t = extract_command_subst (string, &si, flags|SX_NOALLOC);
1290 /* Process a nested OPENER. */
1291 if (STREQN (string + i, opener, len_opener))
1293 si = i + len_opener;
1294 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
1299 /* Process a nested ALT_OPENER */
1300 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1302 si = i + len_alt_opener;
1303 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
1308 /* If the current substring terminates the delimited string, decrement
1309 the nesting level. */
1310 if (STREQN (string + i, closer, len_closer))
1312 i += len_closer - 1; /* move to last byte of the closer */
1314 if (nesting_level == 0)
1318 /* Pass old-style command substitution through verbatim. */
1322 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1327 /* Pass single-quoted and double-quoted strings through verbatim. */
1328 if (c == '\'' || c == '"')
1331 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1332 : skip_double_quoted (string, slen, si);
1336 /* move past this character, which was not special. */
1337 ADVANCE_CHAR (string, slen, i);
1340 if (c == 0 && nesting_level)
1342 if (no_longjmp_on_fatal_error == 0)
1344 last_command_exit_value = EXECUTION_FAILURE;
1345 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1346 exp_jump_to_top_level (DISCARD);
1351 return (char *)NULL;
1355 si = i - *sindex - len_closer + 1;
1356 if (flags & SX_NOALLOC)
1357 result = (char *)NULL;
1360 result = (char *)xmalloc (1 + si);
1361 strncpy (result, string + *sindex, si);
1369 /* Extract a parameter expansion expression within ${ and } from STRING.
1370 Obey the Posix.2 rules for finding the ending `}': count braces while
1371 skipping over enclosed quoted strings and command substitutions.
1372 SINDEX is the address of an int describing the current offset in STRING;
1373 it should point to just after the first `{' found. On exit, SINDEX
1374 gets the position of the matching `}'. QUOTED is non-zero if this
1375 occurs inside double quotes. */
1376 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1378 extract_dollar_brace_string (string, sindex, quoted, flags)
1380 int *sindex, quoted, flags;
1384 int pass_character, nesting_level, si, dolbrace_state;
1390 slen = strlen (string + *sindex) + *sindex;
1392 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1393 parse_matched_pair(). The different initial value is to handle the
1394 case where this function is called to parse the word in
1395 ${param op word} (SX_WORD). */
1396 dolbrace_state = (flags & SX_WORD) ? DOLBRACE_WORD : DOLBRACE_PARAM;
1397 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && (flags & SX_POSIXEXP))
1398 dolbrace_state = DOLBRACE_QUOTE;
1401 while (c = string[i])
1406 ADVANCE_CHAR (string, slen, i);
1410 /* CTLESCs and backslashes quote the next character. */
1411 if (c == CTLESC || c == '\\')
1418 if (string[i] == '$' && string[i+1] == LBRACE)
1428 if (nesting_level == 0)
1434 /* Pass the contents of old-style command substitutions through
1439 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1444 /* Pass the contents of new-style command substitutions and
1445 arithmetic substitutions through verbatim. */
1446 if (string[i] == '$' && string[i+1] == LPAREN)
1449 t = extract_command_subst (string, &si, flags|SX_NOALLOC);
1455 /* Pass the contents of single-quoted and double-quoted strings
1456 through verbatim. */
1457 if (c == '\'' || c == '"')
1460 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1461 : skip_double_quoted (string, slen, si);
1462 /* skip_XXX_quoted leaves index one past close quote */
1465 #else /* XXX - bash-4.2 */
1466 /* Pass the contents of double-quoted strings through verbatim. */
1470 i = skip_double_quoted (string, slen, si);
1471 /* skip_XXX_quoted leaves index one past close quote */
1477 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1478 if (posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
1479 ADVANCE_CHAR (string, slen, i);
1483 i = skip_single_quoted (string, slen, si);
1490 /* move past this character, which was not special. */
1491 ADVANCE_CHAR (string, slen, i);
1493 /* This logic must agree with parse.y:parse_matched_pair, since they
1494 share the same defines. */
1495 if (dolbrace_state == DOLBRACE_PARAM && c == '%' && (i - *sindex) > 1)
1496 dolbrace_state = DOLBRACE_QUOTE;
1497 else if (dolbrace_state == DOLBRACE_PARAM && c == '#' && (i - *sindex) > 1)
1498 dolbrace_state = DOLBRACE_QUOTE;
1499 else if (dolbrace_state == DOLBRACE_PARAM && c == '/' && (i - *sindex) > 1)
1500 dolbrace_state = DOLBRACE_QUOTE;
1501 else if (dolbrace_state == DOLBRACE_PARAM && c == '^' && (i - *sindex) > 1)
1502 dolbrace_state = DOLBRACE_QUOTE;
1503 else if (dolbrace_state == DOLBRACE_PARAM && c == ',' && (i - *sindex) > 1)
1504 dolbrace_state = DOLBRACE_QUOTE;
1505 else if (dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", c) != 0)
1506 dolbrace_state = DOLBRACE_OP;
1507 else if (dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", c) == 0)
1508 dolbrace_state = DOLBRACE_WORD;
1511 if (c == 0 && nesting_level)
1513 if (no_longjmp_on_fatal_error == 0)
1515 last_command_exit_value = EXECUTION_FAILURE;
1516 report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1517 exp_jump_to_top_level (DISCARD);
1522 return ((char *)NULL);
1526 result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1532 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1533 STRING, and returns a pointer to it. */
1535 de_backslash (string)
1538 register size_t slen;
1539 register int i, j, prev_i;
1542 slen = strlen (string);
1545 /* Loop copying string[i] to string[j], i >= j. */
1548 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1549 string[i + 1] == '$'))
1552 ADVANCE_CHAR (string, slen, i);
1554 do string[j++] = string[prev_i++]; while (prev_i < i);
1565 /* Replace instances of \! in a string with !. */
1567 unquote_bang (string)
1571 register char *temp;
1573 temp = (char *)xmalloc (1 + strlen (string));
1575 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1577 if (string[i] == '\\' && string[i + 1] == '!')
1583 strcpy (string, temp);
1588 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1590 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1591 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1592 matched pairs of quotes or backquotes, or skip word expansions; it is
1593 intended to be used after expansion has been performed and during final
1594 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1596 skip_matched_pair (string, start, open, close, flags)
1598 int start, open, close, flags;
1600 int i, pass_next, backq, si, c, count;
1605 slen = strlen (string + start) + start;
1606 no_longjmp_on_fatal_error = 1;
1608 i = start + 1; /* skip over leading bracket */
1610 pass_next = backq = 0;
1611 ss = (char *)string;
1612 while (c = string[i])
1619 ADVANCE_CHAR (string, slen, i);
1632 ADVANCE_CHAR (string, slen, i);
1635 else if ((flags & 1) == 0 && c == '`')
1641 else if ((flags & 1) == 0 && c == open)
1647 else if (c == close)
1655 else if ((flags & 1) == 0 && (c == '\'' || c == '"'))
1657 i = (c == '\'') ? skip_single_quoted (ss, slen, ++i)
1658 : skip_double_quoted (ss, slen, ++i);
1659 /* no increment, the skip functions increment past the closing quote. */
1661 else if ((flags&1) == 0 && c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1664 if (string[si] == '\0')
1667 if (string[i+1] == LPAREN)
1668 temp = extract_delimited_string (ss, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1670 temp = extract_dollar_brace_string (ss, &si, 0, SX_NOALLOC);
1672 if (string[i] == '\0') /* don't increment i past EOS in loop */
1678 ADVANCE_CHAR (string, slen, i);
1684 #if defined (ARRAY_VARS)
1686 skipsubscript (string, start, flags)
1690 return (skip_matched_pair (string, start, '[', ']', flags));
1694 /* Skip characters in STRING until we find a character in DELIMS, and return
1695 the index of that character. START is the index into string at which we
1696 begin. This is similar in spirit to strpbrk, but it returns an index into
1697 STRING and takes a starting index. This little piece of code knows quite
1698 a lot of shell syntax. It's very similar to skip_double_quoted and other
1699 functions of that ilk. */
1701 skip_to_delim (string, start, delims, flags)
1707 int i, pass_next, backq, si, c, invert, skipquote, skipcmd;
1709 char *temp, open[3];
1712 slen = strlen (string + start) + start;
1713 if (flags & SD_NOJMP)
1714 no_longjmp_on_fatal_error = 1;
1715 invert = (flags & SD_INVERT);
1716 skipcmd = (flags & SD_NOSKIPCMD) == 0;
1719 pass_next = backq = 0;
1720 while (c = string[i])
1722 /* If this is non-zero, we should not let quote characters be delimiters
1723 and the current character is a single or double quote. We should not
1724 test whether or not it's a delimiter until after we skip single- or
1725 double-quoted strings. */
1726 skipquote = ((flags & SD_NOQUOTEDELIM) && (c == '\'' || c =='"'));
1732 ADVANCE_CHAR (string, slen, i);
1745 ADVANCE_CHAR (string, slen, i);
1754 else if (skipquote == 0 && invert == 0 && member (c, delims))
1756 else if (c == '\'' || c == '"')
1758 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1759 : skip_double_quoted (string, slen, ++i);
1760 /* no increment, the skip functions increment past the closing quote. */
1762 else if (c == '$' && ((skipcmd && string[i+1] == LPAREN) || string[i+1] == LBRACE))
1765 if (string[si] == '\0')
1768 if (string[i+1] == LPAREN)
1769 temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1771 temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
1773 if (string[i] == '\0') /* don't increment i past EOS in loop */
1778 #if defined (PROCESS_SUBSTITUTION)
1779 else if (skipcmd && (c == '<' || c == '>') && string[i+1] == LPAREN)
1782 if (string[si] == '\0')
1784 temp = extract_process_subst (string, (c == '<') ? "<(" : ">(", &si);
1785 free (temp); /* no SX_ALLOC here */
1787 if (string[i] == '\0')
1792 #endif /* PROCESS_SUBSTITUTION */
1793 #if defined (EXTENDED_GLOB)
1794 else if ((flags & SD_EXTGLOB) && extended_glob && string[i+1] == LPAREN && member (c, "?*+!@"))
1797 if (string[si] == '\0')
1803 temp = extract_delimited_string (string, &si, open, "(", ")", SX_NOALLOC); /* ) */
1806 if (string[i] == '\0') /* don't increment i past EOS in loop */
1812 else if ((skipquote || invert) && (member (c, delims) == 0))
1815 ADVANCE_CHAR (string, slen, i);
1821 #if defined (READLINE)
1822 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1823 an unclosed quoted string), or if the character at EINDEX is quoted
1824 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1825 single and double-quoted string parsing functions should not return an
1826 error if there are unclosed quotes or braces. The characters that this
1827 recognizes need to be the same as the contents of
1828 rl_completer_quote_characters. */
1831 char_is_quoted (string, eindex)
1835 int i, pass_next, c;
1839 slen = strlen (string);
1840 no_longjmp_on_fatal_error = 1;
1849 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1851 ADVANCE_CHAR (string, slen, i);
1860 else if (c == '\'' || c == '"')
1862 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1863 : skip_double_quoted (string, slen, ++i);
1866 /* no increment, the skip_xxx functions go one past end */
1869 ADVANCE_CHAR (string, slen, i);
1876 unclosed_pair (string, eindex, openstr)
1881 int i, pass_next, openc, olen;
1885 slen = strlen (string);
1886 olen = strlen (openstr);
1887 i = pass_next = openc = 0;
1893 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1895 ADVANCE_CHAR (string, slen, i);
1898 else if (string[i] == '\\')
1904 else if (STREQN (string + i, openstr, olen))
1909 else if (string[i] == '\'' || string[i] == '"')
1911 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1912 : skip_double_quoted (string, slen, i);
1917 ADVANCE_CHAR (string, slen, i);
1922 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1923 individual words. If DELIMS is NULL, the current value of $IFS is used
1924 to split the string, and the function follows the shell field splitting
1925 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1926 gets the number of words in the returned list. CWP, if non-NULL, gets
1927 the index of the word containing SENTINEL. Non-whitespace chars in
1928 DELIMS delimit separate fields. */
1930 split_at_delims (string, slen, delims, sentinel, flags, nwp, cwp)
1934 int sentinel, flags;
1937 int ts, te, i, nw, cw, ifs_split, dflags;
1938 char *token, *d, *d2;
1939 WORD_LIST *ret, *tl;
1941 if (string == 0 || *string == '\0')
1947 return ((WORD_LIST *)NULL);
1950 d = (delims == 0) ? ifs_value : delims;
1951 ifs_split = delims == 0;
1953 /* Make d2 the non-whitespace characters in delims */
1958 #if defined (HANDLE_MULTIBYTE)
1959 size_t mblength = 1;
1963 slength = strlen (delims);
1964 d2 = (char *)xmalloc (slength + 1);
1968 #if defined (HANDLE_MULTIBYTE)
1969 mbstate_t state_bak;
1971 mblength = MBRLEN (delims + i, slength, &state);
1972 if (MB_INVALIDCH (mblength))
1974 else if (mblength > 1)
1976 memcpy (d2 + ts, delims + i, mblength);
1979 slength -= mblength;
1983 if (whitespace (delims[i]) == 0)
1984 d2[ts++] = delims[i];
1992 ret = (WORD_LIST *)NULL;
1994 /* Remove sequences of whitespace characters at the start of the string, as
1995 long as those characters are delimiters. */
1996 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1998 if (string[i] == '\0')
2004 dflags = flags|SD_NOJMP;
2007 te = skip_to_delim (string, ts, d, dflags);
2009 /* If we have a non-whitespace delimiter character, use it to make a
2010 separate field. This is just about what $IFS splitting does and
2011 is closer to the behavior of the shell parser. */
2012 if (ts == te && d2 && member (string[ts], d2))
2015 /* If we're using IFS splitting, the non-whitespace delimiter char
2016 and any additional IFS whitespace delimits a field. */
2018 while (member (string[te], d) && spctabnl (string[te]))
2021 while (member (string[te], d2))
2025 token = substring (string, ts, te);
2027 ret = add_string_to_list (token, ret);
2031 if (sentinel >= ts && sentinel <= te)
2034 /* If the cursor is at whitespace just before word start, set the
2035 sentinel word to the current word. */
2036 if (cwp && cw == -1 && sentinel == ts-1)
2039 /* If the cursor is at whitespace between two words, make a new, empty
2040 word, add it before (well, after, since the list is in reverse order)
2041 the word we just added, and set the current word to that one. */
2042 if (cwp && cw == -1 && sentinel < ts)
2044 tl = make_word_list (make_word (""), ret->next);
2050 if (string[te] == 0)
2054 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
2063 /* Special case for SENTINEL at the end of STRING. If we haven't found
2064 the word containing SENTINEL yet, and the index we're looking for is at
2065 the end of STRING (or past the end of the previously-found token,
2066 possible if the end of the line is composed solely of IFS whitespace)
2067 add an additional null argument and set the current word pointer to that. */
2068 if (cwp && cw == -1 && (sentinel >= slen || sentinel >= te))
2070 if (whitespace (string[sentinel - 1]))
2073 ret = add_string_to_list (token, ret);
2086 return (REVERSE_LIST (ret, WORD_LIST *));
2088 #endif /* READLINE */
2092 /* Extract the name of the variable to bind to from the assignment string. */
2094 assignment_name (string)
2100 offset = assignment (string, 0);
2102 return (char *)NULL;
2103 temp = substring (string, 0, offset);
2108 /* **************************************************************** */
2110 /* Functions to convert strings to WORD_LISTs and vice versa */
2112 /* **************************************************************** */
2114 /* Return a single string of all the words in LIST. SEP is the separator
2115 to put between individual elements of LIST in the output string. */
2117 string_list_internal (list, sep)
2121 register WORD_LIST *t;
2123 int word_len, sep_len, result_size;
2126 return ((char *)NULL);
2128 /* Short-circuit quickly if we don't need to separate anything. */
2129 if (list->next == 0)
2130 return (savestring (list->word->word));
2132 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2133 sep_len = STRLEN (sep);
2136 for (t = list; t; t = t->next)
2139 result_size += sep_len;
2140 result_size += strlen (t->word->word);
2143 r = result = (char *)xmalloc (result_size + 1);
2145 for (t = list; t; t = t->next)
2147 if (t != list && sep_len)
2151 FASTCOPY (sep, r, sep_len);
2158 word_len = strlen (t->word->word);
2159 FASTCOPY (t->word->word, r, word_len);
2167 /* Return a single string of all the words present in LIST, separating
2168 each word with a space. */
2173 return (string_list_internal (list, " "));
2176 /* An external interface that can be used by the rest of the shell to
2177 obtain a string containing the first character in $IFS. Handles all
2178 the multibyte complications. If LENP is non-null, it is set to the
2179 length of the returned string. */
2181 ifs_firstchar (lenp)
2187 ret = xmalloc (MB_LEN_MAX + 1);
2188 #if defined (HANDLE_MULTIBYTE)
2189 if (ifs_firstc_len == 1)
2191 ret[0] = ifs_firstc[0];
2193 len = ret[0] ? 1 : 0;
2197 memcpy (ret, ifs_firstc, ifs_firstc_len);
2198 ret[len = ifs_firstc_len] = '\0';
2201 ret[0] = ifs_firstc;
2203 len = ret[0] ? 0 : 1;
2212 /* Return a single string of all the words present in LIST, obeying the
2213 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2214 expansion [of $*] appears within a double quoted string, it expands
2215 to a single field with the value of each parameter separated by the
2216 first character of the IFS variable, or by a <space> if IFS is unset." */
2218 string_list_dollar_star (list)
2222 #if defined (HANDLE_MULTIBYTE)
2223 # if defined (__GNUC__)
2224 char sep[MB_CUR_MAX + 1];
2232 #if defined (HANDLE_MULTIBYTE)
2233 # if !defined (__GNUC__)
2234 sep = (char *)xmalloc (MB_CUR_MAX + 1);
2235 # endif /* !__GNUC__ */
2236 if (ifs_firstc_len == 1)
2238 sep[0] = ifs_firstc[0];
2243 memcpy (sep, ifs_firstc, ifs_firstc_len);
2244 sep[ifs_firstc_len] = '\0';
2247 sep[0] = ifs_firstc;
2251 ret = string_list_internal (list, sep);
2252 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2258 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2259 is non-zero, the $@ appears within double quotes, and we should quote
2260 the list before converting it into a string. If IFS is unset, and the
2261 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2262 in the words in the list, because the default value of $IFS is
2263 <space><tab><newline>, IFS characters in the words in the list should
2264 also be split. If IFS is null, and the word is not quoted, we need
2265 to quote the words in the list to preserve the positional parameters
2268 string_list_dollar_at (list, quoted)
2273 #if defined (HANDLE_MULTIBYTE)
2274 # if defined (__GNUC__)
2275 char sep[MB_CUR_MAX + 1];
2278 # endif /* !__GNUC__ */
2284 /* XXX this could just be ifs = ifs_value; */
2285 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
2287 #if defined (HANDLE_MULTIBYTE)
2288 # if !defined (__GNUC__)
2289 sep = (char *)xmalloc (MB_CUR_MAX + 1);
2290 # endif /* !__GNUC__ */
2293 if (ifs_firstc_len == 1)
2295 sep[0] = ifs_firstc[0];
2300 memcpy (sep, ifs_firstc, ifs_firstc_len);
2301 sep[ifs_firstc_len] = '\0';
2310 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
2314 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2315 it now that quote_escapes quotes spaces */
2316 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
2318 : list_quote_escapes (list);
2320 ret = string_list_internal (tlist, sep);
2321 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2327 /* Turn the positional paramters into a string, understanding quoting and
2328 the various subtleties of using the first character of $IFS as the
2329 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2330 string_list as appropriate. */
2332 string_list_pos_params (pchar, list, quoted)
2340 if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
2342 tlist = quote_list (list);
2343 word_list_remove_quoted_nulls (tlist);
2344 ret = string_list_dollar_star (tlist);
2346 else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
2348 tlist = quote_list (list);
2349 word_list_remove_quoted_nulls (tlist);
2350 ret = string_list (tlist);
2352 else if (pchar == '*')
2354 /* Even when unquoted, string_list_dollar_star does the right thing
2355 making sure that the first character of $IFS is used as the
2357 ret = string_list_dollar_star (list);
2359 else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
2360 /* We use string_list_dollar_at, but only if the string is quoted, since
2361 that quotes the escapes if it's not, which we don't want. We could
2362 use string_list (the old code did), but that doesn't do the right
2363 thing if the first character of $IFS is not a space. We use
2364 string_list_dollar_star if the string is unquoted so we make sure that
2365 the elements of $@ are separated by the first character of $IFS for
2367 ret = string_list_dollar_at (list, quoted);
2368 else if (pchar == '@')
2369 ret = string_list_dollar_star (list);
2371 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
2376 /* Return the list of words present in STRING. Separate the string into
2377 words at any of the characters found in SEPARATORS. If QUOTED is
2378 non-zero then word in the list will have its quoted flag set, otherwise
2379 the quoted flag is left as make_word () deemed fit.
2381 This obeys the P1003.2 word splitting semantics. If `separators' is
2382 exactly <space><tab><newline>, then the splitting algorithm is that of
2383 the Bourne shell, which treats any sequence of characters from `separators'
2384 as a delimiter. If IFS is unset, which results in `separators' being set
2385 to "", no splitting occurs. If separators has some other value, the
2386 following rules are applied (`IFS white space' means zero or more
2387 occurrences of <space>, <tab>, or <newline>, as long as those characters
2388 are in `separators'):
2390 1) IFS white space is ignored at the start and the end of the
2392 2) Each occurrence of a character in `separators' that is not
2393 IFS white space, along with any adjacent occurrences of
2394 IFS white space delimits a field.
2395 3) Any nonzero-length sequence of IFS white space delimits a field.
2398 /* BEWARE! list_string strips null arguments. Don't call it twice and
2399 expect to have "" preserved! */
2401 /* This performs word splitting and quoted null character removal on
2404 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2405 : (c) == (separators)[0]) \
2409 list_string (string, separators, quoted)
2410 register char *string, *separators;
2415 char *current_word, *s;
2416 int sindex, sh_style_split, whitesep, xflags;
2419 if (!string || !*string)
2420 return ((WORD_LIST *)NULL);
2422 sh_style_split = separators && separators[0] == ' ' &&
2423 separators[1] == '\t' &&
2424 separators[2] == '\n' &&
2425 separators[3] == '\0';
2426 for (xflags = 0, s = ifs_value; s && *s; s++)
2428 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2429 else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2433 /* Remove sequences of whitespace at the beginning of STRING, as
2434 long as those characters appear in IFS. Do not do this if
2435 STRING is quoted or if there are no separator characters. */
2436 if (!quoted || !separators || !*separators)
2438 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
2441 return ((WORD_LIST *)NULL);
2446 /* OK, now STRING points to a word that does not begin with white space.
2447 The splitting algorithm is:
2448 extract a word, stopping at a separator
2449 skip sequences of spc, tab, or nl as long as they are separators
2450 This obeys the field splitting rules in Posix.2. */
2451 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
2452 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
2454 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2455 unless multibyte chars are possible. */
2456 current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
2457 if (current_word == 0)
2460 /* If we have a quoted empty string, add a quoted null argument. We
2461 want to preserve the quoted null character iff this is a quoted
2462 empty string; otherwise the quoted null characters are removed
2464 if (QUOTED_NULL (current_word))
2466 t = alloc_word_desc ();
2467 t->word = make_quoted_char ('\0');
2468 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2469 result = make_word_list (t, result);
2471 else if (current_word[0] != '\0')
2473 /* If we have something, then add it regardless. However,
2474 perform quoted null character removal on the current word. */
2475 remove_quoted_nulls (current_word);
2476 result = add_string_to_list (current_word, result);
2477 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
2478 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
2479 result->word->flags |= W_QUOTED;
2482 /* If we're not doing sequences of separators in the traditional
2483 Bourne shell style, then add a quoted null argument. */
2484 else if (!sh_style_split && !spctabnl (string[sindex]))
2486 t = alloc_word_desc ();
2487 t->word = make_quoted_char ('\0');
2488 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2489 result = make_word_list (t, result);
2492 free (current_word);
2494 /* Note whether or not the separator is IFS whitespace, used later. */
2495 whitesep = string[sindex] && spctabnl (string[sindex]);
2497 /* Move past the current separator character. */
2501 ADVANCE_CHAR (string, slen, sindex);
2504 /* Now skip sequences of space, tab, or newline characters if they are
2505 in the list of separators. */
2506 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
2509 /* If the first separator was IFS whitespace and the current character
2510 is a non-whitespace IFS character, it should be part of the current
2511 field delimiter, not a separate delimiter that would result in an
2512 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2513 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
2516 /* An IFS character that is not IFS white space, along with any
2517 adjacent IFS white space, shall delimit a field. (SUSv3) */
2518 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
2522 return (REVERSE_LIST (result, WORD_LIST *));
2525 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2526 ENDPTR is set to the first character after the word. This is used by
2527 the `read' builtin. This is never called with SEPARATORS != $IFS;
2528 it should be simplified.
2530 XXX - this function is very similar to list_string; they should be
2533 get_word_from_string (stringp, separators, endptr)
2534 char **stringp, *separators, **endptr;
2538 int sindex, sh_style_split, whitesep, xflags;
2541 if (!stringp || !*stringp || !**stringp)
2542 return ((char *)NULL);
2544 sh_style_split = separators && separators[0] == ' ' &&
2545 separators[1] == '\t' &&
2546 separators[2] == '\n' &&
2547 separators[3] == '\0';
2548 for (xflags = 0, s = ifs_value; s && *s; s++)
2550 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2551 if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2557 /* Remove sequences of whitespace at the beginning of STRING, as
2558 long as those characters appear in IFS. */
2559 if (sh_style_split || !separators || !*separators)
2561 for (; *s && spctabnl (*s) && isifs (*s); s++);
2563 /* If the string is nothing but whitespace, update it and return. */
2569 return ((char *)NULL);
2573 /* OK, S points to a word that does not begin with white space.
2574 Now extract a word, stopping at a separator, save a pointer to
2575 the first character after the word, then skip sequences of spc,
2576 tab, or nl as long as they are separators.
2578 This obeys the field splitting rules in Posix.2. */
2580 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2581 unless multibyte chars are possible. */
2582 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
2583 current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
2585 /* Set ENDPTR to the first character after the end of the word. */
2587 *endptr = s + sindex;
2589 /* Note whether or not the separator is IFS whitespace, used later. */
2590 whitesep = s[sindex] && spctabnl (s[sindex]);
2592 /* Move past the current separator character. */
2596 ADVANCE_CHAR (s, slen, sindex);
2599 /* Now skip sequences of space, tab, or newline characters if they are
2600 in the list of separators. */
2601 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2604 /* If the first separator was IFS whitespace and the current character is
2605 a non-whitespace IFS character, it should be part of the current field
2606 delimiter, not a separate delimiter that would result in an empty field.
2607 Look at POSIX.2, 3.6.5, (3)(b). */
2608 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
2611 /* An IFS character that is not IFS white space, along with any adjacent
2612 IFS white space, shall delimit a field. */
2613 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2617 /* Update STRING to point to the next field. */
2618 *stringp = s + sindex;
2619 return (current_word);
2622 /* Remove IFS white space at the end of STRING. Start at the end
2623 of the string and walk backwards until the beginning of the string
2624 or we find a character that's not IFS white space and not CTLESC.
2625 Only let CTLESC escape a white space character if SAW_ESCAPE is
2628 strip_trailing_ifs_whitespace (string, separators, saw_escape)
2629 char *string, *separators;
2634 s = string + STRLEN (string) - 1;
2635 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
2636 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
2644 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2645 backslashes, single and double quotes. */
2647 list_string_with_quotes (string)
2653 int c, i, tokstart, len;
2655 for (s = string; s && *s && spctabnl (*s); s++)
2657 if (s == 0 || *s == 0)
2658 return ((WORD_LIST *)NULL);
2662 list = (WORD_LIST *)NULL;
2673 i = skip_single_quoted (s, s_len, ++i);
2675 i = skip_double_quoted (s, s_len, ++i);
2676 else if (c == 0 || spctabnl (c))
2678 /* We have found the end of a token. Make a word out of it and
2679 add it to the word list. */
2680 token = substring (s, tokstart, i);
2681 list = add_string_to_list (token, list);
2683 while (spctabnl (s[i]))
2691 i++; /* normal character */
2693 return (REVERSE_LIST (list, WORD_LIST *));
2697 /********************************************************/
2699 /* Functions to perform assignment statements */
2701 /********************************************************/
2703 #if defined (ARRAY_VARS)
2705 do_compound_assignment (name, value, flags)
2710 int mklocal, mkassoc;
2713 mklocal = flags & ASS_MKLOCAL;
2714 mkassoc = flags & ASS_MKASSOC;
2716 if (mklocal && variable_context)
2718 v = find_variable (name);
2719 list = expand_compound_array_assignment (v, value, flags);
2721 v = make_local_assoc_variable (name);
2722 else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
2723 v = make_local_array_variable (name, 0);
2724 assign_compound_array_list (v, list, flags);
2727 v = assign_array_from_string (name, value, flags);
2733 /* Given STRING, an assignment string, get the value of the right side
2734 of the `=', and bind it to the left side. If EXPAND is true, then
2735 perform parameter expansion, command substitution, and arithmetic
2736 expansion on the right-hand side. Perform tilde expansion in any
2737 case. Do not perform word splitting on the result of expansion. */
2739 do_assignment_internal (word, expand)
2740 const WORD_DESC *word;
2743 int offset, appendop, assign_list, aflags, retval;
2744 char *name, *value, *temp;
2746 #if defined (ARRAY_VARS)
2752 if (word == 0 || word->word == 0)
2755 appendop = assign_list = aflags = 0;
2756 string = word->word;
2757 offset = assignment (string, 0);
2758 name = savestring (string);
2759 value = (char *)NULL;
2761 if (name[offset] == '=')
2763 if (name[offset - 1] == '+')
2766 name[offset - 1] = '\0';
2769 name[offset] = 0; /* might need this set later */
2770 temp = name + offset + 1;
2772 #if defined (ARRAY_VARS)
2773 if (expand && (word->flags & W_COMPASSIGN))
2775 assign_list = ni = 1;
2776 value = extract_array_assignment_list (temp, &ni);
2780 if (expand && temp[0])
2781 value = expand_string_if_necessary (temp, 0, expand_string_assignment);
2783 value = savestring (temp);
2788 value = (char *)xmalloc (1);
2792 if (echo_command_at_execute)
2795 name[offset - 1] = '+';
2796 xtrace_print_assignment (name, value, assign_list, 1);
2798 name[offset - 1] = '\0';
2801 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2804 aflags |= ASS_APPEND;
2806 #if defined (ARRAY_VARS)
2807 if (t = mbschr (name, '[')) /*]*/
2811 report_error (_("%s: cannot assign list to array member"), name);
2814 entry = assign_array_element (name, value, aflags);
2818 else if (assign_list)
2820 if ((word->flags & W_ASSIGNARG) && (word->flags & W_ASSNGLOBAL) == 0)
2821 aflags |= ASS_MKLOCAL;
2822 if (word->flags & W_ASSIGNASSOC)
2823 aflags |= ASS_MKASSOC;
2824 entry = do_compound_assignment (name, value, aflags);
2827 #endif /* ARRAY_VARS */
2828 entry = bind_variable (name, value, aflags);
2830 stupidly_hack_special_variables (name);
2832 /* Return 1 if the assignment seems to have been performed correctly. */
2833 if (entry == 0 || readonly_p (entry))
2834 retval = 0; /* assignment failure */
2835 else if (noassign_p (entry))
2837 last_command_exit_value = EXECUTION_FAILURE;
2838 retval = 1; /* error status, but not assignment failure */
2843 if (entry && retval != 0 && noassign_p (entry) == 0)
2844 VUNSETATTR (entry, att_invisible);
2846 ASSIGN_RETURN (retval);
2849 /* Perform the assignment statement in STRING, and expand the
2850 right side by doing tilde, command and parameter expansion. */
2852 do_assignment (string)
2857 td.flags = W_ASSIGNMENT;
2860 return do_assignment_internal (&td, 1);
2864 do_word_assignment (word, flags)
2868 return do_assignment_internal (word, 1);
2871 /* Given STRING, an assignment string, get the value of the right side
2872 of the `=', and bind it to the left side. Do not perform any word
2873 expansions on the right hand side. */
2875 do_assignment_no_expand (string)
2880 td.flags = W_ASSIGNMENT;
2883 return (do_assignment_internal (&td, 0));
2886 /***************************************************
2888 * Functions to manage the positional parameters *
2890 ***************************************************/
2892 /* Return the word list that corresponds to `$*'. */
2894 list_rest_of_args ()
2896 register WORD_LIST *list, *args;
2899 /* Break out of the loop as soon as one of the dollar variables is null. */
2900 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2901 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2903 for (args = rest_of_args; args; args = args->next)
2904 list = make_word_list (make_bare_word (args->word->word), list);
2906 return (REVERSE_LIST (list, WORD_LIST *));
2912 register WORD_LIST *list;
2915 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2917 for (list = rest_of_args; list; list = list->next)
2922 /* Return the value of a positional parameter. This handles values > 10. */
2924 get_dollar_var_value (ind)
2931 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2932 else /* We want something like ${11} */
2935 for (p = rest_of_args; p && ind--; p = p->next)
2937 temp = p ? savestring (p->word->word) : (char *)NULL;
2942 /* Make a single large string out of the dollar digit variables,
2943 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2944 case of "$*" with respect to IFS. */
2946 string_rest_of_args (dollar_star)
2949 register WORD_LIST *list;
2952 list = list_rest_of_args ();
2953 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2954 dispose_words (list);
2958 /* Return a string containing the positional parameters from START to
2959 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2960 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2961 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2962 no quoting chars are added. */
2964 pos_params (string, start, end, quoted)
2966 int start, end, quoted;
2968 WORD_LIST *save, *params, *h, *t;
2972 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2974 return ((char *)NULL);
2976 save = params = list_rest_of_args ();
2978 return ((char *)NULL);
2980 if (start == 0) /* handle ${@:0[:x]} specially */
2982 t = make_word_list (make_word (dollar_vars[0]), params);
2986 for (i = start ? 1 : 0; params && i < start; i++)
2987 params = params->next;
2989 return ((char *)NULL);
2990 for (h = t = params; params && i < end; i++)
2993 params = params->next;
2996 t->next = (WORD_LIST *)NULL;
2998 ret = string_list_pos_params (string[0], h, quoted);
3003 dispose_words (save);
3007 /******************************************************************/
3009 /* Functions to expand strings to strings or WORD_LISTs */
3011 /******************************************************************/
3013 #if defined (PROCESS_SUBSTITUTION)
3014 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3016 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3019 /* If there are any characters in STRING that require full expansion,
3020 then call FUNC to expand STRING; otherwise just perform quote
3021 removal if necessary. This returns a new string. */
3023 expand_string_if_necessary (string, quoted, func)
3034 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3035 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
3039 if (EXP_CHAR (string[i]))
3041 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
3043 ADVANCE_CHAR (string, slen, i);
3048 list = (*func) (string, quoted);
3051 ret = string_list (list);
3052 dispose_words (list);
3057 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
3058 ret = string_quote_removal (string, quoted);
3060 ret = savestring (string);
3065 static inline char *
3066 expand_string_to_string_internal (string, quoted, func)
3074 if (string == 0 || *string == '\0')
3075 return ((char *)NULL);
3077 list = (*func) (string, quoted);
3080 ret = string_list (list);
3081 dispose_words (list);
3090 expand_string_to_string (string, quoted)
3094 return (expand_string_to_string_internal (string, quoted, expand_string));
3098 expand_string_unsplit_to_string (string, quoted)
3102 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
3106 expand_assignment_string_to_string (string, quoted)
3110 return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
3114 expand_arith_string (string, quoted)
3118 return (expand_string_if_necessary (string, quoted, expand_string));
3121 #if defined (COND_COMMAND)
3122 /* Just remove backslashes in STRING. Returns a new string. */
3124 remove_backslashes (string)
3129 r = ret = (char *)xmalloc (strlen (string) + 1);
3130 for (s = string; s && *s; )
3142 /* This needs better error handling. */
3143 /* Expand W for use as an argument to a unary or binary operator in a
3144 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3145 to the != or == operator, and should be treated as a pattern. In
3146 this case, we quote the string specially for the globbing code. If
3147 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3148 be quoted appropriately for regcomp/regexec. The caller is responsible
3149 for removing the backslashes if the unquoted word is needed later. */
3151 cond_expand_word (w, special)
3159 if (w->word == 0 || w->word[0] == '\0')
3160 return ((char *)NULL);
3162 w->flags |= W_NOSPLIT2;
3163 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
3169 r = string_list (l);
3173 qflags = QGLOB_CVTNULL;
3175 qflags |= QGLOB_REGEXP;
3176 p = string_list (l);
3177 r = quote_string_for_globbing (p, qflags);
3189 /* Call expand_word_internal to expand W and handle error returns.
3190 A convenience function for functions that don't want to handle
3191 any errors or free any memory before aborting. */
3193 call_expand_word_internal (w, q, i, c, e)
3199 result = expand_word_internal (w, q, i, c, e);
3200 if (result == &expand_word_error || result == &expand_word_fatal)
3202 /* By convention, each time this error is returned, w->word has
3203 already been freed (it sometimes may not be in the fatal case,
3204 but that doesn't result in a memory leak because we're going
3205 to exit in most cases). */
3206 w->word = (char *)NULL;
3207 last_command_exit_value = EXECUTION_FAILURE;
3208 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
3215 /* Perform parameter expansion, command substitution, and arithmetic
3216 expansion on STRING, as if it were a word. Leave the result quoted.
3217 Since this does not perform word splitting, it leaves quoted nulls
3220 expand_string_internal (string, quoted)
3227 if (string == 0 || *string == 0)
3228 return ((WORD_LIST *)NULL);
3231 td.word = savestring (string);
3233 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3239 /* Expand STRING by performing parameter expansion, command substitution,
3240 and arithmetic expansion. Dequote the resulting WORD_LIST before
3241 returning it, but do not perform word splitting. The call to
3242 remove_quoted_nulls () is in here because word splitting normally
3243 takes care of quote removal. */
3245 expand_string_unsplit (string, quoted)
3251 if (string == 0 || *string == '\0')
3252 return ((WORD_LIST *)NULL);
3254 expand_no_split_dollar_star = 1;
3255 value = expand_string_internal (string, quoted);
3256 expand_no_split_dollar_star = 0;
3262 remove_quoted_nulls (value->word->word);
3263 value->word->flags &= ~W_HASQUOTEDNULL;
3265 dequote_list (value);
3270 /* Expand the rhs of an assignment statement */
3272 expand_string_assignment (string, quoted)
3279 if (string == 0 || *string == '\0')
3280 return ((WORD_LIST *)NULL);
3282 expand_no_split_dollar_star = 1;
3284 td.flags = W_ASSIGNRHS;
3285 td.word = savestring (string);
3286 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3289 expand_no_split_dollar_star = 0;
3295 remove_quoted_nulls (value->word->word);
3296 value->word->flags &= ~W_HASQUOTEDNULL;
3298 dequote_list (value);
3304 /* Expand one of the PS? prompt strings. This is a sort of combination of
3305 expand_string_unsplit and expand_string_internal, but returns the
3306 passed string when an error occurs. Might want to trap other calls
3307 to jump_to_top_level here so we don't endlessly loop. */
3309 expand_prompt_string (string, quoted, wflags)
3317 if (string == 0 || *string == 0)
3318 return ((WORD_LIST *)NULL);
3321 td.word = savestring (string);
3323 no_longjmp_on_fatal_error = 1;
3324 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
3325 no_longjmp_on_fatal_error = 0;
3327 if (value == &expand_word_error || value == &expand_word_fatal)
3329 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
3337 remove_quoted_nulls (value->word->word);
3338 value->word->flags &= ~W_HASQUOTEDNULL;
3340 dequote_list (value);
3345 /* Expand STRING just as if you were expanding a word, but do not dequote
3346 the resultant WORD_LIST. This is called only from within this file,
3347 and is used to correctly preserve quoted characters when expanding
3348 things like ${1+"$@"}. This does parameter expansion, command
3349 substitution, arithmetic expansion, and word splitting. */
3351 expand_string_leave_quoted (string, quoted)
3358 if (string == 0 || *string == '\0')
3359 return ((WORD_LIST *)NULL);
3361 tlist = expand_string_internal (string, quoted);
3365 tresult = word_list_split (tlist);
3366 dispose_words (tlist);
3369 return ((WORD_LIST *)NULL);
3372 /* This does not perform word splitting or dequote the WORD_LIST
3375 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
3377 int quoted, *dollar_at_p, *has_dollar_at;
3382 if (string == 0 || *string == '\0')
3383 return (WORD_LIST *)NULL;
3385 td.flags = W_NOSPLIT2; /* no splitting, remove "" and '' */
3387 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
3391 /* Expand STRING just as if you were expanding a word. This also returns
3392 a list of words. Note that filename globbing is *NOT* done for word
3393 or string expansion, just when the shell is expanding a command. This
3394 does parameter expansion, command substitution, arithmetic expansion,
3395 and word splitting. Dequote the resultant WORD_LIST before returning. */
3397 expand_string (string, quoted)
3403 if (string == 0 || *string == '\0')
3404 return ((WORD_LIST *)NULL);
3406 result = expand_string_leave_quoted (string, quoted);
3407 return (result ? dequote_list (result) : result);
3410 /***************************************************
3412 * Functions to handle quoting chars *
3414 ***************************************************/
3418 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3419 The parser passes CTLNUL as CTLESC CTLNUL. */
3421 /* Quote escape characters in string s, but no other characters. This is
3422 used to protect CTLESC and CTLNUL in variable values from the rest of
3423 the word expansion process after the variable is expanded (word splitting
3424 and filename generation). If IFS is null, we quote spaces as well, just
3425 in case we split on spaces later (in the case of unquoted $@, we will
3426 eventually attempt to split the entire word on spaces). Corresponding
3427 code exists in dequote_escapes. Even if we don't end up splitting on
3428 spaces, quoting spaces is not a problem. This should never be called on
3429 a string that is quoted with single or double quotes or part of a here
3430 document (effectively double-quoted). */
3432 quote_escapes (string)
3435 register char *s, *t;
3437 char *result, *send;
3438 int quote_spaces, skip_ctlesc, skip_ctlnul;
3441 slen = strlen (string);
3442 send = string + slen;
3444 quote_spaces = (ifs_value && *ifs_value == 0);
3446 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
3447 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
3449 t = result = (char *)xmalloc ((slen * 2) + 1);
3454 if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
3456 COPY_CHAR_P (t, s, send);
3463 list_quote_escapes (list)
3466 register WORD_LIST *w;
3469 for (w = list; w; w = w->next)
3472 w->word->word = quote_escapes (t);
3478 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3480 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3481 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3482 data stream pass through properly.
3484 We need to remove doubled CTLESC characters inside quoted strings before
3485 quoting the entire string, so we do not double the number of CTLESC
3488 Also used by parts of the pattern substitution code. */
3490 dequote_escapes (string)
3493 register char *s, *t, *s1;
3495 char *result, *send;
3502 slen = strlen (string);
3503 send = string + slen;
3505 t = result = (char *)xmalloc (slen + 1);
3507 if (strchr (string, CTLESC) == 0)
3508 return (strcpy (result, string));
3510 quote_spaces = (ifs_value && *ifs_value == 0);
3515 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
3521 COPY_CHAR_P (t, s, send);
3527 /* Return a new string with the quoted representation of character C.
3528 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3529 set in any resultant WORD_DESC where this value is the word. */
3531 make_quoted_char (c)
3536 temp = (char *)xmalloc (3);
3551 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3552 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3553 this value is the word. */
3555 quote_string (string)
3560 char *result, *send;
3564 result = (char *)xmalloc (2);
3572 slen = strlen (string);
3573 send = string + slen;
3575 result = (char *)xmalloc ((slen * 2) + 1);
3577 for (t = result; string < send; )
3580 COPY_CHAR_P (t, string, send);
3587 /* De-quote quoted characters in STRING. */
3589 dequote_string (string)
3592 register char *s, *t;
3594 char *result, *send;
3597 slen = strlen (string);
3599 t = result = (char *)xmalloc (slen + 1);
3601 if (QUOTED_NULL (string))
3607 /* If no character in the string can be quoted, don't bother examining
3608 each character. Just return a copy of the string passed to us. */
3609 if (strchr (string, CTLESC) == NULL)
3610 return (strcpy (result, string));
3612 send = string + slen;
3622 COPY_CHAR_P (t, s, send);
3629 /* Quote the entire WORD_LIST list. */
3634 register WORD_LIST *w;
3637 for (w = list; w; w = w->next)
3640 w->word->word = quote_string (t);
3642 w->word->flags |= W_HASQUOTEDNULL; /* XXX - turn on W_HASQUOTEDNULL here? */
3643 w->word->flags |= W_QUOTED;
3649 /* De-quote quoted characters in each word in LIST. */
3655 register WORD_LIST *tlist;
3657 for (tlist = list; tlist; tlist = tlist->next)
3659 s = dequote_string (tlist->word->word);
3660 if (QUOTED_NULL (tlist->word->word))
3661 tlist->word->flags &= ~W_HASQUOTEDNULL;
3662 free (tlist->word->word);
3663 tlist->word->word = s;
3668 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3671 remove_quoted_escapes (string)
3678 t = dequote_escapes (string);
3686 /* Perform quoted null character removal on STRING. We don't allow any
3687 quoted null characters in the middle or at the ends of strings because
3688 of how expand_word_internal works. remove_quoted_nulls () turns
3689 STRING into an empty string iff it only consists of a quoted null,
3690 and removes all unquoted CTLNUL characters. */
3692 remove_quoted_nulls (string)
3695 register size_t slen;
3696 register int i, j, prev_i;
3699 if (strchr (string, CTLNUL) == 0) /* XXX */
3700 return string; /* XXX */
3702 slen = strlen (string);
3707 if (string[i] == CTLESC)
3709 /* Old code had j++, but we cannot assume that i == j at this
3710 point -- what if a CTLNUL has already been removed from the
3711 string? We don't want to drop the CTLESC or recopy characters
3712 that we've already copied down. */
3713 i++; string[j++] = CTLESC;
3717 else if (string[i] == CTLNUL)
3724 ADVANCE_CHAR (string, slen, i);
3727 do string[j++] = string[prev_i++]; while (prev_i < i);
3737 /* Perform quoted null character removal on each element of LIST.
3738 This modifies LIST. */
3740 word_list_remove_quoted_nulls (list)
3743 register WORD_LIST *t;
3745 for (t = list; t; t = t->next)
3747 remove_quoted_nulls (t->word->word);
3748 t->word->flags &= ~W_HASQUOTEDNULL;
3752 /* **************************************************************** */
3754 /* Functions for Matching and Removing Patterns */
3756 /* **************************************************************** */
3758 #if defined (HANDLE_MULTIBYTE)
3759 #if 0 /* Currently unused */
3760 static unsigned char *
3761 mb_getcharlens (string, len)
3765 int i, offset, last;
3772 ret = (unsigned char *)xmalloc (len);
3773 memset (ret, 0, len);
3774 while (string[last])
3776 ADVANCE_CHAR (string, len, offset);
3777 ret[last] = offset - last;
3785 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3786 can have one of 4 values:
3787 RP_LONG_LEFT remove longest matching portion at start of PARAM
3788 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3789 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3790 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3793 #define RP_LONG_LEFT 1
3794 #define RP_SHORT_LEFT 2
3795 #define RP_LONG_RIGHT 3
3796 #define RP_SHORT_RIGHT 4
3798 /* Returns its first argument if nothing matched; new memory otherwise */
3800 remove_upattern (param, pattern, op)
3801 char *param, *pattern;
3806 register char *p, *ret, c;
3808 len = STRLEN (param);
3813 case RP_LONG_LEFT: /* remove longest match at start */
3814 for (p = end; p >= param; p--)
3817 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3820 return (savestring (p));
3827 case RP_SHORT_LEFT: /* remove shortest match at start */
3828 for (p = param; p <= end; p++)
3831 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3834 return (savestring (p));
3840 case RP_LONG_RIGHT: /* remove longest match at end */
3841 for (p = param; p <= end; p++)
3843 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3846 ret = savestring (param);
3853 case RP_SHORT_RIGHT: /* remove shortest match at end */
3854 for (p = end; p >= param; p--)
3856 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3859 ret = savestring (param);
3867 return (param); /* no match, return original string */
3870 #if defined (HANDLE_MULTIBYTE)
3871 /* Returns its first argument if nothing matched; new memory otherwise */
3873 remove_wpattern (wparam, wstrlen, wpattern, op)
3884 case RP_LONG_LEFT: /* remove longest match at start */
3885 for (n = wstrlen; n >= 0; n--)
3887 wc = wparam[n]; wparam[n] = L'\0';
3888 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3891 return (wcsdup (wparam + n));
3897 case RP_SHORT_LEFT: /* remove shortest match at start */
3898 for (n = 0; n <= wstrlen; n++)
3900 wc = wparam[n]; wparam[n] = L'\0';
3901 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3904 return (wcsdup (wparam + n));
3910 case RP_LONG_RIGHT: /* remove longest match at end */
3911 for (n = 0; n <= wstrlen; n++)
3913 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3915 wc = wparam[n]; wparam[n] = L'\0';
3916 ret = wcsdup (wparam);
3923 case RP_SHORT_RIGHT: /* remove shortest match at end */
3924 for (n = wstrlen; n >= 0; n--)
3926 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3928 wc = wparam[n]; wparam[n] = L'\0';
3929 ret = wcsdup (wparam);
3937 return (wparam); /* no match, return original string */
3939 #endif /* HANDLE_MULTIBYTE */
3942 remove_pattern (param, pattern, op)
3943 char *param, *pattern;
3950 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3951 return (savestring (param));
3953 #if defined (HANDLE_MULTIBYTE)
3956 wchar_t *ret, *oret;
3958 wchar_t *wparam, *wpattern;
3961 n = xdupmbstowcs (&wpattern, NULL, pattern);
3962 if (n == (size_t)-1)
3964 xret = remove_upattern (param, pattern, op);
3965 return ((xret == param) ? savestring (param) : xret);
3967 n = xdupmbstowcs (&wparam, NULL, param);
3968 if (n == (size_t)-1)
3971 xret = remove_upattern (param, pattern, op);
3972 return ((xret == param) ? savestring (param) : xret);
3974 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3975 /* Don't bother to convert wparam back to multibyte string if nothing
3976 matched; just return copy of original string */
3981 return (savestring (param));
3988 xret = (char *)xmalloc (n + 1);
3989 memset (&ps, '\0', sizeof (mbstate_t));
3990 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3991 xret[n] = '\0'; /* just to make sure */
3998 xret = remove_upattern (param, pattern, op);
3999 return ((xret == param) ? savestring (param) : xret);
4003 /* Match PAT anywhere in STRING and return the match boundaries.
4004 This returns 1 in case of a successful match, 0 otherwise. SP
4005 and EP are pointers into the string where the match begins and
4006 ends, respectively. MTYPE controls what kind of match is attempted.
4007 MATCH_BEG and MATCH_END anchor the match at the beginning and end
4008 of the string, respectively. The longest match is returned. */
4010 match_upattern (string, pat, mtype, sp, ep)
4016 register char *p, *p1, *npat;
4020 /* If the pattern doesn't match anywhere in the string, go ahead and
4021 short-circuit right away. A minor optimization, saves a bunch of
4022 unnecessary calls to strmatch (up to N calls for a string of N
4023 characters) if the match is unsuccessful. To preserve the semantics
4024 of the substring matches below, we make sure that the pattern has
4025 `*' as first and last character, making a new pattern if necessary. */
4026 /* XXX - check this later if I ever implement `**' with special meaning,
4027 since this will potentially result in `**' at the beginning or end */
4029 if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
4031 p = npat = (char *)xmalloc (len + 3);
4033 if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
4037 if (p1[-1] != '*' || p[-2] == '\\')
4043 c = strmatch (npat, string, FNMATCH_EXTFLAG);
4046 if (c == FNM_NOMATCH)
4049 len = STRLEN (string);
4052 mlen = umatchlen (pat, len);
4057 for (p = string; p <= end; p++)
4059 if (match_pattern_char (pat, p))
4062 for (p1 = end; p1 >= p; p1--)
4064 p1 = (mlen == -1) ? end : p + mlen;
4065 /* p1 - p = length of portion of string to be considered
4066 p = current position in string
4067 mlen = number of characters consumed by match (-1 for entire string)
4069 we want to break immediately if the potential match len
4070 is greater than the number of characters remaining in the
4075 for ( ; p1 >= p; p1--)
4078 c = *p1; *p1 = '\0';
4079 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
4088 /* If MLEN != -1, we have a fixed length pattern. */
4099 if (match_pattern_char (pat, string) == 0)
4103 for (p = end; p >= string; p--)
4105 for (p = (mlen == -1) ? end : string + mlen; p >= string; p--)
4109 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
4118 /* If MLEN != -1, we have a fixed length pattern. */
4128 for (p = string; p <= end; p++)
4130 for (p = end - ((mlen == -1) ? len : mlen); p <= end; p++)
4133 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
4140 /* If MLEN != -1, we have a fixed length pattern. */
4152 #if defined (HANDLE_MULTIBYTE)
4153 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4154 This returns 1 in case of a successful match, 0 otherwise. Wide
4155 character version. */
4157 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
4165 wchar_t wc, *wp, *nwpat, *wp1;
4168 int n, n1, n2, simple;
4170 simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
4171 #if defined (EXTENDED_GLOB)
4173 simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
4176 /* If the pattern doesn't match anywhere in the string, go ahead and
4177 short-circuit right away. A minor optimization, saves a bunch of
4178 unnecessary calls to strmatch (up to N calls for a string of N
4179 characters) if the match is unsuccessful. To preserve the semantics
4180 of the substring matches below, we make sure that the pattern has
4181 `*' as first and last character, making a new pattern if necessary. */
4182 len = wcslen (wpat);
4183 if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == WLPAREN && extended_glob) || wpat[len - 1] != L'*')
4185 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
4187 if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == WLPAREN && extended_glob))
4189 while (*wp1 != L'\0')
4191 if (wp1[-1] != L'*' || wp1[-2] == L'\\')
4197 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
4200 if (len == FNM_NOMATCH)
4203 mlen = wmatchlen (wpat, wstrlen);
4205 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4209 for (n = 0; n <= wstrlen; n++)
4212 n2 = simple ? (*wpat == wstring[n]) : match_pattern_wchar (wpat, wstring + n);
4214 n2 = match_pattern_wchar (wpat, wstring + n);
4219 for (n1 = wstrlen; n1 >= n; n1--)
4221 n1 = (mlen == -1) ? wstrlen : n + mlen;
4225 for ( ; n1 >= n; n1--)
4228 wc = wstring[n1]; wstring[n1] = L'\0';
4229 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
4238 /* If MLEN != -1, we have a fixed length pattern. */
4249 if (match_pattern_wchar (wpat, wstring) == 0)
4253 for (n = wstrlen; n >= 0; n--)
4255 for (n = (mlen == -1) ? wstrlen : mlen; n >= 0; n--)
4258 wc = wstring[n]; wstring[n] = L'\0';
4259 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
4268 /* If MLEN != -1, we have a fixed length pattern. */
4278 for (n = 0; n <= wstrlen; n++)
4280 for (n = wstrlen - ((mlen == -1) ? wstrlen : mlen); n <= wstrlen; n++)
4283 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
4286 *ep = indices[wstrlen];
4290 /* If MLEN != -1, we have a fixed length pattern. */
4301 #endif /* HANDLE_MULTIBYTE */
4304 match_pattern (string, pat, mtype, sp, ep)
4309 #if defined (HANDLE_MULTIBYTE)
4312 wchar_t *wstring, *wpat;
4314 size_t slen, plen, mslen, mplen;
4317 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
4320 #if defined (HANDLE_MULTIBYTE)
4324 slen = STRLEN (string);
4325 mslen = MBSLEN (string);
4326 plen = STRLEN (pat);
4327 mplen = MBSLEN (pat);
4328 if (slen == mslen && plen == mplen)
4330 if (mbsmbchar (string) == 0 && mbsmbchar (pat) == 0)
4332 return (match_upattern (string, pat, mtype, sp, ep));
4334 n = xdupmbstowcs (&wpat, NULL, pat);
4335 if (n == (size_t)-1)
4336 return (match_upattern (string, pat, mtype, sp, ep));
4337 n = xdupmbstowcs (&wstring, &indices, string);
4338 if (n == (size_t)-1)
4341 return (match_upattern (string, pat, mtype, sp, ep));
4343 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
4353 return (match_upattern (string, pat, mtype, sp, ep));
4357 getpatspec (c, value)
4362 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
4364 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
4367 /* Posix.2 says that the WORD should be run through tilde expansion,
4368 parameter expansion, command substitution and arithmetic expansion.
4369 This leaves the result quoted, so quote_string_for_globbing () has
4370 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4371 it means that the entire expression was enclosed in double quotes.
4372 This means that quoting characters in the pattern do not make any
4373 special pattern characters quoted. For example, the `*' in the
4374 following retains its special meaning: "${foo#'*'}". */
4376 getpattern (value, quoted, expandpat)
4378 int quoted, expandpat;
4385 /* There is a problem here: how to handle single or double quotes in the
4386 pattern string when the whole expression is between double quotes?
4387 POSIX.2 says that enclosing double quotes do not cause the pattern to
4388 be quoted, but does that leave us a problem with @ and array[@] and their
4389 expansions inside a pattern? */
4391 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
4394 pat = string_extract_double_quoted (tword, &i, 1);
4400 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4402 l = *value ? expand_string_for_rhs (value,
4403 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
4404 (int *)NULL, (int *)NULL)
4406 pat = string_list (l);
4410 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
4418 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4419 or ${name#[#]value}. */
4421 variable_remove_pattern (value, pattern, patspec, quoted)
4422 char *value, *pattern;
4423 int patspec, quoted;
4427 tword = remove_pattern (value, pattern, patspec);
4434 list_remove_pattern (list, pattern, patspec, itype, quoted)
4437 int patspec, itype, quoted;
4443 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
4445 tword = remove_pattern (l->word->word, pattern, patspec);
4446 w = alloc_word_desc ();
4447 w->word = tword ? tword : savestring ("");
4448 new = make_word_list (w, new);
4451 l = REVERSE_LIST (new, WORD_LIST *);
4452 tword = string_list_pos_params (itype, l, quoted);
4459 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
4462 int patspec, quoted;
4467 list = list_rest_of_args ();
4469 return ((char *)NULL);
4470 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4471 dispose_words (list);
4475 #if defined (ARRAY_VARS)
4477 array_remove_pattern (var, pattern, patspec, varname, quoted)
4481 char *varname; /* so we can figure out how it's indexed */
4491 /* compute itype from varname here */
4492 v = array_variable_part (varname, &ret, 0);
4495 a = (v && array_p (v)) ? array_cell (v) : 0;
4496 h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
4498 list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
4500 return ((char *)NULL);
4501 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4502 dispose_words (list);
4506 #endif /* ARRAY_VARS */
4509 parameter_brace_remove_pattern (varname, value, ind, patstr, rtype, quoted, flags)
4510 char *varname, *value;
4513 int rtype, quoted, flags;
4515 int vtype, patspec, starsub;
4516 char *temp1, *val, *pattern;
4520 return ((char *)NULL);
4522 this_command_name = varname;
4524 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
4526 return ((char *)NULL);
4528 starsub = vtype & VT_STARSUB;
4529 vtype &= ~VT_STARSUB;
4531 patspec = getpatspec (rtype, patstr);
4532 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
4535 /* Need to pass getpattern newly-allocated memory in case of expansion --
4536 the expansion code will free the passed string on an error. */
4537 temp1 = savestring (patstr);
4538 pattern = getpattern (temp1, quoted, 1);
4541 temp1 = (char *)NULL; /* shut up gcc */
4545 case VT_ARRAYMEMBER:
4546 temp1 = remove_pattern (val, pattern, patspec);
4547 if (vtype == VT_VARIABLE)
4551 val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4552 ? quote_string (temp1)
4553 : quote_escapes (temp1);
4558 #if defined (ARRAY_VARS)
4560 temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
4561 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4563 val = quote_escapes (temp1);
4570 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
4571 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4573 val = quote_escapes (temp1);
4584 /*******************************************
4586 * Functions to expand WORD_DESCs *
4588 *******************************************/
4590 /* Expand WORD, performing word splitting on the result. This does
4591 parameter expansion, command substitution, arithmetic expansion,
4592 word splitting, and quote removal. */
4595 expand_word (word, quoted)
4599 WORD_LIST *result, *tresult;
4601 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4602 result = word_list_split (tresult);
4603 dispose_words (tresult);
4604 return (result ? dequote_list (result) : result);
4607 /* Expand WORD, but do not perform word splitting on the result. This
4608 does parameter expansion, command substitution, arithmetic expansion,
4609 and quote removal. */
4611 expand_word_unsplit (word, quoted)
4617 expand_no_split_dollar_star = 1;
4618 #if defined (HANDLE_MULTIBYTE)
4619 if (ifs_firstc[0] == 0)
4621 if (ifs_firstc == 0)
4623 word->flags |= W_NOSPLIT;
4624 word->flags |= W_NOSPLIT2;
4625 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4626 expand_no_split_dollar_star = 0;
4628 return (result ? dequote_list (result) : result);
4631 /* Perform shell expansions on WORD, but do not perform word splitting or
4632 quote removal on the result. Virtually identical to expand_word_unsplit;
4633 could be combined if implementations don't diverge. */
4635 expand_word_leave_quoted (word, quoted)
4641 expand_no_split_dollar_star = 1;
4642 #if defined (HANDLE_MULTIBYTE)
4643 if (ifs_firstc[0] == 0)
4645 if (ifs_firstc == 0)
4647 word->flags |= W_NOSPLIT;
4648 word->flags |= W_NOSPLIT2;
4649 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4650 expand_no_split_dollar_star = 0;
4655 #if defined (PROCESS_SUBSTITUTION)
4657 /*****************************************************************/
4659 /* Hacking Process Substitution */
4661 /*****************************************************************/
4663 #if !defined (HAVE_DEV_FD)
4664 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4665 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4666 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4667 list. NFIFO is a count of the number of FIFOs in the list. */
4668 #define FIFO_INCR 20
4675 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
4677 static int fifo_list_size;
4680 copy_fifo_list (sizep)
4685 return (char *)NULL;
4689 add_fifo_list (pathname)
4692 if (nfifo >= fifo_list_size - 1)
4694 fifo_list_size += FIFO_INCR;
4695 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
4696 fifo_list_size * sizeof (struct temp_fifo));
4699 fifo_list[nfifo].file = savestring (pathname);
4707 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4709 unlink (fifo_list[i].file);
4710 free (fifo_list[i].file);
4711 fifo_list[i].file = (char *)NULL;
4712 fifo_list[i].proc = -1;
4724 for (i = saved = 0; i < nfifo; i++)
4726 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4728 unlink (fifo_list[i].file);
4729 free (fifo_list[i].file);
4730 fifo_list[i].file = (char *)NULL;
4731 fifo_list[i].proc = -1;
4737 /* If we didn't remove some of the FIFOs, compact the list. */
4740 for (i = j = 0; i < nfifo; i++)
4741 if (fifo_list[i].file)
4743 fifo_list[j].file = fifo_list[i].file;
4744 fifo_list[j].proc = fifo_list[i].proc;
4753 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4754 from some point in the past, and close all open FIFOs in fifo_list
4755 that are not marked as active in LIST. If LIST is NULL, close
4756 everything in fifo_list. LSIZE is the number of elements in LIST, in
4757 case it's larger than fifo_list_size (size of fifo_list). */
4759 close_new_fifos (list, lsize)
4767 unlink_fifo_list ();
4771 for (i = 0; i < lsize; i++)
4772 if (list[i] == 0 && i < fifo_list_size && fifo_list[i].proc != -1)
4775 for (i = lsize; i < fifo_list_size; i++)
4796 tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
4797 if (mkfifo (tname, 0600) < 0)
4800 return ((char *)NULL);
4803 add_fifo_list (tname);
4807 #else /* HAVE_DEV_FD */
4809 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4810 has open to children. NFDS is a count of the number of bits currently
4811 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4813 static char *dev_fd_list = (char *)NULL;
4815 static int totfds; /* The highest possible number of open files. */
4818 copy_fifo_list (sizep)
4823 if (nfds == 0 || totfds == 0)
4827 return (char *)NULL;
4832 ret = (char *)xmalloc (totfds);
4833 return (memcpy (ret, dev_fd_list, totfds));
4840 if (dev_fd_list == 0 || fd >= totfds)
4845 totfds = getdtablesize ();
4846 if (totfds < 0 || totfds > 256)
4851 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
4852 memset (dev_fd_list + ofds, '\0', totfds - ofds);
4855 dev_fd_list[fd] = 1;
4862 return 0; /* used for cleanup; not needed with /dev/fd */
4875 if (dev_fd_list[fd])
4878 dev_fd_list[fd] = 0;
4891 for (i = 0; nfds && i < totfds; i++)
4897 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4898 the past, and close all open fds in dev_fd_list that are not marked
4899 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4900 LSIZE is the number of elements in LIST, in case it's larger than
4901 totfds (size of dev_fd_list). */
4903 close_new_fifos (list, lsize)
4911 unlink_fifo_list ();
4915 for (i = 0; i < lsize; i++)
4916 if (list[i] == 0 && i < totfds && dev_fd_list[i])
4919 for (i = lsize; i < totfds; i++)
4923 #if defined (NOTDEF)
4924 print_dev_fd_list ()
4928 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
4931 for (i = 0; i < totfds; i++)
4934 fprintf (stderr, " %d", i);
4936 fprintf (stderr, "\n");
4941 make_dev_fd_filename (fd)
4944 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
4946 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
4948 strcpy (ret, DEV_FD_PREFIX);
4949 p = inttostr (fd, intbuf, sizeof (intbuf));
4950 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
4956 #endif /* HAVE_DEV_FD */
4958 /* Return a filename that will open a connection to the process defined by
4959 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4960 a filename in /dev/fd corresponding to a descriptor that is one of the
4961 ends of the pipe. If not defined, we use named pipes on systems that have
4962 them. Systems without /dev/fd and named pipes are out of luck.
4964 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4965 use the read end of the pipe and dup that file descriptor to fd 0 in
4966 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4967 writing or use the write end of the pipe in the child, and dup that
4968 file descriptor to fd 1 in the child. The parent does the opposite. */
4971 process_substitute (string, open_for_read_in_child)
4973 int open_for_read_in_child;
4978 #if defined (HAVE_DEV_FD)
4979 int parent_pipe_fd, child_pipe_fd;
4981 #endif /* HAVE_DEV_FD */
4982 #if defined (JOB_CONTROL)
4983 pid_t old_pipeline_pgrp;
4986 if (!string || !*string || wordexp_only)
4987 return ((char *)NULL);
4989 #if !defined (HAVE_DEV_FD)
4990 pathname = make_named_pipe ();
4991 #else /* HAVE_DEV_FD */
4992 if (pipe (fildes) < 0)
4994 sys_error (_("cannot make pipe for process substitution"));
4995 return ((char *)NULL);
4997 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4998 the pipe in the parent, otherwise the read end. */
4999 parent_pipe_fd = fildes[open_for_read_in_child];
5000 child_pipe_fd = fildes[1 - open_for_read_in_child];
5001 /* Move the parent end of the pipe to some high file descriptor, to
5002 avoid clashes with FDs used by the script. */
5003 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
5005 pathname = make_dev_fd_filename (parent_pipe_fd);
5006 #endif /* HAVE_DEV_FD */
5010 sys_error (_("cannot make pipe for process substitution"));
5011 return ((char *)NULL);
5014 old_pid = last_made_pid;
5016 #if defined (JOB_CONTROL)
5017 old_pipeline_pgrp = pipeline_pgrp;
5018 pipeline_pgrp = shell_pgrp;
5020 #endif /* JOB_CONTROL */
5022 pid = make_child ((char *)NULL, 1);
5025 reset_terminating_signals (); /* XXX */
5026 free_pushed_string_input ();
5027 /* Cancel traps, in trap.c. */
5028 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5029 setup_async_signals ();
5030 subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
5033 #if defined (JOB_CONTROL)
5034 set_sigchld_handler ();
5035 stop_making_children ();
5036 /* XXX - should we only do this in the parent? (as in command subst) */
5037 pipeline_pgrp = old_pipeline_pgrp;
5038 #endif /* JOB_CONTROL */
5042 sys_error (_("cannot make child for process substitution"));
5044 #if defined (HAVE_DEV_FD)
5045 close (parent_pipe_fd);
5046 close (child_pipe_fd);
5047 #endif /* HAVE_DEV_FD */
5048 return ((char *)NULL);
5053 #if defined (JOB_CONTROL)
5054 restore_pipeline (1);
5057 #if !defined (HAVE_DEV_FD)
5058 fifo_list[nfifo-1].proc = pid;
5061 last_made_pid = old_pid;
5063 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5065 #endif /* JOB_CONTROL && PGRP_PIPE */
5067 #if defined (HAVE_DEV_FD)
5068 close (child_pipe_fd);
5069 #endif /* HAVE_DEV_FD */
5074 set_sigint_handler ();
5076 #if defined (JOB_CONTROL)
5077 set_job_control (0);
5078 #endif /* JOB_CONTROL */
5080 #if !defined (HAVE_DEV_FD)
5081 /* Open the named pipe in the child. */
5082 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
5085 /* Two separate strings for ease of translation. */
5086 if (open_for_read_in_child)
5087 sys_error (_("cannot open named pipe %s for reading"), pathname);
5089 sys_error (_("cannot open named pipe %s for writing"), pathname);
5093 if (open_for_read_in_child)
5095 if (sh_unset_nodelay_mode (fd) < 0)
5097 sys_error (_("cannot reset nodelay mode for fd %d"), fd);
5101 #else /* HAVE_DEV_FD */
5103 #endif /* HAVE_DEV_FD */
5105 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
5107 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
5108 open_for_read_in_child ? 0 : 1);
5112 if (fd != (open_for_read_in_child ? 0 : 1))
5115 /* Need to close any files that this process has open to pipes inherited
5117 if (current_fds_to_close)
5119 close_fd_bitmap (current_fds_to_close);
5120 current_fds_to_close = (struct fd_bitmap *)NULL;
5123 #if defined (HAVE_DEV_FD)
5124 /* Make sure we close the parent's end of the pipe and clear the slot
5125 in the fd list so it is not closed later, if reallocated by, for
5126 instance, pipe(2). */
5127 close (parent_pipe_fd);
5128 dev_fd_list[parent_pipe_fd] = 0;
5129 #endif /* HAVE_DEV_FD */
5131 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
5133 #if !defined (HAVE_DEV_FD)
5134 /* Make sure we close the named pipe in the child before we exit. */
5135 close (open_for_read_in_child ? 0 : 1);
5136 #endif /* !HAVE_DEV_FD */
5141 #endif /* PROCESS_SUBSTITUTION */
5143 /***********************************/
5145 /* Command Substitution */
5147 /***********************************/
5150 read_comsub (fd, quoted, rflag)
5154 char *istring, buf[128], *bufp, *s;
5155 int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
5158 istring = (char *)NULL;
5159 istring_index = istring_size = bufn = tflag = 0;
5161 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
5162 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
5164 /* Read the output of the command through the pipe. This may need to be
5165 changed to understand multibyte characters in the future. */
5172 bufn = zread (fd, buf, sizeof (buf));
5182 internal_warning ("read_comsub: ignored null byte in input");
5187 /* Add the character to ISTRING, possibly after resizing it. */
5188 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
5190 /* This is essentially quote_string inline */
5191 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
5192 istring[istring_index++] = CTLESC;
5193 /* Escape CTLESC and CTLNUL in the output to protect those characters
5194 from the rest of the word expansions (word splitting and globbing.)
5195 This is essentially quote_escapes inline. */
5196 else if (skip_ctlesc == 0 && c == CTLESC)
5198 tflag |= W_HASCTLESC;
5199 istring[istring_index++] = CTLESC;
5201 else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
5202 istring[istring_index++] = CTLESC;
5204 istring[istring_index++] = c;
5207 #if defined (__CYGWIN__)
5208 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
5211 istring[istring_index - 1] = '\n';
5218 istring[istring_index] = '\0';
5220 /* If we read no output, just return now and save ourselves some
5222 if (istring_index == 0)
5227 return (char *)NULL;
5230 /* Strip trailing newlines from the output of the command. */
5231 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5233 while (istring_index > 0)
5235 if (istring[istring_index - 1] == '\n')
5239 /* If the newline was quoted, remove the quoting char. */
5240 if (istring[istring_index - 1] == CTLESC)
5246 istring[istring_index] = '\0';
5249 strip_trailing (istring, istring_index - 1, 1);
5256 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5257 contained string possibly quoted. */
5259 command_substitute (string, quoted)
5263 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
5265 int result, fildes[2], function_value, pflags, rc, tflag;
5268 istring = (char *)NULL;
5270 /* Don't fork () if there is no need to. In the case of no command to
5271 run, just return NULL. */
5272 if (!string || !*string || (string[0] == '\n' && !string[1]))
5273 return ((WORD_DESC *)NULL);
5275 if (wordexp_only && read_but_dont_execute)
5277 last_command_exit_value = EX_WEXPCOMSUB;
5278 jump_to_top_level (EXITPROG);
5281 /* We're making the assumption here that the command substitution will
5282 eventually run a command from the file system. Since we'll run
5283 maybe_make_export_env in this subshell before executing that command,
5284 the parent shell and any other shells it starts will have to remake
5285 the environment. If we make it before we fork, other shells won't
5286 have to. Don't bother if we have any temporary variable assignments,
5287 though, because the export environment will be remade after this
5288 command completes anyway, but do it if all the words to be expanded
5289 are variable assignments. */
5290 if (subst_assign_varlist == 0 || garglist == 0)
5291 maybe_make_export_env (); /* XXX */
5293 /* Flags to pass to parse_and_execute() */
5294 pflags = (interactive && sourcelevel == 0) ? SEVAL_RESETLINE : 0;
5296 /* Pipe the output of executing STRING into the current shell. */
5297 if (pipe (fildes) < 0)
5299 sys_error (_("cannot make pipe for command substitution"));
5303 old_pid = last_made_pid;
5304 #if defined (JOB_CONTROL)
5305 old_pipeline_pgrp = pipeline_pgrp;
5306 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5307 if ((subshell_environment & SUBSHELL_PIPE) == 0)
5308 pipeline_pgrp = shell_pgrp;
5309 cleanup_the_pipeline ();
5310 #endif /* JOB_CONTROL */
5312 old_async_pid = last_asynchronous_pid;
5313 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
5314 last_asynchronous_pid = old_async_pid;
5318 /* Reset the signal handlers in the child, but don't free the
5319 trap strings. Set a flag noting that we have to free the
5320 trap strings if we run trap to change a signal disposition. */
5321 reset_signal_handlers ();
5322 subshell_environment |= SUBSHELL_RESETTRAP;
5325 #if defined (JOB_CONTROL)
5326 /* XXX DO THIS ONLY IN PARENT ? XXX */
5327 set_sigchld_handler ();
5328 stop_making_children ();
5330 pipeline_pgrp = old_pipeline_pgrp;
5332 stop_making_children ();
5333 #endif /* JOB_CONTROL */
5337 sys_error (_("cannot make child for command substitution"));
5340 last_made_pid = old_pid;
5345 return ((WORD_DESC *)NULL);
5350 set_sigint_handler (); /* XXX */
5352 free_pushed_string_input ();
5354 if (dup2 (fildes[1], 1) < 0)
5356 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5357 exit (EXECUTION_FAILURE);
5360 /* If standard output is closed in the parent shell
5361 (such as after `exec >&-'), file descriptor 1 will be
5362 the lowest available file descriptor, and end up in
5363 fildes[0]. This can happen for stdin and stderr as well,
5364 but stdout is more important -- it will cause no output
5365 to be generated from this command. */
5366 if ((fildes[1] != fileno (stdin)) &&
5367 (fildes[1] != fileno (stdout)) &&
5368 (fildes[1] != fileno (stderr)))
5371 if ((fildes[0] != fileno (stdin)) &&
5372 (fildes[0] != fileno (stdout)) &&
5373 (fildes[0] != fileno (stderr)))
5377 /* Let stdio know the fd may have changed from text to binary mode, and
5378 make sure to preserve stdout line buffering. */
5379 freopen (NULL, "w", stdout);
5380 sh_setlinebuf (stdout);
5381 #endif /* __CYGWIN__ */
5383 /* The currently executing shell is not interactive. */
5386 /* This is a subshell environment. */
5387 subshell_environment |= SUBSHELL_COMSUB;
5389 /* When not in POSIX mode, command substitution does not inherit
5391 if (posixly_correct == 0)
5392 exit_immediately_on_error = 0;
5394 remove_quoted_escapes (string);
5396 startup_state = 2; /* see if we can avoid a fork */
5397 /* Give command substitution a place to jump back to on failure,
5398 so we don't go back up to main (). */
5399 result = setjmp (top_level);
5401 /* If we're running a command substitution inside a shell function,
5402 trap `return' so we don't return from the function in the subshell
5403 and go off to never-never land. */
5404 if (result == 0 && return_catch_flag)
5405 function_value = setjmp (return_catch);
5409 if (result == ERREXIT)
5410 rc = last_command_exit_value;
5411 else if (result == EXITPROG)
5412 rc = last_command_exit_value;
5414 rc = EXECUTION_FAILURE;
5415 else if (function_value)
5416 rc = return_catch_value;
5420 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
5424 last_command_exit_value = rc;
5425 rc = run_exit_trap ();
5426 #if defined (PROCESS_SUBSTITUTION)
5427 unlink_fifo_list ();
5433 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5435 #endif /* JOB_CONTROL && PGRP_PIPE */
5440 istring = read_comsub (fildes[0], quoted, &tflag);
5444 current_command_subst_pid = pid;
5445 last_command_exit_value = wait_for (pid);
5446 last_command_subst_pid = pid;
5447 last_made_pid = old_pid;
5449 #if defined (JOB_CONTROL)
5450 /* If last_command_exit_value > 128, then the substituted command
5451 was terminated by a signal. If that signal was SIGINT, then send
5452 SIGINT to ourselves. This will break out of loops, for instance. */
5453 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
5454 kill (getpid (), SIGINT);
5456 /* wait_for gives the terminal back to shell_pgrp. If some other
5457 process group should have it, give it away to that group here.
5458 pipeline_pgrp is non-zero only while we are constructing a
5459 pipline, so what we are concerned about is whether or not that
5460 pipeline was started in the background. A pipeline started in
5461 the background should never get the tty back here. */
5462 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
5463 give_terminal_to (pipeline_pgrp, 0);
5464 #endif /* JOB_CONTROL */
5466 ret = alloc_word_desc ();
5467 ret->word = istring;
5474 /********************************************************
5476 * Utility functions for parameter expansion *
5478 ********************************************************/
5480 #if defined (ARRAY_VARS)
5483 array_length_reference (s)
5494 var = array_variable_part (s, &t, &len);
5496 /* If unbound variables should generate an error, report one and return
5498 if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
5502 last_command_exit_value = EXECUTION_FAILURE;
5510 /* We support a couple of expansions for variables that are not arrays.
5511 We'll return the length of the value for v[0], and 1 for v[@] or
5512 v[*]. Return 0 for everything else. */
5514 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
5515 h = assoc_p (var) ? assoc_cell (var) : (HASH_TABLE *)NULL;
5517 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
5520 return (h ? assoc_num_elements (h) : 0);
5521 else if (array_p (var))
5522 return (array ? array_num_elements (array) : 0);
5524 return (var_isset (var) ? 1 : 0);
5530 akey = expand_assignment_string_to_string (t, 0); /* [ */
5532 if (akey == 0 || *akey == 0)
5534 err_badarraysub (t);
5538 t = assoc_reference (assoc_cell (var), akey);
5543 ind = array_expand_index (var, t, len);
5544 /* negative subscripts to indexed arrays count back from end */
5545 if (var && array_p (var) && ind < 0)
5546 ind = array_max_index (array_cell (var)) + 1 + ind;
5549 err_badarraysub (t);
5553 t = array_reference (array, ind);
5555 t = (ind == 0) ? value_cell (var) : (char *)NULL;
5558 len = MB_STRLEN (t);
5561 #endif /* ARRAY_VARS */
5564 valid_brace_expansion_word (name, var_is_special)
5568 if (DIGIT (*name) && all_digits (name))
5570 else if (var_is_special)
5572 #if defined (ARRAY_VARS)
5573 else if (valid_array_reference (name))
5575 #endif /* ARRAY_VARS */
5576 else if (legal_identifier (name))
5583 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
5586 int *quoted_dollar_atp, *contains_dollar_at;
5592 if (quoted_dollar_atp)
5593 *quoted_dollar_atp = 0;
5594 if (contains_dollar_at)
5595 *contains_dollar_at = 0;
5599 /* check for $@ and $* */
5600 if (name[0] == '@' && name[1] == 0)
5602 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5603 *quoted_dollar_atp = 1;
5604 if (contains_dollar_at)
5605 *contains_dollar_at = 1;
5608 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
5610 if (contains_dollar_at)
5611 *contains_dollar_at = 1;
5615 /* Now check for ${array[@]} and ${array[*]} */
5616 #if defined (ARRAY_VARS)
5617 else if (valid_array_reference (name))
5619 temp1 = mbschr (name, '[');
5620 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
5622 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5623 *quoted_dollar_atp = 1;
5624 if (contains_dollar_at)
5625 *contains_dollar_at = 1;
5628 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5629 which should result in separate words even when IFS is unset. */
5630 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
5632 if (contains_dollar_at)
5633 *contains_dollar_at = 1;
5641 /* Parameter expand NAME, and return a new string which is the expansion,
5642 or NULL if there was no expansion.
5643 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5644 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5645 NAME was found inside of a double-quoted expression. */
5647 parameter_brace_expand_word (name, var_is_special, quoted, pflags, indp)
5649 int var_is_special, quoted, pflags;
5666 /* Handle multiple digit arguments, as in ${11}. */
5667 if (legal_number (name, &arg_index))
5669 tt = get_dollar_var_value (arg_index);
5671 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5673 : quote_escapes (tt);
5675 temp = (char *)NULL;
5678 else if (var_is_special) /* ${@} */
5681 tt = (char *)xmalloc (2 + strlen (name));
5682 tt[sindex = 0] = '$';
5683 strcpy (tt + 1, name);
5685 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
5686 (int *)NULL, (int *)NULL, pflags);
5689 #if defined (ARRAY_VARS)
5690 else if (valid_array_reference (name))
5693 /* XXX - does this leak if name[@] or name[*]? */
5694 temp = array_value (name, quoted, 0, &atype, &ind);
5695 if (atype == 0 && temp)
5697 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5698 ? quote_string (temp)
5699 : quote_escapes (temp);
5700 rflags |= W_ARRAYIND;
5704 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5705 rflags |= W_HASQUOTEDNULL;
5708 else if (var = find_variable (name))
5710 if (var_isset (var) && invisible_p (var) == 0)
5712 #if defined (ARRAY_VARS)
5714 temp = assoc_reference (assoc_cell (var), "0");
5715 else if (array_p (var))
5716 temp = array_reference (array_cell (var), 0);
5718 temp = value_cell (var);
5720 temp = value_cell (var);
5724 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5725 ? quote_string (temp)
5726 : quote_escapes (temp);
5729 temp = (char *)NULL;
5731 else if (var = find_variable_last_nameref (name))
5733 temp = nameref_cell (var);
5734 #if defined (ARRAY_VARS)
5735 /* Handle expanding nameref whose value is x[n] */
5736 if (temp && *temp && valid_array_reference (temp))
5739 goto expand_arrayref;
5742 /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */
5743 else if (temp && *temp && legal_identifier (temp) == 0)
5745 last_command_exit_value = EXECUTION_FAILURE;
5746 report_error (_("%s: invalid variable name for name reference"), temp);
5747 temp = &expand_param_error;
5750 temp = (char *)NULL;
5753 temp = (char *)NULL;
5757 ret = alloc_word_desc ();
5759 ret->flags |= rflags;
5764 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5765 value of the variable whose name is the value of NAME. */
5767 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
5769 int var_is_special, quoted;
5770 int *quoted_dollar_atp, *contains_dollar_at;
5776 /* See if it's a nameref first, behave in ksh93-compatible fashion.
5777 There is at least one incompatibility: given ${!foo[0]} where foo=bar,
5778 bash performs an indirect lookup on foo[0] and expands the result;
5779 ksh93 expands bar[0]. We could do that here -- there are enough usable
5780 primitives to do that -- but do not at this point. */
5781 if (var_is_special == 0 && (v = find_variable_last_nameref (name)))
5783 if (nameref_p (v) && (t = nameref_cell (v)) && *t)
5785 w = alloc_word_desc ();
5786 w->word = savestring (t);
5792 /* If var_is_special == 0, and name is not an array reference, this does
5793 more expansion than necessary. It should really look up the variable's
5794 value and not try to expand it. */
5795 w = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND, 0);
5797 /* Have to dequote here if necessary */
5800 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5801 ? dequote_string (t)
5802 : dequote_escapes (t);
5806 dispose_word_desc (w);
5808 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
5810 return (WORD_DESC *)NULL;
5812 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted, 0, 0);
5818 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5819 depending on the value of C, the separating character. C can be one of
5820 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5821 between double quotes. */
5823 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
5825 int c, quoted, *qdollaratp, *hasdollarat;
5829 char *t, *t1, *temp;
5832 /* If the entire expression is between double quotes, we want to treat
5833 the value as a double-quoted string, with the exception that we strip
5834 embedded unescaped double quotes (for sh backwards compatibility). */
5835 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
5838 temp = string_extract_double_quoted (value, &hasdol, 1);
5843 w = alloc_word_desc ();
5845 /* XXX was 0 not quoted */
5846 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
5849 *hasdollarat = hasdol || (l && l->next);
5854 /* The expansion of TEMP returned something. We need to treat things
5855 slightly differently if HASDOL is non-zero. If we have "$@", the
5856 individual words have already been quoted. We need to turn them
5857 into a string with the words separated by the first character of
5858 $IFS without any additional quoting, so string_list_dollar_at won't
5859 do the right thing. We use string_list_dollar_star instead. */
5860 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
5862 /* If l->next is not null, we know that TEMP contained "$@", since that
5863 is the only expansion that creates more than one word. */
5864 if (qdollaratp && ((hasdol && quoted) || l->next))
5866 /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
5867 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
5868 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
5869 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5870 (which is more paranoia than anything else), we need to return the
5871 quoted null string and set the flags to indicate it. */
5872 if (l->next == 0 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && QUOTED_NULL (temp) && QUOTED_NULL (l->word->word) && (l->word->flags & W_HASQUOTEDNULL))
5874 w->flags |= W_HASQUOTEDNULL;
5878 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
5880 /* The brace expansion occurred between double quotes and there was
5881 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5882 it does not expand to anything. In this case, we want to return
5883 a quoted empty string. */
5884 temp = make_quoted_char ('\0');
5885 w->flags |= W_HASQUOTEDNULL;
5888 temp = (char *)NULL;
5890 if (c == '-' || c == '+')
5897 t = temp ? savestring (temp) : savestring ("");
5898 t1 = dequote_string (t);
5900 #if defined (ARRAY_VARS)
5901 if (valid_array_reference (name))
5902 assign_array_element (name, t1, 0);
5904 #endif /* ARRAY_VARS */
5905 bind_variable (name, t1, 0);
5907 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5914 /* Deal with the right hand side of a ${name:?value} expansion in the case
5915 that NAME is null or not set. If VALUE is non-null it is expanded and
5916 used as the error message to print, otherwise a standard message is
5919 parameter_brace_expand_error (name, value)
5925 last_command_exit_value = EXECUTION_FAILURE; /* ensure it's non-zero */
5926 if (value && *value)
5928 l = expand_string (value, 0);
5929 temp = string_list (l);
5930 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
5935 report_error (_("%s: parameter null or not set"), name);
5937 /* Free the data we have allocated during this expansion, since we
5938 are about to longjmp out. */
5943 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5946 valid_length_expression (name)
5949 return (name[1] == '\0' || /* ${#} */
5950 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
5951 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
5952 #if defined (ARRAY_VARS)
5953 valid_array_reference (name + 1) || /* ${#a[7]} */
5955 legal_identifier (name + 1)); /* ${#PS1} */
5958 /* Handle the parameter brace expansion that requires us to return the
5959 length of a parameter. */
5961 parameter_brace_expand_length (name)
5965 intmax_t number, arg_index;
5967 #if defined (ARRAY_VARS)
5971 if (name[1] == '\0') /* ${#} */
5972 number = number_of_args ();
5973 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
5974 number = number_of_args ();
5975 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
5977 /* Take the lengths of some of the shell's special parameters. */
5981 t = which_set_flags ();
5984 t = itos (last_command_exit_value);
5987 t = itos (dollar_dollar_pid);
5990 if (last_asynchronous_pid == NO_PID)
5991 t = (char *)NULL; /* XXX - error if set -u set? */
5993 t = itos (last_asynchronous_pid);
5996 t = itos (number_of_args ());
5999 number = STRLEN (t);
6002 #if defined (ARRAY_VARS)
6003 else if (valid_array_reference (name + 1))
6004 number = array_length_reference (name + 1);
6005 #endif /* ARRAY_VARS */
6010 if (legal_number (name + 1, &arg_index)) /* ${#1} */
6012 t = get_dollar_var_value (arg_index);
6013 if (t == 0 && unbound_vars_is_error)
6015 number = MB_STRLEN (t);
6018 #if defined (ARRAY_VARS)
6019 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
6022 t = assoc_reference (assoc_cell (var), "0");
6024 t = array_reference (array_cell (var), 0);
6025 if (t == 0 && unbound_vars_is_error)
6027 number = MB_STRLEN (t);
6032 newname = savestring (name);
6034 list = expand_string (newname, Q_DOUBLE_QUOTES);
6035 t = list ? string_list (list) : (char *)NULL;
6038 dispose_words (list);
6040 number = t ? MB_STRLEN (t) : 0;
6048 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
6049 so we do some ad-hoc parsing of an arithmetic expression to find
6050 the first DELIM, instead of using strchr(3). Two rules:
6051 1. If the substring contains a `(', read until closing `)'.
6052 2. If the substring contains a `?', read past one `:' for each `?'.
6056 skiparith (substr, delim)
6061 int skipcol, pcount, i;
6064 sublen = strlen (substr);
6065 i = skipcol = pcount = 0;
6068 /* Balance parens */
6069 if (substr[i] == LPAREN)
6075 if (substr[i] == RPAREN && pcount)
6083 ADVANCE_CHAR (substr, sublen, i);
6087 /* Skip one `:' for each `?' */
6088 if (substr[i] == ':' && skipcol)
6094 if (substr[i] == delim)
6096 if (substr[i] == '?')
6102 ADVANCE_CHAR (substr, sublen, i);
6105 return (substr + i);
6108 /* Verify and limit the start and end of the desired substring. If
6109 VTYPE == 0, a regular shell variable is being used; if it is 1,
6110 then the positional parameters are being used; if it is 2, then
6111 VALUE is really a pointer to an array variable that should be used.
6112 Return value is 1 if both values were OK, 0 if there was a problem
6113 with an invalid expression, or -1 if the values were out of range. */
6115 verify_substring_values (v, value, substr, vtype, e1p, e2p)
6117 char *value, *substr;
6119 intmax_t *e1p, *e2p;
6121 char *t, *temp1, *temp2;
6124 #if defined (ARRAY_VARS)
6129 /* duplicate behavior of strchr(3) */
6130 t = skiparith (substr, ':');
6131 if (*t && *t == ':')
6136 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
6137 *e1p = evalexp (temp1, &expok);
6142 len = -1; /* paranoia */
6146 case VT_ARRAYMEMBER:
6147 len = MB_STRLEN (value);
6150 len = number_of_args () + 1;
6152 len++; /* add one arg if counting from $0 */
6154 #if defined (ARRAY_VARS)
6156 /* For arrays, the first value deals with array indices. Negative
6157 offsets count from one past the array's maximum index. Associative
6158 arrays treat the number of elements as the maximum index. */
6162 len = assoc_num_elements (h) + (*e1p < 0);
6167 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
6173 if (len == -1) /* paranoia */
6176 if (*e1p < 0) /* negative offsets count from end */
6179 if (*e1p > len || *e1p < 0)
6182 #if defined (ARRAY_VARS)
6183 /* For arrays, the second offset deals with the number of elements. */
6184 if (vtype == VT_ARRAYVAR)
6185 len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
6191 temp2 = savestring (t);
6192 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
6195 *e2p = evalexp (temp1, &expok);
6200 if ((vtype == VT_ARRAYVAR || vtype == VT_POSPARMS) && *e2p < 0)
6202 /* bash-4.3: allow positional parameter length < 0 to count backwards
6203 from end of positional parameters */
6204 if (vtype == VT_ARRAYVAR && *e2p < 0)
6207 internal_error (_("%s: substring expression < 0"), t);
6210 #if defined (ARRAY_VARS)
6211 /* In order to deal with sparse arrays, push the intelligence about how
6212 to deal with the number of elements desired down to the array-
6213 specific functions. */
6214 if (vtype != VT_ARRAYVAR)
6220 if (*e2p < 0 || *e2p < *e1p)
6222 internal_error (_("%s: substring expression < 0"), t);
6227 *e2p += *e1p; /* want E2 chars starting at E1 */
6238 /* Return the type of variable specified by VARNAME (simple variable,
6239 positional param, or array variable). Also return the value specified
6240 by VARNAME (value of a variable or a reference to an array element).
6241 QUOTED is the standard description of quoting state, using Q_* defines.
6242 FLAGS is currently a set of flags to pass to array_value. If IND is
6243 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6244 passed to array_value so the array index is not computed again.
6245 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6246 characters in the value are quoted with CTLESC and takes appropriate
6247 steps. For convenience, *VALP is set to the dequoted VALUE. */
6249 get_var_and_type (varname, value, ind, quoted, flags, varp, valp)
6250 char *varname, *value;
6258 #if defined (ARRAY_VARS)
6263 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6264 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
6265 if (vtype == VT_POSPARMS && varname[0] == '*')
6266 vtype |= VT_STARSUB;
6267 *varp = (SHELL_VAR *)NULL;
6269 #if defined (ARRAY_VARS)
6270 if (valid_array_reference (varname))
6272 v = array_variable_part (varname, &temp, (int *)0);
6273 /* If we want to signal array_value to use an already-computed index,
6274 set LIND to that index */
6275 lind = (ind != INTMAX_MIN && (flags & AV_USEIND)) ? ind : 0;
6276 if (v && (array_p (v) || assoc_p (v)))
6278 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
6280 /* Callers have to differentiate betwen indexed and associative */
6281 vtype = VT_ARRAYVAR;
6283 vtype |= VT_STARSUB;
6284 *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
6288 vtype = VT_ARRAYMEMBER;
6289 *valp = array_value (varname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
6293 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
6295 vtype = VT_VARIABLE;
6297 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6298 *valp = dequote_string (value);
6300 *valp = dequote_escapes (value);
6304 vtype = VT_ARRAYMEMBER;
6306 *valp = array_value (varname, Q_DOUBLE_QUOTES, flags, (int *)NULL, &lind);
6309 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
6311 vtype = VT_ARRAYMEMBER;
6313 *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
6318 if (value && vtype == VT_VARIABLE)
6320 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6321 *valp = dequote_string (value);
6323 *valp = dequote_escapes (value);
6332 /******************************************************/
6334 /* Functions to extract substrings of variable values */
6336 /******************************************************/
6338 #if defined (HANDLE_MULTIBYTE)
6339 /* Character-oriented rather than strictly byte-oriented substrings. S and
6340 E, rather being strict indices into STRING, indicate character (possibly
6341 multibyte character) positions that require calculation.
6342 Used by the ${param:offset[:length]} expansion. */
6344 mb_substring (string, s, e)
6349 int start, stop, i, slen;
6353 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6354 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
6357 while (string[start] && i--)
6358 ADVANCE_CHAR (string, slen, start);
6361 while (string[stop] && i--)
6362 ADVANCE_CHAR (string, slen, stop);
6363 tt = substring (string, start, stop);
6368 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6369 is `@', use the positional parameters; otherwise, use the value of
6370 VARNAME. If VARNAME is an array variable, use the array elements. */
6373 parameter_brace_substring (varname, value, ind, substr, quoted, flags)
6374 char *varname, *value;
6380 int vtype, r, starsub;
6381 char *temp, *val, *tt, *oname;
6385 return ((char *)NULL);
6387 oname = this_command_name;
6388 this_command_name = varname;
6390 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6393 this_command_name = oname;
6394 return ((char *)NULL);
6397 starsub = vtype & VT_STARSUB;
6398 vtype &= ~VT_STARSUB;
6400 r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
6401 this_command_name = oname;
6404 if (vtype == VT_VARIABLE)
6406 return ((r == 0) ? &expand_param_error : (char *)NULL);
6412 case VT_ARRAYMEMBER:
6413 #if defined (HANDLE_MULTIBYTE)
6415 tt = mb_substring (val, e1, e2);
6418 tt = substring (val, e1, e2);
6420 if (vtype == VT_VARIABLE)
6422 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6423 temp = quote_string (tt);
6425 temp = tt ? quote_escapes (tt) : (char *)NULL;
6429 tt = pos_params (varname, e1, e2, quoted);
6430 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
6432 temp = tt ? quote_escapes (tt) : (char *)NULL;
6438 #if defined (ARRAY_VARS)
6441 /* we convert to list and take first e2 elements starting at e1th
6442 element -- officially undefined for now */
6443 temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
6445 /* We want E2 to be the number of elements desired (arrays can be sparse,
6446 so verify_substring_values just returns the numbers specified and we
6447 rely on array_subrange to understand how to deal with them). */
6448 temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
6449 /* array_subrange now calls array_quote_escapes as appropriate, so the
6450 caller no longer needs to. */
6454 temp = (char *)NULL;
6460 /****************************************************************/
6462 /* Functions to perform pattern substitution on variable values */
6464 /****************************************************************/
6467 shouldexp_replacement (s)
6472 for (p = s; p && *p; p++)
6483 pat_subst (string, pat, rep, mflags)
6484 char *string, *pat, *rep;
6487 char *ret, *s, *e, *str, *rstr, *mstr;
6488 int rsize, rptr, l, replen, mtype, rxpand, rslen, mlen;
6491 return (savestring (""));
6493 mtype = mflags & MATCH_TYPEMASK;
6495 #if 0 /* bash-4.2 ? */
6496 rxpand = (rep && *rep) ? shouldexp_replacement (rep) : 0;
6502 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6503 * with REP and return the result.
6504 * 2. A null pattern with mtype == MATCH_END means to append REP to
6505 * STRING and return the result.
6506 * These don't understand or process `&' in the replacement string.
6508 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
6510 replen = STRLEN (rep);
6511 l = STRLEN (string);
6512 ret = (char *)xmalloc (replen + l + 2);
6514 strcpy (ret, string);
6515 else if (mtype == MATCH_BEG)
6518 strcpy (ret + replen, string);
6522 strcpy (ret, string);
6523 strcpy (ret + l, rep);
6528 ret = (char *)xmalloc (rsize = 64);
6531 for (replen = STRLEN (rep), rptr = 0, str = string;;)
6533 if (match_pattern (str, pat, mtype, &s, &e) == 0)
6541 mstr = xmalloc (mlen + 1);
6542 for (x = 0; x < mlen; x++)
6545 rstr = strcreplace (rep, '&', mstr, 0);
6546 rslen = strlen (rstr);
6554 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64);
6556 /* OK, now copy the leading unmatched portion of the string (from
6557 str to s) to ret starting at rptr (the current offset). Then copy
6558 the replacement string at ret + rptr + (s - str). Increment
6559 rptr (if necessary) and str and go on. */
6562 strncpy (ret + rptr, str, l);
6567 strncpy (ret + rptr, rstr, rslen);
6570 str = e; /* e == end of match */
6575 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
6580 /* On a zero-length match, make sure we copy one character, since
6581 we increment one character to avoid infinite recursion. */
6582 RESIZE_MALLOCED_BUFFER (ret, rptr, 1, rsize, 64);
6583 ret[rptr++] = *str++;
6584 e++; /* avoid infinite recursion on zero-length match */
6588 /* Now copy the unmatched portion of the input string */
6591 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
6592 strcpy (ret + rptr, str);
6600 /* Do pattern match and replacement on the positional parameters. */
6602 pos_params_pat_subst (string, pat, rep, mflags)
6603 char *string, *pat, *rep;
6606 WORD_LIST *save, *params;
6611 save = params = list_rest_of_args ();
6613 return ((char *)NULL);
6615 for ( ; params; params = params->next)
6617 ret = pat_subst (params->word->word, pat, rep, mflags);
6618 w = alloc_word_desc ();
6619 w->word = ret ? ret : savestring ("");
6620 dispose_word (params->word);
6624 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
6625 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
6628 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
6629 ret = string_list_dollar_star (quote_list (save));
6630 else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
6631 ret = string_list_dollar_star (save);
6632 else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
6633 ret = string_list_dollar_at (save, qflags);
6635 ret = string_list_dollar_star (save);
6637 ret = string_list_pos_params (pchar, save, qflags);
6640 dispose_words (save);
6645 /* Perform pattern substitution on VALUE, which is the expansion of
6646 VARNAME. PATSUB is an expression supplying the pattern to match
6647 and the string to substitute. QUOTED is a flags word containing
6648 the type of quoting currently in effect. */
6650 parameter_brace_patsub (varname, value, ind, patsub, quoted, flags)
6651 char *varname, *value;
6656 int vtype, mflags, starsub, delim;
6657 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
6661 return ((char *)NULL);
6663 this_command_name = varname;
6665 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6667 return ((char *)NULL);
6669 starsub = vtype & VT_STARSUB;
6670 vtype &= ~VT_STARSUB;
6673 /* PATSUB is never NULL when this is called. */
6676 mflags |= MATCH_GLOBREP;
6680 /* Malloc this because expand_string_if_necessary or one of the expansion
6681 functions in its call chain may free it on a substitution error. */
6682 lpatsub = savestring (patsub);
6684 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6685 mflags |= MATCH_QUOTED;
6688 mflags |= MATCH_STARSUB;
6690 /* If the pattern starts with a `/', make sure we skip over it when looking
6691 for the replacement delimiter. */
6692 delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
6693 if (lpatsub[delim] == '/')
6696 rep = lpatsub + delim + 1;
6701 if (rep && *rep == '\0')
6704 /* Perform the same expansions on the pattern as performed by the
6705 pattern removal expansions. */
6706 pat = getpattern (lpatsub, quoted, 1);
6709 /* We want to perform quote removal on the expanded replacement even if
6710 the entire expansion is double-quoted because the parser and string
6711 extraction functions treated quotes in the replacement string as
6713 rep = expand_string_if_necessary (rep, quoted & ~(Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT), expand_string_unsplit);
6715 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6716 pattern. This is an extension. Make sure we don't anchor the pattern
6717 at the beginning or end of the string if we're doing global replacement,
6720 if (mflags & MATCH_GLOBREP)
6721 mflags |= MATCH_ANY;
6722 else if (pat && pat[0] == '#')
6724 mflags |= MATCH_BEG;
6727 else if (pat && pat[0] == '%')
6729 mflags |= MATCH_END;
6733 mflags |= MATCH_ANY;
6735 /* OK, we now want to substitute REP for PAT in VAL. If
6736 flags & MATCH_GLOBREP is non-zero, the substitution is done
6737 everywhere, otherwise only the first occurrence of PAT is
6738 replaced. The pattern matching code doesn't understand
6739 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6740 values passed in (VT_VARIABLE) so the pattern substitution
6741 code works right. We need to requote special chars after
6742 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6743 other cases if QUOTED == 0, since the posparams and arrays
6744 indexed by * or @ do special things when QUOTED != 0. */
6749 case VT_ARRAYMEMBER:
6750 temp = pat_subst (val, p, rep, mflags);
6751 if (vtype == VT_VARIABLE)
6755 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6761 temp = pos_params_pat_subst (val, p, rep, mflags);
6762 if (temp && (mflags & MATCH_QUOTED) == 0)
6764 tt = quote_escapes (temp);
6769 #if defined (ARRAY_VARS)
6771 temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
6772 : array_patsub (array_cell (v), p, rep, mflags);
6773 /* Don't call quote_escapes anymore; array_patsub calls
6774 array_quote_escapes as appropriate before adding the
6775 space separators; ditto for assoc_patsub. */
6787 /****************************************************************/
6789 /* Functions to perform case modification on variable values */
6791 /****************************************************************/
6793 /* Do case modification on the positional parameters. */
6796 pos_params_modcase (string, pat, modop, mflags)
6801 WORD_LIST *save, *params;
6806 save = params = list_rest_of_args ();
6808 return ((char *)NULL);
6810 for ( ; params; params = params->next)
6812 ret = sh_modcase (params->word->word, pat, modop);
6813 w = alloc_word_desc ();
6814 w->word = ret ? ret : savestring ("");
6815 dispose_word (params->word);
6819 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
6820 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
6822 ret = string_list_pos_params (pchar, save, qflags);
6823 dispose_words (save);
6828 /* Perform case modification on VALUE, which is the expansion of
6829 VARNAME. MODSPEC is an expression supplying the type of modification
6830 to perform. QUOTED is a flags word containing the type of quoting
6831 currently in effect. */
6833 parameter_brace_casemod (varname, value, ind, modspec, patspec, quoted, flags)
6834 char *varname, *value;
6839 int vtype, starsub, modop, mflags, x;
6840 char *val, *temp, *pat, *p, *lpat, *tt;
6844 return ((char *)NULL);
6846 this_command_name = varname;
6848 vtype = get_var_and_type (varname, value, ind, quoted, flags, &v, &val);
6850 return ((char *)NULL);
6852 starsub = vtype & VT_STARSUB;
6853 vtype &= ~VT_STARSUB;
6857 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6858 mflags |= MATCH_QUOTED;
6860 mflags |= MATCH_STARSUB;
6865 x = p && p[0] == modspec;
6866 modop = x ? CASE_UPPER : CASE_UPFIRST;
6869 else if (modspec == ',')
6871 x = p && p[0] == modspec;
6872 modop = x ? CASE_LOWER : CASE_LOWFIRST;
6875 else if (modspec == '~')
6877 x = p && p[0] == modspec;
6878 modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
6882 lpat = p ? savestring (p) : 0;
6883 /* Perform the same expansions on the pattern as performed by the
6884 pattern removal expansions. FOR LATER */
6885 pat = lpat ? getpattern (lpat, quoted, 1) : 0;
6887 /* OK, now we do the case modification. */
6891 case VT_ARRAYMEMBER:
6892 temp = sh_modcase (val, pat, modop);
6893 if (vtype == VT_VARIABLE)
6897 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6904 temp = pos_params_modcase (val, pat, modop, mflags);
6905 if (temp && (mflags & MATCH_QUOTED) == 0)
6907 tt = quote_escapes (temp);
6913 #if defined (ARRAY_VARS)
6915 temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
6916 : array_modcase (array_cell (v), pat, modop, mflags);
6917 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6918 as appropriate before adding the space separators; ditto for
6930 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6931 any occur, this must be a nested command substitution, so return 0.
6932 Otherwise, return 1. A valid arithmetic expression must always have a
6933 ( before a matching ), so any cases where there are more right parens
6934 means that this must not be an arithmetic expression, though the parser
6935 will not accept it without a balanced total number of parens. */
6937 chk_arithsub (s, len)
6949 else if (s[i] == RPAREN)
6959 ADVANCE_CHAR (s, len, i);
6965 ADVANCE_CHAR (s, len, i);
6969 i = skip_single_quoted (s, len, ++i);
6973 i = skip_double_quoted ((char *)s, len, ++i);
6978 return (count == 0);
6981 /****************************************************************/
6983 /* Functions to perform parameter expansion on a string */
6985 /****************************************************************/
6987 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6989 parameter_brace_expand (string, indexp, quoted, pflags, quoted_dollar_atp, contains_dollar_at)
6991 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at, pflags;
6993 int check_nullness, var_is_set, var_is_null, var_is_special;
6994 int want_substring, want_indir, want_patsub, want_casemod;
6995 char *name, *value, *temp, *temp1;
6996 WORD_DESC *tdesc, *ret;
6997 int t_index, sindex, c, tflag, modspec;
7001 temp = temp1 = value = (char *)NULL;
7002 var_is_set = var_is_null = var_is_special = check_nullness = 0;
7003 want_substring = want_indir = want_patsub = want_casemod = 0;
7007 /* ${#var} doesn't have any of the other parameter expansions on it. */
7008 if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */
7009 name = string_extract (string, &t_index, "}", SX_VARNAME);
7011 #if defined (CASEMOD_EXPANSIONS)
7012 /* To enable case-toggling expansions using the `~' operator character
7013 change the 1 to 0. */
7014 # if defined (CASEMOD_CAPCASE)
7015 name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
7017 name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
7018 # endif /* CASEMOD_CAPCASE */
7020 name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
7021 #endif /* CASEMOD_EXPANSIONS */
7028 /* If the name really consists of a special variable, then make sure
7029 that we have the entire name. We don't allow indirect references
7030 to special variables except `#', `?', `@' and `*'. */
7031 if ((sindex == t_index && VALID_SPECIAL_LENGTH_PARAM (string[t_index])) ||
7032 (sindex == t_index - 1 && string[sindex] == '!' && VALID_INDIR_PARAM (string[t_index])))
7035 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
7036 name = (char *)xrealloc (name, 3 + (strlen (temp1)));
7037 *name = string[sindex];
7038 if (string[sindex] == '!')
7040 /* indirect reference of $#, $?, $@, or $* */
7041 name[1] = string[sindex + 1];
7042 strcpy (name + 2, temp1);
7045 strcpy (name + 1, temp1);
7050 /* Find out what character ended the variable name. Then
7051 do the appropriate thing. */
7052 if (c = string[sindex])
7055 /* If c is followed by one of the valid parameter expansion
7056 characters, move past it as normal. If not, assume that
7057 a substring specification is being given, and do not move
7059 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
7062 if (c = string[sindex])
7065 else if (c == ':' && string[sindex] != RBRACE)
7067 else if (c == '/' /* && string[sindex] != RBRACE */) /* XXX */
7069 #if defined (CASEMOD_EXPANSIONS)
7070 else if (c == '^' || c == ',' || c == '~')
7077 /* Catch the valid and invalid brace expressions that made it through the
7079 /* ${#-} is a valid expansion and means to take the length of $-.
7080 Similarly for ${#?} and ${##}... */
7081 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
7082 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
7084 name = (char *)xrealloc (name, 3);
7087 c = string[sindex++];
7090 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7091 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
7092 member (c, "%:=+/") && string[sindex] == RBRACE)
7094 temp = (char *)NULL;
7095 goto bad_substitution;
7098 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7099 either a variable name, one of the positional parameters or a special
7100 variable that expands to one of the positional parameters. */
7101 want_indir = *name == '!' &&
7102 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
7103 || VALID_INDIR_PARAM (name[1]));
7105 /* Determine the value of this variable. */
7107 /* Check for special variables, directly referenced. */
7108 if (SPECIAL_VAR (name, want_indir))
7111 /* Check for special expansion things, like the length of a parameter */
7112 if (*name == '#' && name[1])
7114 /* If we are not pointing at the character just after the
7115 closing brace, then we haven't gotten all of the name.
7116 Since it begins with a special character, this is a bad
7117 substitution. Also check NAME for validity before trying
7119 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
7121 temp = (char *)NULL;
7122 goto bad_substitution;
7125 number = parameter_brace_expand_length (name);
7126 if (number == INTMAX_MIN && unbound_vars_is_error)
7128 last_command_exit_value = EXECUTION_FAILURE;
7129 err_unboundvar (name+1);
7131 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7137 return (&expand_wdesc_error);
7140 ret = alloc_word_desc ();
7141 ret->word = itos (number);
7146 /* ${@} is identical to $@. */
7147 if (name[0] == '@' && name[1] == '\0')
7149 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7150 *quoted_dollar_atp = 1;
7152 if (contains_dollar_at)
7153 *contains_dollar_at = 1;
7155 tflag |= W_DOLLARAT;
7158 /* Process ${!PREFIX*} expansion. */
7159 if (want_indir && string[sindex - 1] == RBRACE &&
7160 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
7161 legal_variable_starter ((unsigned char) name[1]))
7166 temp1 = savestring (name + 1);
7167 number = strlen (temp1);
7168 temp1[number - 1] = '\0';
7169 x = all_variables_matching_prefix (temp1);
7170 xlist = strvec_to_word_list (x, 0, 0);
7171 if (string[sindex - 2] == '*')
7172 temp = string_list_dollar_star (xlist);
7175 temp = string_list_dollar_at (xlist, quoted);
7176 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7177 *quoted_dollar_atp = 1;
7178 if (contains_dollar_at)
7179 *contains_dollar_at = 1;
7181 tflag |= W_DOLLARAT;
7184 dispose_words (xlist);
7190 ret = alloc_word_desc ();
7192 ret->flags = tflag; /* XXX */
7196 #if defined (ARRAY_VARS)
7197 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7198 if (want_indir && string[sindex - 1] == RBRACE &&
7199 string[sindex - 2] == ']' && valid_array_reference (name+1))
7203 temp1 = savestring (name + 1);
7204 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
7206 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
7208 temp = array_keys (temp1, quoted); /* handles assoc vars too */
7211 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7212 *quoted_dollar_atp = 1;
7213 if (contains_dollar_at)
7214 *contains_dollar_at = 1;
7216 tflag |= W_DOLLARAT;
7222 ret = alloc_word_desc ();
7224 ret->flags = tflag; /* XXX */
7230 #endif /* ARRAY_VARS */
7232 /* Make sure that NAME is valid before trying to go on. */
7233 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
7234 var_is_special) == 0)
7236 temp = (char *)NULL;
7237 goto bad_substitution;
7241 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
7243 tdesc = parameter_brace_expand_word (name, var_is_special, quoted, PF_IGNUNBOUND|(pflags&PF_NOSPLIT2), &ind);
7248 tflag = tdesc->flags;
7249 dispose_word_desc (tdesc);
7254 if (temp == &expand_param_error || temp == &expand_param_fatal)
7256 temp = (char *)NULL;
7257 goto bad_substitution;
7260 #if defined (ARRAY_VARS)
7261 if (valid_array_reference (name))
7262 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
7265 var_is_set = temp != (char *)0;
7266 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
7268 /* Get the rest of the stuff inside the braces. */
7269 if (c && c != RBRACE)
7271 /* Extract the contents of the ${ ... } expansion
7272 according to the Posix.2 rules. */
7273 value = extract_dollar_brace_string (string, &sindex, quoted, (c == '%' || c == '#' || c =='/' || c == '^' || c == ',' || c ==':') ? SX_POSIXEXP|SX_WORD : SX_WORD);
7274 if (string[sindex] == RBRACE)
7277 goto bad_substitution;
7280 value = (char *)NULL;
7284 /* All the cases where an expansion can possibly generate an unbound
7286 if (want_substring || want_patsub || want_casemod || c == '#' || c == '%' || c == RBRACE)
7288 if (var_is_set == 0 && unbound_vars_is_error && ((name[0] != '@' && name[0] != '*') || name[1]))
7290 last_command_exit_value = EXECUTION_FAILURE;
7291 err_unboundvar (name);
7295 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7299 /* If this is a substring spec, process it and add the result. */
7302 temp1 = parameter_brace_substring (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7307 if (temp1 == &expand_param_error)
7308 return (&expand_wdesc_error);
7309 else if (temp1 == &expand_param_fatal)
7310 return (&expand_wdesc_fatal);
7312 ret = alloc_word_desc ();
7314 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7315 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7318 else if (want_patsub)
7320 temp1 = parameter_brace_patsub (name, temp, ind, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7325 if (temp1 == &expand_param_error)
7326 return (&expand_wdesc_error);
7327 else if (temp1 == &expand_param_fatal)
7328 return (&expand_wdesc_fatal);
7330 ret = alloc_word_desc ();
7332 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7333 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7336 #if defined (CASEMOD_EXPANSIONS)
7337 else if (want_casemod)
7339 temp1 = parameter_brace_casemod (name, temp, ind, modspec, value, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7344 if (temp1 == &expand_param_error)
7345 return (&expand_wdesc_error);
7346 else if (temp1 == &expand_param_fatal)
7347 return (&expand_wdesc_fatal);
7349 ret = alloc_word_desc ();
7351 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7352 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7357 /* Do the right thing based on which character ended the variable name. */
7363 last_command_exit_value = EXECUTION_FAILURE;
7364 report_error (_("%s: bad substitution"), string ? string : "??");
7368 return &expand_wdesc_error;
7373 case '#': /* ${param#[#]pattern} */
7374 case '%': /* ${param%[%]pattern} */
7375 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
7380 temp1 = parameter_brace_remove_pattern (name, temp, ind, value, c, quoted, (tflag & W_ARRAYIND) ? AV_USEIND : 0);
7385 ret = alloc_word_desc ();
7387 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7388 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
7395 if (var_is_set && var_is_null == 0)
7397 /* If the operator is `+', we don't want the value of the named
7398 variable for anything, just the value of the right hand side. */
7401 /* XXX -- if we're double-quoted and the named variable is "$@",
7402 we want to turn off any special handling of "$@" --
7403 we're not using it, so whatever is on the rhs applies. */
7404 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7405 *quoted_dollar_atp = 0;
7406 if (contains_dollar_at)
7407 *contains_dollar_at = 0;
7412 /* From Posix discussion on austin-group list. Issue 221
7413 requires that backslashes escaping `}' inside
7414 double-quoted ${...} be removed. */
7415 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7416 quoted |= Q_DOLBRACE;
7417 ret = parameter_brace_expand_rhs (name, value, c,
7420 contains_dollar_at);
7421 /* XXX - fix up later, esp. noting presence of
7422 W_HASQUOTEDNULL in ret->flags */
7426 temp = (char *)NULL;
7432 /* Otherwise do nothing; just use the value in TEMP. */
7434 else /* VAR not set or VAR is NULL. */
7437 temp = (char *)NULL;
7438 if (c == '=' && var_is_special)
7440 last_command_exit_value = EXECUTION_FAILURE;
7441 report_error (_("$%s: cannot assign in this way"), name);
7444 return &expand_wdesc_error;
7448 parameter_brace_expand_error (name, value);
7449 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7453 /* XXX -- if we're double-quoted and the named variable is "$@",
7454 we want to turn off any special handling of "$@" --
7455 we're not using it, so whatever is on the rhs applies. */
7456 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
7457 *quoted_dollar_atp = 0;
7458 if (contains_dollar_at)
7459 *contains_dollar_at = 0;
7461 /* From Posix discussion on austin-group list. Issue 221 requires
7462 that backslashes escaping `}' inside double-quoted ${...} be
7464 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7465 quoted |= Q_DOLBRACE;
7466 ret = parameter_brace_expand_rhs (name, value, c, quoted,
7468 contains_dollar_at);
7469 /* XXX - fix up later, esp. noting presence of
7470 W_HASQUOTEDNULL in tdesc->flags */
7481 ret = alloc_word_desc ();
7488 /* Expand a single ${xxx} expansion. The braces are optional. When
7489 the braces are used, parameter_brace_expand() does the work,
7490 possibly calling param_expand recursively. */
7492 param_expand (string, sindex, quoted, expanded_something,
7493 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
7496 int *sindex, quoted, *expanded_something, *contains_dollar_at;
7497 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
7499 char *temp, *temp1, uerror[3];
7500 int zindex, t_index, expok;
7505 WORD_DESC *tdesc, *ret;
7509 c = string[++zindex];
7511 temp = (char *)NULL;
7512 ret = tdesc = (WORD_DESC *)NULL;
7515 /* Do simple cases first. Switch on what follows '$'. */
7529 temp1 = dollar_vars[TODIGIT (c)];
7530 if (unbound_vars_is_error && temp1 == (char *)NULL)
7535 last_command_exit_value = EXECUTION_FAILURE;
7536 err_unboundvar (uerror);
7537 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7540 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7541 ? quote_string (temp1)
7542 : quote_escapes (temp1);
7544 temp = (char *)NULL;
7548 /* $$ -- pid of the invoking shell. */
7550 temp = itos (dollar_dollar_pid);
7553 /* $# -- number of positional parameters. */
7555 temp = itos (number_of_args ());
7558 /* $? -- return value of the last synchronous command. */
7560 temp = itos (last_command_exit_value);
7563 /* $- -- flags supplied to the shell on invocation or by `set'. */
7565 temp = which_set_flags ();
7568 /* $! -- Pid of the last asynchronous command. */
7570 /* If no asynchronous pids have been created, expand to nothing.
7571 If `set -u' has been executed, and no async processes have
7572 been created, this is an expansion error. */
7573 if (last_asynchronous_pid == NO_PID)
7575 if (expanded_something)
7576 *expanded_something = 0;
7577 temp = (char *)NULL;
7578 if (unbound_vars_is_error)
7583 last_command_exit_value = EXECUTION_FAILURE;
7584 err_unboundvar (uerror);
7585 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7589 temp = itos (last_asynchronous_pid);
7592 /* The only difference between this and $@ is when the arg is quoted. */
7593 case '*': /* `$*' */
7594 list = list_rest_of_args ();
7597 /* According to austin-group posix proposal by Geoff Clare in
7598 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7600 "The shell shall write a message to standard error and
7601 immediately exit when it tries to expand an unset parameter
7602 other than the '@' and '*' special parameters."
7605 if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
7610 last_command_exit_value = EXECUTION_FAILURE;
7611 err_unboundvar (uerror);
7612 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7616 /* If there are no command-line arguments, this should just
7617 disappear if there are other characters in the expansion,
7618 even if it's quoted. */
7619 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
7620 temp = (char *)NULL;
7621 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES|Q_PATQUOTE))
7623 /* If we have "$*" we want to make a string of the positional
7624 parameters, separated by the first character of $IFS, and
7625 quote the whole string, including the separators. If IFS
7626 is unset, the parameters are separated by ' '; if $IFS is
7627 null, the parameters are concatenated. */
7628 temp = (quoted & (Q_DOUBLE_QUOTES|Q_PATQUOTE)) ? string_list_dollar_star (list) : string_list (list);
7631 temp1 = quote_string (temp);
7633 tflag |= W_HASQUOTEDNULL;
7640 /* We check whether or not we're eventually going to split $* here,
7641 for example when IFS is empty and we are processing the rhs of
7642 an assignment statement. In that case, we don't separate the
7643 arguments at all. Otherwise, if the $* is not quoted it is
7646 # if defined (HANDLE_MULTIBYTE)
7647 if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
7649 if (expand_no_split_dollar_star && ifs_firstc == 0)
7651 temp = string_list_dollar_star (list);
7653 temp = string_list_dollar_at (list, quoted);
7655 temp = string_list_dollar_at (list, quoted);
7657 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
7658 *contains_dollar_at = 1;
7661 dispose_words (list);
7664 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7665 means that we have to turn quoting off after we split into
7666 the individually quoted arguments so that the final split
7667 on the first character of $IFS is still done. */
7668 case '@': /* `$@' */
7669 list = list_rest_of_args ();
7672 /* According to austin-group posix proposal by Geoff Clare in
7673 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7675 "The shell shall write a message to standard error and
7676 immediately exit when it tries to expand an unset parameter
7677 other than the '@' and '*' special parameters."
7680 if (list == 0 && unbound_vars_is_error && (pflags & PF_IGNUNBOUND) == 0)
7685 last_command_exit_value = EXECUTION_FAILURE;
7686 err_unboundvar (uerror);
7687 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
7691 /* We want to flag the fact that we saw this. We can't turn
7692 off quoting entirely, because other characters in the
7693 string might need it (consider "\"$@\""), but we need some
7694 way to signal that the final split on the first character
7695 of $IFS should be done, even though QUOTED is 1. */
7696 /* XXX - should this test include Q_PATQUOTE? */
7697 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7698 *quoted_dollar_at_p = 1;
7699 if (contains_dollar_at)
7700 *contains_dollar_at = 1;
7702 /* We want to separate the positional parameters with the first
7703 character of $IFS in case $IFS is something other than a space.
7704 We also want to make sure that splitting is done no matter what --
7705 according to POSIX.2, this expands to a list of the positional
7706 parameters no matter what IFS is set to. */
7707 temp = string_list_dollar_at (list, (pflags & PF_ASSIGNRHS) ? (quoted|Q_DOUBLE_QUOTES) : quoted);
7709 tflag |= W_DOLLARAT;
7710 dispose_words (list);
7714 tdesc = parameter_brace_expand (string, &zindex, quoted, pflags,
7716 contains_dollar_at);
7718 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
7720 temp = tdesc ? tdesc->word : (char *)0;
7723 /* Quoted nulls should be removed if there is anything else
7725 /* Note that we saw the quoted null so we can add one back at
7726 the end of this function if there are no other characters
7727 in the string, discard TEMP, and go on. The exception to
7728 this is when we have "${@}" and $1 is '', since $@ needs
7729 special handling. */
7730 if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
7732 if (had_quoted_null_p)
7733 *had_quoted_null_p = 1;
7734 if (*quoted_dollar_at_p == 0)
7737 tdesc->word = temp = (char *)NULL;
7745 /* Do command or arithmetic substitution. */
7747 /* We have to extract the contents of this paren substitution. */
7748 t_index = zindex + 1;
7749 temp = extract_command_subst (string, &t_index, 0);
7752 /* For Posix.2-style `$(( ))' arithmetic substitution,
7753 extract the expression and pass it to the evaluator. */
7754 if (temp && *temp == LPAREN)
7758 temp2 = savestring (temp1);
7759 t_index = strlen (temp2) - 1;
7761 if (temp2[t_index] != RPAREN)
7767 /* Cut off ending `)' */
7768 temp2[t_index] = '\0';
7770 if (chk_arithsub (temp2, t_index) == 0)
7774 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7779 /* Expand variables found inside the expression. */
7780 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
7784 /* No error messages. */
7785 this_command_name = (char *)NULL;
7786 number = evalexp (temp1, &expok);
7791 if (interactive_shell == 0 && posixly_correct)
7793 last_command_exit_value = EXECUTION_FAILURE;
7794 return (&expand_wdesc_fatal);
7797 return (&expand_wdesc_error);
7799 temp = itos (number);
7804 if (pflags & PF_NOCOMSUB)
7805 /* we need zindex+1 because string[zindex] == RPAREN */
7806 temp1 = substring (string, *sindex, zindex+1);
7809 tdesc = command_substitute (temp, quoted);
7810 temp1 = tdesc ? tdesc->word : (char *)NULL;
7812 dispose_word_desc (tdesc);
7818 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7819 away in a future bash release. */
7821 /* Extract the contents of this arithmetic substitution. */
7822 t_index = zindex + 1;
7823 temp = extract_arithmetic_subst (string, &t_index);
7827 temp = savestring (string);
7828 if (expanded_something)
7829 *expanded_something = 0;
7833 /* Do initial variable expansion. */
7834 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
7839 /* Find the variable in VARIABLE_LIST. */
7840 temp = (char *)NULL;
7842 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
7844 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
7846 /* If this isn't a variable name, then just output the `$'. */
7847 if (temp1 == 0 || *temp1 == '\0')
7850 temp = (char *)xmalloc (2);
7853 if (expanded_something)
7854 *expanded_something = 0;
7858 /* If the variable exists, return its value cell. */
7859 var = find_variable (temp1);
7861 if (var && invisible_p (var) == 0 && var_isset (var))
7863 #if defined (ARRAY_VARS)
7864 if (assoc_p (var) || array_p (var))
7866 temp = array_p (var) ? array_reference (array_cell (var), 0)
7867 : assoc_reference (assoc_cell (var), "0");
7869 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7870 ? quote_string (temp)
7871 : quote_escapes (temp);
7872 else if (unbound_vars_is_error)
7873 goto unbound_variable;
7878 temp = value_cell (var);
7880 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7881 ? quote_string (temp)
7882 : quote_escapes (temp);
7889 else if (var = find_variable_last_nameref (temp1))
7891 temp = nameref_cell (var);
7892 #if defined (ARRAY_VARS)
7893 if (temp && *temp && valid_array_reference (temp))
7895 tdesc = parameter_brace_expand_word (temp, SPECIAL_VAR (temp, 0), quoted, pflags, (arrayind_t *)NULL);
7896 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
7903 /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */
7904 if (temp && *temp && legal_identifier (temp) == 0)
7906 last_command_exit_value = EXECUTION_FAILURE;
7907 report_error (_("%s: invalid variable name for name reference"), temp);
7908 return (&expand_wdesc_error); /* XXX */
7911 temp = (char *)NULL;
7914 temp = (char *)NULL;
7917 if (unbound_vars_is_error)
7919 last_command_exit_value = EXECUTION_FAILURE;
7920 err_unboundvar (temp1);
7929 last_command_exit_value = EXECUTION_FAILURE;
7930 return ((unbound_vars_is_error && interactive_shell == 0)
7931 ? &expand_wdesc_fatal
7932 : &expand_wdesc_error);
7943 ret = alloc_word_desc ();
7944 ret->flags = tflag; /* XXX */
7950 /* Make a word list which is the result of parameter and variable
7951 expansion, command substitution, arithmetic substitution, and
7952 quote removal of WORD. Return a pointer to a WORD_LIST which is
7953 the result of the expansion. If WORD contains a null word, the
7954 word list returned is also null.
7956 QUOTED contains flag values defined in shell.h.
7958 ISEXP is used to tell expand_word_internal that the word should be
7959 treated as the result of an expansion. This has implications for
7960 how IFS characters in the word are treated.
7962 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7963 they point to an integer value which receives information about expansion.
7964 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7965 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7968 This only does word splitting in the case of $@ expansion. In that
7969 case, we split on ' '. */
7971 /* Values for the local variable quoted_state. */
7973 #define PARTIALLY_QUOTED 1
7974 #define WHOLLY_QUOTED 2
7977 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
7980 int *contains_dollar_at;
7981 int *expanded_something;
7986 /* The intermediate string that we build while expanding. */
7989 /* The current size of the above object. */
7992 /* Index into ISTRING. */
7995 /* Temporary string storage. */
7998 /* The text of WORD. */
7999 register char *string;
8001 /* The size of STRING. */
8004 /* The index into STRING. */
8007 /* This gets 1 if we see a $@ while quoted. */
8008 int quoted_dollar_at;
8010 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
8011 whether WORD contains no quoting characters, a partially quoted
8012 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
8016 int had_quoted_null;
8017 int has_dollar_at, temp_has_dollar_at;
8019 int pflags; /* flags passed to param_expand */
8021 int assignoff; /* If assignment, offset of `=' */
8023 register unsigned char c; /* Current character. */
8024 int t_index; /* For calls to string_extract_xxx. */
8030 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
8031 istring[istring_index = 0] = '\0';
8032 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
8033 quoted_state = UNQUOTED;
8035 string = word->word;
8037 goto finished_with_string;
8038 /* Don't need the string length for the SADD... and COPY_ macros unless
8039 multibyte characters are possible. */
8040 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
8042 if (contains_dollar_at)
8043 *contains_dollar_at = 0;
8047 /* Begin the expansion. */
8053 /* Case on toplevel character. */
8057 goto finished_with_string;
8061 #if HANDLE_MULTIBYTE
8062 if (MB_CUR_MAX > 1 && string[sindex])
8064 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
8069 temp = (char *)xmalloc (3);
8071 temp[1] = c = string[sindex];
8082 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
8088 #if defined (PROCESS_SUBSTITUTION)
8089 /* Process substitution. */
8093 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
8095 sindex--; /* add_character: label increments sindex */
8099 t_index = sindex + 1; /* skip past both '<' and LPAREN */
8101 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
8104 /* If the process substitution specification is `<()', we want to
8105 open the pipe for writing in the child and produce output; if
8106 it is `>()', we want to open the pipe for reading in the child
8107 and consume input. */
8108 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
8112 goto dollar_add_string;
8114 #endif /* PROCESS_SUBSTITUTION */
8117 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8118 which are not assignment statements are not expanded. If the
8119 shell isn't in posix mode, though, we perform tilde expansion
8120 on `likely candidate' unquoted assignment statements (flags
8121 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8122 contains an unquoted :~ or =~. Something to think about: we
8123 now have a flag that says to perform tilde expansion on arguments
8124 to `assignment builtins' like declare and export that look like
8125 assignment statements. We now do tilde expansion on such words
8126 even in POSIX mode. */
8127 if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
8129 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8130 goto add_ifs_character;
8134 /* If we're not in posix mode or forcing assignment-statement tilde
8135 expansion, note where the `=' appears in the word and prepare to
8136 do tilde expansion following the first `='. */
8137 if ((word->flags & W_ASSIGNMENT) &&
8138 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
8139 assignoff == -1 && sindex > 0)
8141 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */
8142 word->flags |= W_ITILDE;
8144 else if ((word->flags & W_ASSIGNMENT) &&
8145 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
8146 string[sindex+1] == '~')
8147 word->flags |= W_ITILDE;
8149 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8150 goto add_ifs_character;
8155 if (word->flags & W_NOTILDE)
8157 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8158 goto add_ifs_character;
8163 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
8164 string[sindex+1] == '~')
8165 word->flags |= W_ITILDE;
8167 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c))
8168 goto add_ifs_character;
8173 /* If the word isn't supposed to be tilde expanded, or we're not
8174 at the start of a word or after an unquoted : or = in an
8175 assignment statement, we don't do tilde expansion. */
8176 if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
8177 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
8178 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8180 word->flags &= ~W_ITILDE;
8181 if (isexp == 0 && (word->flags & (W_NOSPLIT|W_NOSPLIT2)) == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
8182 goto add_ifs_character;
8187 if (word->flags & W_ASSIGNRHS)
8189 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
8194 temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
8196 word->flags &= ~W_ITILDE;
8198 if (temp && *temp && t_index > 0)
8200 temp1 = bash_tilde_expand (temp, tflag);
8201 if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
8205 goto add_character; /* tilde expansion failed */
8210 goto add_quoted_string; /* XXX was add_string */
8219 if (expanded_something)
8220 *expanded_something = 1;
8222 temp_has_dollar_at = 0;
8223 pflags = (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0;
8224 if (word->flags & W_NOSPLIT2)
8225 pflags |= PF_NOSPLIT2;
8226 if (word->flags & W_ASSIGNRHS)
8227 pflags |= PF_ASSIGNRHS;
8228 tword = param_expand (string, &sindex, quoted, expanded_something,
8229 &temp_has_dollar_at, "ed_dollar_at,
8230 &had_quoted_null, pflags);
8231 has_dollar_at += temp_has_dollar_at;
8233 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
8237 return ((tword == &expand_wdesc_error) ? &expand_word_error
8238 : &expand_word_fatal);
8240 if (contains_dollar_at && has_dollar_at)
8241 *contains_dollar_at = 1;
8243 if (tword && (tword->flags & W_HASQUOTEDNULL))
8244 had_quoted_null = 1;
8246 temp = tword ? tword->word : (char *)NULL;
8247 dispose_word_desc (tword);
8249 /* Kill quoted nulls; we will add them back at the end of
8250 expand_word_internal if nothing else in the string */
8251 if (had_quoted_null && temp && QUOTED_NULL (temp))
8254 temp = (char *)NULL;
8260 case '`': /* Backquoted command substitution. */
8264 temp = string_extract (string, &sindex, "`", SX_REQMATCH);
8265 /* The test of sindex against t_index is to allow bare instances of
8266 ` to pass through, for backwards compatibility. */
8267 if (temp == &extract_string_error || temp == &extract_string_fatal)
8269 if (sindex - 1 == t_index)
8274 last_command_exit_value = EXECUTION_FAILURE;
8275 report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
8278 return ((temp == &extract_string_error) ? &expand_word_error
8279 : &expand_word_fatal);
8282 if (expanded_something)
8283 *expanded_something = 1;
8285 if (word->flags & W_NOCOMSUB)
8286 /* sindex + 1 because string[sindex] == '`' */
8287 temp1 = substring (string, t_index, sindex + 1);
8290 de_backslash (temp);
8291 tword = command_substitute (temp, quoted);
8292 temp1 = tword ? tword->word : (char *)NULL;
8294 dispose_word_desc (tword);
8298 goto dollar_add_string;
8302 if (string[sindex + 1] == '\n')
8308 c = string[++sindex];
8310 if (quoted & Q_HERE_DOCUMENT)
8312 else if (quoted & Q_DOUBLE_QUOTES)
8317 /* From Posix discussion on austin-group list: Backslash escaping
8318 a } in ${...} is removed. Issue 0000221 */
8319 if ((quoted & Q_DOLBRACE) && c == RBRACE)
8321 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
8323 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
8325 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
8330 sindex--; /* add_character: label increments sindex */
8335 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
8340 /* BEFORE jumping here, we need to increment sindex if appropriate */
8341 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
8342 DEFAULT_ARRAY_SIZE);
8343 istring[istring_index++] = twochars[0];
8344 istring[istring_index++] = twochars[1];
8345 istring[istring_index] = '\0';
8351 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
8353 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8358 temp = string_extract_double_quoted (string, &sindex, 0);
8360 /* If the quotes surrounded the entire string, then the
8361 whole word was quoted. */
8362 quoted_state = (t_index == 1 && string[sindex] == '\0')
8368 tword = alloc_word_desc ();
8371 temp = (char *)NULL;
8373 temp_has_dollar_at = 0; /* XXX */
8374 /* Need to get W_HASQUOTEDNULL flag through this function. */
8375 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &temp_has_dollar_at, (int *)NULL);
8376 has_dollar_at += temp_has_dollar_at;
8378 if (list == &expand_word_error || list == &expand_word_fatal)
8382 /* expand_word_internal has already freed temp_word->word
8383 for us because of the way it prints error messages. */
8384 tword->word = (char *)NULL;
8385 dispose_word (tword);
8389 dispose_word (tword);
8391 /* "$@" (a double-quoted dollar-at) expands into nothing,
8392 not even a NULL word, when there are no positional
8394 if (list == 0 && has_dollar_at)
8400 /* If we get "$@", we know we have expanded something, so we
8401 need to remember it for the final split on $IFS. This is
8402 a special case; it's the only case where a quoted string
8403 can expand into more than one word. It's going to come back
8404 from the above call to expand_word_internal as a list with
8405 a single word, in which all characters are quoted and
8406 separated by blanks. What we want to do is to turn it back
8407 into a list for the next piece of code. */
8409 dequote_list (list);
8411 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
8412 had_quoted_null = 1; /* XXX */
8417 if (contains_dollar_at)
8418 *contains_dollar_at = 1;
8419 if (expanded_something)
8420 *expanded_something = 1;
8425 /* What we have is "". This is a minor optimization. */
8427 list = (WORD_LIST *)NULL;
8430 /* The code above *might* return a list (consider the case of "$@",
8431 where it returns "$1", "$2", etc.). We can't throw away the
8432 rest of the list, and we have to make sure each word gets added
8433 as quoted. We test on tresult->next: if it is non-NULL, we
8434 quote the whole list, save it to a string with string_list, and
8435 add that string. We don't need to quote the results of this
8436 (and it would be wrong, since that would quote the separators
8437 as well), so we go directly to add_string. */
8443 if (quoted_dollar_at && (word->flags & W_NOSPLIT2))
8444 temp = string_list_internal (quote_list (list), " ");
8447 /* Testing quoted_dollar_at makes sure that "$@" is
8448 split correctly when $IFS does not contain a space. */
8449 temp = quoted_dollar_at
8450 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
8451 : string_list (quote_list (list));
8452 dispose_words (list);
8457 temp = savestring (list->word->word);
8458 tflag = list->word->flags;
8459 dispose_words (list);
8461 /* If the string is not a quoted null string, we want
8462 to remove any embedded unquoted CTLNUL characters.
8463 We do not want to turn quoted null strings back into
8464 the empty string, though. We do this because we
8465 want to remove any quoted nulls from expansions that
8466 contain other characters. For example, if we have
8467 x"$*"y or "x$*y" and there are no positional parameters,
8468 the $* should expand into nothing. */
8469 /* We use the W_HASQUOTEDNULL flag to differentiate the
8470 cases: a quoted null character as above and when
8471 CTLNUL is contained in the (non-null) expansion
8472 of some variable. We use the had_quoted_null flag to
8473 pass the value through this function to its caller. */
8474 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
8475 remove_quoted_nulls (temp); /* XXX */
8479 temp = (char *)NULL;
8481 /* We do not want to add quoted nulls to strings that are only
8482 partially quoted; we can throw them away. The exception to
8483 this is when we are going to be performing word splitting,
8484 since we have to preserve a null argument if the next character
8485 will cause word splitting. */
8486 if (temp == 0 && quoted_state == PARTIALLY_QUOTED && (word->flags & (W_NOSPLIT|W_NOSPLIT2)))
8494 temp = quote_string (temp);
8502 sindex--; /* add_character: label increments sindex */
8510 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
8512 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
8517 temp = string_extract_single_quoted (string, &sindex);
8519 /* If the entire STRING was surrounded by single quotes,
8520 then the string is wholly quoted. */
8521 quoted_state = (t_index == 1 && string[sindex] == '\0')
8525 /* If all we had was '', it is a null expansion. */
8529 temp = (char *)NULL;
8532 remove_quoted_escapes (temp); /* ??? */
8534 /* We do not want to add quoted nulls to strings that are only
8535 partially quoted; such nulls are discarded. */
8536 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
8539 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8543 sindex--; /* add_character: label increments sindex */
8547 goto add_quoted_string;
8552 /* This is the fix for " $@ " */
8554 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
8556 if (string[sindex]) /* from old goto dollar_add_string */
8565 #if HANDLE_MULTIBYTE
8571 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
8576 twochars[0] = CTLESC;
8583 SADD_MBCHAR (temp, string, sindex, string_size);
8586 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
8587 DEFAULT_ARRAY_SIZE);
8588 istring[istring_index++] = c;
8589 istring[istring_index] = '\0';
8591 /* Next character. */
8596 finished_with_string:
8597 /* OK, we're ready to return. If we have a quoted string, and
8598 quoted_dollar_at is not set, we do no splitting at all; otherwise
8599 we split on ' '. The routines that call this will handle what to
8600 do if nothing has been expanded. */
8602 /* Partially and wholly quoted strings which expand to the empty
8603 string are retained as an empty arguments. Unquoted strings
8604 which expand to the empty string are discarded. The single
8605 exception is the case of expanding "$@" when there are no
8606 positional parameters. In that case, we discard the expansion. */
8608 /* Because of how the code that handles "" and '' in partially
8609 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8610 if we saw quoting characters, but the expansion was empty.
8611 "" and '' are tossed away before we get to this point when
8612 processing partially quoted strings. This makes "" and $xxx""
8613 equivalent when xxx is unset. We also look to see whether we
8614 saw a quoted null from a ${} expansion and add one back if we
8617 /* If we expand to nothing and there were no single or double quotes
8618 in the word, we throw it away. Otherwise, we return a NULL word.
8619 The single exception is for $@ surrounded by double quotes when
8620 there are no positional parameters. In that case, we also throw
8623 if (*istring == '\0')
8625 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
8627 istring[0] = CTLNUL;
8629 tword = make_bare_word (istring);
8630 tword->flags |= W_HASQUOTEDNULL; /* XXX */
8631 list = make_word_list (tword, (WORD_LIST *)NULL);
8632 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8633 tword->flags |= W_QUOTED;
8635 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8636 and a double-quoted "$@" appears anywhere in it, then the entire
8638 else if (quoted_state == UNQUOTED || quoted_dollar_at)
8639 list = (WORD_LIST *)NULL;
8643 tword = make_bare_word (istring);
8644 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8645 tword->flags |= W_QUOTED;
8646 list = make_word_list (tword, (WORD_LIST *)NULL);
8650 list = (WORD_LIST *)NULL;
8653 else if (word->flags & W_NOSPLIT)
8655 tword = make_bare_word (istring);
8656 if (word->flags & W_ASSIGNMENT)
8657 tword->flags |= W_ASSIGNMENT; /* XXX */
8658 if (word->flags & W_COMPASSIGN)
8659 tword->flags |= W_COMPASSIGN; /* XXX */
8660 if (word->flags & W_NOGLOB)
8661 tword->flags |= W_NOGLOB; /* XXX */
8662 if (word->flags & W_NOBRACE)
8663 tword->flags |= W_NOBRACE; /* XXX */
8664 if (word->flags & W_NOEXPAND)
8665 tword->flags |= W_NOEXPAND; /* XXX */
8666 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
8667 tword->flags |= W_QUOTED;
8668 if (had_quoted_null && QUOTED_NULL (istring))
8669 tword->flags |= W_HASQUOTEDNULL;
8670 list = make_word_list (tword, (WORD_LIST *)NULL);
8676 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
8678 /* If we have $@, we need to split the results no matter what. If
8679 IFS is unset or NULL, string_list_dollar_at has separated the
8680 positional parameters with a space, so we split on space (we have
8681 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8682 string_list_dollar_at has separated the positional parameters
8683 with the first character of $IFS, so we split on $IFS. */
8684 if (has_dollar_at && ifs_chars)
8685 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
8688 tword = make_bare_word (istring);
8689 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
8690 tword->flags |= W_QUOTED;
8691 if (word->flags & W_ASSIGNMENT)
8692 tword->flags |= W_ASSIGNMENT;
8693 if (word->flags & W_COMPASSIGN)
8694 tword->flags |= W_COMPASSIGN;
8695 if (word->flags & W_NOGLOB)
8696 tword->flags |= W_NOGLOB;
8697 if (word->flags & W_NOBRACE)
8698 tword->flags |= W_NOBRACE;
8699 if (word->flags & W_NOEXPAND)
8700 tword->flags |= W_NOEXPAND;
8701 if (had_quoted_null && QUOTED_NULL (istring))
8702 tword->flags |= W_HASQUOTEDNULL; /* XXX */
8703 list = make_word_list (tword, (WORD_LIST *)NULL);
8711 /* **************************************************************** */
8713 /* Functions for Quote Removal */
8715 /* **************************************************************** */
8717 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8718 backslash quoting rules for within double quotes or a here document. */
8720 string_quote_removal (string, quoted)
8725 char *r, *result_string, *temp, *send;
8726 int sindex, tindex, dquote;
8730 /* The result can be no longer than the original string. */
8731 slen = strlen (string);
8732 send = string + slen;
8734 r = result_string = (char *)xmalloc (slen + 1);
8736 for (dquote = sindex = 0; c = string[sindex];)
8741 c = string[++sindex];
8747 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
8752 SCOPY_CHAR_M (r, string, send, sindex);
8756 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
8762 tindex = sindex + 1;
8763 temp = string_extract_single_quoted (string, &tindex);
8774 dquote = 1 - dquote;
8780 return (result_string);
8785 /* Perform quote removal on word WORD. This allocates and returns a new
8788 word_quote_removal (word, quoted)
8795 t = string_quote_removal (word->word, quoted);
8796 w = alloc_word_desc ();
8797 w->word = t ? t : savestring ("");
8801 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8802 the members of the list are treated as if they are surrounded by
8803 double quotes. Return a new list, or NULL if LIST is NULL. */
8805 word_list_quote_removal (list, quoted)
8809 WORD_LIST *result, *t, *tresult, *e;
8811 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8813 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
8815 result = (WORD_LIST *) list_append (result, tresult);
8818 result = e = tresult;
8831 /*******************************************
8833 * Functions to perform word splitting *
8835 *******************************************/
8845 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
8847 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8848 handle multibyte chars in IFS */
8849 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
8850 for (t = ifs_value ; t && *t; t++)
8856 #if defined (HANDLE_MULTIBYTE)
8859 ifs_firstc[0] = '\0';
8865 ifs_len = strnlen (ifs_value, MB_CUR_MAX);
8866 ifs_firstc_len = MBLEN (ifs_value, ifs_len);
8867 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
8869 ifs_firstc[0] = ifs_value[0];
8870 ifs_firstc[1] = '\0';
8874 memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
8877 ifs_firstc = ifs_value ? *ifs_value : 0;
8887 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8888 is not quoted. list_string () performs quote removal for us, even if we
8889 don't do any splitting. */
8891 word_split (w, ifs_chars)
8901 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
8902 result = list_string (w->word, xifs, w->flags & W_QUOTED);
8905 result = (WORD_LIST *)NULL;
8910 /* Perform word splitting on LIST and return the RESULT. It is possible
8911 to return (WORD_LIST *)NULL. */
8913 word_list_split (list)
8916 WORD_LIST *result, *t, *tresult, *e;
8918 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8920 tresult = word_split (t->word, ifs_value);
8922 result = e = tresult;
8933 /**************************************************
8935 * Functions to expand an entire WORD_LIST *
8937 **************************************************/
8939 /* Do any word-expansion-specific cleanup and jump to top_level */
8941 exp_jump_to_top_level (v)
8944 set_pipestatus_from_exit (last_command_exit_value);
8946 /* Cleanup code goes here. */
8947 expand_no_split_dollar_star = 0; /* XXX */
8948 expanding_redir = 0;
8949 assigning_in_environment = 0;
8951 if (parse_and_execute_level == 0)
8952 top_level_cleanup (); /* from sig.c */
8954 jump_to_top_level (v);
8957 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8958 ELIST, and set ELIST to the new list. */
8959 #define PREPEND_LIST(nlist, elist) \
8960 do { nlist->next = elist; elist = nlist; } while (0)
8962 /* Separate out any initial variable assignments from TLIST. If set -k has
8963 been executed, remove all assignment statements from TLIST. Initial
8964 variable assignments and other environment assignments are placed
8965 on SUBST_ASSIGN_VARLIST. */
8967 separate_out_assignments (tlist)
8970 register WORD_LIST *vp, *lp;
8973 return ((WORD_LIST *)NULL);
8975 if (subst_assign_varlist)
8976 dispose_words (subst_assign_varlist); /* Clean up after previous error */
8978 subst_assign_varlist = (WORD_LIST *)NULL;
8981 /* Separate out variable assignments at the start of the command.
8982 Loop invariant: vp->next == lp
8984 lp = list of words left after assignment statements skipped
8985 tlist = original list of words
8987 while (lp && (lp->word->flags & W_ASSIGNMENT))
8993 /* If lp != tlist, we have some initial assignment statements.
8994 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8995 words and TLIST point to the remaining words. */
8998 subst_assign_varlist = tlist;
8999 /* ASSERT(vp->next == lp); */
9000 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
9001 tlist = lp; /* remainder of word list */
9004 /* vp == end of variable list */
9005 /* tlist == remainder of original word list without variable assignments */
9007 /* All the words in tlist were assignment statements */
9008 return ((WORD_LIST *)NULL);
9010 /* ASSERT(tlist != NULL); */
9011 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
9013 /* If the -k option is in effect, we need to go through the remaining
9014 words, separate out the assignment words, and place them on
9015 SUBST_ASSIGN_VARLIST. */
9016 if (place_keywords_in_env)
9018 WORD_LIST *tp; /* tp == running pointer into tlist */
9023 /* Loop Invariant: tp->next == lp */
9024 /* Loop postcondition: tlist == word list without assignment statements */
9027 if (lp->word->flags & W_ASSIGNMENT)
9029 /* Found an assignment statement, add this word to end of
9030 subst_assign_varlist (vp). */
9031 if (!subst_assign_varlist)
9032 subst_assign_varlist = vp = lp;
9039 /* Remove the word pointed to by LP from TLIST. */
9040 tp->next = lp->next;
9041 /* ASSERT(vp == lp); */
9042 lp->next = (WORD_LIST *)NULL;
9055 #define WEXP_VARASSIGN 0x001
9056 #define WEXP_BRACEEXP 0x002
9057 #define WEXP_TILDEEXP 0x004
9058 #define WEXP_PARAMEXP 0x008
9059 #define WEXP_PATHEXP 0x010
9061 /* All of the expansions, including variable assignments at the start of
9063 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9065 /* All of the expansions except variable assignments at the start of
9067 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9069 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
9070 expansion, command substitution, arithmetic expansion, word splitting, and
9072 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
9074 /* Take the list of words in LIST and do the various substitutions. Return
9075 a new list of words which is the expanded list, and without things like
9076 variable assignments. */
9082 return (expand_word_list_internal (list, WEXP_ALL));
9085 /* Same as expand_words (), but doesn't hack variable or environment
9088 expand_words_no_vars (list)
9091 return (expand_word_list_internal (list, WEXP_NOVARS));
9095 expand_words_shellexp (list)
9098 return (expand_word_list_internal (list, WEXP_SHELLEXP));
9102 glob_expand_word_list (tlist, eflags)
9106 char **glob_array, *temp_string;
9107 register int glob_index;
9108 WORD_LIST *glob_list, *output_list, *disposables, *next;
9111 output_list = disposables = (WORD_LIST *)NULL;
9112 glob_array = (char **)NULL;
9115 /* For each word, either globbing is attempted or the word is
9116 added to orig_list. If globbing succeeds, the results are
9117 added to orig_list and the word (tlist) is added to the list
9118 of disposable words. If globbing fails and failed glob
9119 expansions are left unchanged (the shell default), the
9120 original word is added to orig_list. If globbing fails and
9121 failed glob expansions are removed, the original word is
9122 added to the list of disposable words. orig_list ends up
9123 in reverse order and requires a call to REVERSE_LIST to
9124 be set right. After all words are examined, the disposable
9128 /* If the word isn't an assignment and contains an unquoted
9129 pattern matching character, then glob it. */
9130 if ((tlist->word->flags & W_NOGLOB) == 0 &&
9131 unquoted_glob_pattern_p (tlist->word->word))
9133 glob_array = shell_glob_filename (tlist->word->word);
9135 /* Handle error cases.
9136 I don't think we should report errors like "No such file
9137 or directory". However, I would like to report errors
9138 like "Read failed". */
9140 if (glob_array == 0 || GLOB_FAILED (glob_array))
9142 glob_array = (char **)xmalloc (sizeof (char *));
9143 glob_array[0] = (char *)NULL;
9146 /* Dequote the current word in case we have to use it. */
9147 if (glob_array[0] == NULL)
9149 temp_string = dequote_string (tlist->word->word);
9150 free (tlist->word->word);
9151 tlist->word->word = temp_string;
9154 /* Make the array into a word list. */
9155 glob_list = (WORD_LIST *)NULL;
9156 for (glob_index = 0; glob_array[glob_index]; glob_index++)
9158 tword = make_bare_word (glob_array[glob_index]);
9159 tword->flags |= W_GLOBEXP; /* XXX */
9160 glob_list = make_word_list (tword, glob_list);
9165 output_list = (WORD_LIST *)list_append (glob_list, output_list);
9166 PREPEND_LIST (tlist, disposables);
9168 else if (fail_glob_expansion != 0)
9170 last_command_exit_value = EXECUTION_FAILURE;
9171 report_error (_("no match: %s"), tlist->word->word);
9172 exp_jump_to_top_level (DISCARD);
9174 else if (allow_null_glob_expansion == 0)
9176 /* Failed glob expressions are left unchanged. */
9177 PREPEND_LIST (tlist, output_list);
9181 /* Failed glob expressions are removed. */
9182 PREPEND_LIST (tlist, disposables);
9187 /* Dequote the string. */
9188 temp_string = dequote_string (tlist->word->word);
9189 free (tlist->word->word);
9190 tlist->word->word = temp_string;
9191 PREPEND_LIST (tlist, output_list);
9194 strvec_dispose (glob_array);
9195 glob_array = (char **)NULL;
9201 dispose_words (disposables);
9204 output_list = REVERSE_LIST (output_list, WORD_LIST *);
9206 return (output_list);
9209 #if defined (BRACE_EXPANSION)
9211 brace_expand_word_list (tlist, eflags)
9215 register char **expansions;
9217 WORD_LIST *disposables, *output_list, *next;
9221 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
9225 if (tlist->word->flags & W_NOBRACE)
9227 itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);
9228 PREPEND_LIST (tlist, output_list);
9232 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
9234 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9235 PREPEND_LIST (tlist, output_list);
9239 /* Only do brace expansion if the word has a brace character. If
9240 not, just add the word list element to BRACES and continue. In
9241 the common case, at least when running shell scripts, this will
9242 degenerate to a bunch of calls to `mbschr', and then what is
9243 basically a reversal of TLIST into BRACES, which is corrected
9244 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9246 if (mbschr (tlist->word->word, LBRACE))
9248 expansions = brace_expand (tlist->word->word);
9250 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
9252 w = alloc_word_desc ();
9253 w->word = temp_string;
9255 /* If brace expansion didn't change the word, preserve
9256 the flags. We may want to preserve the flags
9257 unconditionally someday -- XXX */
9258 if (STREQ (temp_string, tlist->word->word))
9259 w->flags = tlist->word->flags;
9261 w = make_word_flags (w, temp_string);
9263 output_list = make_word_list (w, output_list);
9267 /* Add TLIST to the list of words to be freed after brace
9268 expansion has been performed. */
9269 PREPEND_LIST (tlist, disposables);
9272 PREPEND_LIST (tlist, output_list);
9276 dispose_words (disposables);
9279 output_list = REVERSE_LIST (output_list, WORD_LIST *);
9281 return (output_list);
9285 #if defined (ARRAY_VARS)
9286 /* Take WORD, a compound associative array assignment, and internally run
9287 'declare -A w', where W is the variable name portion of WORD. */
9289 make_internal_declare (word, option)
9297 w = make_word (word);
9299 t = assignment (w->word, 0);
9302 wl = make_word_list (w, (WORD_LIST *)NULL);
9303 wl = make_word_list (make_word (option), wl);
9305 return (declare_builtin (wl));
9310 shell_expand_word_list (tlist, eflags)
9314 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
9315 int expanded_something, has_dollar_at;
9318 /* We do tilde expansion all the time. This is what 1003.2 says. */
9319 new_list = (WORD_LIST *)NULL;
9320 for (orig_list = tlist; tlist; tlist = next)
9322 temp_string = tlist->word->word;
9326 #if defined (ARRAY_VARS)
9327 /* If this is a compound array assignment to a builtin that accepts
9328 such assignments (e.g., `declare'), take the assignment and perform
9329 it separately, handling the semantics of declarations inside shell
9330 functions. This avoids the double-evaluation of such arguments,
9331 because `declare' does some evaluation of compound assignments on
9333 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
9337 if (tlist->word->flags & W_ASSIGNASSOC)
9338 make_internal_declare (tlist->word->word, "-A");
9340 t = do_word_assignment (tlist->word, 0);
9343 last_command_exit_value = EXECUTION_FAILURE;
9344 exp_jump_to_top_level (DISCARD);
9347 /* Now transform the word as ksh93 appears to do and go on */
9348 t = assignment (tlist->word->word, 0);
9349 tlist->word->word[t] = '\0';
9350 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
9354 expanded_something = 0;
9355 expanded = expand_word_internal
9356 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
9358 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
9360 /* By convention, each time this error is returned,
9361 tlist->word->word has already been freed. */
9362 tlist->word->word = (char *)NULL;
9364 /* Dispose our copy of the original list. */
9365 dispose_words (orig_list);
9366 /* Dispose the new list we're building. */
9367 dispose_words (new_list);
9369 last_command_exit_value = EXECUTION_FAILURE;
9370 if (expanded == &expand_word_error)
9371 exp_jump_to_top_level (DISCARD);
9373 exp_jump_to_top_level (FORCE_EOF);
9376 /* Don't split words marked W_NOSPLIT. */
9377 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
9379 temp_list = word_list_split (expanded);
9380 dispose_words (expanded);
9384 /* If no parameter expansion, command substitution, process
9385 substitution, or arithmetic substitution took place, then
9386 do not do word splitting. We still have to remove quoted
9387 null characters from the result. */
9388 word_list_remove_quoted_nulls (expanded);
9389 temp_list = expanded;
9392 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
9393 new_list = (WORD_LIST *)list_append (expanded, new_list);
9397 dispose_words (orig_list);
9400 new_list = REVERSE_LIST (new_list, WORD_LIST *);
9405 /* The workhorse for expand_words () and expand_words_no_vars ().
9406 First arg is LIST, a WORD_LIST of words.
9407 Second arg EFLAGS is a flags word controlling which expansions are
9410 This does all of the substitutions: brace expansion, tilde expansion,
9411 parameter expansion, command substitution, arithmetic expansion,
9412 process substitution, word splitting, and pathname expansion, according
9413 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9414 set, or for which no expansion is done, do not undergo word splitting.
9415 Words with the W_NOGLOB bit set do not undergo pathname expansion; words
9416 with W_NOBRACE set do not undergo brace expansion (see
9417 brace_expand_word_list above). */
9419 expand_word_list_internal (list, eflags)
9423 WORD_LIST *new_list, *temp_list;
9427 return ((WORD_LIST *)NULL);
9429 garglist = new_list = copy_word_list (list);
9430 if (eflags & WEXP_VARASSIGN)
9432 garglist = new_list = separate_out_assignments (new_list);
9435 if (subst_assign_varlist)
9437 /* All the words were variable assignments, so they are placed
9438 into the shell's environment. */
9439 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
9441 this_command_name = (char *)NULL; /* no arithmetic errors */
9442 tint = do_word_assignment (temp_list->word, 0);
9443 /* Variable assignment errors in non-interactive shells
9444 running in Posix.2 mode cause the shell to exit. */
9447 last_command_exit_value = EXECUTION_FAILURE;
9448 if (interactive_shell == 0 && posixly_correct)
9449 exp_jump_to_top_level (FORCE_EOF);
9451 exp_jump_to_top_level (DISCARD);
9454 dispose_words (subst_assign_varlist);
9455 subst_assign_varlist = (WORD_LIST *)NULL;
9457 return ((WORD_LIST *)NULL);
9461 /* Begin expanding the words that remain. The expansions take place on
9462 things that aren't really variable assignments. */
9464 #if defined (BRACE_EXPANSION)
9465 /* Do brace expansion on this word if there are any brace characters
9467 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
9468 new_list = brace_expand_word_list (new_list, eflags);
9469 #endif /* BRACE_EXPANSION */
9471 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9472 variable substitution, command substitution, arithmetic expansion,
9473 and word splitting. */
9474 new_list = shell_expand_word_list (new_list, eflags);
9476 /* Okay, we're almost done. Now let's just do some filename
9480 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
9481 /* Glob expand the word list unless globbing has been disabled. */
9482 new_list = glob_expand_word_list (new_list, eflags);
9484 /* Dequote the words, because we're not performing globbing. */
9485 new_list = dequote_list (new_list);
9488 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
9490 sh_wassign_func_t *assign_func;
9491 int is_special_builtin, is_builtin_or_func;
9493 /* If the remainder of the words expand to nothing, Posix.2 requires
9494 that the variable and environment assignments affect the shell's
9496 assign_func = new_list ? assign_in_env : do_word_assignment;
9497 tempenv_assign_error = 0;
9499 is_builtin_or_func = (new_list && new_list->word && (find_shell_builtin (new_list->word->word) || find_function (new_list->word->word)));
9500 /* Posix says that special builtins exit if a variable assignment error
9501 occurs in an assignment preceding it. */
9502 is_special_builtin = (posixly_correct && new_list && new_list->word && find_special_builtin (new_list->word->word));
9504 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
9506 this_command_name = (char *)NULL;
9507 assigning_in_environment = (assign_func == assign_in_env);
9508 tint = (*assign_func) (temp_list->word, is_builtin_or_func);
9509 assigning_in_environment = 0;
9510 /* Variable assignment errors in non-interactive shells running
9511 in Posix.2 mode cause the shell to exit. */
9514 if (assign_func == do_word_assignment)
9516 last_command_exit_value = EXECUTION_FAILURE;
9517 if (interactive_shell == 0 && posixly_correct && is_special_builtin)
9518 exp_jump_to_top_level (FORCE_EOF);
9520 exp_jump_to_top_level (DISCARD);
9523 tempenv_assign_error++;
9527 dispose_words (subst_assign_varlist);
9528 subst_assign_varlist = (WORD_LIST *)NULL;
9532 tint = list_length (new_list) + 1;
9533 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
9534 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
9535 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
9536 glob_argv_flags[tint] = '\0';