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-2009 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"
47 #include "execute_cmd.h"
51 #include "mailcheck.h"
55 #include "builtins/getopt.h"
56 #include "builtins/common.h"
58 #include "builtins/builtext.h"
60 #include <tilde/tilde.h>
61 #include <glob/strmatch.h>
67 /* The size that strings change by. */
68 #define DEFAULT_INITIAL_ARRAY_SIZE 112
69 #define DEFAULT_ARRAY_SIZE 128
75 #define VT_ARRAYMEMBER 3
78 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
80 /* Flags for quoted_strchr */
81 #define ST_BACKSL 0x01
82 #define ST_CTLESC 0x02
83 #define ST_SQUOTE 0x04 /* unused yet */
84 #define ST_DQUOTE 0x08 /* unused yet */
86 /* Flags for the `pflags' argument to param_expand() */
87 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
89 /* These defs make it easier to use the editor. */
95 /* Evaluates to 1 if C is one of the shell's special parameters whose length
96 can be taken, but is also one of the special expansion characters. */
97 #define VALID_SPECIAL_LENGTH_PARAM(c) \
98 ((c) == '-' || (c) == '?' || (c) == '#')
100 /* Evaluates to 1 if C is one of the shell's special parameters for which an
101 indirect variable reference may be made. */
102 #define VALID_INDIR_PARAM(c) \
103 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
105 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
106 in ${parameter[:]OPword}. */
107 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
109 /* Evaluates to 1 if this is one of the shell's special variables. */
110 #define SPECIAL_VAR(name, wi) \
111 ((DIGIT (*name) && all_digits (name)) || \
112 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
113 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
115 /* An expansion function that takes a string and a quoted flag and returns
116 a WORD_LIST *. Used as the type of the third argument to
117 expand_string_if_necessary(). */
118 typedef WORD_LIST *EXPFUNC __P((char *, int));
120 /* Process ID of the last command executed within command substitution. */
121 pid_t last_command_subst_pid = NO_PID;
122 pid_t current_command_subst_pid = NO_PID;
124 /* Variables used to keep track of the characters in IFS. */
127 unsigned char ifs_cmap[UCHAR_MAX + 1];
129 #if defined (HANDLE_MULTIBYTE)
130 unsigned char ifs_firstc[MB_LEN_MAX];
131 size_t ifs_firstc_len;
133 unsigned char ifs_firstc;
136 int assigning_in_environment;
138 /* Extern functions and variables from different files. */
139 extern int last_command_exit_value, last_command_exit_signal;
140 extern int subshell_environment;
141 extern int subshell_level, parse_and_execute_level;
142 extern int eof_encountered;
143 extern int return_catch_flag, return_catch_value;
144 extern pid_t dollar_dollar_pid;
145 extern int posixly_correct;
146 extern char *this_command_name;
147 extern struct fd_bitmap *current_fds_to_close;
148 extern int wordexp_only;
149 extern int expanding_redir;
150 extern int tempenv_assign_error;
152 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
153 extern wchar_t *wcsdup __P((const wchar_t *));
156 /* Non-zero means to allow unmatched globbed filenames to expand to
158 int allow_null_glob_expansion;
160 /* Non-zero means to throw an error when globbing fails to match anything. */
161 int fail_glob_expansion;
164 /* Variables to keep track of which words in an expanded word list (the
165 output of expand_word_list_internal) are the result of globbing
166 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
167 (CURRENTLY UNUSED). */
168 char *glob_argv_flags;
169 static int glob_argv_flags_size;
172 static WORD_LIST expand_word_error, expand_word_fatal;
173 static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
174 static char expand_param_error, expand_param_fatal;
175 static char extract_string_error, extract_string_fatal;
177 /* Tell the expansion functions to not longjmp back to top_level on fatal
178 errors. Enabled when doing completion and prompt string expansion. */
179 static int no_longjmp_on_fatal_error = 0;
181 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
182 $* on $IFS, primarily when doing assignment statements. */
183 static int expand_no_split_dollar_star = 0;
185 /* Used to hold a list of variable assignments preceding a command. Global
186 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
188 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
190 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
191 without any leading variable assignments. */
192 static WORD_LIST *garglist = (WORD_LIST *)NULL;
194 static char *quoted_substring __P((char *, int, int));
195 static int quoted_strlen __P((char *));
196 static char *quoted_strchr __P((char *, int, int));
198 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
199 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
200 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
201 static WORD_LIST *expand_string_internal __P((char *, int));
202 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
203 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
205 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
206 static char *make_quoted_char __P((int));
207 static WORD_LIST *quote_list __P((WORD_LIST *));
209 static int unquoted_substring __P((char *, char *));
210 static int unquoted_member __P((int, char *));
212 #if defined (ARRAY_VARS)
213 static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
215 static int do_assignment_internal __P((const WORD_DESC *, int));
217 static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));
218 static char *string_extract __P((char *, int *, char *, int));
219 static char *string_extract_double_quoted __P((char *, int *, int));
220 static inline char *string_extract_single_quoted __P((char *, int *));
221 static inline int skip_single_quoted __P((const char *, size_t, int));
222 static int skip_double_quoted __P((char *, size_t, int));
223 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
224 static char *extract_dollar_brace_string __P((char *, int *, int, int));
226 static char *pos_params __P((char *, int, int, int));
228 static unsigned char *mb_getcharlens __P((char *, int));
230 static char *remove_upattern __P((char *, char *, int));
231 #if defined (HANDLE_MULTIBYTE)
232 static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
234 static char *remove_pattern __P((char *, char *, int));
236 static int match_pattern_char __P((char *, char *));
237 static int match_upattern __P((char *, char *, int, char **, char **));
238 #if defined (HANDLE_MULTIBYTE)
239 static int match_pattern_wchar __P((wchar_t *, wchar_t *));
240 static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
242 static int match_pattern __P((char *, char *, int, char **, char **));
243 static int getpatspec __P((int, char *));
244 static char *getpattern __P((char *, int, int));
245 static char *variable_remove_pattern __P((char *, char *, int, int));
246 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
247 static char *parameter_list_remove_pattern __P((int, char *, int, int));
249 static char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));
251 static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
253 static char *process_substitute __P((char *, int));
255 static char *read_comsub __P((int, int, int *));
258 static arrayind_t array_length_reference __P((char *));
261 static int valid_brace_expansion_word __P((char *, int));
262 static int chk_atstar __P((char *, int, int *, int *));
263 static int chk_arithsub __P((const char *, int));
265 static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
266 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
267 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
268 static void parameter_brace_expand_error __P((char *, char *));
270 static int valid_length_expression __P((char *));
271 static intmax_t parameter_brace_expand_length __P((char *));
273 static char *skiparith __P((char *, int));
274 static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));
275 static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
276 static char *mb_substring __P((char *, int, int));
277 static char *parameter_brace_substring __P((char *, char *, char *, int));
279 static char *pos_params_pat_subst __P((char *, char *, char *, int));
281 static char *parameter_brace_patsub __P((char *, char *, char *, int));
283 static char *pos_params_casemod __P((char *, char *, int, int));
284 static char *parameter_brace_casemod __P((char *, char *, int, char *, int));
286 static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int *, int *));
287 static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
289 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
291 static WORD_LIST *word_list_split __P((WORD_LIST *));
293 static void exp_jump_to_top_level __P((int));
295 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
296 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
297 #ifdef BRACE_EXPANSION
298 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
300 #if defined (ARRAY_VARS)
301 static int make_internal_declare __P((char *, char *));
303 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
304 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
306 /* **************************************************************** */
308 /* Utility Functions */
310 /* **************************************************************** */
312 #ifdef INCLUDE_UNUSED
314 quoted_substring (string, start, end)
319 register char *result, *s, *r;
323 /* Move to string[start], skipping quoted characters. */
324 for (s = string, l = 0; *s && l < start; )
336 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
338 /* Copy LEN characters, including quote characters. */
340 for (l = 0; l < len; s++)
354 #ifdef INCLUDE_UNUSED
355 /* Return the length of S, skipping over quoted characters */
379 /* Find the first occurrence of character C in string S, obeying shell
380 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
381 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
382 escaped with CTLESC are skipped. */
384 quoted_strchr (s, c, flags)
392 if (((flags & ST_BACKSL) && *p == '\\')
393 || ((flags & ST_CTLESC) && *p == CTLESC))
397 return ((char *)NULL);
403 return ((char *)NULL);
406 /* Return 1 if CHARACTER appears in an unquoted portion of
407 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
409 unquoted_member (character, string)
417 slen = strlen (string);
419 while (c = string[sindex])
427 ADVANCE_CHAR (string, slen, sindex);
433 ADVANCE_CHAR (string, slen, sindex);
437 sindex = skip_single_quoted (string, slen, ++sindex);
441 sindex = skip_double_quoted (string, slen, ++sindex);
448 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
450 unquoted_substring (substr, string)
451 char *substr, *string;
454 int sindex, c, sublen;
457 if (substr == 0 || *substr == '\0')
460 slen = strlen (string);
461 sublen = strlen (substr);
462 for (sindex = 0; c = string[sindex]; )
464 if (STREQN (string + sindex, substr, sublen))
473 ADVANCE_CHAR (string, slen, sindex);
477 sindex = skip_single_quoted (string, slen, ++sindex);
481 sindex = skip_double_quoted (string, slen, ++sindex);
485 ADVANCE_CHAR (string, slen, sindex);
492 /* Most of the substitutions must be done in parallel. In order
493 to avoid using tons of unclear goto's, I have some functions
494 for manipulating malloc'ed strings. They all take INDX, a
495 pointer to an integer which is the offset into the string
496 where manipulation is taking place. They also take SIZE, a
497 pointer to an integer which is the current length of the
498 character array for this string. */
500 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
501 of space allocated to TARGET. SOURCE can be NULL, in which
502 case nothing happens. Gets rid of SOURCE by freeing it.
503 Returns TARGET in case the location has changed. */
505 sub_append_string (source, target, indx, size)
506 char *source, *target;
513 srclen = STRLEN (source);
514 if (srclen >= (int)(*size - *indx))
517 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
518 target = (char *)xrealloc (target, (*size = n));
521 FASTCOPY (source, target + *indx, srclen);
523 target[*indx] = '\0';
532 /* Append the textual representation of NUMBER to TARGET.
533 INDX and SIZE are as in SUB_APPEND_STRING. */
535 sub_append_number (number, target, indx, size)
542 temp = itos (number);
543 return (sub_append_string (temp, target, indx, size));
547 /* Extract a substring from STRING, starting at SINDEX and ending with
548 one of the characters in CHARLIST. Don't make the ending character
549 part of the string. Leave SINDEX pointing at the ending character.
550 Understand about backslashes in the string. If (flags & SX_VARNAME)
551 is non-zero, and array variables have been compiled into the shell,
552 everything between a `[' and a corresponding `]' is skipped over.
553 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
554 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
555 contain a closing character from CHARLIST. */
557 string_extract (string, sindex, charlist, flags)
569 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
572 while (c = string[i])
581 #if defined (ARRAY_VARS)
582 else if ((flags & SX_VARNAME) && c == '[')
585 /* If this is an array subscript, skip over it and continue. */
586 ni = skipsubscript (string, i);
587 if (string[ni] == ']')
591 else if (MEMBER (c, charlist))
597 ADVANCE_CHAR (string, slen, i);
600 /* If we had to have a matching delimiter and didn't find one, return an
601 error and let the caller deal with it. */
602 if ((flags & SX_REQMATCH) && found == 0)
605 return (&extract_string_error);
608 temp = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
614 /* Extract the contents of STRING as if it is enclosed in double quotes.
615 SINDEX, when passed in, is the offset of the character immediately
616 following the opening double quote; on exit, SINDEX is left pointing after
617 the closing double quote. If STRIPDQ is non-zero, unquoted double
618 quotes are stripped and the string is terminated by a null byte.
619 Backslashes between the embedded double quotes are processed. If STRIPDQ
620 is zero, an unquoted `"' terminates the string. */
622 string_extract_double_quoted (string, sindex, stripdq)
624 int *sindex, stripdq;
630 char *temp, *ret; /* The new string we return. */
631 int pass_next, backquote, si; /* State variables for the machine. */
635 slen = strlen (string + *sindex) + *sindex;
636 send = string + slen;
638 pass_next = backquote = dquote = 0;
639 temp = (char *)xmalloc (1 + slen - *sindex);
643 while (c = string[i])
645 /* Process a character that was quoted by a backslash. */
650 ``The backslash shall retain its special meaning as an escape
651 character only when followed by one of the characters:
654 If STRIPDQ is zero, we handle the double quotes here and let
655 expand_word_internal handle the rest. If STRIPDQ is non-zero,
656 we have already been through one round of backslash stripping,
657 and want to strip these backslashes only if DQUOTE is non-zero,
658 indicating that we are inside an embedded double-quoted string. */
660 /* If we are in an embedded quoted string, then don't strip
661 backslashes before characters for which the backslash
662 retains its special meaning, but remove backslashes in
663 front of other characters. If we are not in an
664 embedded quoted string, don't strip backslashes at all.
665 This mess is necessary because the string was already
666 surrounded by double quotes (and sh has some really weird
668 The returned string will be run through expansion as if
669 it were double-quoted. */
670 if ((stripdq == 0 && c != '"') ||
671 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
676 COPY_CHAR_I (temp, j, string, send, i);
680 /* A backslash protects the next character. The code just above
681 handles preserving the backslash in front of any character but
690 /* Inside backquotes, ``the portion of the quoted string from the
691 initial backquote and the characters up to the next backquote
692 that is not preceded by a backslash, having escape characters
693 removed, defines that command''. */
711 /* Pass everything between `$(' and the matching `)' or a quoted
712 ${ ... } pair through according to the Posix.2 specification. */
713 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
718 if (string[i + 1] == LPAREN)
719 ret = extract_command_subst (string, &si, 0);
721 ret = extract_dollar_brace_string (string, &si, 1, 0);
724 temp[j++] = string[i + 1];
726 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
728 if (ret == 0 && no_longjmp_on_fatal_error)
731 ret = string + i + 2;
734 for (t = 0; ret[t]; t++, j++)
736 temp[j] = string[si];
751 /* Add any character but a double quote to the quoted string we're
754 goto add_one_character;
768 /* Point to after the closing quote. */
776 /* This should really be another option to string_extract_double_quoted. */
778 skip_double_quoted (string, slen, sind)
785 int pass_next, backquote, si;
788 pass_next = backquote = 0;
790 while (c = string[i])
795 ADVANCE_CHAR (string, slen, i);
808 ADVANCE_CHAR (string, slen, i);
817 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
820 if (string[i + 1] == LPAREN)
821 ret = extract_command_subst (string, &si, SX_NOALLOC);
823 ret = extract_dollar_brace_string (string, &si, 1, SX_NOALLOC);
830 ADVANCE_CHAR (string, slen, i);
843 /* Extract the contents of STRING as if it is enclosed in single quotes.
844 SINDEX, when passed in, is the offset of the character immediately
845 following the opening single quote; on exit, SINDEX is left pointing after
846 the closing single quote. */
848 string_extract_single_quoted (string, sindex)
857 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
858 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
860 while (string[i] && string[i] != '\'')
861 ADVANCE_CHAR (string, slen, i);
863 t = substring (string, *sindex, i);
873 skip_single_quoted (string, slen, sind)
882 while (string[c] && string[c] != '\'')
883 ADVANCE_CHAR (string, slen, c);
890 /* Just like string_extract, but doesn't hack backslashes or any of
891 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
893 string_extract_verbatim (string, slen, sindex, charlist, flags)
900 register int i = *sindex;
901 #if defined (HANDLE_MULTIBYTE)
909 if (charlist[0] == '\'' && charlist[1] == '\0')
911 temp = string_extract_single_quoted (string, sindex);
912 --*sindex; /* leave *sindex at separator character */
918 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
919 this only if MB_CUR_MAX > 1. */
920 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
922 #if defined (HANDLE_MULTIBYTE)
923 clen = strlen (charlist);
926 while (c = string[i])
928 #if defined (HANDLE_MULTIBYTE)
931 if ((flags & SX_NOCTLESC) == 0 && c == CTLESC)
936 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
937 through, to protect the CTLNULs from later calls to
938 remove_quoted_nulls. */
939 else if ((flags & SX_NOESCCTLNUL) == 0 && c == CTLESC && string[i+1] == CTLNUL)
945 #if defined (HANDLE_MULTIBYTE)
946 mblength = MBLEN (string + i, slen - i);
950 mblength = mbtowc (&wc, string + i, slen - i);
951 if (MB_INVALIDCH (mblength))
953 if (MEMBER (c, charlist))
961 len = mbstowcs (wcharlist, charlist, 0);
964 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
965 mbstowcs (wcharlist, charlist, len + 1);
968 if (wcschr (wcharlist, wc))
974 if (MEMBER (c, charlist))
977 ADVANCE_CHAR (string, slen, i);
980 #if defined (HANDLE_MULTIBYTE)
984 temp = substring (string, *sindex, i);
990 /* Extract the $( construct in STRING, and return a new string.
991 Start extracting at (SINDEX) as if we had just seen "$(".
992 Make (SINDEX) get the position of the matching ")". )
993 XFLAGS is additional flags to pass to other extraction functions, */
995 extract_command_subst (string, sindex, xflags)
1000 if (string[*sindex] == '(') /*)*/
1001 return (extract_delimited_string (string, sindex, "$(", "(", ")", xflags|SX_COMMAND)); /*)*/
1004 xflags |= (no_longjmp_on_fatal_error ? SX_NOLONGJMP : 0);
1005 return (xparse_dolparen (string, string+*sindex, sindex, xflags));
1009 /* Extract the $[ construct in STRING, and return a new string. (])
1010 Start extracting at (SINDEX) as if we had just seen "$[".
1011 Make (SINDEX) get the position of the matching "]". */
1013 extract_arithmetic_subst (string, sindex)
1017 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
1020 #if defined (PROCESS_SUBSTITUTION)
1021 /* Extract the <( or >( construct in STRING, and return a new string.
1022 Start extracting at (SINDEX) as if we had just seen "<(".
1023 Make (SINDEX) get the position of the matching ")". */ /*))*/
1025 extract_process_subst (string, starter, sindex)
1030 return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
1032 #endif /* PROCESS_SUBSTITUTION */
1034 #if defined (ARRAY_VARS)
1035 /* This can be fooled by unquoted right parens in the passed string. If
1036 each caller verifies that the last character in STRING is a right paren,
1037 we don't even need to call extract_delimited_string. */
1039 extract_array_assignment_list (string, sindex)
1046 slen = strlen (string); /* ( */
1047 if (string[slen - 1] == ')')
1049 ret = substring (string, *sindex, slen - 1);
1057 /* Extract and create a new string from the contents of STRING, a
1058 character string delimited with OPENER and CLOSER. SINDEX is
1059 the address of an int describing the current offset in STRING;
1060 it should point to just after the first OPENER found. On exit,
1061 SINDEX gets the position of the last character of the matching CLOSER.
1062 If OPENER is more than a single character, ALT_OPENER, if non-null,
1063 contains a character string that can also match CLOSER and thus
1064 needs to be skipped. */
1066 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
1069 char *opener, *alt_opener, *closer;
1075 int pass_character, nesting_level, in_comment;
1076 int len_closer, len_opener, len_alt_opener;
1079 slen = strlen (string + *sindex) + *sindex;
1080 len_opener = STRLEN (opener);
1081 len_alt_opener = STRLEN (alt_opener);
1082 len_closer = STRLEN (closer);
1084 pass_character = in_comment = 0;
1089 while (nesting_level)
1100 ADVANCE_CHAR (string, slen, i);
1104 if (pass_character) /* previous char was backslash */
1107 ADVANCE_CHAR (string, slen, i);
1111 /* Not exactly right yet; should handle shell metacharacters and
1112 multibyte characters, too. */
1113 if ((flags & SX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || shellblank (string[i - 1])))
1116 ADVANCE_CHAR (string, slen, i);
1120 if (c == CTLESC || c == '\\')
1127 /* Process a nested OPENER. */
1128 if (STREQN (string + i, opener, len_opener))
1130 si = i + len_opener;
1131 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|SX_NOALLOC);
1136 /* Process a nested ALT_OPENER */
1137 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1139 si = i + len_alt_opener;
1140 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|SX_NOALLOC);
1145 /* If the current substring terminates the delimited string, decrement
1146 the nesting level. */
1147 if (STREQN (string + i, closer, len_closer))
1149 i += len_closer - 1; /* move to last byte of the closer */
1151 if (nesting_level == 0)
1155 /* Pass old-style command substitution through verbatim. */
1159 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1164 /* Pass single-quoted and double-quoted strings through verbatim. */
1165 if (c == '\'' || c == '"')
1168 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1169 : skip_double_quoted (string, slen, si);
1173 /* move past this character, which was not special. */
1174 ADVANCE_CHAR (string, slen, i);
1177 if (c == 0 && nesting_level)
1179 if (no_longjmp_on_fatal_error == 0)
1181 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1182 last_command_exit_value = EXECUTION_FAILURE;
1183 exp_jump_to_top_level (DISCARD);
1188 return (char *)NULL;
1192 si = i - *sindex - len_closer + 1;
1193 if (flags & SX_NOALLOC)
1194 result = (char *)NULL;
1197 result = (char *)xmalloc (1 + si);
1198 strncpy (result, string + *sindex, si);
1206 /* Extract a parameter expansion expression within ${ and } from STRING.
1207 Obey the Posix.2 rules for finding the ending `}': count braces while
1208 skipping over enclosed quoted strings and command substitutions.
1209 SINDEX is the address of an int describing the current offset in STRING;
1210 it should point to just after the first `{' found. On exit, SINDEX
1211 gets the position of the matching `}'. QUOTED is non-zero if this
1212 occurs inside double quotes. */
1213 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1215 extract_dollar_brace_string (string, sindex, quoted, flags)
1217 int *sindex, quoted, flags;
1221 int pass_character, nesting_level, si;
1227 slen = strlen (string + *sindex) + *sindex;
1230 while (c = string[i])
1235 ADVANCE_CHAR (string, slen, i);
1239 /* CTLESCs and backslashes quote the next character. */
1240 if (c == CTLESC || c == '\\')
1247 if (string[i] == '$' && string[i+1] == LBRACE)
1257 if (nesting_level == 0)
1263 /* Pass the contents of old-style command substitutions through
1268 t = string_extract (string, &si, "`", flags|SX_NOALLOC);
1273 /* Pass the contents of new-style command substitutions and
1274 arithmetic substitutions through verbatim. */
1275 if (string[i] == '$' && string[i+1] == LPAREN)
1278 t = extract_command_subst (string, &si, flags|SX_NOALLOC);
1283 /* Pass the contents of single-quoted and double-quoted strings
1284 through verbatim. */
1285 if (c == '\'' || c == '"')
1288 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1289 : skip_double_quoted (string, slen, si);
1290 /* skip_XXX_quoted leaves index one past close quote */
1294 /* move past this character, which was not special. */
1295 ADVANCE_CHAR (string, slen, i);
1298 if (c == 0 && nesting_level)
1300 if (no_longjmp_on_fatal_error == 0)
1302 report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1303 last_command_exit_value = EXECUTION_FAILURE;
1304 exp_jump_to_top_level (DISCARD);
1309 return ((char *)NULL);
1313 result = (flags & SX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1319 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1320 STRING, and returns a pointer to it. */
1322 de_backslash (string)
1325 register size_t slen;
1326 register int i, j, prev_i;
1329 slen = strlen (string);
1332 /* Loop copying string[i] to string[j], i >= j. */
1335 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1336 string[i + 1] == '$'))
1339 ADVANCE_CHAR (string, slen, i);
1341 do string[j++] = string[prev_i++]; while (prev_i < i);
1352 /* Replace instances of \! in a string with !. */
1354 unquote_bang (string)
1358 register char *temp;
1360 temp = (char *)xmalloc (1 + strlen (string));
1362 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1364 if (string[i] == '\\' && string[i + 1] == '!')
1370 strcpy (string, temp);
1375 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1377 /* Skip characters in STRING until we find a character in DELIMS, and return
1378 the index of that character. START is the index into string at which we
1379 begin. This is similar in spirit to strpbrk, but it returns an index into
1380 STRING and takes a starting index. This little piece of code knows quite
1381 a lot of shell syntax. It's very similar to skip_double_quoted and other
1382 functions of that ilk. */
1384 skip_to_delim (string, start, delims, flags)
1390 int i, pass_next, backq, si, c, invert;
1395 slen = strlen (string + start) + start;
1396 if (flags & SD_NOJMP)
1397 no_longjmp_on_fatal_error = 1;
1398 invert = (flags & SD_INVERT);
1401 pass_next = backq = 0;
1402 while (c = string[i])
1409 ADVANCE_CHAR (string, slen, i);
1422 ADVANCE_CHAR (string, slen, i);
1431 else if (invert == 0 && member (c, delims))
1433 else if (c == '\'' || c == '"')
1435 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1436 : skip_double_quoted (string, slen, ++i);
1437 /* no increment, the skip functions increment past the closing quote. */
1439 else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1442 if (string[si] == '\0')
1445 if (string[i+1] == LPAREN)
1446 temp = extract_delimited_string (string, &si, "$(", "(", ")", SX_NOALLOC|SX_COMMAND); /* ) */
1448 temp = extract_dollar_brace_string (string, &si, 0, SX_NOALLOC);
1450 if (string[i] == '\0') /* don't increment i past EOS in loop */
1455 else if (invert && (member (c, delims) == 0))
1458 ADVANCE_CHAR (string, slen, i);
1464 #if defined (READLINE)
1465 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1466 an unclosed quoted string), or if the character at EINDEX is quoted
1467 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1468 single and double-quoted string parsing functions should not return an
1469 error if there are unclosed quotes or braces. The characters that this
1470 recognizes need to be the same as the contents of
1471 rl_completer_quote_characters. */
1474 char_is_quoted (string, eindex)
1478 int i, pass_next, c;
1482 slen = strlen (string);
1483 no_longjmp_on_fatal_error = 1;
1492 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1494 ADVANCE_CHAR (string, slen, i);
1503 else if (c == '\'' || c == '"')
1505 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1506 : skip_double_quoted (string, slen, ++i);
1509 /* no increment, the skip_xxx functions go one past end */
1512 ADVANCE_CHAR (string, slen, i);
1519 unclosed_pair (string, eindex, openstr)
1524 int i, pass_next, openc, olen;
1528 slen = strlen (string);
1529 olen = strlen (openstr);
1530 i = pass_next = openc = 0;
1536 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1538 ADVANCE_CHAR (string, slen, i);
1541 else if (string[i] == '\\')
1547 else if (STREQN (string + i, openstr, olen))
1552 else if (string[i] == '\'' || string[i] == '"')
1554 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1555 : skip_double_quoted (string, slen, i);
1560 ADVANCE_CHAR (string, slen, i);
1565 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1566 individual words. If DELIMS is NULL, the current value of $IFS is used
1567 to split the string, and the function follows the shell field splitting
1568 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1569 gets the number of words in the returned list. CWP, if non-NULL, gets
1570 the index of the word containing SENTINEL. Non-whitespace chars in
1571 DELIMS delimit separate fields. */
1573 split_at_delims (string, slen, delims, sentinel, nwp, cwp)
1580 int ts, te, i, nw, cw, ifs_split;
1581 char *token, *d, *d2;
1582 WORD_LIST *ret, *tl;
1584 if (string == 0 || *string == '\0')
1590 return ((WORD_LIST *)NULL);
1593 d = (delims == 0) ? ifs_value : delims;
1594 ifs_split = delims == 0;
1596 /* Make d2 the non-whitespace characters in delims */
1601 #if defined (HANDLE_MULTIBYTE)
1602 size_t mblength = 1;
1606 slength = strlen (delims);
1607 d2 = (char *)xmalloc (slength + 1);
1611 #if defined (HANDLE_MULTIBYTE)
1612 mbstate_t state_bak;
1614 mblength = MBRLEN (delims + i, slength, &state);
1615 if (MB_INVALIDCH (mblength))
1617 else if (mblength > 1)
1619 memcpy (d2 + ts, delims + i, mblength);
1622 slength -= mblength;
1626 if (whitespace (delims[i]) == 0)
1627 d2[ts++] = delims[i];
1635 ret = (WORD_LIST *)NULL;
1637 /* Remove sequences of whitspace characters at the start of the string, as
1638 long as those characters are delimiters. */
1639 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1641 if (string[i] == '\0')
1649 te = skip_to_delim (string, ts, d, SD_NOJMP);
1651 /* If we have a non-whitespace delimiter character, use it to make a
1652 separate field. This is just about what $IFS splitting does and
1653 is closer to the behavior of the shell parser. */
1654 if (ts == te && d2 && member (string[ts], d2))
1657 /* If we're using IFS splitting, the non-whitespace delimiter char
1658 and any additional IFS whitespace delimits a field. */
1660 while (member (string[te], d) && spctabnl (string[te]))
1663 while (member (string[te], d2))
1667 token = substring (string, ts, te);
1669 ret = add_string_to_list (token, ret);
1673 if (sentinel >= ts && sentinel <= te)
1676 /* If the cursor is at whitespace just before word start, set the
1677 sentinel word to the current word. */
1678 if (cwp && cw == -1 && sentinel == ts-1)
1681 /* If the cursor is at whitespace between two words, make a new, empty
1682 word, add it before (well, after, since the list is in reverse order)
1683 the word we just added, and set the current word to that one. */
1684 if (cwp && cw == -1 && sentinel < ts)
1686 tl = make_word_list (make_word (""), ret->next);
1692 if (string[te] == 0)
1696 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
1705 /* Special case for SENTINEL at the end of STRING. If we haven't found
1706 the word containing SENTINEL yet, and the index we're looking for is at
1707 the end of STRING, add an additional null argument and set the current
1708 word pointer to that. */
1709 if (cwp && cw == -1 && sentinel >= slen)
1711 if (whitespace (string[sentinel - 1]))
1714 ret = add_string_to_list (token, ret);
1725 return (REVERSE_LIST (ret, WORD_LIST *));
1727 #endif /* READLINE */
1731 /* Extract the name of the variable to bind to from the assignment string. */
1733 assignment_name (string)
1739 offset = assignment (string, 0);
1741 return (char *)NULL;
1742 temp = substring (string, 0, offset);
1747 /* **************************************************************** */
1749 /* Functions to convert strings to WORD_LISTs and vice versa */
1751 /* **************************************************************** */
1753 /* Return a single string of all the words in LIST. SEP is the separator
1754 to put between individual elements of LIST in the output string. */
1756 string_list_internal (list, sep)
1760 register WORD_LIST *t;
1762 int word_len, sep_len, result_size;
1765 return ((char *)NULL);
1767 /* Short-circuit quickly if we don't need to separate anything. */
1768 if (list->next == 0)
1769 return (savestring (list->word->word));
1771 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1772 sep_len = STRLEN (sep);
1775 for (t = list; t; t = t->next)
1778 result_size += sep_len;
1779 result_size += strlen (t->word->word);
1782 r = result = (char *)xmalloc (result_size + 1);
1784 for (t = list; t; t = t->next)
1786 if (t != list && sep_len)
1790 FASTCOPY (sep, r, sep_len);
1797 word_len = strlen (t->word->word);
1798 FASTCOPY (t->word->word, r, word_len);
1806 /* Return a single string of all the words present in LIST, separating
1807 each word with a space. */
1812 return (string_list_internal (list, " "));
1815 /* An external interface that can be used by the rest of the shell to
1816 obtain a string containing the first character in $IFS. Handles all
1817 the multibyte complications. If LENP is non-null, it is set to the
1818 length of the returned string. */
1820 ifs_firstchar (lenp)
1826 ret = xmalloc (MB_LEN_MAX + 1);
1827 #if defined (HANDLE_MULTIBYTE)
1828 if (ifs_firstc_len == 1)
1830 ret[0] = ifs_firstc[0];
1832 len = ret[0] ? 1 : 0;
1836 memcpy (ret, ifs_firstc, ifs_firstc_len);
1837 ret[len = ifs_firstc_len] = '\0';
1840 ret[0] = ifs_firstc;
1842 len = ret[0] ? 0 : 1;
1851 /* Return a single string of all the words present in LIST, obeying the
1852 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1853 expansion [of $*] appears within a double quoted string, it expands
1854 to a single field with the value of each parameter separated by the
1855 first character of the IFS variable, or by a <space> if IFS is unset." */
1857 string_list_dollar_star (list)
1861 #if defined (HANDLE_MULTIBYTE)
1862 # if defined (__GNUC__)
1863 char sep[MB_CUR_MAX + 1];
1871 #if defined (HANDLE_MULTIBYTE)
1872 # if !defined (__GNUC__)
1873 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1874 # endif /* !__GNUC__ */
1875 if (ifs_firstc_len == 1)
1877 sep[0] = ifs_firstc[0];
1882 memcpy (sep, ifs_firstc, ifs_firstc_len);
1883 sep[ifs_firstc_len] = '\0';
1886 sep[0] = ifs_firstc;
1890 ret = string_list_internal (list, sep);
1891 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1897 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1898 is non-zero, the $@ appears within double quotes, and we should quote
1899 the list before converting it into a string. If IFS is unset, and the
1900 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1901 in the words in the list, because the default value of $IFS is
1902 <space><tab><newline>, IFS characters in the words in the list should
1903 also be split. If IFS is null, and the word is not quoted, we need
1904 to quote the words in the list to preserve the positional parameters
1907 string_list_dollar_at (list, quoted)
1912 #if defined (HANDLE_MULTIBYTE)
1913 # if defined (__GNUC__)
1914 char sep[MB_CUR_MAX + 1];
1917 # endif /* !__GNUC__ */
1923 /* XXX this could just be ifs = ifs_value; */
1924 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
1926 #if defined (HANDLE_MULTIBYTE)
1927 # if !defined (__GNUC__)
1928 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1929 # endif /* !__GNUC__ */
1932 if (ifs_firstc_len == 1)
1934 sep[0] = ifs_firstc[0];
1939 memcpy (sep, ifs_firstc, ifs_firstc_len);
1940 sep[ifs_firstc_len] = '\0';
1949 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1953 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
1954 it now that quote_escapes quotes spaces */
1956 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1958 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1961 : list_quote_escapes (list);
1963 ret = string_list_internal (tlist, sep);
1964 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1970 /* Turn the positional paramters into a string, understanding quoting and
1971 the various subtleties of using the first character of $IFS as the
1972 separator. Calls string_list_dollar_at, string_list_dollar_star, and
1973 string_list as appropriate. */
1975 string_list_pos_params (pchar, list, quoted)
1983 if (pchar == '*' && (quoted & Q_DOUBLE_QUOTES))
1985 tlist = quote_list (list);
1986 word_list_remove_quoted_nulls (tlist);
1987 ret = string_list_dollar_star (tlist);
1989 else if (pchar == '*' && (quoted & Q_HERE_DOCUMENT))
1991 tlist = quote_list (list);
1992 word_list_remove_quoted_nulls (tlist);
1993 ret = string_list (tlist);
1995 else if (pchar == '*')
1997 /* Even when unquoted, string_list_dollar_star does the right thing
1998 making sure that the first character of $IFS is used as the
2000 ret = string_list_dollar_star (list);
2002 else if (pchar == '@' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
2003 /* We use string_list_dollar_at, but only if the string is quoted, since
2004 that quotes the escapes if it's not, which we don't want. We could
2005 use string_list (the old code did), but that doesn't do the right
2006 thing if the first character of $IFS is not a space. We use
2007 string_list_dollar_star if the string is unquoted so we make sure that
2008 the elements of $@ are separated by the first character of $IFS for
2010 ret = string_list_dollar_at (list, quoted);
2011 else if (pchar == '@')
2012 ret = string_list_dollar_star (list);
2014 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (list) : list);
2019 /* Return the list of words present in STRING. Separate the string into
2020 words at any of the characters found in SEPARATORS. If QUOTED is
2021 non-zero then word in the list will have its quoted flag set, otherwise
2022 the quoted flag is left as make_word () deemed fit.
2024 This obeys the P1003.2 word splitting semantics. If `separators' is
2025 exactly <space><tab><newline>, then the splitting algorithm is that of
2026 the Bourne shell, which treats any sequence of characters from `separators'
2027 as a delimiter. If IFS is unset, which results in `separators' being set
2028 to "", no splitting occurs. If separators has some other value, the
2029 following rules are applied (`IFS white space' means zero or more
2030 occurrences of <space>, <tab>, or <newline>, as long as those characters
2031 are in `separators'):
2033 1) IFS white space is ignored at the start and the end of the
2035 2) Each occurrence of a character in `separators' that is not
2036 IFS white space, along with any adjacent occurrences of
2037 IFS white space delimits a field.
2038 3) Any nonzero-length sequence of IFS white space delimits a field.
2041 /* BEWARE! list_string strips null arguments. Don't call it twice and
2042 expect to have "" preserved! */
2044 /* This performs word splitting and quoted null character removal on
2047 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2048 : (c) == (separators)[0]) \
2052 list_string (string, separators, quoted)
2053 register char *string, *separators;
2058 char *current_word, *s;
2059 int sindex, sh_style_split, whitesep, xflags;
2062 if (!string || !*string)
2063 return ((WORD_LIST *)NULL);
2065 sh_style_split = separators && separators[0] == ' ' &&
2066 separators[1] == '\t' &&
2067 separators[2] == '\n' &&
2068 separators[3] == '\0';
2069 for (xflags = 0, s = ifs_value; s && *s; s++)
2071 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2072 else if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2076 /* Remove sequences of whitespace at the beginning of STRING, as
2077 long as those characters appear in IFS. Do not do this if
2078 STRING is quoted or if there are no separator characters. */
2079 if (!quoted || !separators || !*separators)
2081 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
2084 return ((WORD_LIST *)NULL);
2089 /* OK, now STRING points to a word that does not begin with white space.
2090 The splitting algorithm is:
2091 extract a word, stopping at a separator
2092 skip sequences of spc, tab, or nl as long as they are separators
2093 This obeys the field splitting rules in Posix.2. */
2094 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
2095 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
2097 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2098 unless multibyte chars are possible. */
2099 current_word = string_extract_verbatim (string, slen, &sindex, separators, xflags);
2100 if (current_word == 0)
2103 /* If we have a quoted empty string, add a quoted null argument. We
2104 want to preserve the quoted null character iff this is a quoted
2105 empty string; otherwise the quoted null characters are removed
2107 if (QUOTED_NULL (current_word))
2109 t = alloc_word_desc ();
2110 t->word = make_quoted_char ('\0');
2111 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2112 result = make_word_list (t, result);
2114 else if (current_word[0] != '\0')
2116 /* If we have something, then add it regardless. However,
2117 perform quoted null character removal on the current word. */
2118 remove_quoted_nulls (current_word);
2119 result = add_string_to_list (current_word, result);
2120 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
2121 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
2122 result->word->flags |= W_QUOTED;
2125 /* If we're not doing sequences of separators in the traditional
2126 Bourne shell style, then add a quoted null argument. */
2127 else if (!sh_style_split && !spctabnl (string[sindex]))
2129 t = alloc_word_desc ();
2130 t->word = make_quoted_char ('\0');
2131 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2132 result = make_word_list (t, result);
2135 free (current_word);
2137 /* Note whether or not the separator is IFS whitespace, used later. */
2138 whitesep = string[sindex] && spctabnl (string[sindex]);
2140 /* Move past the current separator character. */
2144 ADVANCE_CHAR (string, slen, sindex);
2147 /* Now skip sequences of space, tab, or newline characters if they are
2148 in the list of separators. */
2149 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
2152 /* If the first separator was IFS whitespace and the current character
2153 is a non-whitespace IFS character, it should be part of the current
2154 field delimiter, not a separate delimiter that would result in an
2155 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2156 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
2159 /* An IFS character that is not IFS white space, along with any
2160 adjacent IFS white space, shall delimit a field. (SUSv3) */
2161 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
2165 return (REVERSE_LIST (result, WORD_LIST *));
2168 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2169 ENDPTR is set to the first character after the word. This is used by
2170 the `read' builtin. This is never called with SEPARATORS != $IFS;
2171 it should be simplified.
2173 XXX - this function is very similar to list_string; they should be
2176 get_word_from_string (stringp, separators, endptr)
2177 char **stringp, *separators, **endptr;
2181 int sindex, sh_style_split, whitesep, xflags;
2184 if (!stringp || !*stringp || !**stringp)
2185 return ((char *)NULL);
2187 sh_style_split = separators && separators[0] == ' ' &&
2188 separators[1] == '\t' &&
2189 separators[2] == '\n' &&
2190 separators[3] == '\0';
2191 for (xflags = 0, s = ifs_value; s && *s; s++)
2193 if (*s == CTLESC) xflags |= SX_NOCTLESC;
2194 if (*s == CTLNUL) xflags |= SX_NOESCCTLNUL;
2200 /* Remove sequences of whitespace at the beginning of STRING, as
2201 long as those characters appear in IFS. */
2202 if (sh_style_split || !separators || !*separators)
2204 for (; *s && spctabnl (*s) && isifs (*s); s++);
2206 /* If the string is nothing but whitespace, update it and return. */
2212 return ((char *)NULL);
2216 /* OK, S points to a word that does not begin with white space.
2217 Now extract a word, stopping at a separator, save a pointer to
2218 the first character after the word, then skip sequences of spc,
2219 tab, or nl as long as they are separators.
2221 This obeys the field splitting rules in Posix.2. */
2223 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2224 unless multibyte chars are possible. */
2225 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
2226 current_word = string_extract_verbatim (s, slen, &sindex, separators, xflags);
2228 /* Set ENDPTR to the first character after the end of the word. */
2230 *endptr = s + sindex;
2232 /* Note whether or not the separator is IFS whitespace, used later. */
2233 whitesep = s[sindex] && spctabnl (s[sindex]);
2235 /* Move past the current separator character. */
2239 ADVANCE_CHAR (s, slen, sindex);
2242 /* Now skip sequences of space, tab, or newline characters if they are
2243 in the list of separators. */
2244 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2247 /* If the first separator was IFS whitespace and the current character is
2248 a non-whitespace IFS character, it should be part of the current field
2249 delimiter, not a separate delimiter that would result in an empty field.
2250 Look at POSIX.2, 3.6.5, (3)(b). */
2251 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
2254 /* An IFS character that is not IFS white space, along with any adjacent
2255 IFS white space, shall delimit a field. */
2256 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2260 /* Update STRING to point to the next field. */
2261 *stringp = s + sindex;
2262 return (current_word);
2265 /* Remove IFS white space at the end of STRING. Start at the end
2266 of the string and walk backwards until the beginning of the string
2267 or we find a character that's not IFS white space and not CTLESC.
2268 Only let CTLESC escape a white space character if SAW_ESCAPE is
2271 strip_trailing_ifs_whitespace (string, separators, saw_escape)
2272 char *string, *separators;
2277 s = string + STRLEN (string) - 1;
2278 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
2279 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
2287 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2288 backslashes, single and double quotes. */
2290 list_string_with_quotes (string)
2296 int c, i, tokstart, len;
2298 for (s = string; s && *s && spctabnl (*s); s++)
2300 if (s == 0 || *s == 0)
2301 return ((WORD_LIST *)NULL);
2305 list = (WORD_LIST *)NULL;
2316 i = skip_single_quoted (s, s_len, ++i);
2318 i = skip_double_quoted (s, s_len, ++i);
2319 else if (c == 0 || spctabnl (c))
2321 /* We have found the end of a token. Make a word out of it and
2322 add it to the word list. */
2323 token = substring (s, tokstart, i);
2324 list = add_string_to_list (token, list);
2326 while (spctabnl (s[i]))
2334 i++; /* normal character */
2336 return (REVERSE_LIST (list, WORD_LIST *));
2340 /********************************************************/
2342 /* Functions to perform assignment statements */
2344 /********************************************************/
2346 #if defined (ARRAY_VARS)
2348 do_compound_assignment (name, value, flags)
2353 int mklocal, mkassoc;
2356 mklocal = flags & ASS_MKLOCAL;
2357 mkassoc = flags & ASS_MKASSOC;
2359 if (mklocal && variable_context)
2361 v = find_variable (name);
2362 list = expand_compound_array_assignment (v, value, flags);
2364 v = make_local_assoc_variable (name);
2365 else if (v == 0 || (array_p (v) == 0 && assoc_p (v) == 0) || v->context != variable_context)
2366 v = make_local_array_variable (name);
2367 assign_compound_array_list (v, list, flags);
2370 v = assign_array_from_string (name, value, flags);
2376 /* Given STRING, an assignment string, get the value of the right side
2377 of the `=', and bind it to the left side. If EXPAND is true, then
2378 perform parameter expansion, command substitution, and arithmetic
2379 expansion on the right-hand side. Perform tilde expansion in any
2380 case. Do not perform word splitting on the result of expansion. */
2382 do_assignment_internal (word, expand)
2383 const WORD_DESC *word;
2386 int offset, tlen, appendop, assign_list, aflags, retval;
2389 #if defined (ARRAY_VARS)
2395 if (word == 0 || word->word == 0)
2398 appendop = assign_list = aflags = 0;
2399 string = word->word;
2400 offset = assignment (string, 0);
2401 name = savestring (string);
2402 value = (char *)NULL;
2404 if (name[offset] == '=')
2408 if (name[offset - 1] == '+')
2411 name[offset - 1] = '\0';
2414 name[offset] = 0; /* might need this set later */
2415 temp = name + offset + 1;
2416 tlen = STRLEN (temp);
2418 #if defined (ARRAY_VARS)
2419 if (expand && (word->flags & W_COMPASSIGN))
2421 assign_list = ni = 1;
2422 value = extract_array_assignment_list (temp, &ni);
2427 if (expand && temp[0])
2428 value = expand_string_if_necessary (temp, 0, expand_string_assignment);
2430 value = savestring (temp);
2435 value = (char *)xmalloc (1);
2439 if (echo_command_at_execute)
2442 name[offset - 1] = '+';
2443 xtrace_print_assignment (name, value, assign_list, 1);
2445 name[offset - 1] = '\0';
2448 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2451 aflags |= ASS_APPEND;
2453 #if defined (ARRAY_VARS)
2454 if (t = xstrchr (name, '[')) /*]*/
2458 report_error (_("%s: cannot assign list to array member"), name);
2461 entry = assign_array_element (name, value, aflags);
2465 else if (assign_list)
2467 if (word->flags & W_ASSIGNARG)
2468 aflags |= ASS_MKLOCAL;
2469 if (word->flags & W_ASSIGNASSOC)
2470 aflags |= ASS_MKASSOC;
2471 entry = do_compound_assignment (name, value, aflags);
2474 #endif /* ARRAY_VARS */
2475 entry = bind_variable (name, value, aflags);
2477 stupidly_hack_special_variables (name);
2480 /* Return 1 if the assignment seems to have been performed correctly. */
2481 if (entry == 0 || readonly_p (entry))
2482 retval = 0; /* assignment failure */
2483 else if (noassign_p (entry))
2485 last_command_exit_value = EXECUTION_FAILURE;
2486 retval = 1; /* error status, but not assignment failure */
2491 if (entry && retval != 0 && noassign_p (entry) == 0)
2492 VUNSETATTR (entry, att_invisible);
2494 ASSIGN_RETURN (retval);
2497 VUNSETATTR (entry, att_invisible);
2499 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
2503 /* Perform the assignment statement in STRING, and expand the
2504 right side by doing tilde, command and parameter expansion. */
2506 do_assignment (string)
2511 td.flags = W_ASSIGNMENT;
2514 return do_assignment_internal (&td, 1);
2518 do_word_assignment (word)
2521 return do_assignment_internal (word, 1);
2524 /* Given STRING, an assignment string, get the value of the right side
2525 of the `=', and bind it to the left side. Do not perform any word
2526 expansions on the right hand side. */
2528 do_assignment_no_expand (string)
2533 td.flags = W_ASSIGNMENT;
2536 return (do_assignment_internal (&td, 0));
2539 /***************************************************
2541 * Functions to manage the positional parameters *
2543 ***************************************************/
2545 /* Return the word list that corresponds to `$*'. */
2547 list_rest_of_args ()
2549 register WORD_LIST *list, *args;
2552 /* Break out of the loop as soon as one of the dollar variables is null. */
2553 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2554 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2556 for (args = rest_of_args; args; args = args->next)
2557 list = make_word_list (make_bare_word (args->word->word), list);
2559 return (REVERSE_LIST (list, WORD_LIST *));
2565 register WORD_LIST *list;
2568 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2570 for (list = rest_of_args; list; list = list->next)
2575 /* Return the value of a positional parameter. This handles values > 10. */
2577 get_dollar_var_value (ind)
2584 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2585 else /* We want something like ${11} */
2588 for (p = rest_of_args; p && ind--; p = p->next)
2590 temp = p ? savestring (p->word->word) : (char *)NULL;
2595 /* Make a single large string out of the dollar digit variables,
2596 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2597 case of "$*" with respect to IFS. */
2599 string_rest_of_args (dollar_star)
2602 register WORD_LIST *list;
2605 list = list_rest_of_args ();
2606 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2607 dispose_words (list);
2611 /* Return a string containing the positional parameters from START to
2612 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2613 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2614 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2615 no quoting chars are added. */
2617 pos_params (string, start, end, quoted)
2619 int start, end, quoted;
2621 WORD_LIST *save, *params, *h, *t;
2625 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2627 return ((char *)NULL);
2629 save = params = list_rest_of_args ();
2631 return ((char *)NULL);
2633 if (start == 0) /* handle ${@:0[:x]} specially */
2635 t = make_word_list (make_word (dollar_vars[0]), params);
2639 for (i = 1; params && i < start; i++)
2640 params = params->next;
2642 return ((char *)NULL);
2643 for (h = t = params; params && i < end; i++)
2646 params = params->next;
2649 t->next = (WORD_LIST *)NULL;
2651 ret = string_list_pos_params (string[0], h, quoted);
2656 dispose_words (save);
2660 /******************************************************************/
2662 /* Functions to expand strings to strings or WORD_LISTs */
2664 /******************************************************************/
2666 #if defined (PROCESS_SUBSTITUTION)
2667 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2669 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2672 /* If there are any characters in STRING that require full expansion,
2673 then call FUNC to expand STRING; otherwise just perform quote
2674 removal if necessary. This returns a new string. */
2676 expand_string_if_necessary (string, quoted, func)
2687 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2688 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
2692 if (EXP_CHAR (string[i]))
2694 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
2696 ADVANCE_CHAR (string, slen, i);
2701 list = (*func) (string, quoted);
2704 ret = string_list (list);
2705 dispose_words (list);
2710 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
2711 ret = string_quote_removal (string, quoted);
2713 ret = savestring (string);
2718 static inline char *
2719 expand_string_to_string_internal (string, quoted, func)
2727 if (string == 0 || *string == '\0')
2728 return ((char *)NULL);
2730 list = (*func) (string, quoted);
2733 ret = string_list (list);
2734 dispose_words (list);
2743 expand_string_to_string (string, quoted)
2747 return (expand_string_to_string_internal (string, quoted, expand_string));
2751 expand_string_unsplit_to_string (string, quoted)
2755 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
2759 expand_assignment_string_to_string (string, quoted)
2763 return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
2767 expand_arith_string (string, quoted)
2771 return (expand_string_if_necessary (string, quoted, expand_string));
2774 #if defined (COND_COMMAND)
2775 /* Just remove backslashes in STRING. Returns a new string. */
2777 remove_backslashes (string)
2782 r = ret = (char *)xmalloc (strlen (string) + 1);
2783 for (s = string; s && *s; )
2795 /* This needs better error handling. */
2796 /* Expand W for use as an argument to a unary or binary operator in a
2797 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2798 to the != or == operator, and should be treated as a pattern. In
2799 this case, we quote the string specially for the globbing code. If
2800 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2801 be quoted appropriately for regcomp/regexec. The caller is responsible
2802 for removing the backslashes if the unquoted word is needed later. */
2804 cond_expand_word (w, special)
2812 if (w->word == 0 || w->word[0] == '\0')
2813 return ((char *)NULL);
2815 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
2821 r = string_list (l);
2825 qflags = QGLOB_CVTNULL;
2827 qflags |= QGLOB_REGEXP;
2828 p = string_list (l);
2829 r = quote_string_for_globbing (p, qflags);
2841 /* Call expand_word_internal to expand W and handle error returns.
2842 A convenience function for functions that don't want to handle
2843 any errors or free any memory before aborting. */
2845 call_expand_word_internal (w, q, i, c, e)
2851 result = expand_word_internal (w, q, i, c, e);
2852 if (result == &expand_word_error || result == &expand_word_fatal)
2854 /* By convention, each time this error is returned, w->word has
2855 already been freed (it sometimes may not be in the fatal case,
2856 but that doesn't result in a memory leak because we're going
2857 to exit in most cases). */
2858 w->word = (char *)NULL;
2859 last_command_exit_value = EXECUTION_FAILURE;
2860 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
2867 /* Perform parameter expansion, command substitution, and arithmetic
2868 expansion on STRING, as if it were a word. Leave the result quoted. */
2870 expand_string_internal (string, quoted)
2877 if (string == 0 || *string == 0)
2878 return ((WORD_LIST *)NULL);
2881 td.word = savestring (string);
2883 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2889 /* Expand STRING by performing parameter expansion, command substitution,
2890 and arithmetic expansion. Dequote the resulting WORD_LIST before
2891 returning it, but do not perform word splitting. The call to
2892 remove_quoted_nulls () is in here because word splitting normally
2893 takes care of quote removal. */
2895 expand_string_unsplit (string, quoted)
2901 if (string == 0 || *string == '\0')
2902 return ((WORD_LIST *)NULL);
2904 expand_no_split_dollar_star = 1;
2905 value = expand_string_internal (string, quoted);
2906 expand_no_split_dollar_star = 0;
2912 remove_quoted_nulls (value->word->word);
2913 value->word->flags &= ~W_HASQUOTEDNULL;
2915 dequote_list (value);
2920 /* Expand the rhs of an assignment statement */
2922 expand_string_assignment (string, quoted)
2929 if (string == 0 || *string == '\0')
2930 return ((WORD_LIST *)NULL);
2932 expand_no_split_dollar_star = 1;
2934 td.flags = W_ASSIGNRHS;
2935 td.word = savestring (string);
2936 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2939 expand_no_split_dollar_star = 0;
2945 remove_quoted_nulls (value->word->word);
2946 value->word->flags &= ~W_HASQUOTEDNULL;
2948 dequote_list (value);
2954 /* Expand one of the PS? prompt strings. This is a sort of combination of
2955 expand_string_unsplit and expand_string_internal, but returns the
2956 passed string when an error occurs. Might want to trap other calls
2957 to jump_to_top_level here so we don't endlessly loop. */
2959 expand_prompt_string (string, quoted, wflags)
2967 if (string == 0 || *string == 0)
2968 return ((WORD_LIST *)NULL);
2971 td.word = savestring (string);
2973 no_longjmp_on_fatal_error = 1;
2974 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2975 no_longjmp_on_fatal_error = 0;
2977 if (value == &expand_word_error || value == &expand_word_fatal)
2979 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
2987 remove_quoted_nulls (value->word->word);
2988 value->word->flags &= ~W_HASQUOTEDNULL;
2990 dequote_list (value);
2995 /* Expand STRING just as if you were expanding a word, but do not dequote
2996 the resultant WORD_LIST. This is called only from within this file,
2997 and is used to correctly preserve quoted characters when expanding
2998 things like ${1+"$@"}. This does parameter expansion, command
2999 substitution, arithmetic expansion, and word splitting. */
3001 expand_string_leave_quoted (string, quoted)
3008 if (string == 0 || *string == '\0')
3009 return ((WORD_LIST *)NULL);
3011 tlist = expand_string_internal (string, quoted);
3015 tresult = word_list_split (tlist);
3016 dispose_words (tlist);
3019 return ((WORD_LIST *)NULL);
3022 /* This does not perform word splitting or dequote the WORD_LIST
3025 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
3027 int quoted, *dollar_at_p, *has_dollar_at;
3032 if (string == 0 || *string == '\0')
3033 return (WORD_LIST *)NULL;
3037 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
3041 /* Expand STRING just as if you were expanding a word. This also returns
3042 a list of words. Note that filename globbing is *NOT* done for word
3043 or string expansion, just when the shell is expanding a command. This
3044 does parameter expansion, command substitution, arithmetic expansion,
3045 and word splitting. Dequote the resultant WORD_LIST before returning. */
3047 expand_string (string, quoted)
3053 if (string == 0 || *string == '\0')
3054 return ((WORD_LIST *)NULL);
3056 result = expand_string_leave_quoted (string, quoted);
3057 return (result ? dequote_list (result) : result);
3060 /***************************************************
3062 * Functions to handle quoting chars *
3064 ***************************************************/
3068 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3069 The parser passes CTLNUL as CTLESC CTLNUL. */
3071 /* Quote escape characters in string s, but no other characters. This is
3072 used to protect CTLESC and CTLNUL in variable values from the rest of
3073 the word expansion process after the variable is expanded (word splitting
3074 and filename generation). If IFS is null, we quote spaces as well, just
3075 in case we split on spaces later (in the case of unquoted $@, we will
3076 eventually attempt to split the entire word on spaces). Corresponding
3077 code exists in dequote_escapes. Even if we don't end up splitting on
3078 spaces, quoting spaces is not a problem. This should never be called on
3079 a string that is quoted with single or double quotes or part of a here
3080 document (effectively double-quoted). */
3082 quote_escapes (string)
3085 register char *s, *t;
3087 char *result, *send;
3088 int quote_spaces, skip_ctlesc, skip_ctlnul;
3091 slen = strlen (string);
3092 send = string + slen;
3094 quote_spaces = (ifs_value && *ifs_value == 0);
3096 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
3097 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
3099 t = result = (char *)xmalloc ((slen * 2) + 1);
3104 if ((skip_ctlesc == 0 && *s == CTLESC) || (skip_ctlnul == 0 && *s == CTLNUL) || (quote_spaces && *s == ' '))
3106 COPY_CHAR_P (t, s, send);
3113 list_quote_escapes (list)
3116 register WORD_LIST *w;
3119 for (w = list; w; w = w->next)
3122 w->word->word = quote_escapes (t);
3128 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3130 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3131 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3132 data stream pass through properly.
3134 We need to remove doubled CTLESC characters inside quoted strings before
3135 quoting the entire string, so we do not double the number of CTLESC
3138 Also used by parts of the pattern substitution code. */
3140 dequote_escapes (string)
3143 register char *s, *t, *s1;
3145 char *result, *send;
3152 slen = strlen (string);
3153 send = string + slen;
3155 t = result = (char *)xmalloc (slen + 1);
3157 if (strchr (string, CTLESC) == 0)
3158 return (strcpy (result, string));
3160 quote_spaces = (ifs_value && *ifs_value == 0);
3165 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
3171 COPY_CHAR_P (t, s, send);
3177 /* Return a new string with the quoted representation of character C.
3178 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3179 set in any resultant WORD_DESC where this value is the word. */
3181 make_quoted_char (c)
3186 temp = (char *)xmalloc (3);
3201 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3202 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3203 this value is the word. */
3205 quote_string (string)
3210 char *result, *send;
3214 result = (char *)xmalloc (2);
3222 slen = strlen (string);
3223 send = string + slen;
3225 result = (char *)xmalloc ((slen * 2) + 1);
3227 for (t = result; string < send; )
3230 COPY_CHAR_P (t, string, send);
3237 /* De-quote quoted characters in STRING. */
3239 dequote_string (string)
3242 register char *s, *t;
3244 char *result, *send;
3247 slen = strlen (string);
3249 t = result = (char *)xmalloc (slen + 1);
3251 if (QUOTED_NULL (string))
3257 /* If no character in the string can be quoted, don't bother examining
3258 each character. Just return a copy of the string passed to us. */
3259 if (strchr (string, CTLESC) == NULL)
3260 return (strcpy (result, string));
3262 send = string + slen;
3272 COPY_CHAR_P (t, s, send);
3279 /* Quote the entire WORD_LIST list. */
3284 register WORD_LIST *w;
3287 for (w = list; w; w = w->next)
3290 w->word->word = quote_string (t);
3292 w->word->flags |= W_HASQUOTEDNULL; /* XXX - turn on W_HASQUOTEDNULL here? */
3293 w->word->flags |= W_QUOTED;
3299 /* De-quote quoted characters in each word in LIST. */
3305 register WORD_LIST *tlist;
3307 for (tlist = list; tlist; tlist = tlist->next)
3309 s = dequote_string (tlist->word->word);
3310 if (QUOTED_NULL (tlist->word->word))
3311 tlist->word->flags &= ~W_HASQUOTEDNULL;
3312 free (tlist->word->word);
3313 tlist->word->word = s;
3318 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3321 remove_quoted_escapes (string)
3328 t = dequote_escapes (string);
3336 /* Perform quoted null character removal on STRING. We don't allow any
3337 quoted null characters in the middle or at the ends of strings because
3338 of how expand_word_internal works. remove_quoted_nulls () turns
3339 STRING into an empty string iff it only consists of a quoted null,
3340 and removes all unquoted CTLNUL characters. */
3342 remove_quoted_nulls (string)
3345 register size_t slen;
3346 register int i, j, prev_i;
3349 if (strchr (string, CTLNUL) == 0) /* XXX */
3350 return string; /* XXX */
3352 slen = strlen (string);
3357 if (string[i] == CTLESC)
3359 /* Old code had j++, but we cannot assume that i == j at this
3360 point -- what if a CTLNUL has already been removed from the
3361 string? We don't want to drop the CTLESC or recopy characters
3362 that we've already copied down. */
3363 i++; string[j++] = CTLESC;
3367 else if (string[i] == CTLNUL)
3371 ADVANCE_CHAR (string, slen, i);
3374 do string[j++] = string[prev_i++]; while (prev_i < i);
3384 /* Perform quoted null character removal on each element of LIST.
3385 This modifies LIST. */
3387 word_list_remove_quoted_nulls (list)
3390 register WORD_LIST *t;
3392 for (t = list; t; t = t->next)
3394 remove_quoted_nulls (t->word->word);
3395 t->word->flags &= ~W_HASQUOTEDNULL;
3399 /* **************************************************************** */
3401 /* Functions for Matching and Removing Patterns */
3403 /* **************************************************************** */
3405 #if defined (HANDLE_MULTIBYTE)
3406 #if 0 /* Currently unused */
3407 static unsigned char *
3408 mb_getcharlens (string, len)
3412 int i, offset, last;
3419 ret = (unsigned char *)xmalloc (len);
3420 memset (ret, 0, len);
3421 while (string[last])
3423 ADVANCE_CHAR (string, len, offset);
3424 ret[last] = offset - last;
3432 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3433 can have one of 4 values:
3434 RP_LONG_LEFT remove longest matching portion at start of PARAM
3435 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3436 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3437 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3440 #define RP_LONG_LEFT 1
3441 #define RP_SHORT_LEFT 2
3442 #define RP_LONG_RIGHT 3
3443 #define RP_SHORT_RIGHT 4
3446 remove_upattern (param, pattern, op)
3447 char *param, *pattern;
3452 register char *p, *ret, c;
3454 len = STRLEN (param);
3459 case RP_LONG_LEFT: /* remove longest match at start */
3460 for (p = end; p >= param; p--)
3463 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3466 return (savestring (p));
3473 case RP_SHORT_LEFT: /* remove shortest match at start */
3474 for (p = param; p <= end; p++)
3477 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3480 return (savestring (p));
3486 case RP_LONG_RIGHT: /* remove longest match at end */
3487 for (p = param; p <= end; p++)
3489 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3492 ret = savestring (param);
3499 case RP_SHORT_RIGHT: /* remove shortest match at end */
3500 for (p = end; p >= param; p--)
3502 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3505 ret = savestring (param);
3513 return (savestring (param)); /* no match, return original string */
3516 #if defined (HANDLE_MULTIBYTE)
3518 remove_wpattern (wparam, wstrlen, wpattern, op)
3529 case RP_LONG_LEFT: /* remove longest match at start */
3530 for (n = wstrlen; n >= 0; n--)
3532 wc = wparam[n]; wparam[n] = L'\0';
3533 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3536 return (wcsdup (wparam + n));
3542 case RP_SHORT_LEFT: /* remove shortest match at start */
3543 for (n = 0; n <= wstrlen; n++)
3545 wc = wparam[n]; wparam[n] = L'\0';
3546 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3549 return (wcsdup (wparam + n));
3555 case RP_LONG_RIGHT: /* remove longest match at end */
3556 for (n = 0; n <= wstrlen; n++)
3558 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3560 wc = wparam[n]; wparam[n] = L'\0';
3561 ret = wcsdup (wparam);
3568 case RP_SHORT_RIGHT: /* remove shortest match at end */
3569 for (n = wstrlen; n >= 0; n--)
3571 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3573 wc = wparam[n]; wparam[n] = L'\0';
3574 ret = wcsdup (wparam);
3582 return (wcsdup (wparam)); /* no match, return original string */
3584 #endif /* HANDLE_MULTIBYTE */
3587 remove_pattern (param, pattern, op)
3588 char *param, *pattern;
3593 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3594 return (savestring (param));
3596 #if defined (HANDLE_MULTIBYTE)
3599 wchar_t *ret, *oret;
3601 wchar_t *wparam, *wpattern;
3605 n = xdupmbstowcs (&wpattern, NULL, pattern);
3606 if (n == (size_t)-1)
3607 return (remove_upattern (param, pattern, op));
3608 n = xdupmbstowcs (&wparam, NULL, param);
3609 if (n == (size_t)-1)
3612 return (remove_upattern (param, pattern, op));
3614 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3620 xret = (char *)xmalloc (n + 1);
3621 memset (&ps, '\0', sizeof (mbstate_t));
3622 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3623 xret[n] = '\0'; /* just to make sure */
3629 return (remove_upattern (param, pattern, op));
3632 /* Return 1 of the first character of STRING could match the first
3633 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3635 match_pattern_char (pat, string)
3646 return (*string == c);
3648 return (*string == *pat);
3650 return (*pat == LPAREN ? 1 : (*string != '\0'));
3656 return (*pat == LPAREN ? 1 : (*string == c));
3658 return (*string != '\0');
3662 /* Match PAT anywhere in STRING and return the match boundaries.
3663 This returns 1 in case of a successful match, 0 otherwise. SP
3664 and EP are pointers into the string where the match begins and
3665 ends, respectively. MTYPE controls what kind of match is attempted.
3666 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3667 of the string, respectively. The longest match is returned. */
3669 match_upattern (string, pat, mtype, sp, ep)
3675 register char *p, *p1, *npat;
3678 /* If the pattern doesn't match anywhere in the string, go ahead and
3679 short-circuit right away. A minor optimization, saves a bunch of
3680 unnecessary calls to strmatch (up to N calls for a string of N
3681 characters) if the match is unsuccessful. To preserve the semantics
3682 of the substring matches below, we make sure that the pattern has
3683 `*' as first and last character, making a new pattern if necessary. */
3684 /* XXX - check this later if I ever implement `**' with special meaning,
3685 since this will potentially result in `**' at the beginning or end */
3687 if (pat[0] != '*' || (pat[0] == '*' && pat[1] == '(' && extended_glob) || pat[len - 1] != '*') /*)*/
3689 p = npat = (char *)xmalloc (len + 3);
3691 if (*p1 != '*' || (*p1 == '*' && p1[1] == '(' && extended_glob)) /*)*/
3695 if (p1[-1] != '*' || p[-2] == '\\')
3701 c = strmatch (npat, string, FNMATCH_EXTFLAG);
3704 if (c == FNM_NOMATCH)
3707 len = STRLEN (string);
3713 for (p = string; p <= end; p++)
3715 if (match_pattern_char (pat, p))
3717 for (p1 = end; p1 >= p; p1--)
3719 c = *p1; *p1 = '\0';
3720 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3735 if (match_pattern_char (pat, string) == 0)
3738 for (p = end; p >= string; p--)
3741 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
3754 for (p = string; p <= end; p++)
3756 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3771 #if defined (HANDLE_MULTIBYTE)
3772 /* Return 1 of the first character of WSTRING could match the first
3773 character of pattern WPAT. Wide character version. */
3775 match_pattern_wchar (wpat, wstring)
3776 wchar_t *wpat, *wstring;
3783 switch (wc = *wpat++)
3786 return (*wstring == wc);
3788 return (*wstring == *wpat);
3790 return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
3796 return (*wpat == LPAREN ? 1 : (*wstring == wc));
3798 return (*wstring != L'\0');
3802 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3803 This returns 1 in case of a successful match, 0 otherwise. Wide
3804 character version. */
3806 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
3814 wchar_t wc, *wp, *nwpat, *wp1;
3817 size_t n, n1; /* Apple's gcc seems to miscompile this badly */
3822 /* If the pattern doesn't match anywhere in the string, go ahead and
3823 short-circuit right away. A minor optimization, saves a bunch of
3824 unnecessary calls to strmatch (up to N calls for a string of N
3825 characters) if the match is unsuccessful. To preserve the semantics
3826 of the substring matches below, we make sure that the pattern has
3827 `*' as first and last character, making a new pattern if necessary. */
3828 /* XXX - check this later if I ever implement `**' with special meaning,
3829 since this will potentially result in `**' at the beginning or end */
3830 len = wcslen (wpat);
3831 if (wpat[0] != L'*' || (wpat[0] == L'*' && wpat[1] == L'(' && extended_glob) || wpat[len - 1] != L'*') /*)*/
3833 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
3835 if (*wp1 != L'*' || (*wp1 == '*' && wp1[1] == '(' && extended_glob)) /*)*/
3837 while (*wp1 != L'\0')
3839 if (wp1[-1] != L'*' || wp1[-2] == L'\\')
3845 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
3848 if (len == FNM_NOMATCH)
3854 for (n = 0; n <= wstrlen; n++)
3856 if (match_pattern_wchar (wpat, wstring + n))
3858 for (n1 = wstrlen; n1 >= n; n1--)
3860 wc = wstring[n1]; wstring[n1] = L'\0';
3861 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3876 if (match_pattern_wchar (wpat, wstring) == 0)
3879 for (n = wstrlen; n >= 0; n--)
3881 wc = wstring[n]; wstring[n] = L'\0';
3882 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
3895 for (n = 0; n <= wstrlen; n++)
3897 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3900 *ep = indices[wstrlen];
3910 #endif /* HANDLE_MULTIBYTE */
3913 match_pattern (string, pat, mtype, sp, ep)
3918 #if defined (HANDLE_MULTIBYTE)
3921 wchar_t *wstring, *wpat;
3925 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
3928 #if defined (HANDLE_MULTIBYTE)
3931 n = xdupmbstowcs (&wpat, NULL, pat);
3932 if (n == (size_t)-1)
3933 return (match_upattern (string, pat, mtype, sp, ep));
3934 n = xdupmbstowcs (&wstring, &indices, string);
3935 if (n == (size_t)-1)
3938 return (match_upattern (string, pat, mtype, sp, ep));
3940 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
3950 return (match_upattern (string, pat, mtype, sp, ep));
3954 getpatspec (c, value)
3959 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
3961 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
3964 /* Posix.2 says that the WORD should be run through tilde expansion,
3965 parameter expansion, command substitution and arithmetic expansion.
3966 This leaves the result quoted, so quote_string_for_globbing () has
3967 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3968 it means that the entire expression was enclosed in double quotes.
3969 This means that quoting characters in the pattern do not make any
3970 special pattern characters quoted. For example, the `*' in the
3971 following retains its special meaning: "${foo#'*'}". */
3973 getpattern (value, quoted, expandpat)
3975 int quoted, expandpat;
3982 /* There is a problem here: how to handle single or double quotes in the
3983 pattern string when the whole expression is between double quotes?
3984 POSIX.2 says that enclosing double quotes do not cause the pattern to
3985 be quoted, but does that leave us a problem with @ and array[@] and their
3986 expansions inside a pattern? */
3988 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
3991 pat = string_extract_double_quoted (tword, &i, 1);
3997 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3999 l = *value ? expand_string_for_rhs (value,
4000 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
4001 (int *)NULL, (int *)NULL)
4003 pat = string_list (l);
4007 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
4015 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4016 or ${name#[#]value}. */
4018 variable_remove_pattern (value, pattern, patspec, quoted)
4019 char *value, *pattern;
4020 int patspec, quoted;
4024 tword = remove_pattern (value, pattern, patspec);
4031 list_remove_pattern (list, pattern, patspec, itype, quoted)
4034 int patspec, itype, quoted;
4040 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
4042 tword = remove_pattern (l->word->word, pattern, patspec);
4043 w = alloc_word_desc ();
4044 w->word = tword ? tword : savestring ("");
4045 new = make_word_list (w, new);
4048 l = REVERSE_LIST (new, WORD_LIST *);
4049 tword = string_list_pos_params (itype, l, quoted);
4056 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
4059 int patspec, quoted;
4064 list = list_rest_of_args ();
4066 return ((char *)NULL);
4067 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4068 dispose_words (list);
4072 #if defined (ARRAY_VARS)
4074 array_remove_pattern (var, pattern, patspec, varname, quoted)
4078 char *varname; /* so we can figure out how it's indexed */
4088 /* compute itype from varname here */
4089 v = array_variable_part (varname, &ret, 0);
4092 a = (v && array_p (v)) ? array_cell (v) : 0;
4093 h = (v && assoc_p (v)) ? assoc_cell (v) : 0;
4095 list = a ? array_to_word_list (a) : (h ? assoc_to_word_list (h) : 0);
4097 return ((char *)NULL);
4098 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
4099 dispose_words (list);
4103 #endif /* ARRAY_VARS */
4106 parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
4107 char *varname, *value, *patstr;
4110 int vtype, patspec, starsub;
4111 char *temp1, *val, *pattern;
4115 return ((char *)NULL);
4117 this_command_name = varname;
4119 vtype = get_var_and_type (varname, value, quoted, &v, &val);
4121 return ((char *)NULL);
4123 starsub = vtype & VT_STARSUB;
4124 vtype &= ~VT_STARSUB;
4126 patspec = getpatspec (rtype, patstr);
4127 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
4130 /* Need to pass getpattern newly-allocated memory in case of expansion --
4131 the expansion code will free the passed string on an error. */
4132 temp1 = savestring (patstr);
4133 pattern = getpattern (temp1, quoted, 1);
4136 temp1 = (char *)NULL; /* shut up gcc */
4140 case VT_ARRAYMEMBER:
4141 temp1 = remove_pattern (val, pattern, patspec);
4142 if (vtype == VT_VARIABLE)
4146 val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4147 ? quote_string (temp1)
4148 : quote_escapes (temp1);
4153 #if defined (ARRAY_VARS)
4155 temp1 = array_remove_pattern (v, pattern, patspec, varname, quoted);
4156 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4158 val = quote_escapes (temp1);
4165 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
4166 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4168 val = quote_escapes (temp1);
4179 /*******************************************
4181 * Functions to expand WORD_DESCs *
4183 *******************************************/
4185 /* Expand WORD, performing word splitting on the result. This does
4186 parameter expansion, command substitution, arithmetic expansion,
4187 word splitting, and quote removal. */
4190 expand_word (word, quoted)
4194 WORD_LIST *result, *tresult;
4196 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4197 result = word_list_split (tresult);
4198 dispose_words (tresult);
4199 return (result ? dequote_list (result) : result);
4202 /* Expand WORD, but do not perform word splitting on the result. This
4203 does parameter expansion, command substitution, arithmetic expansion,
4204 and quote removal. */
4206 expand_word_unsplit (word, quoted)
4212 expand_no_split_dollar_star = 1;
4213 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4214 expand_no_split_dollar_star = 0;
4216 return (result ? dequote_list (result) : result);
4219 /* Perform shell expansions on WORD, but do not perform word splitting or
4220 quote removal on the result. */
4222 expand_word_leave_quoted (word, quoted)
4226 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
4229 #if defined (PROCESS_SUBSTITUTION)
4231 /*****************************************************************/
4233 /* Hacking Process Substitution */
4235 /*****************************************************************/
4237 #if !defined (HAVE_DEV_FD)
4238 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4239 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4240 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4241 list. NFIFO is a count of the number of FIFOs in the list. */
4242 #define FIFO_INCR 20
4249 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
4251 static int fifo_list_size;
4254 add_fifo_list (pathname)
4257 if (nfifo >= fifo_list_size - 1)
4259 fifo_list_size += FIFO_INCR;
4260 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
4261 fifo_list_size * sizeof (struct temp_fifo));
4264 fifo_list[nfifo].file = savestring (pathname);
4276 for (i = saved = 0; i < nfifo; i++)
4278 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4280 unlink (fifo_list[i].file);
4281 free (fifo_list[i].file);
4282 fifo_list[i].file = (char *)NULL;
4283 fifo_list[i].proc = -1;
4289 /* If we didn't remove some of the FIFOs, compact the list. */
4292 for (i = j = 0; i < nfifo; i++)
4293 if (fifo_list[i].file)
4295 fifo_list[j].file = fifo_list[i].file;
4296 fifo_list[j].proc = fifo_list[i].proc;
4316 tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
4317 if (mkfifo (tname, 0600) < 0)
4320 return ((char *)NULL);
4323 add_fifo_list (tname);
4327 #else /* HAVE_DEV_FD */
4329 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4330 has open to children. NFDS is a count of the number of bits currently
4331 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4333 static char *dev_fd_list = (char *)NULL;
4335 static int totfds; /* The highest possible number of open files. */
4341 if (!dev_fd_list || fd >= totfds)
4346 totfds = getdtablesize ();
4347 if (totfds < 0 || totfds > 256)
4352 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
4353 memset (dev_fd_list + ofds, '\0', totfds - ofds);
4356 dev_fd_list[fd] = 1;
4363 return 0; /* used for cleanup; not needed with /dev/fd */
4374 for (i = 0; nfds && i < totfds; i++)
4385 #if defined (NOTDEF)
4386 print_dev_fd_list ()
4390 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
4393 for (i = 0; i < totfds; i++)
4396 fprintf (stderr, " %d", i);
4398 fprintf (stderr, "\n");
4403 make_dev_fd_filename (fd)
4406 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
4408 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 8);
4410 strcpy (ret, DEV_FD_PREFIX);
4411 p = inttostr (fd, intbuf, sizeof (intbuf));
4412 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
4418 #endif /* HAVE_DEV_FD */
4420 /* Return a filename that will open a connection to the process defined by
4421 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4422 a filename in /dev/fd corresponding to a descriptor that is one of the
4423 ends of the pipe. If not defined, we use named pipes on systems that have
4424 them. Systems without /dev/fd and named pipes are out of luck.
4426 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4427 use the read end of the pipe and dup that file descriptor to fd 0 in
4428 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4429 writing or use the write end of the pipe in the child, and dup that
4430 file descriptor to fd 1 in the child. The parent does the opposite. */
4433 process_substitute (string, open_for_read_in_child)
4435 int open_for_read_in_child;
4440 #if defined (HAVE_DEV_FD)
4441 int parent_pipe_fd, child_pipe_fd;
4443 #endif /* HAVE_DEV_FD */
4444 #if defined (JOB_CONTROL)
4445 pid_t old_pipeline_pgrp;
4448 if (!string || !*string || wordexp_only)
4449 return ((char *)NULL);
4451 #if !defined (HAVE_DEV_FD)
4452 pathname = make_named_pipe ();
4453 #else /* HAVE_DEV_FD */
4454 if (pipe (fildes) < 0)
4456 sys_error (_("cannot make pipe for process substitution"));
4457 return ((char *)NULL);
4459 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4460 the pipe in the parent, otherwise the read end. */
4461 parent_pipe_fd = fildes[open_for_read_in_child];
4462 child_pipe_fd = fildes[1 - open_for_read_in_child];
4463 /* Move the parent end of the pipe to some high file descriptor, to
4464 avoid clashes with FDs used by the script. */
4465 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
4467 pathname = make_dev_fd_filename (parent_pipe_fd);
4468 #endif /* HAVE_DEV_FD */
4472 sys_error (_("cannot make pipe for process substitution"));
4473 return ((char *)NULL);
4476 old_pid = last_made_pid;
4478 #if defined (JOB_CONTROL)
4479 old_pipeline_pgrp = pipeline_pgrp;
4480 pipeline_pgrp = shell_pgrp;
4482 #endif /* JOB_CONTROL */
4484 pid = make_child ((char *)NULL, 1);
4487 reset_terminating_signals (); /* XXX */
4488 free_pushed_string_input ();
4489 /* Cancel traps, in trap.c. */
4490 restore_original_signals ();
4491 setup_async_signals ();
4492 subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
4495 #if defined (JOB_CONTROL)
4496 set_sigchld_handler ();
4497 stop_making_children ();
4498 /* XXX - should we only do this in the parent? (as in command subst) */
4499 pipeline_pgrp = old_pipeline_pgrp;
4500 #endif /* JOB_CONTROL */
4504 sys_error (_("cannot make child for process substitution"));
4506 #if defined (HAVE_DEV_FD)
4507 close (parent_pipe_fd);
4508 close (child_pipe_fd);
4509 #endif /* HAVE_DEV_FD */
4510 return ((char *)NULL);
4515 #if defined (JOB_CONTROL)
4516 restore_pipeline (1);
4519 #if !defined (HAVE_DEV_FD)
4520 fifo_list[nfifo-1].proc = pid;
4523 last_made_pid = old_pid;
4525 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4527 #endif /* JOB_CONTROL && PGRP_PIPE */
4529 #if defined (HAVE_DEV_FD)
4530 close (child_pipe_fd);
4531 #endif /* HAVE_DEV_FD */
4536 set_sigint_handler ();
4538 #if defined (JOB_CONTROL)
4539 set_job_control (0);
4540 #endif /* JOB_CONTROL */
4542 #if !defined (HAVE_DEV_FD)
4543 /* Open the named pipe in the child. */
4544 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
4547 /* Two separate strings for ease of translation. */
4548 if (open_for_read_in_child)
4549 sys_error (_("cannot open named pipe %s for reading"), pathname);
4551 sys_error (_("cannot open named pipe %s for writing"), pathname);
4555 if (open_for_read_in_child)
4557 if (sh_unset_nodelay_mode (fd) < 0)
4559 sys_error (_("cannot reset nodelay mode for fd %d"), fd);
4563 #else /* HAVE_DEV_FD */
4565 #endif /* HAVE_DEV_FD */
4567 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
4569 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
4570 open_for_read_in_child ? 0 : 1);
4574 if (fd != (open_for_read_in_child ? 0 : 1))
4577 /* Need to close any files that this process has open to pipes inherited
4579 if (current_fds_to_close)
4581 close_fd_bitmap (current_fds_to_close);
4582 current_fds_to_close = (struct fd_bitmap *)NULL;
4585 #if defined (HAVE_DEV_FD)
4586 /* Make sure we close the parent's end of the pipe and clear the slot
4587 in the fd list so it is not closed later, if reallocated by, for
4588 instance, pipe(2). */
4589 close (parent_pipe_fd);
4590 dev_fd_list[parent_pipe_fd] = 0;
4591 #endif /* HAVE_DEV_FD */
4593 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
4595 #if !defined (HAVE_DEV_FD)
4596 /* Make sure we close the named pipe in the child before we exit. */
4597 close (open_for_read_in_child ? 0 : 1);
4598 #endif /* !HAVE_DEV_FD */
4603 #endif /* PROCESS_SUBSTITUTION */
4605 /***********************************/
4607 /* Command Substitution */
4609 /***********************************/
4612 read_comsub (fd, quoted, rflag)
4616 char *istring, buf[128], *bufp, *s;
4617 int istring_index, istring_size, c, tflag, skip_ctlesc, skip_ctlnul;
4620 istring = (char *)NULL;
4621 istring_index = istring_size = bufn = tflag = 0;
4623 for (skip_ctlesc = skip_ctlnul = 0, s = ifs_value; s && *s; s++)
4624 skip_ctlesc |= *s == CTLESC, skip_ctlnul |= *s == CTLNUL;
4627 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
4630 /* Read the output of the command through the pipe. This may need to be
4631 changed to understand multibyte characters in the future. */
4638 bufn = zread (fd, buf, sizeof (buf));
4648 internal_warning ("read_comsub: ignored null byte in input");
4653 /* Add the character to ISTRING, possibly after resizing it. */
4654 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
4656 /* This is essentially quote_string inline */
4657 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
4658 istring[istring_index++] = CTLESC;
4659 /* Escape CTLESC and CTLNUL in the output to protect those characters
4660 from the rest of the word expansions (word splitting and globbing.)
4661 This is essentially quote_escapes inline. */
4662 else if (skip_ctlesc == 0 && c == CTLESC)
4664 tflag |= W_HASCTLESC;
4665 istring[istring_index++] = CTLESC;
4667 else if ((skip_ctlnul == 0 && c == CTLNUL) || (c == ' ' && (ifs_value && *ifs_value == 0)))
4668 istring[istring_index++] = CTLESC;
4670 istring[istring_index++] = c;
4673 #if defined (__CYGWIN__)
4674 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
4677 istring[istring_index - 1] = '\n';
4684 istring[istring_index] = '\0';
4686 /* If we read no output, just return now and save ourselves some
4688 if (istring_index == 0)
4693 return (char *)NULL;
4696 /* Strip trailing newlines from the output of the command. */
4697 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4699 while (istring_index > 0)
4701 if (istring[istring_index - 1] == '\n')
4705 /* If the newline was quoted, remove the quoting char. */
4706 if (istring[istring_index - 1] == CTLESC)
4712 istring[istring_index] = '\0';
4715 strip_trailing (istring, istring_index - 1, 1);
4722 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
4723 contained string possibly quoted. */
4725 command_substitute (string, quoted)
4729 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
4731 int result, fildes[2], function_value, pflags, rc, tflag;
4734 istring = (char *)NULL;
4736 /* Don't fork () if there is no need to. In the case of no command to
4737 run, just return NULL. */
4738 if (!string || !*string || (string[0] == '\n' && !string[1]))
4739 return ((WORD_DESC *)NULL);
4741 if (wordexp_only && read_but_dont_execute)
4743 last_command_exit_value = 125;
4744 jump_to_top_level (EXITPROG);
4747 /* We're making the assumption here that the command substitution will
4748 eventually run a command from the file system. Since we'll run
4749 maybe_make_export_env in this subshell before executing that command,
4750 the parent shell and any other shells it starts will have to remake
4751 the environment. If we make it before we fork, other shells won't
4752 have to. Don't bother if we have any temporary variable assignments,
4753 though, because the export environment will be remade after this
4754 command completes anyway, but do it if all the words to be expanded
4755 are variable assignments. */
4756 if (subst_assign_varlist == 0 || garglist == 0)
4757 maybe_make_export_env (); /* XXX */
4759 /* Flags to pass to parse_and_execute() */
4760 pflags = interactive ? SEVAL_RESETLINE : 0;
4762 /* Pipe the output of executing STRING into the current shell. */
4763 if (pipe (fildes) < 0)
4765 sys_error (_("cannot make pipe for command substitution"));
4769 old_pid = last_made_pid;
4770 #if defined (JOB_CONTROL)
4771 old_pipeline_pgrp = pipeline_pgrp;
4772 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4773 if ((subshell_environment & SUBSHELL_PIPE) == 0)
4774 pipeline_pgrp = shell_pgrp;
4775 cleanup_the_pipeline ();
4776 #endif /* JOB_CONTROL */
4778 old_async_pid = last_asynchronous_pid;
4779 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
4780 last_asynchronous_pid = old_async_pid;
4783 /* Reset the signal handlers in the child, but don't free the
4785 reset_signal_handlers ();
4787 #if defined (JOB_CONTROL)
4788 /* XXX DO THIS ONLY IN PARENT ? XXX */
4789 set_sigchld_handler ();
4790 stop_making_children ();
4792 pipeline_pgrp = old_pipeline_pgrp;
4794 stop_making_children ();
4795 #endif /* JOB_CONTROL */
4799 sys_error (_("cannot make child for command substitution"));
4805 return ((WORD_DESC *)NULL);
4810 set_sigint_handler (); /* XXX */
4812 free_pushed_string_input ();
4814 if (dup2 (fildes[1], 1) < 0)
4816 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4817 exit (EXECUTION_FAILURE);
4820 /* If standard output is closed in the parent shell
4821 (such as after `exec >&-'), file descriptor 1 will be
4822 the lowest available file descriptor, and end up in
4823 fildes[0]. This can happen for stdin and stderr as well,
4824 but stdout is more important -- it will cause no output
4825 to be generated from this command. */
4826 if ((fildes[1] != fileno (stdin)) &&
4827 (fildes[1] != fileno (stdout)) &&
4828 (fildes[1] != fileno (stderr)))
4831 if ((fildes[0] != fileno (stdin)) &&
4832 (fildes[0] != fileno (stdout)) &&
4833 (fildes[0] != fileno (stderr)))
4836 /* The currently executing shell is not interactive. */
4839 /* This is a subshell environment. */
4840 subshell_environment |= SUBSHELL_COMSUB;
4842 /* When not in POSIX mode, command substitution does not inherit
4844 if (posixly_correct == 0)
4845 exit_immediately_on_error = 0;
4847 remove_quoted_escapes (string);
4849 startup_state = 2; /* see if we can avoid a fork */
4850 /* Give command substitution a place to jump back to on failure,
4851 so we don't go back up to main (). */
4852 result = setjmp (top_level);
4854 /* If we're running a command substitution inside a shell function,
4855 trap `return' so we don't return from the function in the subshell
4856 and go off to never-never land. */
4857 if (result == 0 && return_catch_flag)
4858 function_value = setjmp (return_catch);
4862 if (result == ERREXIT)
4863 rc = last_command_exit_value;
4864 else if (result == EXITPROG)
4865 rc = last_command_exit_value;
4867 rc = EXECUTION_FAILURE;
4868 else if (function_value)
4869 rc = return_catch_value;
4873 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
4877 last_command_exit_value = rc;
4878 rc = run_exit_trap ();
4879 #if defined (PROCESS_SUBSTITUTION)
4880 unlink_fifo_list ();
4886 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4888 #endif /* JOB_CONTROL && PGRP_PIPE */
4893 istring = read_comsub (fildes[0], quoted, &tflag);
4897 current_command_subst_pid = pid;
4898 last_command_exit_value = wait_for (pid);
4899 last_command_subst_pid = pid;
4900 last_made_pid = old_pid;
4902 #if defined (JOB_CONTROL)
4903 /* If last_command_exit_value > 128, then the substituted command
4904 was terminated by a signal. If that signal was SIGINT, then send
4905 SIGINT to ourselves. This will break out of loops, for instance. */
4906 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
4907 kill (getpid (), SIGINT);
4909 /* wait_for gives the terminal back to shell_pgrp. If some other
4910 process group should have it, give it away to that group here.
4911 pipeline_pgrp is non-zero only while we are constructing a
4912 pipline, so what we are concerned about is whether or not that
4913 pipeline was started in the background. A pipeline started in
4914 the background should never get the tty back here. */
4916 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
4918 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
4920 give_terminal_to (pipeline_pgrp, 0);
4921 #endif /* JOB_CONTROL */
4923 ret = alloc_word_desc ();
4924 ret->word = istring;
4931 /********************************************************
4933 * Utility functions for parameter expansion *
4935 ********************************************************/
4937 #if defined (ARRAY_VARS)
4940 array_length_reference (s)
4950 var = array_variable_part (s, &t, &len);
4952 /* If unbound variables should generate an error, report one and return
4954 if ((var == 0 || (assoc_p (var) == 0 && array_p (var) == 0)) && unbound_vars_is_error)
4965 /* We support a couple of expansions for variables that are not arrays.
4966 We'll return the length of the value for v[0], and 1 for v[@] or
4967 v[*]. Return 0 for everything else. */
4969 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
4971 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
4974 return (assoc_num_elements (assoc_cell (var)));
4975 else if (array_p (var))
4976 return (array_num_elements (array));
4984 akey = expand_assignment_string_to_string (t, 0); /* [ */
4986 if (akey == 0 || *akey == 0)
4988 err_badarraysub (t);
4991 t = assoc_reference (assoc_cell (var), akey);
4995 ind = array_expand_index (t, len);
4998 err_badarraysub (t);
5002 t = array_reference (array, ind);
5004 t = (ind == 0) ? value_cell (var) : (char *)NULL;
5007 len = MB_STRLEN (t);
5010 #endif /* ARRAY_VARS */
5013 valid_brace_expansion_word (name, var_is_special)
5017 if (DIGIT (*name) && all_digits (name))
5019 else if (var_is_special)
5021 #if defined (ARRAY_VARS)
5022 else if (valid_array_reference (name))
5024 #endif /* ARRAY_VARS */
5025 else if (legal_identifier (name))
5032 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
5035 int *quoted_dollar_atp, *contains_dollar_at;
5041 if (quoted_dollar_atp)
5042 *quoted_dollar_atp = 0;
5043 if (contains_dollar_at)
5044 *contains_dollar_at = 0;
5048 /* check for $@ and $* */
5049 if (name[0] == '@' && name[1] == 0)
5051 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5052 *quoted_dollar_atp = 1;
5053 if (contains_dollar_at)
5054 *contains_dollar_at = 1;
5057 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
5059 if (contains_dollar_at)
5060 *contains_dollar_at = 1;
5064 /* Now check for ${array[@]} and ${array[*]} */
5065 #if defined (ARRAY_VARS)
5066 else if (valid_array_reference (name))
5068 temp1 = xstrchr (name, '[');
5069 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
5071 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5072 *quoted_dollar_atp = 1;
5073 if (contains_dollar_at)
5074 *contains_dollar_at = 1;
5077 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5078 which should result in separate words even when IFS is unset. */
5079 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
5081 if (contains_dollar_at)
5082 *contains_dollar_at = 1;
5090 /* Parameter expand NAME, and return a new string which is the expansion,
5091 or NULL if there was no expansion.
5092 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5093 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5094 NAME was found inside of a double-quoted expression. */
5096 parameter_brace_expand_word (name, var_is_special, quoted)
5098 int var_is_special, quoted;
5110 /* Handle multiple digit arguments, as in ${11}. */
5111 if (legal_number (name, &arg_index))
5113 tt = get_dollar_var_value (arg_index);
5115 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5117 : quote_escapes (tt);
5119 temp = (char *)NULL;
5122 else if (var_is_special) /* ${@} */
5125 tt = (char *)xmalloc (2 + strlen (name));
5126 tt[sindex = 0] = '$';
5127 strcpy (tt + 1, name);
5129 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
5130 (int *)NULL, (int *)NULL, 0);
5133 #if defined (ARRAY_VARS)
5134 else if (valid_array_reference (name))
5136 temp = array_value (name, quoted, &atype);
5137 if (atype == 0 && temp)
5138 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5139 ? quote_string (temp)
5140 : quote_escapes (temp);
5141 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5142 rflags |= W_HASQUOTEDNULL;
5145 else if (var = find_variable (name))
5147 if (var_isset (var) && invisible_p (var) == 0)
5149 #if defined (ARRAY_VARS)
5151 temp = assoc_reference (assoc_cell (var), "0");
5152 else if (array_p (var))
5153 temp = array_reference (array_cell (var), 0);
5155 temp = value_cell (var);
5157 temp = value_cell (var);
5161 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
5162 ? quote_string (temp)
5163 : quote_escapes (temp);
5166 temp = (char *)NULL;
5169 temp = (char *)NULL;
5173 ret = alloc_word_desc ();
5175 ret->flags |= rflags;
5180 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5181 value of the variable whose name is the value of NAME. */
5183 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
5185 int var_is_special, quoted;
5186 int *quoted_dollar_atp, *contains_dollar_at;
5191 w = parameter_brace_expand_word (name, var_is_special, quoted);
5193 /* Have to dequote here if necessary */
5196 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5197 ? dequote_string (t)
5198 : dequote_escapes (t);
5202 dispose_word_desc (w);
5204 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
5206 return (WORD_DESC *)NULL;
5208 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
5214 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5215 depending on the value of C, the separating character. C can be one of
5216 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5217 between double quotes. */
5219 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
5221 int c, quoted, *qdollaratp, *hasdollarat;
5225 char *t, *t1, *temp;
5228 /* If the entire expression is between double quotes, we want to treat
5229 the value as a double-quoted string, with the exception that we strip
5230 embedded unescaped double quotes (for sh backwards compatibility). */
5231 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
5234 temp = string_extract_double_quoted (value, &hasdol, 1);
5239 w = alloc_word_desc ();
5241 /* XXX was 0 not quoted */
5242 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
5245 *hasdollarat = hasdol || (l && l->next);
5250 /* The expansion of TEMP returned something. We need to treat things
5251 slightly differently if HASDOL is non-zero. If we have "$@", the
5252 individual words have already been quoted. We need to turn them
5253 into a string with the words separated by the first character of
5254 $IFS without any additional quoting, so string_list_dollar_at won't
5255 do the right thing. We use string_list_dollar_star instead. */
5256 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
5258 /* If l->next is not null, we know that TEMP contained "$@", since that
5259 is the only expansion that creates more than one word. */
5260 if (qdollaratp && ((hasdol && quoted) || l->next))
5264 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
5266 /* The brace expansion occurred between double quotes and there was
5267 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5268 it does not expand to anything. In this case, we want to return
5269 a quoted empty string. */
5270 temp = make_quoted_char ('\0');
5271 w->flags |= W_HASQUOTEDNULL;
5274 temp = (char *)NULL;
5276 if (c == '-' || c == '+')
5283 t = temp ? savestring (temp) : savestring ("");
5284 t1 = dequote_string (t);
5286 #if defined (ARRAY_VARS)
5287 if (valid_array_reference (name))
5288 assign_array_element (name, t1, 0);
5290 #endif /* ARRAY_VARS */
5291 bind_variable (name, t1, 0);
5298 /* Deal with the right hand side of a ${name:?value} expansion in the case
5299 that NAME is null or not set. If VALUE is non-null it is expanded and
5300 used as the error message to print, otherwise a standard message is
5303 parameter_brace_expand_error (name, value)
5309 if (value && *value)
5311 l = expand_string (value, 0);
5312 temp = string_list (l);
5313 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
5318 report_error (_("%s: parameter null or not set"), name);
5320 /* Free the data we have allocated during this expansion, since we
5321 are about to longjmp out. */
5326 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5329 valid_length_expression (name)
5332 return (name[1] == '\0' || /* ${#} */
5333 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
5334 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
5335 #if defined (ARRAY_VARS)
5336 valid_array_reference (name + 1) || /* ${#a[7]} */
5338 legal_identifier (name + 1)); /* ${#PS1} */
5341 #if defined (HANDLE_MULTIBYTE)
5347 mbstate_t mbs, mbsbak;
5350 memset (&mbs, 0, sizeof (mbs));
5352 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
5354 if (MB_INVALIDCH(clen))
5356 clen = 1; /* assume single byte */
5369 /* Handle the parameter brace expansion that requires us to return the
5370 length of a parameter. */
5372 parameter_brace_expand_length (name)
5376 intmax_t number, arg_index;
5378 #if defined (ARRAY_VARS)
5382 if (name[1] == '\0') /* ${#} */
5383 number = number_of_args ();
5384 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
5385 number = number_of_args ();
5386 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
5388 /* Take the lengths of some of the shell's special parameters. */
5392 t = which_set_flags ();
5395 t = itos (last_command_exit_value);
5398 t = itos (dollar_dollar_pid);
5401 if (last_asynchronous_pid == NO_PID)
5404 t = itos (last_asynchronous_pid);
5407 t = itos (number_of_args ());
5410 number = STRLEN (t);
5413 #if defined (ARRAY_VARS)
5414 else if (valid_array_reference (name + 1))
5415 number = array_length_reference (name + 1);
5416 #endif /* ARRAY_VARS */
5421 if (legal_number (name + 1, &arg_index)) /* ${#1} */
5423 t = get_dollar_var_value (arg_index);
5424 number = MB_STRLEN (t);
5427 #if defined (ARRAY_VARS)
5428 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && (array_p (var) || assoc_p (var)))
5431 t = assoc_reference (assoc_cell (var), "0");
5433 t = array_reference (array_cell (var), 0);
5434 number = MB_STRLEN (t);
5439 newname = savestring (name);
5441 list = expand_string (newname, Q_DOUBLE_QUOTES);
5442 t = list ? string_list (list) : (char *)NULL;
5445 dispose_words (list);
5447 number = MB_STRLEN (t);
5455 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5456 so we do some ad-hoc parsing of an arithmetic expression to find
5457 the first DELIM, instead of using strchr(3). Two rules:
5458 1. If the substring contains a `(', read until closing `)'.
5459 2. If the substring contains a `?', read past one `:' for each `?'.
5463 skiparith (substr, delim)
5468 int skipcol, pcount, i;
5471 sublen = strlen (substr);
5472 i = skipcol = pcount = 0;
5475 /* Balance parens */
5476 if (substr[i] == LPAREN)
5482 if (substr[i] == RPAREN && pcount)
5490 ADVANCE_CHAR (substr, sublen, i);
5494 /* Skip one `:' for each `?' */
5495 if (substr[i] == ':' && skipcol)
5501 if (substr[i] == delim)
5503 if (substr[i] == '?')
5509 ADVANCE_CHAR (substr, sublen, i);
5512 return (substr + i);
5515 /* Verify and limit the start and end of the desired substring. If
5516 VTYPE == 0, a regular shell variable is being used; if it is 1,
5517 then the positional parameters are being used; if it is 2, then
5518 VALUE is really a pointer to an array variable that should be used.
5519 Return value is 1 if both values were OK, 0 if there was a problem
5520 with an invalid expression, or -1 if the values were out of range. */
5522 verify_substring_values (v, value, substr, vtype, e1p, e2p)
5524 char *value, *substr;
5526 intmax_t *e1p, *e2p;
5528 char *t, *temp1, *temp2;
5531 #if defined (ARRAY_VARS)
5536 /* duplicate behavior of strchr(3) */
5537 t = skiparith (substr, ':');
5538 if (*t && *t == ':')
5543 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
5544 *e1p = evalexp (temp1, &expok);
5549 len = -1; /* paranoia */
5553 case VT_ARRAYMEMBER:
5554 len = MB_STRLEN (value);
5557 len = number_of_args () + 1;
5559 len++; /* add one arg if counting from $0 */
5561 #if defined (ARRAY_VARS)
5563 /* For arrays, the first value deals with array indices. Negative
5564 offsets count from one past the array's maximum index. Associative
5565 arrays treat the number of elements as the maximum index. */
5569 len = assoc_num_elements (h) + (*e1p < 0);
5574 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
5580 if (len == -1) /* paranoia */
5583 if (*e1p < 0) /* negative offsets count from end */
5586 if (*e1p > len || *e1p < 0)
5589 #if defined (ARRAY_VARS)
5590 /* For arrays, the second offset deals with the number of elements. */
5591 if (vtype == VT_ARRAYVAR)
5592 len = assoc_p (v) ? assoc_num_elements (h) : array_num_elements (a);
5598 temp2 = savestring (t);
5599 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
5602 *e2p = evalexp (temp1, &expok);
5608 internal_error (_("%s: substring expression < 0"), t);
5611 #if defined (ARRAY_VARS)
5612 /* In order to deal with sparse arrays, push the intelligence about how
5613 to deal with the number of elements desired down to the array-
5614 specific functions. */
5615 if (vtype != VT_ARRAYVAR)
5618 *e2p += *e1p; /* want E2 chars starting at E1 */
5629 /* Return the type of variable specified by VARNAME (simple variable,
5630 positional param, or array variable). Also return the value specified
5631 by VARNAME (value of a variable or a reference to an array element).
5632 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5633 characters in the value are quoted with CTLESC and takes appropriate
5634 steps. For convenience, *VALP is set to the dequoted VALUE. */
5636 get_var_and_type (varname, value, quoted, varp, valp)
5637 char *varname, *value;
5644 #if defined (ARRAY_VARS)
5648 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5649 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
5650 if (vtype == VT_POSPARMS && varname[0] == '*')
5651 vtype |= VT_STARSUB;
5652 *varp = (SHELL_VAR *)NULL;
5654 #if defined (ARRAY_VARS)
5655 if (valid_array_reference (varname))
5657 v = array_variable_part (varname, &temp, (int *)0);
5658 if (v && (array_p (v) || assoc_p (v)))
5660 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
5662 /* Callers have to differentiate betwen indexed and associative */
5663 vtype = VT_ARRAYVAR;
5665 vtype |= VT_STARSUB;
5666 *valp = array_p (v) ? (char *)array_cell (v) : (char *)assoc_cell (v);
5670 vtype = VT_ARRAYMEMBER;
5671 *valp = array_value (varname, 1, (int *)NULL);
5675 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
5677 vtype = VT_VARIABLE;
5679 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5680 *valp = dequote_string (value);
5682 *valp = dequote_escapes (value);
5686 vtype = VT_ARRAYMEMBER;
5688 *valp = array_value (varname, 1, (int *)NULL);
5691 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && (assoc_p (v) || array_p (v)))
5693 vtype = VT_ARRAYMEMBER;
5695 *valp = assoc_p (v) ? assoc_reference (assoc_cell (v), "0") : array_reference (array_cell (v), 0);
5700 if (value && vtype == VT_VARIABLE)
5702 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5703 *valp = dequote_string (value);
5705 *valp = dequote_escapes (value);
5714 /******************************************************/
5716 /* Functions to extract substrings of variable values */
5718 /******************************************************/
5720 #if defined (HANDLE_MULTIBYTE)
5721 /* Character-oriented rather than strictly byte-oriented substrings. S and
5722 E, rather being strict indices into STRING, indicate character (possibly
5723 multibyte character) positions that require calculation.
5724 Used by the ${param:offset[:length]} expansion. */
5726 mb_substring (string, s, e)
5731 int start, stop, i, slen;
5735 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5736 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
5739 while (string[start] && i--)
5740 ADVANCE_CHAR (string, slen, start);
5743 while (string[stop] && i--)
5744 ADVANCE_CHAR (string, slen, stop);
5745 tt = substring (string, start, stop);
5750 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5751 is `@', use the positional parameters; otherwise, use the value of
5752 VARNAME. If VARNAME is an array variable, use the array elements. */
5755 parameter_brace_substring (varname, value, substr, quoted)
5756 char *varname, *value, *substr;
5760 int vtype, r, starsub;
5761 char *temp, *val, *tt, *oname;
5765 return ((char *)NULL);
5767 oname = this_command_name;
5768 this_command_name = varname;
5770 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5773 this_command_name = oname;
5774 return ((char *)NULL);
5777 starsub = vtype & VT_STARSUB;
5778 vtype &= ~VT_STARSUB;
5780 r = verify_substring_values (v, val, substr, vtype, &e1, &e2);
5781 this_command_name = oname;
5783 return ((r == 0) ? &expand_param_error : (char *)NULL);
5788 case VT_ARRAYMEMBER:
5789 #if defined (HANDLE_MULTIBYTE)
5791 tt = mb_substring (val, e1, e2);
5794 tt = substring (val, e1, e2);
5796 if (vtype == VT_VARIABLE)
5798 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5799 temp = quote_string (tt);
5801 temp = tt ? quote_escapes (tt) : (char *)NULL;
5805 tt = pos_params (varname, e1, e2, quoted);
5806 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5808 temp = tt ? quote_escapes (tt) : (char *)NULL;
5814 #if defined (ARRAY_VARS)
5817 /* we convert to list and take first e2 elements starting at e1th
5818 element -- officially undefined for now */
5819 temp = assoc_subrange (assoc_cell (v), e1, e2, starsub, quoted);
5821 /* We want E2 to be the number of elements desired (arrays can be sparse,
5822 so verify_substring_values just returns the numbers specified and we
5823 rely on array_subrange to understand how to deal with them). */
5824 temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
5825 /* array_subrange now calls array_quote_escapes as appropriate, so the
5826 caller no longer needs to. */
5830 temp = (char *)NULL;
5836 /****************************************************************/
5838 /* Functions to perform pattern substitution on variable values */
5840 /****************************************************************/
5843 pat_subst (string, pat, rep, mflags)
5844 char *string, *pat, *rep;
5847 char *ret, *s, *e, *str;
5848 int rsize, rptr, l, replen, mtype;
5850 mtype = mflags & MATCH_TYPEMASK;
5853 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5854 * with REP and return the result.
5855 * 2. A null pattern with mtype == MATCH_END means to append REP to
5856 * STRING and return the result.
5858 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
5860 replen = STRLEN (rep);
5861 l = strlen (string);
5862 ret = (char *)xmalloc (replen + l + 2);
5864 strcpy (ret, string);
5865 else if (mtype == MATCH_BEG)
5868 strcpy (ret + replen, string);
5872 strcpy (ret, string);
5873 strcpy (ret + l, rep);
5878 ret = (char *)xmalloc (rsize = 64);
5881 for (replen = STRLEN (rep), rptr = 0, str = string;;)
5883 if (match_pattern (str, pat, mtype, &s, &e) == 0)
5886 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
5888 /* OK, now copy the leading unmatched portion of the string (from
5889 str to s) to ret starting at rptr (the current offset). Then copy
5890 the replacement string at ret + rptr + (s - str). Increment
5891 rptr (if necessary) and str and go on. */
5894 strncpy (ret + rptr, str, l);
5899 strncpy (ret + rptr, rep, replen);
5902 str = e; /* e == end of match */
5904 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
5908 e++, str++; /* avoid infinite recursion on zero-length match */
5911 /* Now copy the unmatched portion of the input string */
5914 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
5915 strcpy (ret + rptr, str);
5923 /* Do pattern match and replacement on the positional parameters. */
5925 pos_params_pat_subst (string, pat, rep, mflags)
5926 char *string, *pat, *rep;
5929 WORD_LIST *save, *params;
5934 save = params = list_rest_of_args ();
5936 return ((char *)NULL);
5938 for ( ; params; params = params->next)
5940 ret = pat_subst (params->word->word, pat, rep, mflags);
5941 w = alloc_word_desc ();
5942 w->word = ret ? ret : savestring ("");
5943 dispose_word (params->word);
5947 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
5948 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
5951 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
5952 ret = string_list_dollar_star (quote_list (save));
5953 else if ((mflags & MATCH_STARSUB) == MATCH_STARSUB)
5954 ret = string_list_dollar_star (save);
5955 else if ((mflags & MATCH_QUOTED) == MATCH_QUOTED)
5956 ret = string_list_dollar_at (save, qflags);
5958 ret = string_list_dollar_star (save);
5960 ret = string_list_pos_params (pchar, save, qflags);
5963 dispose_words (save);
5968 /* Perform pattern substitution on VALUE, which is the expansion of
5969 VARNAME. PATSUB is an expression supplying the pattern to match
5970 and the string to substitute. QUOTED is a flags word containing
5971 the type of quoting currently in effect. */
5973 parameter_brace_patsub (varname, value, patsub, quoted)
5974 char *varname, *value, *patsub;
5977 int vtype, mflags, starsub, delim;
5978 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
5982 return ((char *)NULL);
5984 this_command_name = varname;
5986 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5988 return ((char *)NULL);
5990 starsub = vtype & VT_STARSUB;
5991 vtype &= ~VT_STARSUB;
5994 if (patsub && *patsub == '/')
5996 mflags |= MATCH_GLOBREP;
6000 /* Malloc this because expand_string_if_necessary or one of the expansion
6001 functions in its call chain may free it on a substitution error. */
6002 lpatsub = savestring (patsub);
6004 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6005 mflags |= MATCH_QUOTED;
6008 mflags |= MATCH_STARSUB;
6010 /* If the pattern starts with a `/', make sure we skip over it when looking
6011 for the replacement delimiter. */
6013 if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
6018 delim = skip_to_delim (lpatsub, ((*patsub == '/') ? 1 : 0), "/", 0);
6019 if (lpatsub[delim] == '/')
6022 rep = lpatsub + delim + 1;
6028 if (rep && *rep == '\0')
6031 /* Perform the same expansions on the pattern as performed by the
6032 pattern removal expansions. */
6033 pat = getpattern (lpatsub, quoted, 1);
6037 if ((mflags & MATCH_QUOTED) == 0)
6038 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
6040 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
6043 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6044 pattern. This is an extension. Make sure we don't anchor the pattern
6045 at the beginning or end of the string if we're doing global replacement,
6048 if (mflags & MATCH_GLOBREP)
6049 mflags |= MATCH_ANY;
6050 else if (pat && pat[0] == '#')
6052 mflags |= MATCH_BEG;
6055 else if (pat && pat[0] == '%')
6057 mflags |= MATCH_END;
6061 mflags |= MATCH_ANY;
6063 /* OK, we now want to substitute REP for PAT in VAL. If
6064 flags & MATCH_GLOBREP is non-zero, the substitution is done
6065 everywhere, otherwise only the first occurrence of PAT is
6066 replaced. The pattern matching code doesn't understand
6067 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6068 values passed in (VT_VARIABLE) so the pattern substitution
6069 code works right. We need to requote special chars after
6070 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6071 other cases if QUOTED == 0, since the posparams and arrays
6072 indexed by * or @ do special things when QUOTED != 0. */
6077 case VT_ARRAYMEMBER:
6078 temp = pat_subst (val, p, rep, mflags);
6079 if (vtype == VT_VARIABLE)
6083 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6089 temp = pos_params_pat_subst (val, p, rep, mflags);
6090 if (temp && (mflags & MATCH_QUOTED) == 0)
6092 tt = quote_escapes (temp);
6097 #if defined (ARRAY_VARS)
6099 temp = assoc_p (v) ? assoc_patsub (assoc_cell (v), p, rep, mflags)
6100 : array_patsub (array_cell (v), p, rep, mflags);
6101 /* Don't call quote_escapes anymore; array_patsub calls
6102 array_quote_escapes as appropriate before adding the
6103 space separators; ditto for assoc_patsub. */
6115 /****************************************************************/
6117 /* Functions to perform case modification on variable values */
6119 /****************************************************************/
6121 /* Do case modification on the positional parameters. */
6124 pos_params_modcase (string, pat, modop, mflags)
6129 WORD_LIST *save, *params;
6134 save = params = list_rest_of_args ();
6136 return ((char *)NULL);
6138 for ( ; params; params = params->next)
6140 ret = sh_modcase (params->word->word, pat, modop);
6141 w = alloc_word_desc ();
6142 w->word = ret ? ret : savestring ("");
6143 dispose_word (params->word);
6147 pchar = (mflags & MATCH_STARSUB) == MATCH_STARSUB ? '*' : '@';
6148 qflags = (mflags & MATCH_QUOTED) == MATCH_QUOTED ? Q_DOUBLE_QUOTES : 0;
6150 ret = string_list_pos_params (pchar, save, qflags);
6151 dispose_words (save);
6156 /* Perform case modification on VALUE, which is the expansion of
6157 VARNAME. MODSPEC is an expression supplying the type of modification
6158 to perform. QUOTED is a flags word containing the type of quoting
6159 currently in effect. */
6161 parameter_brace_casemod (varname, value, modspec, patspec, quoted)
6162 char *varname, *value;
6167 int vtype, starsub, modop, mflags, x;
6168 char *val, *temp, *pat, *p, *lpat, *tt;
6172 return ((char *)NULL);
6174 this_command_name = varname;
6176 vtype = get_var_and_type (varname, value, quoted, &v, &val);
6178 return ((char *)NULL);
6180 starsub = vtype & VT_STARSUB;
6181 vtype &= ~VT_STARSUB;
6185 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6186 mflags |= MATCH_QUOTED;
6188 mflags |= MATCH_STARSUB;
6193 x = p && p[0] == modspec;
6194 modop = x ? CASE_UPPER : CASE_UPFIRST;
6197 else if (modspec == ',')
6199 x = p && p[0] == modspec;
6200 modop = x ? CASE_LOWER : CASE_LOWFIRST;
6203 else if (modspec == '~')
6205 x = p && p[0] == modspec;
6206 modop = x ? CASE_TOGGLEALL : CASE_TOGGLE;
6210 lpat = p ? savestring (p) : 0;
6211 /* Perform the same expansions on the pattern as performed by the
6212 pattern removal expansions. FOR LATER */
6213 pat = lpat ? getpattern (lpat, quoted, 1) : 0;
6215 /* OK, now we do the case modification. */
6219 case VT_ARRAYMEMBER:
6220 temp = sh_modcase (val, pat, modop);
6221 if (vtype == VT_VARIABLE)
6225 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
6232 temp = pos_params_modcase (val, pat, modop, mflags);
6233 if (temp && (mflags & MATCH_QUOTED) == 0)
6235 tt = quote_escapes (temp);
6241 #if defined (ARRAY_VARS)
6243 temp = assoc_p (v) ? assoc_modcase (assoc_cell (v), pat, modop, mflags)
6244 : array_modcase (array_cell (v), pat, modop, mflags);
6245 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6246 as appropriate before adding the space separators; ditto for
6258 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6259 any occur, this must be a nested command substitution, so return 0.
6260 Otherwise, return 1. A valid arithmetic expression must always have a
6261 ( before a matching ), so any cases where there are more right parens
6262 means that this must not be an arithmetic expression, though the parser
6263 will not accept it without a balanced total number of parens. */
6265 chk_arithsub (s, len)
6277 else if (s[i] == ')')
6287 ADVANCE_CHAR (s, len, i);
6293 ADVANCE_CHAR (s, len, i);
6297 i = skip_single_quoted (s, len, ++i);
6301 i = skip_double_quoted ((char *)s, len, ++i);
6306 return (count == 0);
6309 /****************************************************************/
6311 /* Functions to perform parameter expansion on a string */
6313 /****************************************************************/
6315 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6317 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
6319 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
6321 int check_nullness, var_is_set, var_is_null, var_is_special;
6322 int want_substring, want_indir, want_patsub, want_casemod;
6323 char *name, *value, *temp, *temp1;
6324 WORD_DESC *tdesc, *ret;
6325 int t_index, sindex, c, tflag, modspec;
6328 temp = temp1 = value = (char *)NULL;
6329 var_is_set = var_is_null = var_is_special = check_nullness = 0;
6330 want_substring = want_indir = want_patsub = want_casemod = 0;
6334 /* ${#var} doesn't have any of the other parameter expansions on it. */
6335 if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */
6336 name = string_extract (string, &t_index, "}", SX_VARNAME);
6338 #if defined (CASEMOD_EXPANSIONS)
6339 /* To enable case-toggling expansions using the `~' operator character
6340 change the 1 to 0. */
6341 # if defined (CASEMOD_CAPCASE)
6342 name = string_extract (string, &t_index, "#%^,~:-=?+/}", SX_VARNAME);
6344 name = string_extract (string, &t_index, "#%^,:-=?+/}", SX_VARNAME);
6345 # endif /* CASEMOD_CAPCASE */
6347 name = string_extract (string, &t_index, "#%:-=?+/}", SX_VARNAME);
6348 #endif /* CASEMOD_EXPANSIONS */
6353 /* If the name really consists of a special variable, then make sure
6354 that we have the entire name. We don't allow indirect references
6355 to special variables except `#', `?', `@' and `*'. */
6356 if ((sindex == t_index &&
6357 (string[t_index] == '-' ||
6358 string[t_index] == '?' ||
6359 string[t_index] == '#')) ||
6360 (sindex == t_index - 1 && string[sindex] == '!' &&
6361 (string[t_index] == '#' ||
6362 string[t_index] == '?' ||
6363 string[t_index] == '@' ||
6364 string[t_index] == '*')))
6368 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
6369 name = (char *)xmalloc (3 + (strlen (temp1)));
6370 *name = string[sindex];
6371 if (string[sindex] == '!')
6373 /* indirect reference of $#, $?, $@, or $* */
6374 name[1] = string[sindex + 1];
6375 strcpy (name + 2, temp1);
6378 strcpy (name + 1, temp1);
6383 /* Find out what character ended the variable name. Then
6384 do the appropriate thing. */
6385 if (c = string[sindex])
6388 /* If c is followed by one of the valid parameter expansion
6389 characters, move past it as normal. If not, assume that
6390 a substring specification is being given, and do not move
6392 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
6395 if (c = string[sindex])
6398 else if (c == ':' && string[sindex] != RBRACE)
6400 else if (c == '/' && string[sindex] != RBRACE)
6402 #if defined (CASEMOD_EXPANSIONS)
6403 else if (c == '^' || c == ',' || c == '~')
6410 /* Catch the valid and invalid brace expressions that made it through the
6412 /* ${#-} is a valid expansion and means to take the length of $-.
6413 Similarly for ${#?} and ${##}... */
6414 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6415 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
6417 name = (char *)xrealloc (name, 3);
6420 c = string[sindex++];
6423 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6424 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6425 member (c, "%:=+/") && string[sindex] == RBRACE)
6427 temp = (char *)NULL;
6428 goto bad_substitution;
6431 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6432 either a variable name, one of the positional parameters or a special
6433 variable that expands to one of the positional parameters. */
6434 want_indir = *name == '!' &&
6435 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
6436 || VALID_INDIR_PARAM (name[1]));
6438 /* Determine the value of this variable. */
6440 /* Check for special variables, directly referenced. */
6441 if (SPECIAL_VAR (name, want_indir))
6444 /* Check for special expansion things, like the length of a parameter */
6445 if (*name == '#' && name[1])
6447 /* If we are not pointing at the character just after the
6448 closing brace, then we haven't gotten all of the name.
6449 Since it begins with a special character, this is a bad
6450 substitution. Also check NAME for validity before trying
6452 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
6454 temp = (char *)NULL;
6455 goto bad_substitution;
6458 number = parameter_brace_expand_length (name);
6463 return (&expand_wdesc_error);
6466 ret = alloc_word_desc ();
6467 ret->word = itos (number);
6472 /* ${@} is identical to $@. */
6473 if (name[0] == '@' && name[1] == '\0')
6475 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6476 *quoted_dollar_atp = 1;
6478 if (contains_dollar_at)
6479 *contains_dollar_at = 1;
6482 /* Process ${!PREFIX*} expansion. */
6483 if (want_indir && string[sindex - 1] == RBRACE &&
6484 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
6485 legal_variable_starter ((unsigned char) name[1]))
6490 temp1 = savestring (name + 1);
6491 number = strlen (temp1);
6492 temp1[number - 1] = '\0';
6493 x = all_variables_matching_prefix (temp1);
6494 xlist = strvec_to_word_list (x, 0, 0);
6495 if (string[sindex - 2] == '*')
6496 temp = string_list_dollar_star (xlist);
6499 temp = string_list_dollar_at (xlist, quoted);
6500 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6501 *quoted_dollar_atp = 1;
6502 if (contains_dollar_at)
6503 *contains_dollar_at = 1;
6510 ret = alloc_word_desc ();
6515 #if defined (ARRAY_VARS)
6516 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6517 if (want_indir && string[sindex - 1] == RBRACE &&
6518 string[sindex - 2] == ']' && valid_array_reference (name+1))
6522 temp1 = savestring (name + 1);
6523 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
6525 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
6527 temp = array_keys (temp1, quoted); /* handles assoc vars too */
6530 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6531 *quoted_dollar_atp = 1;
6532 if (contains_dollar_at)
6533 *contains_dollar_at = 1;
6539 ret = alloc_word_desc ();
6546 #endif /* ARRAY_VARS */
6548 /* Make sure that NAME is valid before trying to go on. */
6549 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
6550 var_is_special) == 0)
6552 temp = (char *)NULL;
6553 goto bad_substitution;
6557 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
6559 tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
6564 tflag = tdesc->flags;
6565 dispose_word_desc (tdesc);
6570 #if defined (ARRAY_VARS)
6571 if (valid_array_reference (name))
6572 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
6575 var_is_set = temp != (char *)0;
6576 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
6578 /* Get the rest of the stuff inside the braces. */
6579 if (c && c != RBRACE)
6581 /* Extract the contents of the ${ ... } expansion
6582 according to the Posix.2 rules. */
6583 value = extract_dollar_brace_string (string, &sindex, quoted, 0);
6584 if (string[sindex] == RBRACE)
6587 goto bad_substitution;
6590 value = (char *)NULL;
6594 /* If this is a substring spec, process it and add the result. */
6597 temp1 = parameter_brace_substring (name, temp, value, quoted);
6602 if (temp1 == &expand_param_error)
6603 return (&expand_wdesc_error);
6604 else if (temp1 == &expand_param_fatal)
6605 return (&expand_wdesc_fatal);
6607 ret = alloc_word_desc ();
6609 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6610 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
6613 else if (want_patsub)
6615 temp1 = parameter_brace_patsub (name, temp, value, quoted);
6620 if (temp1 == &expand_param_error)
6621 return (&expand_wdesc_error);
6622 else if (temp1 == &expand_param_fatal)
6623 return (&expand_wdesc_fatal);
6625 ret = alloc_word_desc ();
6627 ret = alloc_word_desc ();
6629 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6630 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
6633 #if defined (CASEMOD_EXPANSIONS)
6634 else if (want_casemod)
6636 temp1 = parameter_brace_casemod (name, temp, modspec, value, quoted);
6641 if (temp1 == &expand_param_error)
6642 return (&expand_wdesc_error);
6643 else if (temp1 == &expand_param_fatal)
6644 return (&expand_wdesc_fatal);
6646 ret = alloc_word_desc ();
6648 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6649 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
6654 /* Do the right thing based on which character ended the variable name. */
6660 report_error (_("%s: bad substitution"), string ? string : "??");
6664 return &expand_wdesc_error;
6667 if (var_is_set == 0 && unbound_vars_is_error)
6669 err_unboundvar (name);
6673 last_command_exit_value = EXECUTION_FAILURE;
6674 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6678 case '#': /* ${param#[#]pattern} */
6679 case '%': /* ${param%[%]pattern} */
6680 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
6685 temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
6689 ret = alloc_word_desc ();
6691 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6692 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
6699 if (var_is_set && var_is_null == 0)
6701 /* If the operator is `+', we don't want the value of the named
6702 variable for anything, just the value of the right hand side. */
6706 /* XXX -- if we're double-quoted and the named variable is "$@",
6707 we want to turn off any special handling of "$@" --
6708 we're not using it, so whatever is on the rhs applies. */
6709 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6710 *quoted_dollar_atp = 0;
6711 if (contains_dollar_at)
6712 *contains_dollar_at = 0;
6717 ret = parameter_brace_expand_rhs (name, value, c,
6720 contains_dollar_at);
6721 /* XXX - fix up later, esp. noting presence of
6722 W_HASQUOTEDNULL in ret->flags */
6726 temp = (char *)NULL;
6732 /* Otherwise do nothing; just use the value in TEMP. */
6734 else /* VAR not set or VAR is NULL. */
6737 temp = (char *)NULL;
6738 if (c == '=' && var_is_special)
6740 report_error (_("$%s: cannot assign in this way"), name);
6743 return &expand_wdesc_error;
6747 parameter_brace_expand_error (name, value);
6748 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6752 /* XXX -- if we're double-quoted and the named variable is "$@",
6753 we want to turn off any special handling of "$@" --
6754 we're not using it, so whatever is on the rhs applies. */
6755 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6756 *quoted_dollar_atp = 0;
6757 if (contains_dollar_at)
6758 *contains_dollar_at = 0;
6760 ret = parameter_brace_expand_rhs (name, value, c, quoted,
6762 contains_dollar_at);
6763 /* XXX - fix up later, esp. noting presence of
6764 W_HASQUOTEDNULL in tdesc->flags */
6775 ret = alloc_word_desc ();
6782 /* Expand a single ${xxx} expansion. The braces are optional. When
6783 the braces are used, parameter_brace_expand() does the work,
6784 possibly calling param_expand recursively. */
6786 param_expand (string, sindex, quoted, expanded_something,
6787 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
6790 int *sindex, quoted, *expanded_something, *contains_dollar_at;
6791 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
6793 char *temp, *temp1, uerror[3];
6794 int zindex, t_index, expok;
6799 WORD_DESC *tdesc, *ret;
6803 c = string[++zindex];
6805 temp = (char *)NULL;
6806 ret = tdesc = (WORD_DESC *)NULL;
6809 /* Do simple cases first. Switch on what follows '$'. */
6823 temp1 = dollar_vars[TODIGIT (c)];
6824 if (unbound_vars_is_error && temp1 == (char *)NULL)
6829 err_unboundvar (uerror);
6830 last_command_exit_value = EXECUTION_FAILURE;
6831 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6834 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6835 ? quote_string (temp1)
6836 : quote_escapes (temp1);
6838 temp = (char *)NULL;
6842 /* $$ -- pid of the invoking shell. */
6844 temp = itos (dollar_dollar_pid);
6847 /* $# -- number of positional parameters. */
6849 temp = itos (number_of_args ());
6852 /* $? -- return value of the last synchronous command. */
6854 temp = itos (last_command_exit_value);
6857 /* $- -- flags supplied to the shell on invocation or by `set'. */
6859 temp = which_set_flags ();
6862 /* $! -- Pid of the last asynchronous command. */
6864 /* If no asynchronous pids have been created, expand to nothing.
6865 If `set -u' has been executed, and no async processes have
6866 been created, this is an expansion error. */
6867 if (last_asynchronous_pid == NO_PID)
6869 if (expanded_something)
6870 *expanded_something = 0;
6871 temp = (char *)NULL;
6872 if (unbound_vars_is_error)
6877 err_unboundvar (uerror);
6878 last_command_exit_value = EXECUTION_FAILURE;
6879 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6883 temp = itos (last_asynchronous_pid);
6886 /* The only difference between this and $@ is when the arg is quoted. */
6887 case '*': /* `$*' */
6888 list = list_rest_of_args ();
6890 if (list == 0 && unbound_vars_is_error)
6895 err_unboundvar (uerror);
6896 last_command_exit_value = EXECUTION_FAILURE;
6897 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6900 /* If there are no command-line arguments, this should just
6901 disappear if there are other characters in the expansion,
6902 even if it's quoted. */
6903 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
6904 temp = (char *)NULL;
6905 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6907 /* If we have "$*" we want to make a string of the positional
6908 parameters, separated by the first character of $IFS, and
6909 quote the whole string, including the separators. If IFS
6910 is unset, the parameters are separated by ' '; if $IFS is
6911 null, the parameters are concatenated. */
6912 temp = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (list) : string_list (list);
6913 temp1 = quote_string (temp);
6915 tflag |= W_HASQUOTEDNULL;
6921 /* We check whether or not we're eventually going to split $* here,
6922 for example when IFS is empty and we are processing the rhs of
6923 an assignment statement. In that case, we don't separate the
6924 arguments at all. Otherwise, if the $* is not quoted it is
6927 # if defined (HANDLE_MULTIBYTE)
6928 if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
6930 if (expand_no_split_dollar_star && ifs_firstc == 0)
6932 temp = string_list_dollar_star (list);
6934 temp = string_list_dollar_at (list, quoted);
6936 temp = string_list_dollar_at (list, quoted);
6938 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
6939 *contains_dollar_at = 1;
6942 dispose_words (list);
6945 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
6946 means that we have to turn quoting off after we split into
6947 the individually quoted arguments so that the final split
6948 on the first character of $IFS is still done. */
6949 case '@': /* `$@' */
6950 list = list_rest_of_args ();
6952 if (list == 0 && unbound_vars_is_error)
6957 err_unboundvar (uerror);
6958 last_command_exit_value = EXECUTION_FAILURE;
6959 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6962 /* We want to flag the fact that we saw this. We can't turn
6963 off quoting entirely, because other characters in the
6964 string might need it (consider "\"$@\""), but we need some
6965 way to signal that the final split on the first character
6966 of $IFS should be done, even though QUOTED is 1. */
6967 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6968 *quoted_dollar_at_p = 1;
6969 if (contains_dollar_at)
6970 *contains_dollar_at = 1;
6972 /* We want to separate the positional parameters with the first
6973 character of $IFS in case $IFS is something other than a space.
6974 We also want to make sure that splitting is done no matter what --
6975 according to POSIX.2, this expands to a list of the positional
6976 parameters no matter what IFS is set to. */
6977 temp = string_list_dollar_at (list, quoted);
6979 dispose_words (list);
6983 tdesc = parameter_brace_expand (string, &zindex, quoted,
6985 contains_dollar_at);
6987 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
6989 temp = tdesc ? tdesc->word : (char *)0;
6992 /* Quoted nulls should be removed if there is anything else
6994 /* Note that we saw the quoted null so we can add one back at
6995 the end of this function if there are no other characters
6996 in the string, discard TEMP, and go on. The exception to
6997 this is when we have "${@}" and $1 is '', since $@ needs
6998 special handling. */
6999 if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
7001 if (had_quoted_null_p)
7002 *had_quoted_null_p = 1;
7003 if (*quoted_dollar_at_p == 0)
7006 tdesc->word = temp = (char *)NULL;
7014 /* Do command or arithmetic substitution. */
7016 /* We have to extract the contents of this paren substitution. */
7017 t_index = zindex + 1;
7018 temp = extract_command_subst (string, &t_index, 0);
7021 /* For Posix.2-style `$(( ))' arithmetic substitution,
7022 extract the expression and pass it to the evaluator. */
7023 if (temp && *temp == LPAREN)
7027 temp2 = savestring (temp1);
7028 t_index = strlen (temp2) - 1;
7030 if (temp2[t_index] != RPAREN)
7036 /* Cut off ending `)' */
7037 temp2[t_index] = '\0';
7039 if (chk_arithsub (temp2, t_index) == 0)
7045 /* Expand variables found inside the expression. */
7046 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
7050 /* No error messages. */
7051 this_command_name = (char *)NULL;
7052 number = evalexp (temp1, &expok);
7057 if (interactive_shell == 0 && posixly_correct)
7059 last_command_exit_value = EXECUTION_FAILURE;
7060 return (&expand_wdesc_fatal);
7063 return (&expand_wdesc_error);
7065 temp = itos (number);
7070 if (pflags & PF_NOCOMSUB)
7071 /* we need zindex+1 because string[zindex] == RPAREN */
7072 temp1 = substring (string, *sindex, zindex+1);
7075 tdesc = command_substitute (temp, quoted);
7076 temp1 = tdesc ? tdesc->word : (char *)NULL;
7078 dispose_word_desc (tdesc);
7084 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7085 away in a future bash release. */
7087 /* Extract the contents of this arithmetic substitution. */
7088 t_index = zindex + 1;
7089 temp = extract_arithmetic_subst (string, &t_index);
7093 temp = savestring (string);
7094 if (expanded_something)
7095 *expanded_something = 0;
7099 /* Do initial variable expansion. */
7100 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
7105 /* Find the variable in VARIABLE_LIST. */
7106 temp = (char *)NULL;
7108 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
7110 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
7112 /* If this isn't a variable name, then just output the `$'. */
7113 if (temp1 == 0 || *temp1 == '\0')
7116 temp = (char *)xmalloc (2);
7119 if (expanded_something)
7120 *expanded_something = 0;
7124 /* If the variable exists, return its value cell. */
7125 var = find_variable (temp1);
7127 if (var && invisible_p (var) == 0 && var_isset (var))
7129 #if defined (ARRAY_VARS)
7130 if (assoc_p (var) || array_p (var))
7132 temp = array_p (var) ? array_reference (array_cell (var), 0)
7133 : assoc_reference (assoc_cell (var), "0");
7135 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7136 ? quote_string (temp)
7137 : quote_escapes (temp);
7138 else if (unbound_vars_is_error)
7139 goto unbound_variable;
7144 temp = value_cell (var);
7146 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
7147 ? quote_string (temp)
7148 : quote_escapes (temp);
7156 temp = (char *)NULL;
7159 if (unbound_vars_is_error)
7160 err_unboundvar (temp1);
7168 last_command_exit_value = EXECUTION_FAILURE;
7169 return ((unbound_vars_is_error && interactive_shell == 0)
7170 ? &expand_wdesc_fatal
7171 : &expand_wdesc_error);
7182 ret = alloc_word_desc ();
7183 ret->flags = tflag; /* XXX */
7189 /* Make a word list which is the result of parameter and variable
7190 expansion, command substitution, arithmetic substitution, and
7191 quote removal of WORD. Return a pointer to a WORD_LIST which is
7192 the result of the expansion. If WORD contains a null word, the
7193 word list returned is also null.
7195 QUOTED contains flag values defined in shell.h.
7197 ISEXP is used to tell expand_word_internal that the word should be
7198 treated as the result of an expansion. This has implications for
7199 how IFS characters in the word are treated.
7201 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7202 they point to an integer value which receives information about expansion.
7203 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7204 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7207 This only does word splitting in the case of $@ expansion. In that
7208 case, we split on ' '. */
7210 /* Values for the local variable quoted_state. */
7212 #define PARTIALLY_QUOTED 1
7213 #define WHOLLY_QUOTED 2
7216 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
7219 int *contains_dollar_at;
7220 int *expanded_something;
7225 /* The intermediate string that we build while expanding. */
7228 /* The current size of the above object. */
7231 /* Index into ISTRING. */
7234 /* Temporary string storage. */
7237 /* The text of WORD. */
7238 register char *string;
7240 /* The size of STRING. */
7243 /* The index into STRING. */
7246 /* This gets 1 if we see a $@ while quoted. */
7247 int quoted_dollar_at;
7249 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7250 whether WORD contains no quoting characters, a partially quoted
7251 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7255 int had_quoted_null;
7259 int assignoff; /* If assignment, offset of `=' */
7261 register unsigned char c; /* Current character. */
7262 int t_index; /* For calls to string_extract_xxx. */
7268 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
7269 istring[istring_index = 0] = '\0';
7270 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
7271 quoted_state = UNQUOTED;
7273 string = word->word;
7275 goto finished_with_string;
7276 /* Don't need the string length for the SADD... and COPY_ macros unless
7277 multibyte characters are possible. */
7278 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
7280 if (contains_dollar_at)
7281 *contains_dollar_at = 0;
7285 /* Begin the expansion. */
7291 /* Case on toplevel character. */
7295 goto finished_with_string;
7299 #if HANDLE_MULTIBYTE
7300 if (MB_CUR_MAX > 1 && string[sindex])
7302 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
7307 temp = (char *)xmalloc (3);
7309 temp[1] = c = string[sindex];
7320 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
7326 #if defined (PROCESS_SUBSTITUTION)
7327 /* Process substitution. */
7331 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
7333 sindex--; /* add_character: label increments sindex */
7337 t_index = sindex + 1; /* skip past both '<' and LPAREN */
7339 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
7342 /* If the process substitution specification is `<()', we want to
7343 open the pipe for writing in the child and produce output; if
7344 it is `>()', we want to open the pipe for reading in the child
7345 and consume input. */
7346 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
7350 goto dollar_add_string;
7352 #endif /* PROCESS_SUBSTITUTION */
7355 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7356 which are not assignment statements are not expanded. If the
7357 shell isn't in posix mode, though, we perform tilde expansion
7358 on `likely candidate' unquoted assignment statements (flags
7359 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7360 contains an unquoted :~ or =~. Something to think about: we
7361 now have a flag that says to perform tilde expansion on arguments
7362 to `assignment builtins' like declare and export that look like
7363 assignment statements. We now do tilde expansion on such words
7364 even in POSIX mode. */
7365 if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
7367 if (isexp == 0 && isifs (c))
7368 goto add_ifs_character;
7372 /* If we're not in posix mode or forcing assignment-statement tilde
7373 expansion, note where the `=' appears in the word and prepare to
7374 do tilde expansion following the first `='. */
7375 if ((word->flags & W_ASSIGNMENT) &&
7376 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
7377 assignoff == -1 && sindex > 0)
7379 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */
7380 word->flags |= W_ITILDE;
7382 else if ((word->flags & W_ASSIGNMENT) &&
7383 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
7384 string[sindex+1] == '~')
7385 word->flags |= W_ITILDE;
7387 if (isexp == 0 && isifs (c))
7388 goto add_ifs_character;
7393 if (word->flags & W_NOTILDE)
7395 if (isexp == 0 && isifs (c))
7396 goto add_ifs_character;
7401 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
7402 string[sindex+1] == '~')
7403 word->flags |= W_ITILDE;
7405 if (isexp == 0 && isifs (c))
7406 goto add_ifs_character;
7411 /* If the word isn't supposed to be tilde expanded, or we're not
7412 at the start of a word or after an unquoted : or = in an
7413 assignment statement, we don't do tilde expansion. */
7414 if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
7415 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
7416 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7418 word->flags &= ~W_ITILDE;
7419 if (isexp == 0 && isifs (c) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
7420 goto add_ifs_character;
7425 if (word->flags & W_ASSIGNRHS)
7427 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
7432 temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
7434 word->flags &= ~W_ITILDE;
7436 if (temp && *temp && t_index > 0)
7438 temp1 = bash_tilde_expand (temp, tflag);
7439 if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
7443 goto add_character; /* tilde expansion failed */
7448 goto add_quoted_string; /* XXX was add_string */
7457 if (expanded_something)
7458 *expanded_something = 1;
7461 tword = param_expand (string, &sindex, quoted, expanded_something,
7462 &has_dollar_at, "ed_dollar_at,
7464 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
7466 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
7470 return ((tword == &expand_wdesc_error) ? &expand_word_error
7471 : &expand_word_fatal);
7473 if (contains_dollar_at && has_dollar_at)
7474 *contains_dollar_at = 1;
7476 if (tword && (tword->flags & W_HASQUOTEDNULL))
7477 had_quoted_null = 1;
7480 dispose_word_desc (tword);
7485 case '`': /* Backquoted command substitution. */
7489 temp = string_extract (string, &sindex, "`", SX_REQMATCH);
7490 /* The test of sindex against t_index is to allow bare instances of
7491 ` to pass through, for backwards compatibility. */
7492 if (temp == &extract_string_error || temp == &extract_string_fatal)
7494 if (sindex - 1 == t_index)
7499 report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
7502 return ((temp == &extract_string_error) ? &expand_word_error
7503 : &expand_word_fatal);
7506 if (expanded_something)
7507 *expanded_something = 1;
7509 if (word->flags & W_NOCOMSUB)
7510 /* sindex + 1 because string[sindex] == '`' */
7511 temp1 = substring (string, t_index, sindex + 1);
7514 de_backslash (temp);
7515 tword = command_substitute (temp, quoted);
7516 temp1 = tword ? tword->word : (char *)NULL;
7518 dispose_word_desc (tword);
7522 goto dollar_add_string;
7526 if (string[sindex + 1] == '\n')
7532 c = string[++sindex];
7534 if (quoted & Q_HERE_DOCUMENT)
7536 else if (quoted & Q_DOUBLE_QUOTES)
7541 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
7543 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
7548 sindex--; /* add_character: label increments sindex */
7553 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
7558 /* BEFORE jumping here, we need to increment sindex if appropriate */
7559 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
7560 DEFAULT_ARRAY_SIZE);
7561 istring[istring_index++] = twochars[0];
7562 istring[istring_index++] = twochars[1];
7563 istring[istring_index] = '\0';
7569 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7571 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7576 temp = string_extract_double_quoted (string, &sindex, 0);
7578 /* If the quotes surrounded the entire string, then the
7579 whole word was quoted. */
7580 quoted_state = (t_index == 1 && string[sindex] == '\0')
7586 tword = alloc_word_desc ();
7589 temp = (char *)NULL;
7592 /* Need to get W_HASQUOTEDNULL flag through this function. */
7593 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
7595 if (list == &expand_word_error || list == &expand_word_fatal)
7599 /* expand_word_internal has already freed temp_word->word
7600 for us because of the way it prints error messages. */
7601 tword->word = (char *)NULL;
7602 dispose_word (tword);
7606 dispose_word (tword);
7608 /* "$@" (a double-quoted dollar-at) expands into nothing,
7609 not even a NULL word, when there are no positional
7611 if (list == 0 && has_dollar_at)
7617 /* If we get "$@", we know we have expanded something, so we
7618 need to remember it for the final split on $IFS. This is
7619 a special case; it's the only case where a quoted string
7620 can expand into more than one word. It's going to come back
7621 from the above call to expand_word_internal as a list with
7622 a single word, in which all characters are quoted and
7623 separated by blanks. What we want to do is to turn it back
7624 into a list for the next piece of code. */
7626 dequote_list (list);
7628 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
7629 had_quoted_null = 1;
7634 if (contains_dollar_at)
7635 *contains_dollar_at = 1;
7636 if (expanded_something)
7637 *expanded_something = 1;
7642 /* What we have is "". This is a minor optimization. */
7644 list = (WORD_LIST *)NULL;
7647 /* The code above *might* return a list (consider the case of "$@",
7648 where it returns "$1", "$2", etc.). We can't throw away the
7649 rest of the list, and we have to make sure each word gets added
7650 as quoted. We test on tresult->next: if it is non-NULL, we
7651 quote the whole list, save it to a string with string_list, and
7652 add that string. We don't need to quote the results of this
7653 (and it would be wrong, since that would quote the separators
7654 as well), so we go directly to add_string. */
7659 /* Testing quoted_dollar_at makes sure that "$@" is
7660 split correctly when $IFS does not contain a space. */
7661 temp = quoted_dollar_at
7662 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
7663 : string_list (quote_list (list));
7664 dispose_words (list);
7669 temp = savestring (list->word->word);
7670 tflag = list->word->flags;
7671 dispose_words (list);
7673 /* If the string is not a quoted null string, we want
7674 to remove any embedded unquoted CTLNUL characters.
7675 We do not want to turn quoted null strings back into
7676 the empty string, though. We do this because we
7677 want to remove any quoted nulls from expansions that
7678 contain other characters. For example, if we have
7679 x"$*"y or "x$*y" and there are no positional parameters,
7680 the $* should expand into nothing. */
7681 /* We use the W_HASQUOTEDNULL flag to differentiate the
7682 cases: a quoted null character as above and when
7683 CTLNUL is contained in the (non-null) expansion
7684 of some variable. We use the had_quoted_null flag to
7685 pass the value through this function to its caller. */
7686 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
7687 remove_quoted_nulls (temp); /* XXX */
7691 temp = (char *)NULL;
7693 /* We do not want to add quoted nulls to strings that are only
7694 partially quoted; we can throw them away. */
7695 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
7703 temp = quote_string (temp);
7711 sindex--; /* add_character: label increments sindex */
7719 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7721 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7726 temp = string_extract_single_quoted (string, &sindex);
7728 /* If the entire STRING was surrounded by single quotes,
7729 then the string is wholly quoted. */
7730 quoted_state = (t_index == 1 && string[sindex] == '\0')
7734 /* If all we had was '', it is a null expansion. */
7738 temp = (char *)NULL;
7741 remove_quoted_escapes (temp); /* ??? */
7743 /* We do not want to add quoted nulls to strings that are only
7744 partially quoted; such nulls are discarded. */
7745 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
7748 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7752 sindex--; /* add_character: label increments sindex */
7756 goto add_quoted_string;
7761 /* This is the fix for " $@ " */
7763 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
7765 if (string[sindex]) /* from old goto dollar_add_string */
7774 #if HANDLE_MULTIBYTE
7780 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
7785 twochars[0] = CTLESC;
7792 SADD_MBCHAR (temp, string, sindex, string_size);
7795 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
7796 DEFAULT_ARRAY_SIZE);
7797 istring[istring_index++] = c;
7798 istring[istring_index] = '\0';
7800 /* Next character. */
7805 finished_with_string:
7806 /* OK, we're ready to return. If we have a quoted string, and
7807 quoted_dollar_at is not set, we do no splitting at all; otherwise
7808 we split on ' '. The routines that call this will handle what to
7809 do if nothing has been expanded. */
7811 /* Partially and wholly quoted strings which expand to the empty
7812 string are retained as an empty arguments. Unquoted strings
7813 which expand to the empty string are discarded. The single
7814 exception is the case of expanding "$@" when there are no
7815 positional parameters. In that case, we discard the expansion. */
7817 /* Because of how the code that handles "" and '' in partially
7818 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7819 if we saw quoting characters, but the expansion was empty.
7820 "" and '' are tossed away before we get to this point when
7821 processing partially quoted strings. This makes "" and $xxx""
7822 equivalent when xxx is unset. We also look to see whether we
7823 saw a quoted null from a ${} expansion and add one back if we
7826 /* If we expand to nothing and there were no single or double quotes
7827 in the word, we throw it away. Otherwise, we return a NULL word.
7828 The single exception is for $@ surrounded by double quotes when
7829 there are no positional parameters. In that case, we also throw
7832 if (*istring == '\0')
7834 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
7836 istring[0] = CTLNUL;
7838 tword = make_bare_word (istring);
7839 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7840 list = make_word_list (tword, (WORD_LIST *)NULL);
7841 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7842 tword->flags |= W_QUOTED;
7844 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7845 and a double-quoted "$@" appears anywhere in it, then the entire
7847 else if (quoted_state == UNQUOTED || quoted_dollar_at)
7848 list = (WORD_LIST *)NULL;
7852 tword = make_bare_word (istring);
7853 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7854 tword->flags |= W_QUOTED;
7855 list = make_word_list (tword, (WORD_LIST *)NULL);
7859 list = (WORD_LIST *)NULL;
7862 else if (word->flags & W_NOSPLIT)
7864 tword = make_bare_word (istring);
7865 if (word->flags & W_ASSIGNMENT)
7866 tword->flags |= W_ASSIGNMENT; /* XXX */
7867 if (word->flags & W_COMPASSIGN)
7868 tword->flags |= W_COMPASSIGN; /* XXX */
7869 if (word->flags & W_NOGLOB)
7870 tword->flags |= W_NOGLOB; /* XXX */
7871 if (word->flags & W_NOEXPAND)
7872 tword->flags |= W_NOEXPAND; /* XXX */
7873 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7874 tword->flags |= W_QUOTED;
7875 if (had_quoted_null)
7876 tword->flags |= W_HASQUOTEDNULL;
7877 list = make_word_list (tword, (WORD_LIST *)NULL);
7883 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
7885 /* If we have $@, we need to split the results no matter what. If
7886 IFS is unset or NULL, string_list_dollar_at has separated the
7887 positional parameters with a space, so we split on space (we have
7888 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7889 string_list_dollar_at has separated the positional parameters
7890 with the first character of $IFS, so we split on $IFS. */
7891 if (has_dollar_at && ifs_chars)
7892 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
7895 tword = make_bare_word (istring);
7896 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
7897 tword->flags |= W_QUOTED;
7898 if (word->flags & W_ASSIGNMENT)
7899 tword->flags |= W_ASSIGNMENT;
7900 if (word->flags & W_COMPASSIGN)
7901 tword->flags |= W_COMPASSIGN;
7902 if (word->flags & W_NOGLOB)
7903 tword->flags |= W_NOGLOB;
7904 if (word->flags & W_NOEXPAND)
7905 tword->flags |= W_NOEXPAND;
7906 if (had_quoted_null)
7907 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7908 list = make_word_list (tword, (WORD_LIST *)NULL);
7916 /* **************************************************************** */
7918 /* Functions for Quote Removal */
7920 /* **************************************************************** */
7922 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7923 backslash quoting rules for within double quotes or a here document. */
7925 string_quote_removal (string, quoted)
7930 char *r, *result_string, *temp, *send;
7931 int sindex, tindex, dquote;
7935 /* The result can be no longer than the original string. */
7936 slen = strlen (string);
7937 send = string + slen;
7939 r = result_string = (char *)xmalloc (slen + 1);
7941 for (dquote = sindex = 0; c = string[sindex];)
7946 c = string[++sindex];
7952 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
7957 SCOPY_CHAR_M (r, string, send, sindex);
7961 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
7967 tindex = sindex + 1;
7968 temp = string_extract_single_quoted (string, &tindex);
7979 dquote = 1 - dquote;
7985 return (result_string);
7990 /* Perform quote removal on word WORD. This allocates and returns a new
7993 word_quote_removal (word, quoted)
8000 t = string_quote_removal (word->word, quoted);
8001 w = alloc_word_desc ();
8002 w->word = t ? t : savestring ("");
8006 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8007 the members of the list are treated as if they are surrounded by
8008 double quotes. Return a new list, or NULL if LIST is NULL. */
8010 word_list_quote_removal (list, quoted)
8014 WORD_LIST *result, *t, *tresult, *e;
8016 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8018 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
8020 result = (WORD_LIST *) list_append (result, tresult);
8023 result = e = tresult;
8036 /*******************************************
8038 * Functions to perform word splitting *
8040 *******************************************/
8050 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
8052 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8053 handle multibyte chars in IFS */
8054 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
8055 for (t = ifs_value ; t && *t; t++)
8061 #if defined (HANDLE_MULTIBYTE)
8064 ifs_firstc[0] = '\0';
8070 ifs_len = strnlen (ifs_value, MB_CUR_MAX);
8071 ifs_firstc_len = MBLEN (ifs_value, ifs_len);
8072 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
8074 ifs_firstc[0] = ifs_value[0];
8075 ifs_firstc[1] = '\0';
8079 memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
8082 ifs_firstc = ifs_value ? *ifs_value : 0;
8092 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8093 is not quoted. list_string () performs quote removal for us, even if we
8094 don't do any splitting. */
8096 word_split (w, ifs_chars)
8106 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
8107 result = list_string (w->word, xifs, w->flags & W_QUOTED);
8110 result = (WORD_LIST *)NULL;
8115 /* Perform word splitting on LIST and return the RESULT. It is possible
8116 to return (WORD_LIST *)NULL. */
8118 word_list_split (list)
8121 WORD_LIST *result, *t, *tresult, *e;
8123 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
8125 tresult = word_split (t->word, ifs_value);
8127 result = e = tresult;
8138 /**************************************************
8140 * Functions to expand an entire WORD_LIST *
8142 **************************************************/
8144 /* Do any word-expansion-specific cleanup and jump to top_level */
8146 exp_jump_to_top_level (v)
8149 set_pipestatus_from_exit (last_command_exit_value);
8151 /* Cleanup code goes here. */
8152 expand_no_split_dollar_star = 0; /* XXX */
8153 expanding_redir = 0;
8154 assigning_in_environment = 0;
8156 if (parse_and_execute_level == 0)
8157 top_level_cleanup (); /* from sig.c */
8159 jump_to_top_level (v);
8162 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8163 ELIST, and set ELIST to the new list. */
8164 #define PREPEND_LIST(nlist, elist) \
8165 do { nlist->next = elist; elist = nlist; } while (0)
8167 /* Separate out any initial variable assignments from TLIST. If set -k has
8168 been executed, remove all assignment statements from TLIST. Initial
8169 variable assignments and other environment assignments are placed
8170 on SUBST_ASSIGN_VARLIST. */
8172 separate_out_assignments (tlist)
8175 register WORD_LIST *vp, *lp;
8178 return ((WORD_LIST *)NULL);
8180 if (subst_assign_varlist)
8181 dispose_words (subst_assign_varlist); /* Clean up after previous error */
8183 subst_assign_varlist = (WORD_LIST *)NULL;
8186 /* Separate out variable assignments at the start of the command.
8187 Loop invariant: vp->next == lp
8189 lp = list of words left after assignment statements skipped
8190 tlist = original list of words
8192 while (lp && (lp->word->flags & W_ASSIGNMENT))
8198 /* If lp != tlist, we have some initial assignment statements.
8199 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8200 words and TLIST point to the remaining words. */
8203 subst_assign_varlist = tlist;
8204 /* ASSERT(vp->next == lp); */
8205 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
8206 tlist = lp; /* remainder of word list */
8209 /* vp == end of variable list */
8210 /* tlist == remainder of original word list without variable assignments */
8212 /* All the words in tlist were assignment statements */
8213 return ((WORD_LIST *)NULL);
8215 /* ASSERT(tlist != NULL); */
8216 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8218 /* If the -k option is in effect, we need to go through the remaining
8219 words, separate out the assignment words, and place them on
8220 SUBST_ASSIGN_VARLIST. */
8221 if (place_keywords_in_env)
8223 WORD_LIST *tp; /* tp == running pointer into tlist */
8228 /* Loop Invariant: tp->next == lp */
8229 /* Loop postcondition: tlist == word list without assignment statements */
8232 if (lp->word->flags & W_ASSIGNMENT)
8234 /* Found an assignment statement, add this word to end of
8235 subst_assign_varlist (vp). */
8236 if (!subst_assign_varlist)
8237 subst_assign_varlist = vp = lp;
8244 /* Remove the word pointed to by LP from TLIST. */
8245 tp->next = lp->next;
8246 /* ASSERT(vp == lp); */
8247 lp->next = (WORD_LIST *)NULL;
8260 #define WEXP_VARASSIGN 0x001
8261 #define WEXP_BRACEEXP 0x002
8262 #define WEXP_TILDEEXP 0x004
8263 #define WEXP_PARAMEXP 0x008
8264 #define WEXP_PATHEXP 0x010
8266 /* All of the expansions, including variable assignments at the start of
8268 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8270 /* All of the expansions except variable assignments at the start of
8272 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8274 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8275 expansion, command substitution, arithmetic expansion, word splitting, and
8277 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8279 /* Take the list of words in LIST and do the various substitutions. Return
8280 a new list of words which is the expanded list, and without things like
8281 variable assignments. */
8287 return (expand_word_list_internal (list, WEXP_ALL));
8290 /* Same as expand_words (), but doesn't hack variable or environment
8293 expand_words_no_vars (list)
8296 return (expand_word_list_internal (list, WEXP_NOVARS));
8300 expand_words_shellexp (list)
8303 return (expand_word_list_internal (list, WEXP_SHELLEXP));
8307 glob_expand_word_list (tlist, eflags)
8311 char **glob_array, *temp_string;
8312 register int glob_index;
8313 WORD_LIST *glob_list, *output_list, *disposables, *next;
8316 output_list = disposables = (WORD_LIST *)NULL;
8317 glob_array = (char **)NULL;
8320 /* For each word, either globbing is attempted or the word is
8321 added to orig_list. If globbing succeeds, the results are
8322 added to orig_list and the word (tlist) is added to the list
8323 of disposable words. If globbing fails and failed glob
8324 expansions are left unchanged (the shell default), the
8325 original word is added to orig_list. If globbing fails and
8326 failed glob expansions are removed, the original word is
8327 added to the list of disposable words. orig_list ends up
8328 in reverse order and requires a call to REVERSE_LIST to
8329 be set right. After all words are examined, the disposable
8333 /* If the word isn't an assignment and contains an unquoted
8334 pattern matching character, then glob it. */
8335 if ((tlist->word->flags & W_NOGLOB) == 0 &&
8336 unquoted_glob_pattern_p (tlist->word->word))
8338 glob_array = shell_glob_filename (tlist->word->word);
8340 /* Handle error cases.
8341 I don't think we should report errors like "No such file
8342 or directory". However, I would like to report errors
8343 like "Read failed". */
8345 if (glob_array == 0 || GLOB_FAILED (glob_array))
8347 glob_array = (char **)xmalloc (sizeof (char *));
8348 glob_array[0] = (char *)NULL;
8351 /* Dequote the current word in case we have to use it. */
8352 if (glob_array[0] == NULL)
8354 temp_string = dequote_string (tlist->word->word);
8355 free (tlist->word->word);
8356 tlist->word->word = temp_string;
8359 /* Make the array into a word list. */
8360 glob_list = (WORD_LIST *)NULL;
8361 for (glob_index = 0; glob_array[glob_index]; glob_index++)
8363 tword = make_bare_word (glob_array[glob_index]);
8364 tword->flags |= W_GLOBEXP; /* XXX */
8365 glob_list = make_word_list (tword, glob_list);
8370 output_list = (WORD_LIST *)list_append (glob_list, output_list);
8371 PREPEND_LIST (tlist, disposables);
8373 else if (fail_glob_expansion != 0)
8375 report_error (_("no match: %s"), tlist->word->word);
8376 exp_jump_to_top_level (DISCARD);
8378 else if (allow_null_glob_expansion == 0)
8380 /* Failed glob expressions are left unchanged. */
8381 PREPEND_LIST (tlist, output_list);
8385 /* Failed glob expressions are removed. */
8386 PREPEND_LIST (tlist, disposables);
8391 /* Dequote the string. */
8392 temp_string = dequote_string (tlist->word->word);
8393 free (tlist->word->word);
8394 tlist->word->word = temp_string;
8395 PREPEND_LIST (tlist, output_list);
8398 strvec_dispose (glob_array);
8399 glob_array = (char **)NULL;
8405 dispose_words (disposables);
8408 output_list = REVERSE_LIST (output_list, WORD_LIST *);
8410 return (output_list);
8413 #if defined (BRACE_EXPANSION)
8415 brace_expand_word_list (tlist, eflags)
8419 register char **expansions;
8421 WORD_LIST *disposables, *output_list, *next;
8425 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
8429 /* Only do brace expansion if the word has a brace character. If
8430 not, just add the word list element to BRACES and continue. In
8431 the common case, at least when running shell scripts, this will
8432 degenerate to a bunch of calls to `xstrchr', and then what is
8433 basically a reversal of TLIST into BRACES, which is corrected
8434 by a call to REVERSE_LIST () on BRACES when the end of TLIST
8436 if (xstrchr (tlist->word->word, LBRACE))
8438 expansions = brace_expand (tlist->word->word);
8440 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
8442 w = make_word (temp_string);
8443 /* If brace expansion didn't change the word, preserve
8444 the flags. We may want to preserve the flags
8445 unconditionally someday -- XXX */
8446 if (STREQ (temp_string, tlist->word->word))
8447 w->flags = tlist->word->flags;
8448 output_list = make_word_list (w, output_list);
8449 free (expansions[eindex]);
8453 /* Add TLIST to the list of words to be freed after brace
8454 expansion has been performed. */
8455 PREPEND_LIST (tlist, disposables);
8458 PREPEND_LIST (tlist, output_list);
8462 dispose_words (disposables);
8465 output_list = REVERSE_LIST (output_list, WORD_LIST *);
8467 return (output_list);
8471 #if defined (ARRAY_VARS)
8472 /* Take WORD, a compound associative array assignment, and internally run
8473 'declare -A w', where W is the variable name portion of WORD. */
8475 make_internal_declare (word, option)
8483 w = make_word (word);
8485 t = assignment (w->word, 0);
8488 wl = make_word_list (w, (WORD_LIST *)NULL);
8489 wl = make_word_list (make_word (option), wl);
8491 return (declare_builtin (wl));
8496 shell_expand_word_list (tlist, eflags)
8500 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
8501 int expanded_something, has_dollar_at;
8504 /* We do tilde expansion all the time. This is what 1003.2 says. */
8505 new_list = (WORD_LIST *)NULL;
8506 for (orig_list = tlist; tlist; tlist = next)
8508 temp_string = tlist->word->word;
8512 #if defined (ARRAY_VARS)
8513 /* If this is a compound array assignment to a builtin that accepts
8514 such assignments (e.g., `declare'), take the assignment and perform
8515 it separately, handling the semantics of declarations inside shell
8516 functions. This avoids the double-evaluation of such arguments,
8517 because `declare' does some evaluation of compound assignments on
8519 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
8523 if (tlist->word->flags & W_ASSIGNASSOC)
8524 make_internal_declare (tlist->word->word, "-A");
8526 t = do_word_assignment (tlist->word);
8529 last_command_exit_value = EXECUTION_FAILURE;
8530 exp_jump_to_top_level (DISCARD);
8533 /* Now transform the word as ksh93 appears to do and go on */
8534 t = assignment (tlist->word->word, 0);
8535 tlist->word->word[t] = '\0';
8536 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG|W_ASSIGNASSOC);
8540 expanded_something = 0;
8541 expanded = expand_word_internal
8542 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
8544 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
8546 /* By convention, each time this error is returned,
8547 tlist->word->word has already been freed. */
8548 tlist->word->word = (char *)NULL;
8550 /* Dispose our copy of the original list. */
8551 dispose_words (orig_list);
8552 /* Dispose the new list we're building. */
8553 dispose_words (new_list);
8555 last_command_exit_value = EXECUTION_FAILURE;
8556 if (expanded == &expand_word_error)
8557 exp_jump_to_top_level (DISCARD);
8559 exp_jump_to_top_level (FORCE_EOF);
8562 /* Don't split words marked W_NOSPLIT. */
8563 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
8565 temp_list = word_list_split (expanded);
8566 dispose_words (expanded);
8570 /* If no parameter expansion, command substitution, process
8571 substitution, or arithmetic substitution took place, then
8572 do not do word splitting. We still have to remove quoted
8573 null characters from the result. */
8574 word_list_remove_quoted_nulls (expanded);
8575 temp_list = expanded;
8578 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
8579 new_list = (WORD_LIST *)list_append (expanded, new_list);
8583 dispose_words (orig_list);
8586 new_list = REVERSE_LIST (new_list, WORD_LIST *);
8591 /* The workhorse for expand_words () and expand_words_no_vars ().
8592 First arg is LIST, a WORD_LIST of words.
8593 Second arg EFLAGS is a flags word controlling which expansions are
8596 This does all of the substitutions: brace expansion, tilde expansion,
8597 parameter expansion, command substitution, arithmetic expansion,
8598 process substitution, word splitting, and pathname expansion, according
8599 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8600 set, or for which no expansion is done, do not undergo word splitting.
8601 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8603 expand_word_list_internal (list, eflags)
8607 WORD_LIST *new_list, *temp_list;
8611 return ((WORD_LIST *)NULL);
8613 garglist = new_list = copy_word_list (list);
8614 if (eflags & WEXP_VARASSIGN)
8616 garglist = new_list = separate_out_assignments (new_list);
8619 if (subst_assign_varlist)
8621 /* All the words were variable assignments, so they are placed
8622 into the shell's environment. */
8623 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8625 this_command_name = (char *)NULL; /* no arithmetic errors */
8626 tint = do_word_assignment (temp_list->word);
8627 /* Variable assignment errors in non-interactive shells
8628 running in Posix.2 mode cause the shell to exit. */
8631 last_command_exit_value = EXECUTION_FAILURE;
8632 if (interactive_shell == 0 && posixly_correct)
8633 exp_jump_to_top_level (FORCE_EOF);
8635 exp_jump_to_top_level (DISCARD);
8638 dispose_words (subst_assign_varlist);
8639 subst_assign_varlist = (WORD_LIST *)NULL;
8641 return ((WORD_LIST *)NULL);
8645 /* Begin expanding the words that remain. The expansions take place on
8646 things that aren't really variable assignments. */
8648 #if defined (BRACE_EXPANSION)
8649 /* Do brace expansion on this word if there are any brace characters
8651 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
8652 new_list = brace_expand_word_list (new_list, eflags);
8653 #endif /* BRACE_EXPANSION */
8655 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8656 variable substitution, command substitution, arithmetic expansion,
8657 and word splitting. */
8658 new_list = shell_expand_word_list (new_list, eflags);
8660 /* Okay, we're almost done. Now let's just do some filename
8664 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
8665 /* Glob expand the word list unless globbing has been disabled. */
8666 new_list = glob_expand_word_list (new_list, eflags);
8668 /* Dequote the words, because we're not performing globbing. */
8669 new_list = dequote_list (new_list);
8672 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
8674 sh_wassign_func_t *assign_func;
8676 /* If the remainder of the words expand to nothing, Posix.2 requires
8677 that the variable and environment assignments affect the shell's
8679 assign_func = new_list ? assign_in_env : do_word_assignment;
8680 tempenv_assign_error = 0;
8682 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8684 this_command_name = (char *)NULL;
8685 assigning_in_environment = (assign_func == assign_in_env);
8686 tint = (*assign_func) (temp_list->word);
8687 assigning_in_environment = 0;
8688 /* Variable assignment errors in non-interactive shells running
8689 in Posix.2 mode cause the shell to exit. */
8692 if (assign_func == do_word_assignment)
8694 last_command_exit_value = EXECUTION_FAILURE;
8695 if (interactive_shell == 0 && posixly_correct)
8696 exp_jump_to_top_level (FORCE_EOF);
8698 exp_jump_to_top_level (DISCARD);
8701 tempenv_assign_error++;
8705 dispose_words (subst_assign_varlist);
8706 subst_assign_varlist = (WORD_LIST *)NULL;
8710 tint = list_length (new_list) + 1;
8711 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
8712 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
8713 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
8714 glob_argv_flags[tint] = '\0';