1 /* subst.c -- The part of the shell that does parameter, command, and
2 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-2004 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 it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License along
22 with Bash; see the file COPYING. If not, write to the Free Software
23 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
27 #include "bashtypes.h"
29 #include "chartypes.h"
34 #if defined (HAVE_UNISTD_H)
39 #include "posixstat.h"
45 #include "execute_cmd.h"
49 #include "mailcheck.h"
53 #include "builtins/getopt.h"
54 #include "builtins/common.h"
56 #include <tilde/tilde.h>
57 #include <glob/strmatch.h>
63 /* The size that strings change by. */
64 #define DEFAULT_INITIAL_ARRAY_SIZE 112
65 #define DEFAULT_ARRAY_SIZE 128
71 #define VT_ARRAYMEMBER 3
73 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
75 /* Flags for quoted_strchr */
76 #define ST_BACKSL 0x01
77 #define ST_CTLESC 0x02
78 #define ST_SQUOTE 0x04 /* unused yet */
79 #define ST_DQUOTE 0x08 /* unused yet */
81 /* Flags for the string extraction functions. */
82 #define EX_NOALLOC 0x01 /* just skip; don't return substring */
83 #define EX_VARNAME 0x02 /* variable name; for string_extract () */
85 /* Flags for the `pflags' argument to param_expand() */
86 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
88 /* These defs make it easier to use the editor. */
94 /* Evaluates to 1 if C is one of the shell's special parameters whose length
95 can be taken, but is also one of the special expansion characters. */
96 #define VALID_SPECIAL_LENGTH_PARAM(c) \
97 ((c) == '-' || (c) == '?' || (c) == '#')
99 /* Evaluates to 1 if C is one of the shell's special parameters for which an
100 indirect variable reference may be made. */
101 #define VALID_INDIR_PARAM(c) \
102 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
104 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
105 in ${parameter[:]OPword}. */
106 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
108 /* Evaluates to 1 if this is one of the shell's special variables. */
109 #define SPECIAL_VAR(name, wi) \
110 ((DIGIT (*name) && all_digits (name)) || \
111 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
112 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
114 /* An expansion function that takes a string and a quoted flag and returns
115 a WORD_LIST *. Used as the type of the third argument to
116 expand_string_if_necessary(). */
117 typedef WORD_LIST *EXPFUNC __P((char *, int));
119 /* Process ID of the last command executed within command substitution. */
120 pid_t last_command_subst_pid = NO_PID;
121 pid_t current_command_subst_pid = NO_PID;
123 /* Variables used to keep track of the characters in IFS. */
126 unsigned char ifs_cmap[UCHAR_MAX + 1];
127 unsigned char ifs_firstc;
129 /* Extern functions and variables from different files. */
130 extern int last_command_exit_value, last_command_exit_signal;
131 extern int subshell_environment;
132 extern int subshell_level;
133 extern int eof_encountered;
134 extern int return_catch_flag, return_catch_value;
135 extern pid_t dollar_dollar_pid;
136 extern int posixly_correct;
137 extern char *this_command_name;
138 extern struct fd_bitmap *current_fds_to_close;
139 extern int wordexp_only;
140 extern int expanding_redir;
141 extern int tempenv_assign_error;
143 /* Non-zero means to allow unmatched globbed filenames to expand to
145 int allow_null_glob_expansion;
147 /* Non-zero means to throw an error when globbing fails to match anything. */
148 int fail_glob_expansion;
151 /* Variables to keep track of which words in an expanded word list (the
152 output of expand_word_list_internal) are the result of globbing
153 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
154 (CURRENTLY UNUSED). */
155 char *glob_argv_flags;
156 static int glob_argv_flags_size;
159 static WORD_LIST expand_word_error, expand_word_fatal;
160 static char expand_param_error, expand_param_fatal;
162 /* Tell the expansion functions to not longjmp back to top_level on fatal
163 errors. Enabled when doing completion and prompt string expansion. */
164 static int no_longjmp_on_fatal_error = 0;
166 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
167 $* on $IFS, primarily when doing assignment statements. */
168 static int expand_no_split_dollar_star = 0;
170 /* Used to hold a list of variable assignments preceding a command. Global
171 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
173 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
175 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
176 without any leading variable assignments. */
177 static WORD_LIST *garglist = (WORD_LIST *)NULL;
179 static char *quoted_substring __P((char *, int, int));
180 static int quoted_strlen __P((char *));
181 static char *quoted_strchr __P((char *, int, int));
183 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
184 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
185 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
186 static WORD_LIST *expand_string_internal __P((char *, int));
187 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
188 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
190 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
191 static char *dequote_escapes __P((char *));
192 static char *make_quoted_char __P((int));
193 static WORD_LIST *quote_list __P((WORD_LIST *));
194 static WORD_LIST *dequote_list __P((WORD_LIST *));
195 static char *remove_quoted_escapes __P((char *));
196 static char *remove_quoted_nulls __P((char *));
198 static int unquoted_substring __P((char *, char *));
199 static int unquoted_member __P((int, char *));
201 static int do_assignment_internal __P((const char *, int));
203 static char *string_extract_verbatim __P((char *, int *, char *));
204 static char *string_extract __P((char *, int *, char *, int));
205 static char *string_extract_double_quoted __P((char *, int *, int));
206 static inline char *string_extract_single_quoted __P((char *, int *));
207 static inline int skip_single_quoted __P((char *, size_t, int));
208 static int skip_double_quoted __P((char *, size_t, int));
209 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
210 static char *extract_dollar_brace_string __P((char *, int *, int, int));
212 static char *pos_params __P((char *, int, int, int));
214 static unsigned char *mb_getcharlens __P((char *, int));
216 static char *remove_upattern __P((char *, char *, int));
217 #if defined (HANDLE_MULTIBYTE)
218 # if !defined (HAVE_WCSDUP)
219 static wchar_t *wcsdup __P((wchar_t *));
221 static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
223 static char *remove_pattern __P((char *, char *, int));
225 static int match_pattern_char __P((char *, char *));
226 static int match_upattern __P((char *, char *, int, char **, char **));
227 #if defined (HANDLE_MULTIBYTE)
228 static int match_pattern_wchar __P((wchar_t *, wchar_t *));
229 static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
231 static int match_pattern __P((char *, char *, int, char **, char **));
232 static int getpatspec __P((int, char *));
233 static char *getpattern __P((char *, int, int));
234 static char *variable_remove_pattern __P((char *, char *, int, int));
235 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
236 static char *parameter_list_remove_pattern __P((int, char *, int, int));
238 static char *array_remove_pattern __P((ARRAY *, char *, int, char *, int));
240 static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
242 static char *process_substitute __P((char *, int));
244 static char *read_comsub __P((int, int));
247 static arrayind_t array_length_reference __P((char *));
250 static int valid_brace_expansion_word __P((char *, int));
251 static int chk_atstar __P((char *, int, int *, int *));
253 static char *parameter_brace_expand_word __P((char *, int, int));
254 static char *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
255 static char *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
256 static void parameter_brace_expand_error __P((char *, char *));
258 static int valid_length_expression __P((char *));
259 static intmax_t parameter_brace_expand_length __P((char *));
261 static char *skiparith __P((char *, int));
262 static int verify_substring_values __P((char *, char *, int, intmax_t *, intmax_t *));
263 static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
264 static char *mb_substring __P((char *, int, int));
265 static char *parameter_brace_substring __P((char *, char *, char *, int));
267 static char *pos_params_pat_subst __P((char *, char *, char *, int));
269 static char *parameter_brace_patsub __P((char *, char *, char *, int));
271 static char *parameter_brace_expand __P((char *, int *, int, int *, int *));
272 static char *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
274 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
276 static WORD_LIST *word_list_split __P((WORD_LIST *));
278 static void exp_jump_to_top_level __P((int));
280 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
281 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
282 #ifdef BRACE_EXPANSION
283 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
285 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
286 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
288 /* **************************************************************** */
290 /* Utility Functions */
292 /* **************************************************************** */
294 #ifdef INCLUDE_UNUSED
296 quoted_substring (string, start, end)
301 register char *result, *s, *r;
305 /* Move to string[start], skipping quoted characters. */
306 for (s = string, l = 0; *s && l < start; )
318 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
320 /* Copy LEN characters, including quote characters. */
322 for (l = 0; l < len; s++)
336 #ifdef INCLUDE_UNUSED
337 /* Return the length of S, skipping over quoted characters */
361 /* Find the first occurrence of character C in string S, obeying shell
362 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
363 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
364 escaped with CTLESC are skipped. */
366 quoted_strchr (s, c, flags)
374 if (((flags & ST_BACKSL) && *p == '\\')
375 || ((flags & ST_CTLESC) && *p == CTLESC))
379 return ((char *)NULL);
385 return ((char *)NULL);
388 /* Return 1 if CHARACTER appears in an unquoted portion of
389 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
391 unquoted_member (character, string)
399 slen = strlen (string);
401 while (c = string[sindex])
409 ADVANCE_CHAR (string, slen, sindex);
415 ADVANCE_CHAR (string, slen, sindex);
419 sindex = skip_single_quoted (string, slen, ++sindex);
423 sindex = skip_double_quoted (string, slen, ++sindex);
430 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
432 unquoted_substring (substr, string)
433 char *substr, *string;
436 int sindex, c, sublen;
439 if (substr == 0 || *substr == '\0')
442 slen = strlen (string);
443 sublen = strlen (substr);
444 for (sindex = 0; c = string[sindex]; )
446 if (STREQN (string + sindex, substr, sublen))
455 ADVANCE_CHAR (string, slen, sindex);
459 sindex = skip_single_quoted (string, slen, ++sindex);
463 sindex = skip_double_quoted (string, slen, ++sindex);
467 ADVANCE_CHAR (string, slen, sindex);
474 /* Most of the substitutions must be done in parallel. In order
475 to avoid using tons of unclear goto's, I have some functions
476 for manipulating malloc'ed strings. They all take INDX, a
477 pointer to an integer which is the offset into the string
478 where manipulation is taking place. They also take SIZE, a
479 pointer to an integer which is the current length of the
480 character array for this string. */
482 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
483 of space allocated to TARGET. SOURCE can be NULL, in which
484 case nothing happens. Gets rid of SOURCE by freeing it.
485 Returns TARGET in case the location has changed. */
487 sub_append_string (source, target, indx, size)
488 char *source, *target;
495 srclen = STRLEN (source);
496 if (srclen >= (int)(*size - *indx))
499 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
500 target = (char *)xrealloc (target, (*size = n));
503 FASTCOPY (source, target + *indx, srclen);
505 target[*indx] = '\0';
514 /* Append the textual representation of NUMBER to TARGET.
515 INDX and SIZE are as in SUB_APPEND_STRING. */
517 sub_append_number (number, target, indx, size)
524 temp = itos (number);
525 return (sub_append_string (temp, target, indx, size));
529 /* Extract a substring from STRING, starting at SINDEX and ending with
530 one of the characters in CHARLIST. Don't make the ending character
531 part of the string. Leave SINDEX pointing at the ending character.
532 Understand about backslashes in the string. If (flags & EX_VARNAME)
533 is non-zero, and array variables have been compiled into the shell,
534 everything between a `[' and a corresponding `]' is skipped over.
535 If (flags & EX_NOALLOC) is non-zero, don't return the substring, just
538 string_extract (string, sindex, charlist, flags)
549 slen = strlen (string + *sindex) + *sindex;
551 while (c = string[i])
560 #if defined (ARRAY_VARS)
561 else if ((flags & EX_VARNAME) && c == '[')
564 /* If this is an array subscript, skip over it and continue. */
565 ni = skipsubscript (string, i);
566 if (string[ni] == ']')
570 else if (MEMBER (c, charlist))
573 ADVANCE_CHAR (string, slen, i);
576 temp = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
581 /* Extract the contents of STRING as if it is enclosed in double quotes.
582 SINDEX, when passed in, is the offset of the character immediately
583 following the opening double quote; on exit, SINDEX is left pointing after
584 the closing double quote. If STRIPDQ is non-zero, unquoted double
585 quotes are stripped and the string is terminated by a null byte.
586 Backslashes between the embedded double quotes are processed. If STRIPDQ
587 is zero, an unquoted `"' terminates the string. */
589 string_extract_double_quoted (string, sindex, stripdq)
591 int *sindex, stripdq;
597 char *temp, *ret; /* The new string we return. */
598 int pass_next, backquote, si; /* State variables for the machine. */
602 slen = strlen (string + *sindex) + *sindex;
603 send = string + slen;
605 pass_next = backquote = dquote = 0;
606 temp = (char *)xmalloc (1 + slen - *sindex);
610 while (c = string[i])
612 /* Process a character that was quoted by a backslash. */
617 ``The backslash shall retain its special meaning as an escape
618 character only when followed by one of the characters:
621 If STRIPDQ is zero, we handle the double quotes here and let
622 expand_word_internal handle the rest. If STRIPDQ is non-zero,
623 we have already been through one round of backslash stripping,
624 and want to strip these backslashes only if DQUOTE is non-zero,
625 indicating that we are inside an embedded double-quoted string. */
627 /* If we are in an embedded quoted string, then don't strip
628 backslashes before characters for which the backslash
629 retains its special meaning, but remove backslashes in
630 front of other characters. If we are not in an
631 embedded quoted string, don't strip backslashes at all.
632 This mess is necessary because the string was already
633 surrounded by double quotes (and sh has some really weird
635 The returned string will be run through expansion as if
636 it were double-quoted. */
637 if ((stripdq == 0 && c != '"') ||
638 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
643 COPY_CHAR_I (temp, j, string, send, i);
647 /* A backslash protects the next character. The code just above
648 handles preserving the backslash in front of any character but
657 /* Inside backquotes, ``the portion of the quoted string from the
658 initial backquote and the characters up to the next backquote
659 that is not preceded by a backslash, having escape characters
660 removed, defines that command''. */
678 /* Pass everything between `$(' and the matching `)' or a quoted
679 ${ ... } pair through according to the Posix.2 specification. */
680 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
685 if (string[i + 1] == LPAREN)
686 ret = extract_delimited_string (string, &si, "$(", "(", ")", 0); /*)*/
688 ret = extract_dollar_brace_string (string, &si, 1, 0);
691 temp[j++] = string[i + 1];
693 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
695 if (ret == 0 && no_longjmp_on_fatal_error)
698 ret = string + i + 2;
701 for (t = 0; ret[t]; t++, j++)
703 temp[j] = string[si];
718 /* Add any character but a double quote to the quoted string we're
721 goto add_one_character;
735 /* Point to after the closing quote. */
743 /* This should really be another option to string_extract_double_quoted. */
745 skip_double_quoted (string, slen, sind)
752 int pass_next, backquote, si;
755 pass_next = backquote = 0;
757 while (c = string[i])
762 ADVANCE_CHAR (string, slen, i);
775 ADVANCE_CHAR (string, slen, i);
784 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
787 if (string[i + 1] == LPAREN)
788 ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC);
790 ret = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
797 ADVANCE_CHAR (string, slen, i);
810 /* Extract the contents of STRING as if it is enclosed in single quotes.
811 SINDEX, when passed in, is the offset of the character immediately
812 following the opening single quote; on exit, SINDEX is left pointing after
813 the closing single quote. */
815 string_extract_single_quoted (string, sindex)
824 slen = strlen (string + *sindex) + *sindex;
826 while (string[i] && string[i] != '\'')
827 ADVANCE_CHAR (string, slen, i);
829 t = substring (string, *sindex, i);
839 skip_single_quoted (string, slen, sind)
848 while (string[c] && string[c] != '\'')
849 ADVANCE_CHAR (string, slen, c);
856 /* Just like string_extract, but doesn't hack backslashes or any of
857 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
859 string_extract_verbatim (string, sindex, charlist)
864 register int i = *sindex;
868 if (charlist[0] == '\'' && charlist[1] == '\0')
870 temp = string_extract_single_quoted (string, sindex);
871 --*sindex; /* leave *sindex at separator character */
875 for (i = *sindex; c = string[i]; i++)
883 if (MEMBER (c, charlist))
887 temp = substring (string, *sindex, i);
893 /* Extract the $( construct in STRING, and return a new string.
894 Start extracting at (SINDEX) as if we had just seen "$(".
895 Make (SINDEX) get the position of the matching ")". */
897 extract_command_subst (string, sindex)
901 return (extract_delimited_string (string, sindex, "$(", "(", ")", 0));
904 /* Extract the $[ construct in STRING, and return a new string. (])
905 Start extracting at (SINDEX) as if we had just seen "$[".
906 Make (SINDEX) get the position of the matching "]". */
908 extract_arithmetic_subst (string, sindex)
912 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
915 #if defined (PROCESS_SUBSTITUTION)
916 /* Extract the <( or >( construct in STRING, and return a new string.
917 Start extracting at (SINDEX) as if we had just seen "<(".
918 Make (SINDEX) get the position of the matching ")". */ /*))*/
920 extract_process_subst (string, starter, sindex)
925 return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
927 #endif /* PROCESS_SUBSTITUTION */
929 #if defined (ARRAY_VARS)
931 extract_array_assignment_list (string, sindex)
935 return (extract_delimited_string (string, sindex, "(", (char *)NULL, ")", 0));
939 /* Extract and create a new string from the contents of STRING, a
940 character string delimited with OPENER and CLOSER. SINDEX is
941 the address of an int describing the current offset in STRING;
942 it should point to just after the first OPENER found. On exit,
943 SINDEX gets the position of the last character of the matching CLOSER.
944 If OPENER is more than a single character, ALT_OPENER, if non-null,
945 contains a character string that can also match CLOSER and thus
946 needs to be skipped. */
948 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
951 char *opener, *alt_opener, *closer;
957 int pass_character, nesting_level;
958 int len_closer, len_opener, len_alt_opener;
961 slen = strlen (string + *sindex) + *sindex;
962 len_opener = STRLEN (opener);
963 len_alt_opener = STRLEN (alt_opener);
964 len_closer = STRLEN (closer);
971 while (nesting_level)
978 if (pass_character) /* previous char was backslash */
981 ADVANCE_CHAR (string, slen, i);
985 if (c == CTLESC || c == '\\')
992 /* Process a nested OPENER. */
993 if (STREQN (string + i, opener, len_opener))
996 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|EX_NOALLOC);
1001 /* Process a nested ALT_OPENER */
1002 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1004 si = i + len_alt_opener;
1005 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|EX_NOALLOC);
1010 /* If the current substring terminates the delimited string, decrement
1011 the nesting level. */
1012 if (STREQN (string + i, closer, len_closer))
1014 i += len_closer - 1; /* move to last byte of the closer */
1016 if (nesting_level == 0)
1020 /* Pass old-style command substitution through verbatim. */
1024 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1029 /* Pass single-quoted and double-quoted strings through verbatim. */
1030 if (c == '\'' || c == '"')
1033 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1034 : skip_double_quoted (string, slen, si);
1038 /* move past this character, which was not special. */
1039 ADVANCE_CHAR (string, slen, i);
1042 if (c == 0 && nesting_level)
1044 if (no_longjmp_on_fatal_error == 0)
1046 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1047 last_command_exit_value = EXECUTION_FAILURE;
1048 exp_jump_to_top_level (DISCARD);
1053 return (char *)NULL;
1057 si = i - *sindex - len_closer + 1;
1058 if (flags & EX_NOALLOC)
1059 result = (char *)NULL;
1062 result = (char *)xmalloc (1 + si);
1063 strncpy (result, string + *sindex, si);
1071 /* Extract a parameter expansion expression within ${ and } from STRING.
1072 Obey the Posix.2 rules for finding the ending `}': count braces while
1073 skipping over enclosed quoted strings and command substitutions.
1074 SINDEX is the address of an int describing the current offset in STRING;
1075 it should point to just after the first `{' found. On exit, SINDEX
1076 gets the position of the matching `}'. QUOTED is non-zero if this
1077 occurs inside double quotes. */
1078 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1080 extract_dollar_brace_string (string, sindex, quoted, flags)
1082 int *sindex, quoted, flags;
1086 int pass_character, nesting_level, si;
1092 slen = strlen (string + *sindex) + *sindex;
1095 while (c = string[i])
1100 ADVANCE_CHAR (string, slen, i);
1104 /* CTLESCs and backslashes quote the next character. */
1105 if (c == CTLESC || c == '\\')
1112 if (string[i] == '$' && string[i+1] == LBRACE)
1122 if (nesting_level == 0)
1128 /* Pass the contents of old-style command substitutions through
1133 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1138 /* Pass the contents of new-style command substitutions and
1139 arithmetic substitutions through verbatim. */
1140 if (string[i] == '$' && string[i+1] == LPAREN)
1143 t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC); /*)*/
1148 /* Pass the contents of single-quoted and double-quoted strings
1149 through verbatim. */
1150 if (c == '\'' || c == '"')
1153 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1154 : skip_double_quoted (string, slen, si);
1155 /* skip_XXX_quoted leaves index one past close quote */
1159 /* move past this character, which was not special. */
1160 ADVANCE_CHAR (string, slen, i);
1163 if (c == 0 && nesting_level)
1165 if (no_longjmp_on_fatal_error == 0)
1167 report_error ("bad substitution: no closing `%s' in %s", "}", string);
1168 last_command_exit_value = EXECUTION_FAILURE;
1169 exp_jump_to_top_level (DISCARD);
1174 return ((char *)NULL);
1178 result = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1184 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1185 STRING, and returns a pointer to it. */
1187 de_backslash (string)
1190 register size_t slen;
1191 register int i, j, prev_i;
1194 slen = strlen (string);
1197 /* Loop copying string[i] to string[j], i >= j. */
1200 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1201 string[i + 1] == '$'))
1204 ADVANCE_CHAR (string, slen, i);
1206 do string[j++] = string[prev_i++]; while (prev_i < i);
1217 /* Replace instances of \! in a string with !. */
1219 unquote_bang (string)
1223 register char *temp;
1225 temp = (char *)xmalloc (1 + strlen (string));
1227 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1229 if (string[i] == '\\' && string[i + 1] == '!')
1235 strcpy (string, temp);
1240 #if defined (READLINE)
1241 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1242 an unclosed quoted string), or if the character at EINDEX is quoted
1243 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1244 single and double-quoted string parsing functions should not return an
1245 error if there are unclosed quotes or braces. The characters that this
1246 recognizes need to be the same as the contents of
1247 rl_completer_quote_characters. */
1249 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1252 char_is_quoted (string, eindex)
1256 int i, pass_next, c;
1260 slen = strlen (string);
1261 no_longjmp_on_fatal_error = 1;
1270 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1272 ADVANCE_CHAR (string, slen, i);
1281 else if (c == '\'' || c == '"')
1283 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1284 : skip_double_quoted (string, slen, ++i);
1287 /* no increment, the skip_xxx functions go one past end */
1290 ADVANCE_CHAR (string, slen, i);
1297 unclosed_pair (string, eindex, openstr)
1302 int i, pass_next, openc, olen;
1306 slen = strlen (string);
1307 olen = strlen (openstr);
1308 i = pass_next = openc = 0;
1314 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1316 ADVANCE_CHAR (string, slen, i);
1319 else if (string[i] == '\\')
1325 else if (STREQN (string + i, openstr, olen))
1330 else if (string[i] == '\'' || string[i] == '"')
1332 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1333 : skip_double_quoted (string, slen, i);
1338 ADVANCE_CHAR (string, slen, i);
1343 /* Skip characters in STRING until we find a character in DELIMS, and return
1344 the index of that character. START is the index into string at which we
1345 begin. This is similar in spirit to strpbrk, but it returns an index into
1346 STRING and takes a starting index. This little piece of code knows quite
1347 a lot of shell syntax. It's very similar to skip_double_quoted and other
1348 functions of that ilk. */
1350 skip_to_delim (string, start, delims)
1355 int i, pass_next, backq, si, c;
1360 slen = strlen (string + start) + start;
1361 no_longjmp_on_fatal_error = 1;
1363 pass_next = backq = 0;
1364 while (c = string[i])
1371 ADVANCE_CHAR (string, slen, i);
1384 ADVANCE_CHAR (string, slen, i);
1393 else if (c == '\'' || c == '"')
1395 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1396 : skip_double_quoted (string, slen, ++i);
1397 /* no increment, the skip functions increment past the closing quote. */
1399 else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1402 if (string[si] == '\0')
1405 if (string[i+1] == LPAREN)
1406 temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC); /* ) */
1408 temp = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
1410 if (string[i] == '\0') /* don't increment i past EOS in loop */
1415 else if (member (c, delims))
1418 ADVANCE_CHAR (string, slen, i);
1424 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1425 individual words. If DELIMS is NULL, the current value of $IFS is used
1426 to split the string, and the function follows the shell field splitting
1427 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1428 gets the number of words in the returned list. CWP, if non-NULL, gets
1429 the index of the word containing SENTINEL. Non-whitespace chars in
1430 DELIMS delimit separate fields. */
1432 split_at_delims (string, slen, delims, sentinel, nwp, cwp)
1439 int ts, te, i, nw, cw, ifs_split;
1440 char *token, *d, *d2;
1441 WORD_LIST *ret, *tl;
1443 if (string == 0 || *string == '\0')
1449 return ((WORD_LIST *)NULL);
1452 d = (delims == 0) ? ifs_value : delims;
1453 ifs_split = delims == 0;
1455 /* Make d2 the non-whitespace characters in delims */
1459 d2 = (char *)xmalloc (strlen (delims) + 1);
1460 for (i = ts = 0; delims[i]; i++)
1462 if (whitespace(delims[i]) == 0)
1463 d2[ts++] = delims[i];
1468 ret = (WORD_LIST *)NULL;
1470 /* Remove sequences of whitspace characters at the start of the string, as
1471 long as those characters are delimiters. */
1472 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1474 if (string[i] == '\0')
1482 te = skip_to_delim (string, ts, d);
1484 /* If we have a non-whitespace delimiter character, use it to make a
1485 separate field. This is just about what $IFS splitting does and
1486 is closer to the behavior of the shell parser. */
1487 if (ts == te && d2 && member (string[ts], d2))
1490 /* If we're using IFS splitting, the non-whitespace delimiter char
1491 and any additional IFS whitespace delimits a field. */
1493 while (member (string[te], d) && spctabnl (string[te]))
1496 while (member (string[te], d2))
1500 token = substring (string, ts, te);
1502 ret = add_string_to_list (token, ret);
1506 if (sentinel >= ts && sentinel <= te)
1509 /* If the cursor is at whitespace just before word start, set the
1510 sentinel word to the current word. */
1511 if (cwp && cw == -1 && sentinel == ts-1)
1514 /* If the cursor is at whitespace between two words, make a new, empty
1515 word, add it before (well, after, since the list is in reverse order)
1516 the word we just added, and set the current word to that one. */
1517 if (cwp && cw == -1 && sentinel < ts)
1519 tl = make_word_list (make_word (""), ret->next);
1525 if (string[te] == 0)
1529 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
1538 /* Special case for SENTINEL at the end of STRING. If we haven't found
1539 the word containing SENTINEL yet, and the index we're looking for is at
1540 the end of STRING, add an additional null argument and set the current
1541 word pointer to that. */
1542 if (cwp && cw == -1 && sentinel >= slen)
1544 if (whitespace (string[sentinel - 1]))
1547 ret = add_string_to_list (token, ret);
1558 return (REVERSE_LIST (ret, WORD_LIST *));
1560 #endif /* READLINE */
1564 /* Extract the name of the variable to bind to from the assignment string. */
1566 assignment_name (string)
1572 offset = assignment (string, 0);
1574 return (char *)NULL;
1575 temp = substring (string, 0, offset);
1580 /* **************************************************************** */
1582 /* Functions to convert strings to WORD_LISTs and vice versa */
1584 /* **************************************************************** */
1586 /* Return a single string of all the words in LIST. SEP is the separator
1587 to put between individual elements of LIST in the output string. */
1589 string_list_internal (list, sep)
1593 register WORD_LIST *t;
1595 int word_len, sep_len, result_size;
1598 return ((char *)NULL);
1600 /* Short-circuit quickly if we don't need to separate anything. */
1601 if (list->next == 0)
1602 return (savestring (list->word->word));
1604 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1605 sep_len = STRLEN (sep);
1608 for (t = list; t; t = t->next)
1611 result_size += sep_len;
1612 result_size += strlen (t->word->word);
1615 r = result = (char *)xmalloc (result_size + 1);
1617 for (t = list; t; t = t->next)
1619 if (t != list && sep_len)
1623 FASTCOPY (sep, r, sep_len);
1630 word_len = strlen (t->word->word);
1631 FASTCOPY (t->word->word, r, word_len);
1639 /* Return a single string of all the words present in LIST, separating
1640 each word with a space. */
1645 return (string_list_internal (list, " "));
1648 /* Return a single string of all the words present in LIST, obeying the
1649 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1650 expansion [of $*] appears within a double quoted string, it expands
1651 to a single field with the value of each parameter separated by the
1652 first character of the IFS variable, or by a <space> if IFS is unset." */
1654 string_list_dollar_star (list)
1659 sep[0] = ifs_firstc;
1662 return (string_list_internal (list, sep));
1665 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1666 is non-zero, the $@ appears within double quotes, and we should quote
1667 the list before converting it into a string. If IFS is unset, and the
1668 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1669 in the words in the list, because the default value of $IFS is
1670 <space><tab><newline>, IFS characters in the words in the list should
1671 also be split. If IFS is null, and the word is not quoted, we need
1672 to quote the words in the list to preserve the positional parameters
1675 string_list_dollar_at (list, quoted)
1682 /* XXX this could just be ifs = ifs_value; */
1683 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
1685 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1688 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1690 : list_quote_escapes (list);
1691 return (string_list_internal (tlist, sep));
1694 /* Return the list of words present in STRING. Separate the string into
1695 words at any of the characters found in SEPARATORS. If QUOTED is
1696 non-zero then word in the list will have its quoted flag set, otherwise
1697 the quoted flag is left as make_word () deemed fit.
1699 This obeys the P1003.2 word splitting semantics. If `separators' is
1700 exactly <space><tab><newline>, then the splitting algorithm is that of
1701 the Bourne shell, which treats any sequence of characters from `separators'
1702 as a delimiter. If IFS is unset, which results in `separators' being set
1703 to "", no splitting occurs. If separators has some other value, the
1704 following rules are applied (`IFS white space' means zero or more
1705 occurrences of <space>, <tab>, or <newline>, as long as those characters
1706 are in `separators'):
1708 1) IFS white space is ignored at the start and the end of the
1710 2) Each occurrence of a character in `separators' that is not
1711 IFS white space, along with any adjacent occurrences of
1712 IFS white space delimits a field.
1713 3) Any nonzero-length sequence of IFS white space delimits a field.
1716 /* BEWARE! list_string strips null arguments. Don't call it twice and
1717 expect to have "" preserved! */
1719 /* This performs word splitting and quoted null character removal on
1722 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1723 : (c) == (separators)[0]) \
1727 list_string (string, separators, quoted)
1728 register char *string, *separators;
1733 char *current_word, *s;
1734 int sindex, sh_style_split, whitesep;
1736 if (!string || !*string)
1737 return ((WORD_LIST *)NULL);
1739 sh_style_split = separators && separators[0] == ' ' &&
1740 separators[1] == '\t' &&
1741 separators[2] == '\n' &&
1742 separators[3] == '\0';
1744 /* Remove sequences of whitespace at the beginning of STRING, as
1745 long as those characters appear in IFS. Do not do this if
1746 STRING is quoted or if there are no separator characters. */
1747 if (!quoted || !separators || !*separators)
1749 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1752 return ((WORD_LIST *)NULL);
1757 /* OK, now STRING points to a word that does not begin with white space.
1758 The splitting algorithm is:
1759 extract a word, stopping at a separator
1760 skip sequences of spc, tab, or nl as long as they are separators
1761 This obeys the field splitting rules in Posix.2. */
1762 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1764 current_word = string_extract_verbatim (string, &sindex, separators);
1765 if (current_word == 0)
1768 /* If we have a quoted empty string, add a quoted null argument. We
1769 want to preserve the quoted null character iff this is a quoted
1770 empty string; otherwise the quoted null characters are removed
1772 if (QUOTED_NULL (current_word))
1774 t = make_bare_word ("");
1775 t->flags |= W_QUOTED;
1777 t->word = make_quoted_char ('\0');
1778 result = make_word_list (t, result);
1780 else if (current_word[0] != '\0')
1782 /* If we have something, then add it regardless. However,
1783 perform quoted null character removal on the current word. */
1784 remove_quoted_nulls (current_word);
1785 result = add_string_to_list (current_word, result);
1786 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
1787 result->word->flags |= W_QUOTED;
1790 /* If we're not doing sequences of separators in the traditional
1791 Bourne shell style, then add a quoted null argument. */
1792 else if (!sh_style_split && !spctabnl (string[sindex]))
1794 t = make_bare_word ("");
1795 t->flags |= W_QUOTED;
1797 t->word = make_quoted_char ('\0');
1798 result = make_word_list (t, result);
1801 free (current_word);
1803 /* Note whether or not the separator is IFS whitespace, used later. */
1804 whitesep = string[sindex] && spctabnl (string[sindex]);
1806 /* Move past the current separator character. */
1810 /* Now skip sequences of space, tab, or newline characters if they are
1811 in the list of separators. */
1812 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
1815 /* If the first separator was IFS whitespace and the current character
1816 is a non-whitespace IFS character, it should be part of the current
1817 field delimiter, not a separate delimiter that would result in an
1818 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
1819 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
1822 return (REVERSE_LIST (result, WORD_LIST *));
1825 /* Parse a single word from STRING, using SEPARATORS to separate fields.
1826 ENDPTR is set to the first character after the word. This is used by
1827 the `read' builtin. This is never called with SEPARATORS != $IFS;
1828 it should be simplified.
1830 XXX - this function is very similar to list_string; they should be
1833 get_word_from_string (stringp, separators, endptr)
1834 char **stringp, *separators, **endptr;
1838 int sindex, sh_style_split, whitesep;
1840 if (!stringp || !*stringp || !**stringp)
1841 return ((char *)NULL);
1845 sh_style_split = separators && separators[0] == ' ' &&
1846 separators[1] == '\t' &&
1847 separators[2] == '\n' &&
1848 separators[3] == '\0';
1850 /* Remove sequences of whitespace at the beginning of STRING, as
1851 long as those characters appear in IFS. */
1852 if (sh_style_split || !separators || !*separators)
1854 for (; *s && spctabnl (*s) && isifs (*s); s++);
1856 /* If the string is nothing but whitespace, update it and return. */
1862 return ((char *)NULL);
1866 /* OK, S points to a word that does not begin with white space.
1867 Now extract a word, stopping at a separator, save a pointer to
1868 the first character after the word, then skip sequences of spc,
1869 tab, or nl as long as they are separators.
1871 This obeys the field splitting rules in Posix.2. */
1873 current_word = string_extract_verbatim (s, &sindex, separators);
1875 /* Set ENDPTR to the first character after the end of the word. */
1877 *endptr = s + sindex;
1879 /* Note whether or not the separator is IFS whitespace, used later. */
1880 whitesep = s[sindex] && spctabnl (s[sindex]);
1882 /* Move past the current separator character. */
1886 /* Now skip sequences of space, tab, or newline characters if they are
1887 in the list of separators. */
1888 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
1891 /* If the first separator was IFS whitespace and the current character is
1892 a non-whitespace IFS character, it should be part of the current field
1893 delimiter, not a separate delimiter that would result in an empty field.
1894 Look at POSIX.2, 3.6.5, (3)(b). */
1895 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
1898 /* Update STRING to point to the next field. */
1899 *stringp = s + sindex;
1900 return (current_word);
1903 /* Remove IFS white space at the end of STRING. Start at the end
1904 of the string and walk backwards until the beginning of the string
1905 or we find a character that's not IFS white space and not CTLESC.
1906 Only let CTLESC escape a white space character if SAW_ESCAPE is
1909 strip_trailing_ifs_whitespace (string, separators, saw_escape)
1910 char *string, *separators;
1915 s = string + STRLEN (string) - 1;
1916 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
1917 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
1925 /* Split STRING into words at whitespace. Obeys shell-style quoting with
1926 backslashes, single and double quotes. */
1928 list_string_with_quotes (string)
1934 int c, i, tokstart, len;
1936 for (s = string; s && *s && spctabnl (*s); s++)
1938 if (s == 0 || *s == 0)
1939 return ((WORD_LIST *)NULL);
1943 list = (WORD_LIST *)NULL;
1954 i = skip_single_quoted (s, s_len, ++i);
1956 i = skip_double_quoted (s, s_len, ++i);
1957 else if (c == 0 || spctabnl (c))
1959 /* We have found the end of a token. Make a word out of it and
1960 add it to the word list. */
1961 token = substring (s, tokstart, i);
1962 list = add_string_to_list (token, list);
1964 while (spctabnl (s[i]))
1972 i++; /* normal character */
1974 return (REVERSE_LIST (list, WORD_LIST *));
1978 /********************************************************/
1980 /* Functions to perform assignment statements */
1982 /********************************************************/
1984 /* Given STRING, an assignment string, get the value of the right side
1985 of the `=', and bind it to the left side. If EXPAND is true, then
1986 perform parameter expansion, command substitution, and arithmetic
1987 expansion on the right-hand side. Perform tilde expansion in any
1988 case. Do not perform word splitting on the result of expansion. */
1990 do_assignment_internal (string, expand)
1997 #if defined (ARRAY_VARS)
2001 int assign_list = 0;
2003 offset = assignment (string, 0);
2004 name = savestring (string);
2005 value = (char *)NULL;
2007 if (name[offset] == '=')
2012 temp = name + offset + 1;
2014 #if defined (ARRAY_VARS)
2015 if (expand && temp[0] == LPAREN && xstrchr (temp, RPAREN))
2017 assign_list = ni = 1;
2018 value = extract_delimited_string (temp, &ni, "(", (char *)NULL, ")", 0);
2023 /* Perform tilde expansion. */
2024 if (expand && temp[0])
2026 temp = (xstrchr (temp, '~') && unquoted_member ('~', temp))
2027 ? bash_tilde_expand (temp, 1)
2028 : savestring (temp);
2030 value = expand_string_if_necessary (temp, 0, expand_string_unsplit);
2034 value = savestring (temp);
2039 value = (char *)xmalloc (1);
2043 if (echo_command_at_execute)
2044 xtrace_print_assignment (name, value, assign_list, 1);
2046 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2048 #if defined (ARRAY_VARS)
2049 if (t = xstrchr (name, '[')) /*]*/
2053 report_error (_("%s: cannot assign list to array member"), name);
2056 entry = assign_array_element (name, value);
2060 else if (assign_list)
2061 entry = assign_array_from_string (name, value);
2063 #endif /* ARRAY_VARS */
2064 entry = bind_variable (name, value);
2066 stupidly_hack_special_variables (name);
2069 VUNSETATTR (entry, att_invisible);
2071 /* Return 1 if the assignment seems to have been performed correctly. */
2072 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
2075 /* Perform the assignment statement in STRING, and expand the
2076 right side by doing command and parameter expansion. */
2078 do_assignment (string)
2081 return do_assignment_internal (string, 1);
2084 /* Given STRING, an assignment string, get the value of the right side
2085 of the `=', and bind it to the left side. Do not do command and
2086 parameter substitution on the right hand side. */
2088 do_assignment_no_expand (string)
2091 return do_assignment_internal (string, 0);
2094 /***************************************************
2096 * Functions to manage the positional parameters *
2098 ***************************************************/
2100 /* Return the word list that corresponds to `$*'. */
2102 list_rest_of_args ()
2104 register WORD_LIST *list, *args;
2107 /* Break out of the loop as soon as one of the dollar variables is null. */
2108 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2109 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2111 for (args = rest_of_args; args; args = args->next)
2112 list = make_word_list (make_bare_word (args->word->word), list);
2114 return (REVERSE_LIST (list, WORD_LIST *));
2120 register WORD_LIST *list;
2123 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2125 for (list = rest_of_args; list; list = list->next)
2130 /* Return the value of a positional parameter. This handles values > 10. */
2132 get_dollar_var_value (ind)
2139 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2140 else /* We want something like ${11} */
2143 for (p = rest_of_args; p && ind--; p = p->next)
2145 temp = p ? savestring (p->word->word) : (char *)NULL;
2150 /* Make a single large string out of the dollar digit variables,
2151 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2152 case of "$*" with respect to IFS. */
2154 string_rest_of_args (dollar_star)
2157 register WORD_LIST *list;
2160 list = list_rest_of_args ();
2161 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2162 dispose_words (list);
2166 /* Return a string containing the positional parameters from START to
2167 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2168 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2169 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2170 no quoting chars are added. */
2172 pos_params (string, start, end, quoted)
2174 int start, end, quoted;
2176 WORD_LIST *save, *params, *h, *t;
2180 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2182 return ((char *)NULL);
2184 save = params = list_rest_of_args ();
2186 return ((char *)NULL);
2188 for (i = 1; params && i < start; i++)
2189 params = params->next;
2191 return ((char *)NULL);
2192 for (h = t = params; params && i < end; i++)
2195 params = params->next;
2198 t->next = (WORD_LIST *)NULL;
2199 if (string[0] == '*')
2201 ret = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (quote_list (h)) : string_list (h);
2204 if (quoted & Q_DOUBLE_QUOTES)
2205 ret = string_list_dollar_star (quote_list (h));
2206 else if (quoted & Q_HERE_DOCUMENT)
2207 ret = string_list (quote_list (h));
2209 ret = string_list (h);
2213 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
2217 dispose_words (save);
2221 /******************************************************************/
2223 /* Functions to expand strings to strings or WORD_LISTs */
2225 /******************************************************************/
2227 #if defined (PROCESS_SUBSTITUTION)
2228 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC)
2230 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
2233 /* If there are any characters in STRING that require full expansion,
2234 then call FUNC to expand STRING; otherwise just perform quote
2235 removal if necessary. This returns a new string. */
2237 expand_string_if_necessary (string, quoted, func)
2248 slen = strlen (string);
2252 if (EXP_CHAR (string[i]))
2254 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
2256 ADVANCE_CHAR (string, slen, i);
2261 list = (*func) (string, quoted);
2264 ret = string_list (list);
2265 dispose_words (list);
2270 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
2271 ret = string_quote_removal (string, quoted);
2273 ret = savestring (string);
2278 static inline char *
2279 expand_string_to_string_internal (string, quoted, func)
2287 if (string == 0 || *string == '\0')
2288 return ((char *)NULL);
2290 list = (*func) (string, quoted);
2293 ret = string_list (list);
2294 dispose_words (list);
2303 expand_string_to_string (string, quoted)
2307 return (expand_string_to_string_internal (string, quoted, expand_string));
2311 expand_string_unsplit_to_string (string, quoted)
2315 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
2318 #if defined (COND_COMMAND)
2319 /* Just remove backslashes in STRING. Returns a new string. */
2321 remove_backslashes (string)
2326 r = ret = (char *)xmalloc (strlen (string) + 1);
2327 for (s = string; s && *s; )
2339 /* This needs better error handling. */
2340 /* Expand W for use as an argument to a unary or binary operator in a
2341 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
2342 to the != or == operator, and should be treated as a pattern. In
2343 this case, we quote the string specially for the globbing code. The
2344 caller is responsible for removing the backslashes if the unquoted
2345 words is needed later. */
2347 cond_expand_word (w, special)
2354 if (w->word == 0 || w->word[0] == '\0')
2355 return ((char *)NULL);
2357 if (xstrchr (w->word, '~') && unquoted_member ('~', w->word))
2359 p = bash_tilde_expand (w->word, 0);
2364 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
2370 r = string_list (l);
2374 p = string_list (l);
2375 r = quote_string_for_globbing (p, QGLOB_CVTNULL);
2387 /* Call expand_word_internal to expand W and handle error returns.
2388 A convenience function for functions that don't want to handle
2389 any errors or free any memory before aborting. */
2391 call_expand_word_internal (w, q, i, c, e)
2397 result = expand_word_internal (w, q, i, c, e);
2398 if (result == &expand_word_error || result == &expand_word_fatal)
2400 /* By convention, each time this error is returned, w->word has
2401 already been freed (it sometimes may not be in the fatal case,
2402 but that doesn't result in a memory leak because we're going
2403 to exit in most cases). */
2404 w->word = (char *)NULL;
2405 last_command_exit_value = EXECUTION_FAILURE;
2406 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
2413 /* Perform parameter expansion, command substitution, and arithmetic
2414 expansion on STRING, as if it were a word. Leave the result quoted. */
2416 expand_string_internal (string, quoted)
2423 if (string == 0 || *string == 0)
2424 return ((WORD_LIST *)NULL);
2427 td.word = savestring (string);
2429 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2435 /* Expand STRING by performing parameter expansion, command substitution,
2436 and arithmetic expansion. Dequote the resulting WORD_LIST before
2437 returning it, but do not perform word splitting. The call to
2438 remove_quoted_nulls () is in here because word splitting normally
2439 takes care of quote removal. */
2441 expand_string_unsplit (string, quoted)
2447 if (string == 0 || *string == '\0')
2448 return ((WORD_LIST *)NULL);
2450 expand_no_split_dollar_star = 1;
2451 value = expand_string_internal (string, quoted);
2452 expand_no_split_dollar_star = 0;
2457 remove_quoted_nulls (value->word->word);
2458 dequote_list (value);
2464 /* Expand one of the PS? prompt strings. This is a sort of combination of
2465 expand_string_unsplit and expand_string_internal, but returns the
2466 passed string when an error occurs. Might want to trap other calls
2467 to jump_to_top_level here so we don't endlessly loop. */
2469 expand_prompt_string (string, quoted)
2476 if (string == 0 || *string == 0)
2477 return ((WORD_LIST *)NULL);
2480 td.word = savestring (string);
2482 no_longjmp_on_fatal_error = 1;
2483 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2484 no_longjmp_on_fatal_error = 0;
2486 if (value == &expand_word_error || value == &expand_word_fatal)
2488 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
2495 remove_quoted_nulls (value->word->word);
2496 dequote_list (value);
2501 /* Expand STRING just as if you were expanding a word, but do not dequote
2502 the resultant WORD_LIST. This is called only from within this file,
2503 and is used to correctly preserve quoted characters when expanding
2504 things like ${1+"$@"}. This does parameter expansion, command
2505 substitution, arithmetic expansion, and word splitting. */
2507 expand_string_leave_quoted (string, quoted)
2514 if (string == 0 || *string == '\0')
2515 return ((WORD_LIST *)NULL);
2517 tlist = expand_string_internal (string, quoted);
2521 tresult = word_list_split (tlist);
2522 dispose_words (tlist);
2525 return ((WORD_LIST *)NULL);
2528 /* This does not perform word splitting or dequote the WORD_LIST
2531 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
2533 int quoted, *dollar_at_p, *has_dollar_at;
2538 if (string == 0 || *string == '\0')
2539 return (WORD_LIST *)NULL;
2543 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
2547 /* Expand STRING just as if you were expanding a word. This also returns
2548 a list of words. Note that filename globbing is *NOT* done for word
2549 or string expansion, just when the shell is expanding a command. This
2550 does parameter expansion, command substitution, arithmetic expansion,
2551 and word splitting. Dequote the resultant WORD_LIST before returning. */
2553 expand_string (string, quoted)
2559 if (string == 0 || *string == '\0')
2560 return ((WORD_LIST *)NULL);
2562 result = expand_string_leave_quoted (string, quoted);
2563 return (result ? dequote_list (result) : result);
2566 /***************************************************
2568 * Functions to handle quoting chars *
2570 ***************************************************/
2574 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2575 The parser passes CTLNUL as CTLESC CTLNUL. */
2577 /* Quote escape characters in string s, but no other characters. This is
2578 used to protect CTLESC and CTLNUL in variable values from the rest of
2579 the word expansion process after the variable is expanded. */
2581 quote_escapes (string)
2584 register char *s, *t;
2586 char *result, *send;
2589 slen = strlen (string);
2590 send = string + slen;
2592 t = result = (char *)xmalloc ((slen * 2) + 1);
2597 if (*s == CTLESC || *s == CTLNUL)
2599 COPY_CHAR_P (t, s, send);
2606 list_quote_escapes (list)
2609 register WORD_LIST *w;
2612 for (w = list; w; w = w->next)
2615 w->word->word = quote_escapes (t);
2621 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2623 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2624 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2625 data stream pass through properly.
2627 We need to remove doubled CTLESC characters inside quoted strings before
2628 quoting the entire string, so we do not double the number of CTLESC
2631 Also used by parts of the pattern substitution code. */
2633 dequote_escapes (string)
2636 register char *s, *t;
2638 char *result, *send;
2644 slen = strlen (string);
2645 send = string + slen;
2647 t = result = (char *)xmalloc (slen + 1);
2650 if (strchr (string, CTLESC) == 0)
2651 return (strcpy (result, s));
2655 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2661 COPY_CHAR_P (t, s, send);
2667 /* Return a new string with the quoted representation of character C. */
2669 make_quoted_char (c)
2674 temp = (char *)xmalloc (3);
2689 /* Quote STRING. Return a new string. */
2691 quote_string (string)
2696 char *result, *send;
2700 result = (char *)xmalloc (2);
2708 slen = strlen (string);
2709 send = string + slen;
2711 result = (char *)xmalloc ((slen * 2) + 1);
2713 for (t = result; string < send; )
2716 COPY_CHAR_P (t, string, send);
2723 /* De-quoted quoted characters in STRING. */
2725 dequote_string (string)
2728 register char *s, *t;
2730 char *result, *send;
2733 slen = strlen (string);
2735 t = result = (char *)xmalloc (slen + 1);
2737 if (QUOTED_NULL (string))
2743 /* If no character in the string can be quoted, don't bother examining
2744 each character. Just return a copy of the string passed to us. */
2745 if (strchr (string, CTLESC) == NULL)
2746 return (strcpy (result, string));
2748 send = string + slen;
2758 COPY_CHAR_P (t, s, send);
2765 /* Quote the entire WORD_LIST list. */
2770 register WORD_LIST *w;
2773 for (w = list; w; w = w->next)
2776 w->word->word = quote_string (t);
2778 w->word->flags |= W_QUOTED;
2788 register WORD_LIST *tlist;
2790 for (tlist = list; tlist; tlist = tlist->next)
2792 s = dequote_string (tlist->word->word);
2793 free (tlist->word->word);
2794 tlist->word->word = s;
2799 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
2802 remove_quoted_escapes (string)
2809 t = dequote_escapes (string);
2817 /* Perform quoted null character removal on STRING. We don't allow any
2818 quoted null characters in the middle or at the ends of strings because
2819 of how expand_word_internal works. remove_quoted_nulls () turns
2820 STRING into an empty string iff it only consists of a quoted null,
2821 and removes all unquoted CTLNUL characters. */
2823 remove_quoted_nulls (string)
2826 register size_t slen;
2827 register int i, j, prev_i;
2830 if (strchr (string, CTLNUL) == 0) /* XXX */
2831 return string; /* XXX */
2833 slen = strlen (string);
2838 if (string[i] == CTLESC)
2840 /* Old code had j++, but we cannot assume that i == j at this
2841 point -- what if a CTLNUL has already been removed from the
2842 string? We don't want to drop the CTLESC or recopy characters
2843 that we've already copied down. */
2844 i++; string[j++] = CTLESC;
2848 else if (string[i] == CTLNUL)
2852 ADVANCE_CHAR (string, slen, i);
2855 do string[j++] = string[prev_i++]; while (prev_i < i);
2865 /* Perform quoted null character removal on each element of LIST.
2866 This modifies LIST. */
2868 word_list_remove_quoted_nulls (list)
2871 register WORD_LIST *t;
2873 for (t = list; t; t = t->next)
2874 remove_quoted_nulls (t->word->word);
2877 /* **************************************************************** */
2879 /* Functions for Matching and Removing Patterns */
2881 /* **************************************************************** */
2883 #if defined (HANDLE_MULTIBYTE)
2884 #if 0 /* Currently unused */
2885 static unsigned char *
2886 mb_getcharlens (string, len)
2890 int i, offset, last;
2897 ret = (unsigned char *)xmalloc (len);
2898 memset (ret, 0, len);
2899 while (string[last])
2901 ADVANCE_CHAR (string, len, offset);
2902 ret[last] = offset - last;
2910 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
2911 can have one of 4 values:
2912 RP_LONG_LEFT remove longest matching portion at start of PARAM
2913 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
2914 RP_LONG_RIGHT remove longest matching portion at end of PARAM
2915 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
2918 #define RP_LONG_LEFT 1
2919 #define RP_SHORT_LEFT 2
2920 #define RP_LONG_RIGHT 3
2921 #define RP_SHORT_RIGHT 4
2924 remove_upattern (param, pattern, op)
2925 char *param, *pattern;
2930 register char *p, *ret, c;
2932 len = STRLEN (param);
2937 case RP_LONG_LEFT: /* remove longest match at start */
2938 for (p = end; p >= param; p--)
2941 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2944 return (savestring (p));
2951 case RP_SHORT_LEFT: /* remove shortest match at start */
2952 for (p = param; p <= end; p++)
2955 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2958 return (savestring (p));
2964 case RP_LONG_RIGHT: /* remove longest match at end */
2965 for (p = param; p <= end; p++)
2967 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2970 ret = savestring (param);
2977 case RP_SHORT_RIGHT: /* remove shortest match at end */
2978 for (p = end; p >= param; p--)
2980 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2983 ret = savestring (param);
2991 return (savestring (param)); /* no match, return original string */
2994 #if defined (HANDLE_MULTIBYTE)
2996 #if !defined (HAVE_WCSDUP)
3005 ret = xmalloc ((len + 1) * sizeof (wchar_t));
3008 return (wcscpy (ret, ws));
3010 #endif /* !HAVE_WCSDUP */
3013 remove_wpattern (wparam, wstrlen, wpattern, op)
3025 case RP_LONG_LEFT: /* remove longest match at start */
3026 for (n = wstrlen; n >= 0; n--)
3028 wc = wparam[n]; wparam[n] = L'\0';
3029 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3032 return (wcsdup (wparam + n));
3038 case RP_SHORT_LEFT: /* remove shortest match at start */
3039 for (n = 0; n <= wstrlen; n++)
3041 wc = wparam[n]; wparam[n] = L'\0';
3042 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3045 return (wcsdup (wparam + n));
3051 case RP_LONG_RIGHT: /* remove longest match at end */
3052 for (n = 0; n <= wstrlen; n++)
3054 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3056 wc = wparam[n]; wparam[n] = L'\0';
3057 ret = wcsdup (wparam);
3064 case RP_SHORT_RIGHT: /* remove shortest match at end */
3065 for (n = wstrlen; n >= 0; n--)
3067 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3069 wc = wparam[n]; wparam[n] = L'\0';
3070 ret = wcsdup (wparam);
3078 return (wcsdup (wparam)); /* no match, return original string */
3080 #endif /* HANDLE_MULTIBYTE */
3083 remove_pattern (param, pattern, op)
3084 char *param, *pattern;
3089 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3090 return (savestring (param));
3092 #if defined (HANDLE_MULTIBYTE)
3095 wchar_t *ret, *oret;
3097 wchar_t *wparam, *wpattern;
3101 n = xdupmbstowcs (&wpattern, NULL, pattern);
3102 if (n == (size_t)-1)
3103 return (remove_upattern (param, pattern, op));
3104 n = xdupmbstowcs (&wparam, NULL, param);
3105 if (n == (size_t)-1)
3108 return (remove_upattern (param, pattern, op));
3110 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3116 xret = xmalloc (n + 1);
3117 memset (&ps, '\0', sizeof (mbstate_t));
3118 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3119 xret[n] = '\0'; /* just to make sure */
3125 return (remove_upattern (param, pattern, op));
3128 /* Return 1 of the first character of STRING could match the first
3129 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3131 match_pattern_char (pat, string)
3142 return (*string == c);
3144 return (*string == *pat);
3146 return (*pat == LPAREN ? 1 : (*string != '\0'));
3152 return (*pat == LPAREN ? 1 : (*string == c));
3154 return (*string != '\0');
3158 /* Match PAT anywhere in STRING and return the match boundaries.
3159 This returns 1 in case of a successful match, 0 otherwise. SP
3160 and EP are pointers into the string where the match begins and
3161 ends, respectively. MTYPE controls what kind of match is attempted.
3162 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3163 of the string, respectively. The longest match is returned. */
3165 match_upattern (string, pat, mtype, sp, ep)
3171 register char *p, *p1;
3174 len = STRLEN (string);
3180 for (p = string; p <= end; p++)
3182 if (match_pattern_char (pat, p))
3184 for (p1 = end; p1 >= p; p1--)
3186 c = *p1; *p1 = '\0';
3187 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3202 if (match_pattern_char (pat, string) == 0)
3205 for (p = end; p >= string; p--)
3208 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
3221 for (p = string; p <= end; p++)
3223 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3238 #if defined (HANDLE_MULTIBYTE)
3239 /* Return 1 of the first character of WSTRING could match the first
3240 character of pattern WPAT. Wide character version. */
3242 match_pattern_wchar (wpat, wstring)
3243 wchar_t *wpat, *wstring;
3250 switch (wc = *wpat++)
3253 return (*wstring == wc);
3255 return (*wstring == *wpat);
3257 return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
3263 return (*wpat == LPAREN ? 1 : (*wstring == wc));
3265 return (*wstring != L'\0');
3269 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3270 This returns 1 in case of a successful match, 0 otherwise. Wide
3271 character version. */
3273 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
3284 size_t n, n1; /* Apple's gcc seems to miscompile this badly */
3292 for (n = 0; n <= wstrlen; n++)
3294 if (match_pattern_wchar (wpat, wstring + n))
3296 for (n1 = wstrlen; n1 >= n; n1--)
3298 wc = wstring[n1]; wstring[n1] = L'\0';
3299 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3314 if (match_pattern_wchar (wpat, wstring) == 0)
3317 for (n = wstrlen; n >= 0; n--)
3319 wc = wstring[n]; wstring[n] = L'\0';
3320 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
3333 for (n = 0; n <= wstrlen; n++)
3335 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3338 *ep = indices[wstrlen];
3348 #endif /* HANDLE_MULTIBYTE */
3351 match_pattern (string, pat, mtype, sp, ep)
3356 #if defined (HANDLE_MULTIBYTE)
3359 wchar_t *wstring, *wpat;
3363 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
3366 #if defined (HANDLE_MULTIBYTE)
3369 n = xdupmbstowcs (&wpat, NULL, pat);
3370 if (n == (size_t)-1)
3371 return (match_upattern (string, pat, mtype, sp, ep));
3372 n = xdupmbstowcs (&wstring, &indices, string);
3373 if (n == (size_t)-1)
3376 return (match_upattern (string, pat, mtype, sp, ep));
3378 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
3388 return (match_upattern (string, pat, mtype, sp, ep));
3392 getpatspec (c, value)
3397 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
3399 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
3402 /* Posix.2 says that the WORD should be run through tilde expansion,
3403 parameter expansion, command substitution and arithmetic expansion.
3404 This leaves the result quoted, so quote_string_for_globbing () has
3405 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3406 it means that the entire expression was enclosed in double quotes.
3407 This means that quoting characters in the pattern do not make any
3408 special pattern characters quoted. For example, the `*' in the
3409 following retains its special meaning: "${foo#'*'}". */
3411 getpattern (value, quoted, expandpat)
3413 int quoted, expandpat;
3419 tword = xstrchr (value, '~') ? bash_tilde_expand (value, 0) : savestring (value);
3421 /* There is a problem here: how to handle single or double quotes in the
3422 pattern string when the whole expression is between double quotes?
3423 POSIX.2 says that enclosing double quotes do not cause the pattern to
3424 be quoted, but does that leave us a problem with @ and array[@] and their
3425 expansions inside a pattern? */
3427 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
3430 pat = string_extract_double_quoted (tword, &i, 1);
3436 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3438 l = *tword ? expand_string_for_rhs (tword,
3439 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
3440 (int *)NULL, (int *)NULL)
3443 pat = string_list (l);
3447 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
3455 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3456 or ${name#[#]value}. */
3458 variable_remove_pattern (value, pattern, patspec, quoted)
3459 char *value, *pattern;
3460 int patspec, quoted;
3464 tword = remove_pattern (value, pattern, patspec);
3471 list_remove_pattern (list, pattern, patspec, itype, quoted)
3474 int patspec, itype, quoted;
3480 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
3482 tword = remove_pattern (l->word->word, pattern, patspec);
3483 w = make_bare_word (tword);
3485 new = make_word_list (w, new);
3488 l = REVERSE_LIST (new, WORD_LIST *);
3491 tword = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
3493 tword = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (l) : string_list (l);
3496 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
3503 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
3506 int patspec, quoted;
3511 list = list_rest_of_args ();
3513 return ((char *)NULL);
3514 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3515 dispose_words (list);
3519 #if defined (ARRAY_VARS)
3521 array_remove_pattern (a, pattern, patspec, varname, quoted)
3525 char *varname; /* so we can figure out how it's indexed */
3533 /* compute itype from varname here */
3534 v = array_variable_part (varname, &ret, 0);
3537 list = array_to_word_list (a);
3539 return ((char *)NULL);
3540 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3541 dispose_words (list);
3545 #endif /* ARRAY_VARS */
3548 parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
3549 char *varname, *value, *patstr;
3552 int vtype, patspec, starsub;
3553 char *temp1, *val, *pattern;
3557 return ((char *)NULL);
3559 this_command_name = varname;
3561 vtype = get_var_and_type (varname, value, quoted, &v, &val);
3563 return ((char *)NULL);
3565 starsub = vtype & VT_STARSUB;
3566 vtype &= ~VT_STARSUB;
3568 patspec = getpatspec (rtype, patstr);
3569 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
3572 pattern = getpattern (patstr, quoted, 1);
3574 temp1 = (char *)NULL; /* shut up gcc */
3578 case VT_ARRAYMEMBER:
3579 temp1 = remove_pattern (val, pattern, patspec);
3580 if (vtype == VT_VARIABLE)
3584 val = quote_escapes (temp1);
3589 #if defined (ARRAY_VARS)
3591 temp1 = array_remove_pattern (array_cell (v), pattern, patspec, varname, quoted);
3592 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
3594 val = quote_escapes (temp1);
3601 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
3602 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
3604 val = quote_escapes (temp1);
3615 /*******************************************
3617 * Functions to expand WORD_DESCs *
3619 *******************************************/
3621 /* Expand WORD, performing word splitting on the result. This does
3622 parameter expansion, command substitution, arithmetic expansion,
3623 word splitting, and quote removal. */
3626 expand_word (word, quoted)
3630 WORD_LIST *result, *tresult;
3632 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
3633 result = word_list_split (tresult);
3634 dispose_words (tresult);
3635 return (result ? dequote_list (result) : result);
3638 /* Expand WORD, but do not perform word splitting on the result. This
3639 does parameter expansion, command substitution, arithmetic expansion,
3640 and quote removal. */
3642 expand_word_unsplit (word, quoted)
3648 expand_no_split_dollar_star = 1;
3649 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
3650 expand_no_split_dollar_star = 0;
3652 return (result ? dequote_list (result) : result);
3655 /* Perform shell expansions on WORD, but do not perform word splitting or
3656 quote removal on the result. */
3658 expand_word_leave_quoted (word, quoted)
3662 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
3665 #if defined (PROCESS_SUBSTITUTION)
3667 /*****************************************************************/
3669 /* Hacking Process Substitution */
3671 /*****************************************************************/
3673 #if !defined (HAVE_DEV_FD)
3674 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
3675 of FIFOs the shell has open. unlink_fifo_list will walk the list and
3676 unlink all of them. add_fifo_list adds the name of an open FIFO to the
3677 list. NFIFO is a count of the number of FIFOs in the list. */
3678 #define FIFO_INCR 20
3685 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
3687 static int fifo_list_size;
3690 add_fifo_list (pathname)
3693 if (nfifo >= fifo_list_size - 1)
3695 fifo_list_size += FIFO_INCR;
3696 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
3697 fifo_list_size * sizeof (struct temp_fifo));
3700 fifo_list[nfifo].file = savestring (pathname);
3712 for (i = saved = 0; i < nfifo; i++)
3714 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
3716 unlink (fifo_list[i].file);
3717 free (fifo_list[i].file);
3718 fifo_list[i].file = (char *)NULL;
3719 fifo_list[i].proc = -1;
3725 /* If we didn't remove some of the FIFOs, compact the list. */
3728 for (i = j = 0; i < nfifo; i++)
3729 if (fifo_list[i].file)
3731 fifo_list[j].file = fifo_list[i].file;
3732 fifo_list[j].proc = fifo_list[i].proc;
3746 tname = sh_mktmpname ("sh-np", MT_USERANDOM);
3747 if (mkfifo (tname, 0600) < 0)
3750 return ((char *)NULL);
3753 add_fifo_list (tname);
3757 #else /* HAVE_DEV_FD */
3759 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
3760 has open to children. NFDS is a count of the number of bits currently
3761 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
3763 static char *dev_fd_list = (char *)NULL;
3765 static int totfds; /* The highest possible number of open files. */
3771 if (!dev_fd_list || fd >= totfds)
3776 totfds = getdtablesize ();
3777 if (totfds < 0 || totfds > 256)
3782 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
3783 memset (dev_fd_list + ofds, '\0', totfds - ofds);
3786 dev_fd_list[fd] = 1;
3798 for (i = 0; nfds && i < totfds; i++)
3809 #if defined (NOTDEF)
3810 print_dev_fd_list ()
3814 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
3817 for (i = 0; i < totfds; i++)
3820 fprintf (stderr, " %d", i);
3822 fprintf (stderr, "\n");
3827 make_dev_fd_filename (fd)
3830 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
3832 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 4);
3834 strcpy (ret, DEV_FD_PREFIX);
3835 p = inttostr (fd, intbuf, sizeof (intbuf));
3836 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
3842 #endif /* HAVE_DEV_FD */
3844 /* Return a filename that will open a connection to the process defined by
3845 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
3846 a filename in /dev/fd corresponding to a descriptor that is one of the
3847 ends of the pipe. If not defined, we use named pipes on systems that have
3848 them. Systems without /dev/fd and named pipes are out of luck.
3850 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
3851 use the read end of the pipe and dup that file descriptor to fd 0 in
3852 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
3853 writing or use the write end of the pipe in the child, and dup that
3854 file descriptor to fd 1 in the child. The parent does the opposite. */
3857 process_substitute (string, open_for_read_in_child)
3859 int open_for_read_in_child;
3864 #if defined (HAVE_DEV_FD)
3865 int parent_pipe_fd, child_pipe_fd;
3867 #endif /* HAVE_DEV_FD */
3868 #if defined (JOB_CONTROL)
3869 pid_t old_pipeline_pgrp;
3872 if (!string || !*string || wordexp_only)
3873 return ((char *)NULL);
3875 #if !defined (HAVE_DEV_FD)
3876 pathname = make_named_pipe ();
3877 #else /* HAVE_DEV_FD */
3878 if (pipe (fildes) < 0)
3880 sys_error (_("cannot make pipe for process substitution"));
3881 return ((char *)NULL);
3883 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
3884 the pipe in the parent, otherwise the read end. */
3885 parent_pipe_fd = fildes[open_for_read_in_child];
3886 child_pipe_fd = fildes[1 - open_for_read_in_child];
3887 /* Move the parent end of the pipe to some high file descriptor, to
3888 avoid clashes with FDs used by the script. */
3889 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
3891 pathname = make_dev_fd_filename (parent_pipe_fd);
3892 #endif /* HAVE_DEV_FD */
3896 sys_error (_("cannot make pipe for process substitution"));
3897 return ((char *)NULL);
3900 old_pid = last_made_pid;
3902 #if defined (JOB_CONTROL)
3903 old_pipeline_pgrp = pipeline_pgrp;
3904 pipeline_pgrp = shell_pgrp;
3906 #endif /* JOB_CONTROL */
3908 pid = make_child ((char *)NULL, 1);
3911 reset_terminating_signals (); /* XXX */
3912 free_pushed_string_input ();
3913 /* Cancel traps, in trap.c. */
3914 restore_original_signals ();
3915 setup_async_signals ();
3916 subshell_environment |= SUBSHELL_COMSUB;
3919 #if defined (JOB_CONTROL)
3920 set_sigchld_handler ();
3921 stop_making_children ();
3922 pipeline_pgrp = old_pipeline_pgrp;
3923 #endif /* JOB_CONTROL */
3927 sys_error (_("cannot make child for process substitution"));
3929 #if defined (HAVE_DEV_FD)
3930 close (parent_pipe_fd);
3931 close (child_pipe_fd);
3932 #endif /* HAVE_DEV_FD */
3933 return ((char *)NULL);
3938 #if defined (JOB_CONTROL)
3939 restore_pipeline (1);
3942 #if !defined (HAVE_DEV_FD)
3943 fifo_list[nfifo-1].proc = pid;
3946 last_made_pid = old_pid;
3948 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
3950 #endif /* JOB_CONTROL && PGRP_PIPE */
3952 #if defined (HAVE_DEV_FD)
3953 close (child_pipe_fd);
3954 #endif /* HAVE_DEV_FD */
3959 set_sigint_handler ();
3961 #if defined (JOB_CONTROL)
3962 set_job_control (0);
3963 #endif /* JOB_CONTROL */
3965 #if !defined (HAVE_DEV_FD)
3966 /* Open the named pipe in the child. */
3967 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
3970 /* Two separate strings for ease of translation. */
3971 if (open_for_read_in_child)
3972 sys_error (_("cannot open named pipe %s for reading"), pathname);
3974 sys_error (_("cannot open named pipe %s for writing"), pathname);
3978 if (open_for_read_in_child)
3980 if (sh_unset_nodelay_mode (fd) < 0)
3982 sys_error (_("cannout reset nodelay mode for fd %d"), fd);
3986 #else /* HAVE_DEV_FD */
3988 #endif /* HAVE_DEV_FD */
3990 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
3992 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
3993 open_for_read_in_child ? 0 : 1);
3997 if (fd != (open_for_read_in_child ? 0 : 1))
4000 /* Need to close any files that this process has open to pipes inherited
4002 if (current_fds_to_close)
4004 close_fd_bitmap (current_fds_to_close);
4005 current_fds_to_close = (struct fd_bitmap *)NULL;
4008 #if defined (HAVE_DEV_FD)
4009 /* Make sure we close the parent's end of the pipe and clear the slot
4010 in the fd list so it is not closed later, if reallocated by, for
4011 instance, pipe(2). */
4012 close (parent_pipe_fd);
4013 dev_fd_list[parent_pipe_fd] = 0;
4014 #endif /* HAVE_DEV_FD */
4016 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
4018 #if !defined (HAVE_DEV_FD)
4019 /* Make sure we close the named pipe in the child before we exit. */
4020 close (open_for_read_in_child ? 0 : 1);
4021 #endif /* !HAVE_DEV_FD */
4026 #endif /* PROCESS_SUBSTITUTION */
4028 /***********************************/
4030 /* Command Substitution */
4032 /***********************************/
4035 read_comsub (fd, quoted)
4038 char *istring, buf[128], *bufp;
4039 int istring_index, istring_size, c;
4042 istring = (char *)NULL;
4043 istring_index = istring_size = bufn = 0;
4046 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
4049 /* Read the output of the command through the pipe. */
4056 bufn = zread (fd, buf, sizeof (buf));
4066 internal_warning ("read_comsub: ignored null byte in input");
4071 /* Add the character to ISTRING, possibly after resizing it. */
4072 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
4074 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
4075 istring[istring_index++] = CTLESC;
4077 istring[istring_index++] = c;
4080 #if defined (__CYGWIN__)
4081 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
4084 istring[istring_index - 1] = '\n';
4091 istring[istring_index] = '\0';
4093 /* If we read no output, just return now and save ourselves some
4095 if (istring_index == 0)
4098 return (char *)NULL;
4101 /* Strip trailing newlines from the output of the command. */
4102 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4104 while (istring_index > 0)
4106 if (istring[istring_index - 1] == '\n')
4110 /* If the newline was quoted, remove the quoting char. */
4111 if (istring[istring_index - 1] == CTLESC)
4117 istring[istring_index] = '\0';
4120 strip_trailing (istring, istring_index - 1, 1);
4125 /* Perform command substitution on STRING. This returns a string,
4128 command_substitute (string, quoted)
4132 pid_t pid, old_pid, old_pipeline_pgrp;
4134 int result, fildes[2], function_value, pflags, rc;
4136 istring = (char *)NULL;
4138 /* Don't fork () if there is no need to. In the case of no command to
4139 run, just return NULL. */
4140 if (!string || !*string || (string[0] == '\n' && !string[1]))
4141 return ((char *)NULL);
4143 if (wordexp_only && read_but_dont_execute)
4145 last_command_exit_value = 125;
4146 jump_to_top_level (EXITPROG);
4149 /* We're making the assumption here that the command substitution will
4150 eventually run a command from the file system. Since we'll run
4151 maybe_make_export_env in this subshell before executing that command,
4152 the parent shell and any other shells it starts will have to remake
4153 the environment. If we make it before we fork, other shells won't
4154 have to. Don't bother if we have any temporary variable assignments,
4155 though, because the export environment will be remade after this
4156 command completes anyway, but do it if all the words to be expanded
4157 are variable assignments. */
4158 if (subst_assign_varlist == 0 || garglist == 0)
4159 maybe_make_export_env (); /* XXX */
4161 /* Flags to pass to parse_and_execute() */
4162 pflags = interactive ? SEVAL_RESETLINE : 0;
4164 /* Pipe the output of executing STRING into the current shell. */
4165 if (pipe (fildes) < 0)
4167 sys_error (_("cannot make pipe for command substitution"));
4171 old_pid = last_made_pid;
4172 #if defined (JOB_CONTROL)
4173 old_pipeline_pgrp = pipeline_pgrp;
4174 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4175 if ((subshell_environment & SUBSHELL_PIPE) == 0)
4176 pipeline_pgrp = shell_pgrp;
4177 cleanup_the_pipeline ();
4180 pid = make_child ((char *)NULL, 0);
4182 /* Reset the signal handlers in the child, but don't free the
4184 reset_signal_handlers ();
4186 #if defined (JOB_CONTROL)
4187 set_sigchld_handler ();
4188 stop_making_children ();
4189 pipeline_pgrp = old_pipeline_pgrp;
4191 stop_making_children ();
4192 #endif /* JOB_CONTROL */
4196 sys_error (_("cannot make child for command substitution"));
4202 return ((char *)NULL);
4207 set_sigint_handler (); /* XXX */
4209 free_pushed_string_input ();
4211 if (dup2 (fildes[1], 1) < 0)
4213 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4214 exit (EXECUTION_FAILURE);
4217 /* If standard output is closed in the parent shell
4218 (such as after `exec >&-'), file descriptor 1 will be
4219 the lowest available file descriptor, and end up in
4220 fildes[0]. This can happen for stdin and stderr as well,
4221 but stdout is more important -- it will cause no output
4222 to be generated from this command. */
4223 if ((fildes[1] != fileno (stdin)) &&
4224 (fildes[1] != fileno (stdout)) &&
4225 (fildes[1] != fileno (stderr)))
4228 if ((fildes[0] != fileno (stdin)) &&
4229 (fildes[0] != fileno (stdout)) &&
4230 (fildes[0] != fileno (stderr)))
4233 /* The currently executing shell is not interactive. */
4236 /* This is a subshell environment. */
4237 subshell_environment |= SUBSHELL_COMSUB;
4239 /* When not in POSIX mode, command substitution does not inherit
4241 if (posixly_correct == 0)
4242 exit_immediately_on_error = 0;
4244 remove_quoted_escapes (string);
4246 startup_state = 2; /* see if we can avoid a fork */
4247 /* Give command substitution a place to jump back to on failure,
4248 so we don't go back up to main (). */
4249 result = setjmp (top_level);
4251 /* If we're running a command substitution inside a shell function,
4252 trap `return' so we don't return from the function in the subshell
4253 and go off to never-never land. */
4254 if (result == 0 && return_catch_flag)
4255 function_value = setjmp (return_catch);
4259 if (result == ERREXIT)
4260 rc = last_command_exit_value;
4261 else if (result == EXITPROG)
4262 rc = last_command_exit_value;
4264 rc = EXECUTION_FAILURE;
4265 else if (function_value)
4266 rc = return_catch_value;
4270 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
4274 last_command_exit_value = rc;
4275 rc = run_exit_trap ();
4280 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4282 #endif /* JOB_CONTROL && PGRP_PIPE */
4286 istring = read_comsub (fildes[0], quoted);
4290 current_command_subst_pid = pid;
4291 last_command_exit_value = wait_for (pid);
4292 last_command_subst_pid = pid;
4293 last_made_pid = old_pid;
4295 #if defined (JOB_CONTROL)
4296 /* If last_command_exit_value > 128, then the substituted command
4297 was terminated by a signal. If that signal was SIGINT, then send
4298 SIGINT to ourselves. This will break out of loops, for instance. */
4299 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
4300 kill (getpid (), SIGINT);
4302 /* wait_for gives the terminal back to shell_pgrp. If some other
4303 process group should have it, give it away to that group here.
4304 pipeline_pgrp is non-zero only while we are constructing a
4305 pipline, so what we are concerned about is whether or not that
4306 pipeline was started in the background. A pipeline started in
4307 the background should never get the tty back here. */
4309 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
4311 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
4313 give_terminal_to (pipeline_pgrp, 0);
4314 #endif /* JOB_CONTROL */
4320 /********************************************************
4322 * Utility functions for parameter expansion *
4324 ********************************************************/
4326 #if defined (ARRAY_VARS)
4329 array_length_reference (s)
4338 var = array_variable_part (s, &t, &len);
4340 /* If unbound variables should generate an error, report one and return
4342 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
4353 /* We support a couple of expansions for variables that are not arrays.
4354 We'll return the length of the value for v[0], and 1 for v[@] or
4355 v[*]. Return 0 for everything else. */
4357 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
4359 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
4360 return (array_p (var) ? array_num_elements (array) : 1);
4362 ind = array_expand_index (t, len);
4365 err_badarraysub (t);
4370 t = array_reference (array, ind);
4372 t = (ind == 0) ? value_cell (var) : (char *)NULL;
4377 #endif /* ARRAY_VARS */
4380 valid_brace_expansion_word (name, var_is_special)
4384 if (DIGIT (*name) && all_digits (name))
4386 else if (var_is_special)
4388 #if defined (ARRAY_VARS)
4389 else if (valid_array_reference (name))
4391 #endif /* ARRAY_VARS */
4392 else if (legal_identifier (name))
4399 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
4402 int *quoted_dollar_atp, *contains_dollar_at;
4408 if (quoted_dollar_atp)
4409 *quoted_dollar_atp = 0;
4410 if (contains_dollar_at)
4411 *contains_dollar_at = 0;
4415 /* check for $@ and $* */
4416 if (name[0] == '@' && name[1] == 0)
4418 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4419 *quoted_dollar_atp = 1;
4420 if (contains_dollar_at)
4421 *contains_dollar_at = 1;
4424 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
4426 if (contains_dollar_at)
4427 *contains_dollar_at = 1;
4431 /* Now check for ${array[@]} and ${array[*]} */
4432 #if defined (ARRAY_VARS)
4433 else if (valid_array_reference (name))
4435 temp1 = xstrchr (name, '[');
4436 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4438 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4439 *quoted_dollar_atp = 1;
4440 if (contains_dollar_at)
4441 *contains_dollar_at = 1;
4444 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4445 which should result in separate words even when IFS is unset. */
4446 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4448 if (contains_dollar_at)
4449 *contains_dollar_at = 1;
4457 /* Parameter expand NAME, and return a new string which is the expansion,
4458 or NULL if there was no expansion.
4459 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4460 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4461 NAME was found inside of a double-quoted expression. */
4463 parameter_brace_expand_word (name, var_is_special, quoted)
4465 int var_is_special, quoted;
4472 /* Handle multiple digit arguments, as in ${11}. */
4474 if (legal_number (name, &arg_index))
4476 tt = get_dollar_var_value (arg_index);
4478 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4480 : quote_escapes (tt);
4482 temp = (char *)NULL;
4485 else if (var_is_special) /* ${@} */
4488 tt = (char *)xmalloc (2 + strlen (name));
4489 tt[sindex = 0] = '$';
4490 strcpy (tt + 1, name);
4492 temp = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
4493 (int *)NULL, (int *)NULL, 0);
4496 #if defined (ARRAY_VARS)
4497 else if (valid_array_reference (name))
4499 temp = array_value (name, quoted, &atype);
4500 if (atype == 0 && temp)
4501 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4502 ? quote_string (temp)
4503 : quote_escapes (temp);
4506 else if (var = find_variable (name))
4508 if (var_isset (var) && invisible_p (var) == 0)
4510 #if defined (ARRAY_VARS)
4511 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
4513 temp = value_cell (var);
4517 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4518 ? quote_string (temp)
4519 : quote_escapes (temp);
4522 temp = (char *)NULL;
4525 temp = (char *)NULL;
4530 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4531 value of the variable whose name is the value of NAME. */
4533 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
4535 int var_is_special, quoted;
4536 int *quoted_dollar_atp, *contains_dollar_at;
4540 t = parameter_brace_expand_word (name, var_is_special, quoted);
4541 /* Have to dequote here if necessary */
4544 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
4545 ? dequote_string (t)
4546 : dequote_escapes (t);
4550 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
4553 temp = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
4558 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
4559 depending on the value of C, the separating character. C can be one of
4560 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
4561 between double quotes. */
4563 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
4565 int c, quoted, *qdollaratp, *hasdollarat;
4568 char *t, *t1, *temp;
4571 /* XXX - Should we tilde expand in an assignment context if C is `='? */
4573 temp = bash_tilde_expand (value, 0);
4574 else if (xstrchr (value, '~') && unquoted_substring ("=~", value))
4575 temp = bash_tilde_expand (value, 1);
4577 temp = savestring (value);
4579 /* If the entire expression is between double quotes, we want to treat
4580 the value as a double-quoted string, with the exception that we strip
4581 embedded unescaped double quotes. */
4582 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *temp)
4585 t = string_extract_double_quoted (temp, &hasdol, 1);
4591 /* XXX was 0 not quoted */
4592 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
4595 *hasdollarat = hasdol || (l && l->next);
4599 /* The expansion of TEMP returned something. We need to treat things
4600 slightly differently if HASDOL is non-zero. If we have "$@", the
4601 individual words have already been quoted. We need to turn them
4602 into a string with the words separated by the first character of
4603 $IFS without any additional quoting, so string_list_dollar_at won't
4604 do the right thing. We use string_list_dollar_star instead. */
4605 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
4607 /* If l->next is not null, we know that TEMP contained "$@", since that
4608 is the only expansion that creates more than one word. */
4609 if (qdollaratp && ((hasdol && quoted) || l->next))
4613 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
4615 /* The brace expansion occurred between double quotes and there was
4616 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
4617 it does not expand to anything. In this case, we want to return
4618 a quoted empty string. */
4619 temp = (char *)xmalloc (2);
4624 temp = (char *)NULL;
4626 if (c == '-' || c == '+')
4630 t = temp ? savestring (temp) : savestring ("");
4631 t1 = dequote_string (t);
4633 #if defined (ARRAY_VARS)
4634 if (valid_array_reference (name))
4635 assign_array_element (name, t1);
4637 #endif /* ARRAY_VARS */
4638 bind_variable (name, t1);
4643 /* Deal with the right hand side of a ${name:?value} expansion in the case
4644 that NAME is null or not set. If VALUE is non-null it is expanded and
4645 used as the error message to print, otherwise a standard message is
4648 parameter_brace_expand_error (name, value)
4654 if (value && *value)
4657 temp = bash_tilde_expand (value, 0);
4658 else if (xstrchr (value, '~') && unquoted_substring ("=~", value))
4659 temp = bash_tilde_expand (value, 1);
4661 temp = savestring (value);
4663 l = expand_string (temp, 0);
4665 temp = string_list (l);
4666 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
4671 report_error (_("%s: parameter null or not set"), name);
4673 /* Free the data we have allocated during this expansion, since we
4674 are about to longjmp out. */
4679 /* Return 1 if NAME is something for which parameter_brace_expand_length is
4682 valid_length_expression (name)
4685 return (name[1] == '\0' || /* ${#} */
4686 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
4687 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
4688 #if defined (ARRAY_VARS)
4689 valid_array_reference (name + 1) || /* ${#a[7]} */
4691 legal_identifier (name + 1)); /* ${#PS1} */
4694 #if defined (HANDLE_MULTIBYTE)
4703 memset (&mbs, 0, sizeof (mbs));
4704 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0 && (MB_INVALIDCH(clen) == 0))
4714 /* Handle the parameter brace expansion that requires us to return the
4715 length of a parameter. */
4717 parameter_brace_expand_length (name)
4721 intmax_t number, arg_index;
4723 #if defined (ARRAY_VARS)
4727 if (name[1] == '\0') /* ${#} */
4728 number = number_of_args ();
4729 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
4730 number = number_of_args ();
4731 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
4733 /* Take the lengths of some of the shell's special parameters. */
4737 t = which_set_flags ();
4740 t = itos (last_command_exit_value);
4743 t = itos (dollar_dollar_pid);
4746 if (last_asynchronous_pid == NO_PID)
4749 t = itos (last_asynchronous_pid);
4752 t = itos (number_of_args ());
4755 number = STRLEN (t);
4758 #if defined (ARRAY_VARS)
4759 else if (valid_array_reference (name + 1))
4760 number = array_length_reference (name + 1);
4761 #endif /* ARRAY_VARS */
4766 if (legal_number (name + 1, &arg_index)) /* ${#1} */
4768 t = get_dollar_var_value (arg_index);
4769 number = MB_STRLEN (t);
4772 #if defined (ARRAY_VARS)
4773 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var))
4775 t = array_reference (array_cell (var), 0);
4776 number = MB_STRLEN (t);
4781 newname = savestring (name);
4783 list = expand_string (newname, Q_DOUBLE_QUOTES);
4784 t = list ? string_list (list) : (char *)NULL;
4787 dispose_words (list);
4789 number = MB_STRLEN (t);
4797 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
4798 so we do some ad-hoc parsing of an arithmetic expression to find
4799 the first DELIM, instead of using strchr(3). Two rules:
4800 1. If the substring contains a `(', read until closing `)'.
4801 2. If the substring contains a `?', read past one `:' for each `?'.
4805 skiparith (substr, delim)
4810 int skipcol, pcount, i;
4813 sublen = strlen (substr);
4814 i = skipcol = pcount = 0;
4817 /* Balance parens */
4818 if (substr[i] == LPAREN)
4824 if (substr[i] == RPAREN && pcount)
4832 ADVANCE_CHAR (substr, sublen, i);
4836 /* Skip one `:' for each `?' */
4837 if (substr[i] == ':' && skipcol)
4843 if (substr[i] == delim)
4845 if (substr[i] == '?')
4851 ADVANCE_CHAR (substr, sublen, i);
4854 return (substr + i);
4857 /* Verify and limit the start and end of the desired substring. If
4858 VTYPE == 0, a regular shell variable is being used; if it is 1,
4859 then the positional parameters are being used; if it is 2, then
4860 VALUE is really a pointer to an array variable that should be used.
4861 Return value is 1 if both values were OK, 0 if there was a problem
4862 with an invalid expression, or -1 if the values were out of range. */
4864 verify_substring_values (value, substr, vtype, e1p, e2p)
4865 char *value, *substr;
4867 intmax_t *e1p, *e2p;
4869 char *t, *temp1, *temp2;
4872 #if defined (ARRAY_VARS)
4876 /* duplicate behavior of strchr(3) */
4877 t = skiparith (substr, ':');
4878 if (*t && *t == ':')
4883 temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string);
4884 *e1p = evalexp (temp1, &expok);
4889 len = -1; /* paranoia */
4893 case VT_ARRAYMEMBER:
4894 len = MB_STRLEN (value);
4897 len = number_of_args () + 1;
4899 #if defined (ARRAY_VARS)
4902 /* For arrays, the first value deals with array indices. Negative
4903 offsets count from one past the array's maximum index. */
4904 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
4909 if (len == -1) /* paranoia */
4912 if (*e1p < 0) /* negative offsets count from end */
4915 if (*e1p > len || *e1p < 0)
4918 #if defined (ARRAY_VARS)
4919 /* For arrays, the second offset deals with the number of elements. */
4920 if (vtype == VT_ARRAYVAR)
4921 len = array_num_elements (a);
4927 temp2 = savestring (t);
4928 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
4931 *e2p = evalexp (temp1, &expok);
4937 internal_error (_("%s: substring expression < 0"), t);
4940 #if defined (ARRAY_VARS)
4941 /* In order to deal with sparse arrays, push the intelligence about how
4942 to deal with the number of elements desired down to the array-
4943 specific functions. */
4944 if (vtype != VT_ARRAYVAR)
4947 *e2p += *e1p; /* want E2 chars starting at E1 */
4958 /* Return the type of variable specified by VARNAME (simple variable,
4959 positional param, or array variable). Also return the value specified
4960 by VARNAME (value of a variable or a reference to an array element).
4961 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
4962 characters in the value are quoted with CTLESC and takes appropriate
4963 steps. For convenience, *VALP is set to the dequoted VALUE. */
4965 get_var_and_type (varname, value, quoted, varp, valp)
4966 char *varname, *value;
4973 #if defined (ARRAY_VARS)
4977 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
4978 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
4979 if (vtype == VT_POSPARMS && varname[0] == '*')
4980 vtype |= VT_STARSUB;
4981 *varp = (SHELL_VAR *)NULL;
4983 #if defined (ARRAY_VARS)
4984 if (valid_array_reference (varname))
4986 v = array_variable_part (varname, &temp, (int *)0);
4987 if (v && array_p (v))
4989 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
4991 vtype = VT_ARRAYVAR;
4993 vtype |= VT_STARSUB;
4994 *valp = (char *)array_cell (v);
4998 vtype = VT_ARRAYMEMBER;
4999 *valp = array_value (varname, 1, (int *)NULL);
5006 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v))
5008 vtype = VT_ARRAYMEMBER;
5010 *valp = array_reference (array_cell (v), 0);
5016 if (value && vtype == VT_VARIABLE)
5018 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5019 *valp = dequote_string (value);
5021 *valp = dequote_escapes (value);
5027 *valp = (value && vtype == VT_VARIABLE) ? dequote_escapes (value) : value;
5033 /******************************************************/
5035 /* Functions to extract substrings of variable values */
5037 /******************************************************/
5039 #if defined (HANDLE_MULTIBYTE)
5040 /* Character-oriented rather than strictly byte-oriented substrings. S and
5041 E, rather being strict indices into STRING, indicate character (possibly
5042 multibyte character) positions that require calculation.
5043 Used by the ${param:offset[:length]} expansion. */
5045 mb_substring (string, s, e)
5050 int start, stop, i, slen;
5054 slen = STRLEN (string);
5057 while (string[start] && i--)
5058 ADVANCE_CHAR (string, slen, start);
5061 while (string[stop] && i--)
5062 ADVANCE_CHAR (string, slen, stop);
5063 tt = substring (string, start, stop);
5068 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5069 is `@', use the positional parameters; otherwise, use the value of
5070 VARNAME. If VARNAME is an array variable, use the array elements. */
5073 parameter_brace_substring (varname, value, substr, quoted)
5074 char *varname, *value, *substr;
5078 int vtype, r, starsub;
5079 char *temp, *val, *tt;
5083 return ((char *)NULL);
5085 this_command_name = varname;
5087 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5089 return ((char *)NULL);
5091 starsub = vtype & VT_STARSUB;
5092 vtype &= ~VT_STARSUB;
5094 r = verify_substring_values (val, substr, vtype, &e1, &e2);
5096 return ((r == 0) ? &expand_param_error : (char *)NULL);
5101 case VT_ARRAYMEMBER:
5102 #if defined (HANDLE_MULTIBYTE)
5104 tt = mb_substring (val, e1, e2);
5107 tt = substring (val, e1, e2);
5109 if (vtype == VT_VARIABLE)
5111 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5112 temp = quote_string (tt);
5114 temp = tt ? quote_escapes (tt) : (char *)NULL;
5118 tt = pos_params (varname, e1, e2, quoted);
5119 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5121 temp = tt ? quote_escapes (tt) : (char *)NULL;
5127 #if defined (ARRAY_VARS)
5129 /* We want E2 to be the number of elements desired (arrays can be sparse,
5130 so verify_substring_values just returns the numbers specified and we
5131 rely on array_subrange to understand how to deal with them). */
5132 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
5133 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5135 temp = tt ? quote_escapes (tt) : (char *)NULL;
5143 temp = (char *)NULL;
5149 /****************************************************************/
5151 /* Functions to perform pattern substitution on variable values */
5153 /****************************************************************/
5156 pat_subst (string, pat, rep, mflags)
5157 char *string, *pat, *rep;
5160 char *ret, *s, *e, *str;
5161 int rsize, rptr, l, replen, mtype;
5163 mtype = mflags & MATCH_TYPEMASK;
5166 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5167 * with REP and return the result.
5168 * 2. A null pattern with mtype == MATCH_END means to append REP to
5169 * STRING and return the result.
5171 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
5173 replen = STRLEN (rep);
5174 l = strlen (string);
5175 ret = (char *)xmalloc (replen + l + 2);
5177 strcpy (ret, string);
5178 else if (mtype == MATCH_BEG)
5181 strcpy (ret + replen, string);
5185 strcpy (ret, string);
5186 strcpy (ret + l, rep);
5191 ret = (char *)xmalloc (rsize = 64);
5194 for (replen = STRLEN (rep), rptr = 0, str = string;;)
5196 if (match_pattern (str, pat, mtype, &s, &e) == 0)
5199 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
5201 /* OK, now copy the leading unmatched portion of the string (from
5202 str to s) to ret starting at rptr (the current offset). Then copy
5203 the replacement string at ret + rptr + (s - str). Increment
5204 rptr (if necessary) and str and go on. */
5207 strncpy (ret + rptr, str, l);
5212 strncpy (ret + rptr, rep, replen);
5215 str = e; /* e == end of match */
5217 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
5221 e++, str++; /* avoid infinite recursion on zero-length match */
5224 /* Now copy the unmatched portion of the input string */
5227 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
5228 strcpy (ret + rptr, str);
5236 /* Do pattern match and replacement on the positional parameters. */
5238 pos_params_pat_subst (string, pat, rep, mflags)
5239 char *string, *pat, *rep;
5242 WORD_LIST *save, *params;
5246 save = params = list_rest_of_args ();
5248 return ((char *)NULL);
5250 for ( ; params; params = params->next)
5252 ret = pat_subst (params->word->word, pat, rep, mflags);
5253 w = make_bare_word (ret);
5254 dispose_word (params->word);
5259 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
5260 ret = string_list_dollar_star (quote_list (save));
5262 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
5263 dispose_words (save);
5268 /* Perform pattern substitution on VALUE, which is the expansion of
5269 VARNAME. PATSUB is an expression supplying the pattern to match
5270 and the string to substitute. QUOTED is a flags word containing
5271 the type of quoting currently in effect. */
5273 parameter_brace_patsub (varname, value, patsub, quoted)
5274 char *varname, *value, *patsub;
5277 int vtype, mflags, starsub;
5278 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
5282 return ((char *)NULL);
5284 this_command_name = varname;
5286 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5288 return ((char *)NULL);
5290 starsub = vtype & VT_STARSUB;
5291 vtype &= ~VT_STARSUB;
5296 mflags |= MATCH_GLOBREP;
5300 /* Malloc this because expand_string_if_necessary or one of the expansion
5301 functions in its call chain may free it on a substitution error. */
5302 lpatsub = savestring (patsub);
5304 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5305 mflags |= MATCH_QUOTED;
5308 mflags |= MATCH_STARSUB;
5310 if (rep = quoted_strchr (lpatsub, '/', ST_BACKSL))
5315 if (rep && *rep == '\0')
5319 /* Expand PAT and REP for command, variable and parameter, arithmetic,
5320 and process substitution. Also perform quote removal. Do not
5321 perform word splitting or filename generation. */
5322 pat = expand_string_if_necessary (lpatsub, (quoted & ~Q_DOUBLE_QUOTES), expand_string_unsplit);
5324 /* Perform the same expansions on the pattern as performed by the
5325 pattern removal expansions. */
5326 pat = getpattern (lpatsub, quoted, 1);
5331 if ((mflags & MATCH_QUOTED) == 0)
5332 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
5334 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
5338 if (pat && pat[0] == '#')
5340 mflags |= MATCH_BEG;
5343 else if (pat && pat[0] == '%')
5345 mflags |= MATCH_END;
5349 mflags |= MATCH_ANY;
5351 /* OK, we now want to substitute REP for PAT in VAL. If
5352 flags & MATCH_GLOBREP is non-zero, the substitution is done
5353 everywhere, otherwise only the first occurrence of PAT is
5354 replaced. The pattern matching code doesn't understand
5355 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5356 values passed in (VT_VARIABLE) so the pattern substitution
5357 code works right. We need to requote special chars after
5358 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5359 other cases if QUOTED == 0, since the posparams and arrays
5360 indexed by * or @ do special things when QUOTED != 0. */
5365 case VT_ARRAYMEMBER:
5366 temp = pat_subst (val, p, rep, mflags);
5367 if (vtype == VT_VARIABLE)
5371 tt = quote_escapes (temp);
5377 temp = pos_params_pat_subst (val, p, rep, mflags);
5378 if (temp && (mflags & MATCH_QUOTED) == 0)
5380 tt = quote_escapes (temp);
5385 #if defined (ARRAY_VARS)
5387 temp = array_patsub (array_cell (v), p, rep, mflags);
5388 if (temp && (mflags & MATCH_QUOTED) == 0)
5390 tt = quote_escapes (temp);
5405 /****************************************************************/
5407 /* Functions to perform parameter expansion on a string */
5409 /****************************************************************/
5411 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5413 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
5415 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
5417 int check_nullness, var_is_set, var_is_null, var_is_special;
5418 int want_substring, want_indir, want_patsub;
5419 char *name, *value, *temp, *temp1;
5420 int t_index, sindex, c;
5423 value = (char *)NULL;
5424 var_is_set = var_is_null = var_is_special = check_nullness = 0;
5425 want_substring = want_indir = want_patsub = 0;
5429 name = string_extract (string, &t_index, "#%:-=?+/}", EX_VARNAME);
5431 /* If the name really consists of a special variable, then make sure
5432 that we have the entire name. We don't allow indirect references
5433 to special variables except `#', `?', `@' and `*'. */
5434 if ((sindex == t_index &&
5435 (string[t_index] == '-' ||
5436 string[t_index] == '?' ||
5437 string[t_index] == '#')) ||
5438 (sindex == t_index - 1 && string[sindex] == '!' &&
5439 (string[t_index] == '#' ||
5440 string[t_index] == '?' ||
5441 string[t_index] == '@' ||
5442 string[t_index] == '*')))
5446 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
5447 name = (char *)xmalloc (3 + (strlen (temp1)));
5448 *name = string[sindex];
5449 if (string[sindex] == '!')
5451 /* indirect reference of $#, $?, $@, or $* */
5452 name[1] = string[sindex + 1];
5453 strcpy (name + 2, temp1);
5456 strcpy (name + 1, temp1);
5461 /* Find out what character ended the variable name. Then
5462 do the appropriate thing. */
5463 if (c = string[sindex])
5466 /* If c is followed by one of the valid parameter expansion
5467 characters, move past it as normal. If not, assume that
5468 a substring specification is being given, and do not move
5470 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
5473 if (c = string[sindex])
5476 else if (c == ':' && string[sindex] != RBRACE)
5478 else if (c == '/' && string[sindex] != RBRACE)
5481 /* Catch the valid and invalid brace expressions that made it through the
5483 /* ${#-} is a valid expansion and means to take the length of $-.
5484 Similarly for ${#?} and ${##}... */
5485 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
5486 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
5488 name = (char *)xrealloc (name, 3);
5491 c = string[sindex++];
5494 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
5495 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
5496 member (c, "%:=+/") && string[sindex] == RBRACE)
5498 temp = (char *)NULL;
5499 goto bad_substitution;
5502 /* Indirect expansion begins with a `!'. A valid indirect expansion is
5503 either a variable name, one of the positional parameters or a special
5504 variable that expands to one of the positional parameters. */
5505 want_indir = *name == '!' &&
5506 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
5507 || VALID_INDIR_PARAM (name[1]));
5509 /* Determine the value of this variable. */
5511 /* Check for special variables, directly referenced. */
5512 if (SPECIAL_VAR (name, want_indir))
5515 /* Check for special expansion things, like the length of a parameter */
5516 if (*name == '#' && name[1])
5518 /* If we are not pointing at the character just after the
5519 closing brace, then we haven't gotten all of the name.
5520 Since it begins with a special character, this is a bad
5521 substitution. Also check NAME for validity before trying
5523 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
5525 temp = (char *)NULL;
5526 goto bad_substitution;
5529 number = parameter_brace_expand_length (name);
5533 return ((number < 0) ? &expand_param_error : itos (number));
5536 /* ${@} is identical to $@. */
5537 if (name[0] == '@' && name[1] == '\0')
5539 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5540 *quoted_dollar_atp = 1;
5542 if (contains_dollar_at)
5543 *contains_dollar_at = 1;
5546 /* Process ${!PREFIX*} expansion. */
5547 if (want_indir && string[sindex - 1] == RBRACE &&
5548 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
5549 legal_variable_starter ((unsigned char) name[1]))
5554 temp1 = savestring (name + 1);
5555 number = strlen (temp1);
5556 temp1[number - 1] = '\0';
5557 x = all_variables_matching_prefix (temp1);
5558 xlist = strvec_to_word_list (x, 0, 0);
5559 if (string[sindex - 2] == '*')
5560 temp = string_list_dollar_star (xlist);
5563 temp = string_list_dollar_at (xlist, quoted);
5564 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5565 *quoted_dollar_atp = 1;
5566 if (contains_dollar_at)
5567 *contains_dollar_at = 1;
5576 #if defined (ARRAY_VARS)
5577 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
5578 if (want_indir && string[sindex - 1] == RBRACE &&
5579 string[sindex - 2] == ']' && valid_array_reference (name+1))
5583 temp1 = savestring (name + 1);
5584 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
5586 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
5588 temp = array_keys (temp1, quoted);
5591 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5592 *quoted_dollar_atp = 1;
5593 if (contains_dollar_at)
5594 *contains_dollar_at = 1;
5604 #endif /* ARRAY_VARS */
5606 /* Make sure that NAME is valid before trying to go on. */
5607 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
5608 var_is_special) == 0)
5610 temp = (char *)NULL;
5611 goto bad_substitution;
5615 temp = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
5617 temp = parameter_brace_expand_word (name, var_is_special, quoted);
5619 #if defined (ARRAY_VARS)
5620 if (valid_array_reference (name))
5621 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
5624 var_is_set = temp != (char *)0;
5625 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
5627 /* Get the rest of the stuff inside the braces. */
5628 if (c && c != RBRACE)
5630 /* Extract the contents of the ${ ... } expansion
5631 according to the Posix.2 rules. */
5632 value = extract_dollar_brace_string (string, &sindex, quoted, 0);
5633 if (string[sindex] == RBRACE)
5636 goto bad_substitution;
5639 value = (char *)NULL;
5643 /* If this is a substring spec, process it and add the result. */
5646 temp1 = parameter_brace_substring (name, temp, value, quoted);
5652 else if (want_patsub)
5654 temp1 = parameter_brace_patsub (name, temp, value, quoted);
5661 /* Do the right thing based on which character ended the variable name. */
5667 report_error (_("%s: bad substitution"), string ? string : "??");
5671 return &expand_param_error;
5674 if (var_is_set == 0 && unbound_vars_is_error)
5676 err_unboundvar (name);
5680 last_command_exit_value = EXECUTION_FAILURE;
5681 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5685 case '#': /* ${param#[#]pattern} */
5686 case '%': /* ${param%[%]pattern} */
5687 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
5692 temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
5702 if (var_is_set && var_is_null == 0)
5704 /* If the operator is `+', we don't want the value of the named
5705 variable for anything, just the value of the right hand side. */
5709 /* XXX -- if we're double-quoted and the named variable is "$@",
5710 we want to turn off any special handling of "$@" --
5711 we're not using it, so whatever is on the rhs applies. */
5712 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5713 *quoted_dollar_atp = 0;
5714 if (contains_dollar_at)
5715 *contains_dollar_at = 0;
5720 temp = parameter_brace_expand_rhs (name, value, c,
5723 contains_dollar_at);
5727 temp = (char *)NULL;
5733 /* Otherwise do nothing; just use the value in TEMP. */
5735 else /* VAR not set or VAR is NULL. */
5738 temp = (char *)NULL;
5739 if (c == '=' && var_is_special)
5741 report_error (_("$%s: cannot assign in this way"), name);
5744 return &expand_param_error;
5748 parameter_brace_expand_error (name, value);
5749 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5753 /* XXX -- if we're double-quoted and the named variable is "$@",
5754 we want to turn off any special handling of "$@" --
5755 we're not using it, so whatever is on the rhs applies. */
5756 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5757 *quoted_dollar_atp = 0;
5758 if (contains_dollar_at)
5759 *contains_dollar_at = 0;
5761 temp = parameter_brace_expand_rhs (name, value, c, quoted,
5763 contains_dollar_at);
5774 /* Expand a single ${xxx} expansion. The braces are optional. When
5775 the braces are used, parameter_brace_expand() does the work,
5776 possibly calling param_expand recursively. */
5778 param_expand (string, sindex, quoted, expanded_something,
5779 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
5782 int *sindex, quoted, *expanded_something, *contains_dollar_at;
5783 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
5785 char *temp, *temp1, uerror[3];
5786 int zindex, t_index, expok;
5793 c = string[++zindex];
5795 temp = (char *)NULL;
5797 /* Do simple cases first. Switch on what follows '$'. */
5811 temp1 = dollar_vars[TODIGIT (c)];
5812 if (unbound_vars_is_error && temp1 == (char *)NULL)
5817 err_unboundvar (uerror);
5818 last_command_exit_value = EXECUTION_FAILURE;
5819 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5823 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
5824 ? quote_string (temp1)
5825 : quote_escapes (temp1);
5827 temp = (char *)NULL;
5829 temp = temp1 ? quote_escapes (temp1) : (char *)NULL;
5833 /* $$ -- pid of the invoking shell. */
5835 temp = itos (dollar_dollar_pid);
5838 /* $# -- number of positional parameters. */
5840 temp = itos (number_of_args ());
5843 /* $? -- return value of the last synchronous command. */
5845 temp = itos (last_command_exit_value);
5848 /* $- -- flags supplied to the shell on invocation or by `set'. */
5850 temp = which_set_flags ();
5853 /* $! -- Pid of the last asynchronous command. */
5855 /* If no asynchronous pids have been created, expand to nothing.
5856 If `set -u' has been executed, and no async processes have
5857 been created, this is an expansion error. */
5858 if (last_asynchronous_pid == NO_PID)
5860 if (expanded_something)
5861 *expanded_something = 0;
5862 temp = (char *)NULL;
5863 if (unbound_vars_is_error)
5868 err_unboundvar (uerror);
5869 last_command_exit_value = EXECUTION_FAILURE;
5870 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5874 temp = itos (last_asynchronous_pid);
5877 /* The only difference between this and $@ is when the arg is quoted. */
5878 case '*': /* `$*' */
5879 list = list_rest_of_args ();
5881 /* If there are no command-line arguments, this should just
5882 disappear if there are other characters in the expansion,
5883 even if it's quoted. */
5884 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
5885 temp = (char *)NULL;
5886 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5888 /* If we have "$*" we want to make a string of the positional
5889 parameters, separated by the first character of $IFS, and
5890 quote the whole string, including the separators. If IFS
5891 is unset, the parameters are separated by ' '; if $IFS is
5892 null, the parameters are concatenated. */
5894 temp = string_list_dollar_star (list);
5896 temp = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (list) : string_list (list);
5898 temp1 = quote_string (temp);
5904 /* If the $* is not quoted it is identical to $@ */
5905 temp = string_list_dollar_at (list, quoted);
5906 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
5907 *contains_dollar_at = 1;
5910 dispose_words (list);
5913 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
5914 means that we have to turn quoting off after we split into
5915 the individually quoted arguments so that the final split
5916 on the first character of $IFS is still done. */
5917 case '@': /* `$@' */
5918 list = list_rest_of_args ();
5920 /* We want to flag the fact that we saw this. We can't turn
5921 off quoting entirely, because other characters in the
5922 string might need it (consider "\"$@\""), but we need some
5923 way to signal that the final split on the first character
5924 of $IFS should be done, even though QUOTED is 1. */
5925 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
5926 *quoted_dollar_at_p = 1;
5927 if (contains_dollar_at)
5928 *contains_dollar_at = 1;
5930 /* We want to separate the positional parameters with the first
5931 character of $IFS in case $IFS is something other than a space.
5932 We also want to make sure that splitting is done no matter what --
5933 according to POSIX.2, this expands to a list of the positional
5934 parameters no matter what IFS is set to. */
5935 temp = string_list_dollar_at (list, quoted);
5937 dispose_words (list);
5941 temp = parameter_brace_expand (string, &zindex, quoted,
5943 contains_dollar_at);
5944 if (temp == &expand_param_error || temp == &expand_param_fatal)
5948 /* Quoted nulls should be removed if there is anything else
5950 /* Note that we saw the quoted null so we can add one back at
5951 the end of this function if there are no other characters
5952 in the string, discard TEMP, and go on. The exception to
5953 this is when we have "${@}" and $1 is '', since $@ needs
5954 special handling. */
5955 if (temp && QUOTED_NULL (temp))
5957 if (had_quoted_null_p)
5958 *had_quoted_null_p = 1;
5959 if (*quoted_dollar_at_p == 0)
5962 temp = (char *)NULL;
5969 /* Do command or arithmetic substitution. */
5971 /* We have to extract the contents of this paren substitution. */
5972 t_index = zindex + 1;
5973 temp = extract_command_subst (string, &t_index);
5976 /* For Posix.2-style `$(( ))' arithmetic substitution,
5977 extract the expression and pass it to the evaluator. */
5978 if (temp && *temp == LPAREN)
5982 temp2 = savestring (temp1);
5983 t_index = strlen (temp2) - 1;
5985 if (temp2[t_index] != RPAREN)
5991 /* Cut off ending `)' */
5992 temp2[t_index] = '\0';
5994 /* Expand variables found inside the expression. */
5995 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
5999 /* No error messages. */
6000 this_command_name = (char *)NULL;
6001 number = evalexp (temp1, &expok);
6006 if (interactive_shell == 0 && posixly_correct)
6008 last_command_exit_value = EXECUTION_FAILURE;
6009 return (&expand_param_fatal);
6012 return (&expand_param_error);
6014 temp = itos (number);
6019 if (pflags & PF_NOCOMSUB)
6020 /* we need zindex+1 because string[zindex] == RPAREN */
6021 temp1 = substring (string, *sindex, zindex+1);
6023 temp1 = command_substitute (temp, quoted);
6028 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6029 away in a future bash release. */
6031 /* Extract the contents of this arithmetic substitution. */
6032 t_index = zindex + 1;
6033 temp = extract_arithmetic_subst (string, &t_index);
6036 /* Do initial variable expansion. */
6037 temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string);
6042 /* Find the variable in VARIABLE_LIST. */
6043 temp = (char *)NULL;
6045 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
6047 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
6049 /* If this isn't a variable name, then just output the `$'. */
6050 if (temp1 == 0 || *temp1 == '\0')
6053 temp = (char *)xmalloc (2);
6056 if (expanded_something)
6057 *expanded_something = 0;
6061 /* If the variable exists, return its value cell. */
6062 var = find_variable (temp1);
6064 if (var && invisible_p (var) == 0 && var_isset (var))
6066 #if defined (ARRAY_VARS)
6069 temp = array_reference (array_cell (var), 0);
6071 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6072 ? quote_string (temp)
6073 : quote_escapes (temp);
6074 else if (unbound_vars_is_error)
6075 goto unbound_variable;
6080 temp = value_cell (var);
6082 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6083 ? quote_string (temp)
6084 : quote_escapes (temp);
6092 temp = (char *)NULL;
6095 if (unbound_vars_is_error)
6096 err_unboundvar (temp1);
6104 last_command_exit_value = EXECUTION_FAILURE;
6105 return ((unbound_vars_is_error && interactive_shell == 0)
6106 ? &expand_param_fatal
6107 : &expand_param_error);
6118 /* Make a word list which is the result of parameter and variable
6119 expansion, command substitution, arithmetic substitution, and
6120 quote removal of WORD. Return a pointer to a WORD_LIST which is
6121 the result of the expansion. If WORD contains a null word, the
6122 word list returned is also null.
6124 QUOTED contains flag values defined in shell.h.
6126 ISEXP is used to tell expand_word_internal that the word should be
6127 treated as the result of an expansion. This has implications for
6128 how IFS characters in the word are treated.
6130 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6131 they point to an integer value which receives information about expansion.
6132 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6133 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6136 This only does word splitting in the case of $@ expansion. In that
6137 case, we split on ' '. */
6139 /* Values for the local variable quoted_state. */
6141 #define PARTIALLY_QUOTED 1
6142 #define WHOLLY_QUOTED 2
6145 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
6148 int *contains_dollar_at;
6149 int *expanded_something;
6154 /* The intermediate string that we build while expanding. */
6157 /* The current size of the above object. */
6160 /* Index into ISTRING. */
6163 /* Temporary string storage. */
6166 /* The text of WORD. */
6167 register char *string;
6169 /* The size of STRING. */
6172 /* The index into STRING. */
6175 /* This gets 1 if we see a $@ while quoted. */
6176 int quoted_dollar_at;
6178 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6179 whether WORD contains no quoting characters, a partially quoted
6180 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6183 int had_quoted_null;
6187 register unsigned char c; /* Current character. */
6188 int t_index; /* For calls to string_extract_xxx. */
6194 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
6195 istring[istring_index = 0] = '\0';
6196 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
6197 quoted_state = UNQUOTED;
6199 string = word->word;
6201 goto finished_with_string;
6202 string_size = strlen (string);
6204 if (contains_dollar_at)
6205 *contains_dollar_at = 0;
6207 /* Begin the expansion. */
6213 /* Case on toplevel character. */
6217 goto finished_with_string;
6221 #if HANDLE_MULTIBYTE
6222 if (MB_CUR_MAX > 1 && string[sindex])
6224 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6229 temp = (char *)xmalloc (3);
6231 temp[1] = c = string[sindex];
6242 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
6248 #if defined (PROCESS_SUBSTITUTION)
6249 /* Process substitution. */
6253 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || posixly_correct)
6255 sindex--; /* add_character: label increments sindex */
6259 t_index = sindex + 1; /* skip past both '<' and LPAREN */
6261 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
6264 /* If the process substitution specification is `<()', we want to
6265 open the pipe for writing in the child and produce output; if
6266 it is `>()', we want to open the pipe for reading in the child
6267 and consume input. */
6268 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
6272 goto dollar_add_string;
6274 #endif /* PROCESS_SUBSTITUTION */
6277 if (expanded_something)
6278 *expanded_something = 1;
6281 temp = param_expand (string, &sindex, quoted, expanded_something,
6282 &has_dollar_at, "ed_dollar_at,
6284 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
6286 if (temp == &expand_param_error || temp == &expand_param_fatal)
6290 return ((temp == &expand_param_error) ? &expand_word_error
6291 : &expand_word_fatal);
6293 if (contains_dollar_at && has_dollar_at)
6294 *contains_dollar_at = 1;
6298 case '`': /* Backquoted command substitution. */
6302 if (expanded_something)
6303 *expanded_something = 1;
6305 temp = string_extract (string, &sindex, "`", 0);
6306 if (word->flags & W_NOCOMSUB)
6307 /* sindex + 1 because string[sindex] == '`' */
6308 temp1 = substring (string, t_index, sindex + 1);
6311 de_backslash (temp);
6312 temp1 = command_substitute (temp, quoted);
6316 goto dollar_add_string;
6320 if (string[sindex + 1] == '\n')
6326 c = string[++sindex];
6328 if (quoted & Q_HERE_DOCUMENT)
6330 else if (quoted & Q_DOUBLE_QUOTES)
6335 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
6337 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
6342 sindex--; /* add_character: label increments sindex */
6347 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
6352 /* BEFORE jumping here, we need to increment sindex if appropriate */
6353 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
6354 DEFAULT_ARRAY_SIZE);
6355 istring[istring_index++] = twochars[0];
6356 istring[istring_index++] = twochars[1];
6357 istring[istring_index] = '\0';
6363 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_PATQUOTE))
6365 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6370 temp = string_extract_double_quoted (string, &sindex, 0);
6372 /* If the quotes surrounded the entire string, then the
6373 whole word was quoted. */
6374 quoted_state = (t_index == 1 && string[sindex] == '\0')
6380 tword = make_word (temp); /* XXX */
6382 temp = (char *)NULL;
6385 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
6387 if (list == &expand_word_error || list == &expand_word_fatal)
6391 /* expand_word_internal has already freed temp_word->word
6392 for us because of the way it prints error messages. */
6393 tword->word = (char *)NULL;
6394 dispose_word (tword);
6398 dispose_word (tword);
6400 /* "$@" (a double-quoted dollar-at) expands into nothing,
6401 not even a NULL word, when there are no positional
6403 if (list == 0 && has_dollar_at)
6409 /* If we get "$@", we know we have expanded something, so we
6410 need to remember it for the final split on $IFS. This is
6411 a special case; it's the only case where a quoted string
6412 can expand into more than one word. It's going to come back
6413 from the above call to expand_word_internal as a list with
6414 a single word, in which all characters are quoted and
6415 separated by blanks. What we want to do is to turn it back
6416 into a list for the next piece of code. */
6418 dequote_list (list);
6423 if (contains_dollar_at)
6424 *contains_dollar_at = 1;
6425 if (expanded_something)
6426 *expanded_something = 1;
6431 /* What we have is "". This is a minor optimization. */
6433 list = (WORD_LIST *)NULL;
6436 /* The code above *might* return a list (consider the case of "$@",
6437 where it returns "$1", "$2", etc.). We can't throw away the
6438 rest of the list, and we have to make sure each word gets added
6439 as quoted. We test on tresult->next: if it is non-NULL, we
6440 quote the whole list, save it to a string with string_list, and
6441 add that string. We don't need to quote the results of this
6442 (and it would be wrong, since that would quote the separators
6443 as well), so we go directly to add_string. */
6448 /* Testing quoted_dollar_at makes sure that "$@" is
6449 split correctly when $IFS does not contain a space. */
6450 temp = quoted_dollar_at
6451 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
6452 : string_list (quote_list (list));
6453 dispose_words (list);
6458 temp = savestring (list->word->word);
6459 dispose_words (list);
6461 /* If the string is not a quoted null string, we want
6462 to remove any embedded unquoted CTLNUL characters.
6463 We do not want to turn quoted null strings back into
6464 the empty string, though. We do this because we
6465 want to remove any quoted nulls from expansions that
6466 contain other characters. For example, if we have
6467 x"$*"y or "x$*y" and there are no positional parameters,
6468 the $* should expand into nothing. */
6469 /* HOWEVER, this fails if the string contains a literal
6470 CTLNUL or CTLNUL is contained in the (non-null) expansion
6471 of some variable. I'm not sure what to do about this
6472 yet. There has to be some way to indicate the difference
6473 between the two. An auxiliary data structure might be
6475 if (QUOTED_NULL (temp) == 0)
6476 remove_quoted_nulls (temp); /* XXX */
6481 temp = (char *)NULL;
6483 /* We do not want to add quoted nulls to strings that are only
6484 partially quoted; we can throw them away. */
6485 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
6493 temp = quote_string (temp);
6501 sindex--; /* add_character: label increments sindex */
6509 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_PATQUOTE))
6511 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6516 temp = string_extract_single_quoted (string, &sindex);
6518 /* If the entire STRING was surrounded by single quotes,
6519 then the string is wholly quoted. */
6520 quoted_state = (t_index == 1 && string[sindex] == '\0')
6524 /* If all we had was '', it is a null expansion. */
6528 temp = (char *)NULL;
6531 remove_quoted_escapes (temp); /* ??? */
6533 /* We do not want to add quoted nulls to strings that are only
6534 partially quoted; such nulls are discarded. */
6535 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
6538 /* If we have a quoted null expansion, add a quoted NULL to istring. */
6542 sindex--; /* add_character: label increments sindex */
6546 goto add_quoted_string;
6551 /* This is the fix for " $@ " */
6552 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
6554 if (string[sindex]) /* from old goto dollar_add_string */
6563 #if HANDLE_MULTIBYTE
6569 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6574 twochars[0] = CTLESC;
6581 SADD_MBCHAR (temp, string, sindex, string_size);
6584 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
6585 DEFAULT_ARRAY_SIZE);
6586 istring[istring_index++] = c;
6587 istring[istring_index] = '\0';
6589 /* Next character. */
6594 finished_with_string:
6595 /* OK, we're ready to return. If we have a quoted string, and
6596 quoted_dollar_at is not set, we do no splitting at all; otherwise
6597 we split on ' '. The routines that call this will handle what to
6598 do if nothing has been expanded. */
6600 /* Partially and wholly quoted strings which expand to the empty
6601 string are retained as an empty arguments. Unquoted strings
6602 which expand to the empty string are discarded. The single
6603 exception is the case of expanding "$@" when there are no
6604 positional parameters. In that case, we discard the expansion. */
6606 /* Because of how the code that handles "" and '' in partially
6607 quoted strings works, we need to make ISTRING into a QUOTED_NULL
6608 if we saw quoting characters, but the expansion was empty.
6609 "" and '' are tossed away before we get to this point when
6610 processing partially quoted strings. This makes "" and $xxx""
6611 equivalent when xxx is unset. We also look to see whether we
6612 saw a quoted null from a ${} expansion and add one back if we
6615 /* If we expand to nothing and there were no single or double quotes
6616 in the word, we throw it away. Otherwise, we return a NULL word.
6617 The single exception is for $@ surrounded by double quotes when
6618 there are no positional parameters. In that case, we also throw
6621 if (*istring == '\0')
6623 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
6625 istring[0] = CTLNUL;
6627 tword = make_bare_word (istring);
6628 list = make_word_list (tword, (WORD_LIST *)NULL);
6629 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6630 tword->flags |= W_QUOTED;
6632 /* According to sh, ksh, and Posix.2, if a word expands into nothing
6633 and a double-quoted "$@" appears anywhere in it, then the entire
6635 else if (quoted_state == UNQUOTED || quoted_dollar_at)
6636 list = (WORD_LIST *)NULL;
6640 tword = make_bare_word (istring);
6641 list = make_word_list (tword, (WORD_LIST *)NULL);
6642 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6643 tword->flags |= W_QUOTED;
6647 list = (WORD_LIST *)NULL;
6650 else if (word->flags & W_NOSPLIT)
6652 tword = make_bare_word (istring);
6653 list = make_word_list (tword, (WORD_LIST *)NULL);
6654 if (word->flags & W_ASSIGNMENT)
6655 tword->flags |= W_ASSIGNMENT; /* XXX */
6656 if (word->flags & W_NOGLOB)
6657 tword->flags |= W_NOGLOB; /* XXX */
6658 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6659 tword->flags |= W_QUOTED;
6665 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
6667 /* If we have $@, we need to split the results no matter what. If
6668 IFS is unset or NULL, string_list_dollar_at has separated the
6669 positional parameters with a space, so we split on space (we have
6670 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
6671 string_list_dollar_at has separated the positional parameters
6672 with the first character of $IFS, so we split on $IFS. */
6673 if (has_dollar_at && ifs_chars)
6674 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
6677 tword = make_bare_word (istring);
6678 list = make_word_list (tword, (WORD_LIST *)NULL);
6679 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
6680 tword->flags |= W_QUOTED;
6681 if (word->flags & W_ASSIGNMENT)
6682 tword->flags |= W_ASSIGNMENT;
6683 if (word->flags & W_NOGLOB)
6684 tword->flags |= W_NOGLOB;
6692 /* **************************************************************** */
6694 /* Functions for Quote Removal */
6696 /* **************************************************************** */
6698 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
6699 backslash quoting rules for within double quotes or a here document. */
6701 string_quote_removal (string, quoted)
6706 char *r, *result_string, *temp, *send;
6707 int sindex, tindex, dquote;
6711 /* The result can be no longer than the original string. */
6712 slen = strlen (string);
6713 send = string + slen;
6715 r = result_string = (char *)xmalloc (slen + 1);
6717 for (dquote = sindex = 0; c = string[sindex];)
6722 c = string[++sindex];
6723 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
6728 SCOPY_CHAR_M (r, string, send, sindex);
6732 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
6738 tindex = sindex + 1;
6739 temp = string_extract_single_quoted (string, &tindex);
6750 dquote = 1 - dquote;
6756 return (result_string);
6761 /* Perform quote removal on word WORD. This allocates and returns a new
6764 word_quote_removal (word, quoted)
6771 t = string_quote_removal (word->word, quoted);
6772 w = make_bare_word (t);
6777 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
6778 the members of the list are treated as if they are surrounded by
6779 double quotes. Return a new list, or NULL if LIST is NULL. */
6781 word_list_quote_removal (list, quoted)
6785 WORD_LIST *result, *t, *tresult;
6787 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
6789 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
6790 result = (WORD_LIST *) list_append (result, tresult);
6796 /*******************************************
6798 * Functions to perform word splitting *
6800 *******************************************/
6810 ifs_value = v ? value_cell (v) : " \t\n";
6812 /* Should really merge ifs_cmap with sh_syntaxtab. */
6813 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
6814 for (t = ifs_value ; t && *t; t++)
6820 ifs_firstc = ifs_value ? *ifs_value : 0;
6829 /* This splits a single word into a WORD LIST on $IFS, but only if the word
6830 is not quoted. list_string () performs quote removal for us, even if we
6831 don't do any splitting. */
6833 word_split (w, ifs_chars)
6843 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
6844 result = list_string (w->word, xifs, w->flags & W_QUOTED);
6847 result = (WORD_LIST *)NULL;
6852 /* Perform word splitting on LIST and return the RESULT. It is possible
6853 to return (WORD_LIST *)NULL. */
6855 word_list_split (list)
6858 WORD_LIST *result, *t, *tresult;
6860 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
6862 tresult = word_split (t->word, ifs_value);
6863 result = (WORD_LIST *) list_append (result, tresult);
6868 /**************************************************
6870 * Functions to expand an entire WORD_LIST *
6872 **************************************************/
6874 /* Do any word-expansion-specific cleanup and jump to top_level */
6876 exp_jump_to_top_level (v)
6879 /* Cleanup code goes here. */
6880 expand_no_split_dollar_star = 0; /* XXX */
6881 expanding_redir = 0;
6883 jump_to_top_level (v);
6886 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
6887 ELIST, and set ELIST to the new list. */
6888 #define PREPEND_LIST(nlist, elist) \
6889 do { nlist->next = elist; elist = nlist; } while (0)
6891 /* Separate out any initial variable assignments from TLIST. If set -k has
6892 been executed, remove all assignment statements from TLIST. Initial
6893 variable assignments and other environment assignments are placed
6894 on SUBST_ASSIGN_VARLIST. */
6896 separate_out_assignments (tlist)
6899 register WORD_LIST *vp, *lp;
6902 return ((WORD_LIST *)NULL);
6904 if (subst_assign_varlist)
6905 dispose_words (subst_assign_varlist); /* Clean up after previous error */
6907 subst_assign_varlist = (WORD_LIST *)NULL;
6910 /* Separate out variable assignments at the start of the command.
6911 Loop invariant: vp->next == lp
6913 lp = list of words left after assignment statements skipped
6914 tlist = original list of words
6916 while (lp && (lp->word->flags & W_ASSIGNMENT))
6922 /* If lp != tlist, we have some initial assignment statements.
6923 We make SUBST_ASSIGN_VARLIST point to the list of assignment
6924 words and TLIST point to the remaining words. */
6927 subst_assign_varlist = tlist;
6928 /* ASSERT(vp->next == lp); */
6929 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
6930 tlist = lp; /* remainder of word list */
6933 /* vp == end of variable list */
6934 /* tlist == remainder of original word list without variable assignments */
6936 /* All the words in tlist were assignment statements */
6937 return ((WORD_LIST *)NULL);
6939 /* ASSERT(tlist != NULL); */
6940 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
6942 /* If the -k option is in effect, we need to go through the remaining
6943 words, separate out the assignment words, and place them on
6944 SUBST_ASSIGN_VARLIST. */
6945 if (place_keywords_in_env)
6947 WORD_LIST *tp; /* tp == running pointer into tlist */
6952 /* Loop Invariant: tp->next == lp */
6953 /* Loop postcondition: tlist == word list without assignment statements */
6956 if (lp->word->flags & W_ASSIGNMENT)
6958 /* Found an assignment statement, add this word to end of
6959 subst_assign_varlist (vp). */
6960 if (!subst_assign_varlist)
6961 subst_assign_varlist = vp = lp;
6968 /* Remove the word pointed to by LP from TLIST. */
6969 tp->next = lp->next;
6970 /* ASSERT(vp == lp); */
6971 lp->next = (WORD_LIST *)NULL;
6984 #define WEXP_VARASSIGN 0x001
6985 #define WEXP_BRACEEXP 0x002
6986 #define WEXP_TILDEEXP 0x004
6987 #define WEXP_PARAMEXP 0x008
6988 #define WEXP_PATHEXP 0x010
6990 /* All of the expansions, including variable assignments at the start of
6992 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6994 /* All of the expansions except variable assignments at the start of
6996 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6998 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
6999 expansion, command substitution, arithmetic expansion, word splitting, and
7001 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7003 /* Take the list of words in LIST and do the various substitutions. Return
7004 a new list of words which is the expanded list, and without things like
7005 variable assignments. */
7011 return (expand_word_list_internal (list, WEXP_ALL));
7014 /* Same as expand_words (), but doesn't hack variable or environment
7017 expand_words_no_vars (list)
7020 return (expand_word_list_internal (list, WEXP_NOVARS));
7024 expand_words_shellexp (list)
7027 return (expand_word_list_internal (list, WEXP_SHELLEXP));
7031 glob_expand_word_list (tlist, eflags)
7035 char **glob_array, *temp_string;
7036 register int glob_index;
7037 WORD_LIST *glob_list, *output_list, *disposables, *next;
7040 output_list = disposables = (WORD_LIST *)NULL;
7041 glob_array = (char **)NULL;
7044 /* For each word, either globbing is attempted or the word is
7045 added to orig_list. If globbing succeeds, the results are
7046 added to orig_list and the word (tlist) is added to the list
7047 of disposable words. If globbing fails and failed glob
7048 expansions are left unchanged (the shell default), the
7049 original word is added to orig_list. If globbing fails and
7050 failed glob expansions are removed, the original word is
7051 added to the list of disposable words. orig_list ends up
7052 in reverse order and requires a call to REVERSE_LIST to
7053 be set right. After all words are examined, the disposable
7057 /* If the word isn't an assignment and contains an unquoted
7058 pattern matching character, then glob it. */
7059 if ((tlist->word->flags & W_NOGLOB) == 0 &&
7060 unquoted_glob_pattern_p (tlist->word->word))
7062 glob_array = shell_glob_filename (tlist->word->word);
7064 /* Handle error cases.
7065 I don't think we should report errors like "No such file
7066 or directory". However, I would like to report errors
7067 like "Read failed". */
7069 if (glob_array == 0 || GLOB_FAILED (glob_array))
7071 glob_array = (char **)xmalloc (sizeof (char *));
7072 glob_array[0] = (char *)NULL;
7075 /* Dequote the current word in case we have to use it. */
7076 if (glob_array[0] == NULL)
7078 temp_string = dequote_string (tlist->word->word);
7079 free (tlist->word->word);
7080 tlist->word->word = temp_string;
7083 /* Make the array into a word list. */
7084 glob_list = (WORD_LIST *)NULL;
7085 for (glob_index = 0; glob_array[glob_index]; glob_index++)
7087 tword = make_bare_word (glob_array[glob_index]);
7088 tword->flags |= W_GLOBEXP; /* XXX */
7089 glob_list = make_word_list (tword, glob_list);
7094 output_list = (WORD_LIST *)list_append (glob_list, output_list);
7095 PREPEND_LIST (tlist, disposables);
7097 else if (fail_glob_expansion != 0)
7099 report_error (_("no match: %s"), tlist->word->word);
7100 jump_to_top_level (DISCARD);
7102 else if (allow_null_glob_expansion == 0)
7104 /* Failed glob expressions are left unchanged. */
7105 PREPEND_LIST (tlist, output_list);
7109 /* Failed glob expressions are removed. */
7110 PREPEND_LIST (tlist, disposables);
7115 /* Dequote the string. */
7116 temp_string = dequote_string (tlist->word->word);
7117 free (tlist->word->word);
7118 tlist->word->word = temp_string;
7119 PREPEND_LIST (tlist, output_list);
7122 strvec_dispose (glob_array);
7123 glob_array = (char **)NULL;
7129 dispose_words (disposables);
7132 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7134 return (output_list);
7137 #if defined (BRACE_EXPANSION)
7139 brace_expand_word_list (tlist, eflags)
7143 register char **expansions;
7145 WORD_LIST *disposables, *output_list, *next;
7149 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
7153 /* Only do brace expansion if the word has a brace character. If
7154 not, just add the word list element to BRACES and continue. In
7155 the common case, at least when running shell scripts, this will
7156 degenerate to a bunch of calls to `xstrchr', and then what is
7157 basically a reversal of TLIST into BRACES, which is corrected
7158 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7160 if (xstrchr (tlist->word->word, LBRACE))
7162 expansions = brace_expand (tlist->word->word);
7164 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
7166 w = make_word (temp_string);
7167 /* If brace expansion didn't change the word, preserve
7168 the flags. We may want to preserve the flags
7169 unconditionally someday -- XXX */
7170 if (STREQ (temp_string, tlist->word->word))
7171 w->flags = tlist->word->flags;
7172 output_list = make_word_list (w, output_list);
7173 free (expansions[eindex]);
7177 /* Add TLIST to the list of words to be freed after brace
7178 expansion has been performed. */
7179 PREPEND_LIST (tlist, disposables);
7182 PREPEND_LIST (tlist, output_list);
7186 dispose_words (disposables);
7189 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7191 return (output_list);
7196 shell_expand_word_list (tlist, eflags)
7200 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
7201 int expanded_something, has_dollar_at;
7204 /* We do tilde expansion all the time. This is what 1003.2 says. */
7205 new_list = (WORD_LIST *)NULL;
7206 for (orig_list = tlist; tlist; tlist = next)
7208 temp_string = tlist->word->word;
7212 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7213 which are not assignment statements are not expanded. If the
7214 shell isn't in posix mode, though, we perform tilde expansion
7215 on `likely candidate' unquoted assignment statements (flags
7216 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7217 contains an unquoted :~ or =~. Something to think about: we
7218 now have a flag that says to perform tilde expansion on arguments
7219 to `assignment builtins' like declare and export that look like
7220 assignment statements. We now do tilde expansion on such words
7221 even in POSIX mode. */
7222 if (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
7223 (posixly_correct == 0 || (tlist->word->flags & W_TILDEEXP)) &&
7224 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string)))
7226 tlist->word->word = bash_tilde_expand (temp_string, 1);
7229 else if (temp_string[0] == '~')
7231 tlist->word->word = bash_tilde_expand (temp_string, 0);
7235 expanded_something = 0;
7236 expanded = expand_word_internal
7237 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
7239 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
7241 /* By convention, each time this error is returned,
7242 tlist->word->word has already been freed. */
7243 tlist->word->word = (char *)NULL;
7245 /* Dispose our copy of the original list. */
7246 dispose_words (orig_list);
7247 /* Dispose the new list we're building. */
7248 dispose_words (new_list);
7250 last_command_exit_value = EXECUTION_FAILURE;
7251 if (expanded == &expand_word_error)
7252 exp_jump_to_top_level (DISCARD);
7254 exp_jump_to_top_level (FORCE_EOF);
7257 /* Don't split words marked W_NOSPLIT. */
7258 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
7260 temp_list = word_list_split (expanded);
7261 dispose_words (expanded);
7265 /* If no parameter expansion, command substitution, process
7266 substitution, or arithmetic substitution took place, then
7267 do not do word splitting. We still have to remove quoted
7268 null characters from the result. */
7269 word_list_remove_quoted_nulls (expanded);
7270 temp_list = expanded;
7273 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
7274 new_list = (WORD_LIST *)list_append (expanded, new_list);
7278 dispose_words (orig_list);
7281 new_list = REVERSE_LIST (new_list, WORD_LIST *);
7286 /* The workhorse for expand_words () and expand_words_no_vars ().
7287 First arg is LIST, a WORD_LIST of words.
7288 Second arg EFLAGS is a flags word controlling which expansions are
7291 This does all of the substitutions: brace expansion, tilde expansion,
7292 parameter expansion, command substitution, arithmetic expansion,
7293 process substitution, word splitting, and pathname expansion, according
7294 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
7295 set, or for which no expansion is done, do not undergo word splitting.
7296 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
7298 expand_word_list_internal (list, eflags)
7302 WORD_LIST *new_list, *temp_list;
7306 return ((WORD_LIST *)NULL);
7308 garglist = new_list = copy_word_list (list);
7309 if (eflags & WEXP_VARASSIGN)
7311 garglist = new_list = separate_out_assignments (new_list);
7314 if (subst_assign_varlist)
7316 /* All the words were variable assignments, so they are placed
7317 into the shell's environment. */
7318 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
7320 this_command_name = (char *)NULL; /* no arithmetic errors */
7321 tint = do_assignment (temp_list->word->word);
7322 /* Variable assignment errors in non-interactive shells
7323 running in Posix.2 mode cause the shell to exit. */
7326 last_command_exit_value = EXECUTION_FAILURE;
7327 if (interactive_shell == 0 && posixly_correct)
7328 exp_jump_to_top_level (FORCE_EOF);
7330 exp_jump_to_top_level (DISCARD);
7333 dispose_words (subst_assign_varlist);
7334 subst_assign_varlist = (WORD_LIST *)NULL;
7336 return ((WORD_LIST *)NULL);
7340 /* Begin expanding the words that remain. The expansions take place on
7341 things that aren't really variable assignments. */
7343 #if defined (BRACE_EXPANSION)
7344 /* Do brace expansion on this word if there are any brace characters
7346 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
7347 new_list = brace_expand_word_list (new_list, eflags);
7348 #endif /* BRACE_EXPANSION */
7350 /* Perform the `normal' shell expansions: tilde expansion, parameter and
7351 variable substitution, command substitution, arithmetic expansion,
7352 and word splitting. */
7353 new_list = shell_expand_word_list (new_list, eflags);
7355 /* Okay, we're almost done. Now let's just do some filename
7359 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
7360 /* Glob expand the word list unless globbing has been disabled. */
7361 new_list = glob_expand_word_list (new_list, eflags);
7363 /* Dequote the words, because we're not performing globbing. */
7364 new_list = dequote_list (new_list);
7367 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
7369 sh_assign_func_t *assign_func;
7371 /* If the remainder of the words expand to nothing, Posix.2 requires
7372 that the variable and environment assignments affect the shell's
7374 assign_func = new_list ? assign_in_env : do_assignment;
7375 tempenv_assign_error = 0;
7377 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
7379 this_command_name = (char *)NULL;
7380 tint = (*assign_func) (temp_list->word->word);
7381 /* Variable assignment errors in non-interactive shells running
7382 in Posix.2 mode cause the shell to exit. */
7385 if (assign_func == do_assignment)
7387 last_command_exit_value = EXECUTION_FAILURE;
7388 if (interactive_shell == 0 && posixly_correct)
7389 exp_jump_to_top_level (FORCE_EOF);
7391 exp_jump_to_top_level (DISCARD);
7394 tempenv_assign_error++;
7398 dispose_words (subst_assign_varlist);
7399 subst_assign_varlist = (WORD_LIST *)NULL;
7403 tint = list_length (new_list) + 1;
7404 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
7405 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
7406 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
7407 glob_argv_flags[tint] = '\0';