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 /* Handle the parameter brace expansion that requires us to return the
4695 length of a parameter. */
4697 parameter_brace_expand_length (name)
4701 intmax_t number, arg_index;
4703 #if defined (ARRAY_VARS)
4707 if (name[1] == '\0') /* ${#} */
4708 number = number_of_args ();
4709 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
4710 number = number_of_args ();
4711 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
4713 /* Take the lengths of some of the shell's special parameters. */
4717 t = which_set_flags ();
4720 t = itos (last_command_exit_value);
4723 t = itos (dollar_dollar_pid);
4726 if (last_asynchronous_pid == NO_PID)
4729 t = itos (last_asynchronous_pid);
4732 t = itos (number_of_args ());
4735 number = STRLEN (t);
4738 #if defined (ARRAY_VARS)
4739 else if (valid_array_reference (name + 1))
4740 number = array_length_reference (name + 1);
4741 #endif /* ARRAY_VARS */
4746 if (legal_number (name + 1, &arg_index)) /* ${#1} */
4748 t = get_dollar_var_value (arg_index);
4749 number = STRLEN (t);
4752 #if defined (ARRAY_VARS)
4753 else if ((var = find_variable (name + 1)) && array_p (var))
4755 t = array_reference (array_cell (var), 0);
4756 number = STRLEN (t);
4761 newname = savestring (name);
4763 list = expand_string (newname, Q_DOUBLE_QUOTES);
4764 t = list ? string_list (list) : (char *)NULL;
4767 dispose_words (list);
4769 number = STRLEN (t);
4777 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
4778 so we do some ad-hoc parsing of an arithmetic expression to find
4779 the first DELIM, instead of using strchr(3). Two rules:
4780 1. If the substring contains a `(', read until closing `)'.
4781 2. If the substring contains a `?', read past one `:' for each `?'.
4785 skiparith (substr, delim)
4790 int skipcol, pcount, i;
4793 sublen = strlen (substr);
4794 i = skipcol = pcount = 0;
4797 /* Balance parens */
4798 if (substr[i] == LPAREN)
4804 if (substr[i] == RPAREN && pcount)
4812 ADVANCE_CHAR (substr, sublen, i);
4816 /* Skip one `:' for each `?' */
4817 if (substr[i] == ':' && skipcol)
4823 if (substr[i] == delim)
4825 if (substr[i] == '?')
4831 ADVANCE_CHAR (substr, sublen, i);
4834 return (substr + i);
4837 /* Verify and limit the start and end of the desired substring. If
4838 VTYPE == 0, a regular shell variable is being used; if it is 1,
4839 then the positional parameters are being used; if it is 2, then
4840 VALUE is really a pointer to an array variable that should be used.
4841 Return value is 1 if both values were OK, 0 if there was a problem
4842 with an invalid expression, or -1 if the values were out of range. */
4844 verify_substring_values (value, substr, vtype, e1p, e2p)
4845 char *value, *substr;
4847 intmax_t *e1p, *e2p;
4849 char *t, *temp1, *temp2;
4852 #if defined (ARRAY_VARS)
4856 /* duplicate behavior of strchr(3) */
4857 t = skiparith (substr, ':');
4858 if (*t && *t == ':')
4863 temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string);
4864 *e1p = evalexp (temp1, &expok);
4869 len = -1; /* paranoia */
4873 case VT_ARRAYMEMBER:
4874 len = strlen (value);
4877 len = number_of_args () + 1;
4879 #if defined (ARRAY_VARS)
4882 /* For arrays, the first value deals with array indices. */
4883 len = array_max_index (a); /* arrays index from 0 to n - 1 */
4888 if (len == -1) /* paranoia */
4891 if (*e1p < 0) /* negative offsets count from end */
4894 if (*e1p >= len || *e1p < 0)
4897 #if defined (ARRAY_VARS)
4898 /* For arrays, the second offset deals with the number of elements. */
4899 if (vtype == VT_ARRAYVAR)
4900 len = array_num_elements (a);
4906 temp2 = savestring (t);
4907 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
4910 *e2p = evalexp (temp1, &expok);
4916 internal_error (_("%s: substring expression < 0"), t);
4919 #if defined (ARRAY_VARS)
4920 /* In order to deal with sparse arrays, push the intelligence about how
4921 to deal with the number of elements desired down to the array-
4922 specific functions. */
4923 if (vtype != VT_ARRAYVAR)
4926 *e2p += *e1p; /* want E2 chars starting at E1 */
4937 /* Return the type of variable specified by VARNAME (simple variable,
4938 positional param, or array variable). Also return the value specified
4939 by VARNAME (value of a variable or a reference to an array element).
4940 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
4941 characters in the value are quoted with CTLESC and takes appropriate
4942 steps. For convenience, *VALP is set to the dequoted VALUE. */
4944 get_var_and_type (varname, value, quoted, varp, valp)
4945 char *varname, *value;
4952 #if defined (ARRAY_VARS)
4956 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
4957 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
4958 if (vtype == VT_POSPARMS && varname[0] == '*')
4959 vtype |= VT_STARSUB;
4960 *varp = (SHELL_VAR *)NULL;
4962 #if defined (ARRAY_VARS)
4963 if (valid_array_reference (varname))
4965 v = array_variable_part (varname, &temp, (int *)0);
4966 if (v && array_p (v))
4968 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
4970 vtype = VT_ARRAYVAR;
4972 vtype |= VT_STARSUB;
4973 *valp = (char *)array_cell (v);
4977 vtype = VT_ARRAYMEMBER;
4978 *valp = array_value (varname, 1, (int *)NULL);
4985 else if ((v = find_variable (varname)) && array_p (v))
4987 vtype = VT_ARRAYMEMBER;
4989 *valp = array_reference (array_cell (v), 0);
4995 if (value && vtype == VT_VARIABLE)
4997 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
4998 *valp = dequote_string (value);
5000 *valp = dequote_escapes (value);
5006 *valp = (value && vtype == VT_VARIABLE) ? dequote_escapes (value) : value;
5012 /******************************************************/
5014 /* Functions to extract substrings of variable values */
5016 /******************************************************/
5018 #if defined (HANDLE_MULTIBYTE)
5019 /* Character-oriented rather than strictly byte-oriented substrings. S and
5020 E, rather being strict indices into STRING, indicate character (possibly
5021 multibyte character) positions that require calculation.
5022 Used by the ${param:offset[:length]} expansion. */
5024 mb_substring (string, s, e)
5029 int start, stop, i, slen;
5033 slen = STRLEN (string);
5036 while (string[start] && i--)
5037 ADVANCE_CHAR (string, slen, start);
5040 while (string[stop] && i--)
5041 ADVANCE_CHAR (string, slen, stop);
5042 tt = substring (string, start, stop);
5047 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5048 is `@', use the positional parameters; otherwise, use the value of
5049 VARNAME. If VARNAME is an array variable, use the array elements. */
5052 parameter_brace_substring (varname, value, substr, quoted)
5053 char *varname, *value, *substr;
5057 int vtype, r, starsub;
5058 char *temp, *val, *tt;
5062 return ((char *)NULL);
5064 this_command_name = varname;
5066 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5068 return ((char *)NULL);
5070 starsub = vtype & VT_STARSUB;
5071 vtype &= ~VT_STARSUB;
5073 r = verify_substring_values (val, substr, vtype, &e1, &e2);
5075 return ((r == 0) ? &expand_param_error : (char *)NULL);
5080 case VT_ARRAYMEMBER:
5081 #if defined (HANDLE_MULTIBYTE)
5083 tt = mb_substring (val, e1, e2);
5086 tt = substring (val, e1, e2);
5088 if (vtype == VT_VARIABLE)
5090 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5091 temp = quote_string (tt);
5093 temp = tt ? quote_escapes (tt) : (char *)NULL;
5097 tt = pos_params (varname, e1, e2, quoted);
5098 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5100 temp = tt ? quote_escapes (tt) : (char *)NULL;
5106 #if defined (ARRAY_VARS)
5108 /* We want E2 to be the number of elements desired (arrays can be sparse,
5109 so verify_substring_values just returns the numbers specified and we
5110 rely on array_subrange to understand how to deal with them). */
5111 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
5112 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5114 temp = tt ? quote_escapes (tt) : (char *)NULL;
5122 temp = (char *)NULL;
5128 /****************************************************************/
5130 /* Functions to perform pattern substitution on variable values */
5132 /****************************************************************/
5135 pat_subst (string, pat, rep, mflags)
5136 char *string, *pat, *rep;
5139 char *ret, *s, *e, *str;
5140 int rsize, rptr, l, replen, mtype;
5142 mtype = mflags & MATCH_TYPEMASK;
5145 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5146 * with REP and return the result.
5147 * 2. A null pattern with mtype == MATCH_END means to append REP to
5148 * STRING and return the result.
5150 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
5152 replen = STRLEN (rep);
5153 l = strlen (string);
5154 ret = (char *)xmalloc (replen + l + 2);
5156 strcpy (ret, string);
5157 else if (mtype == MATCH_BEG)
5160 strcpy (ret + replen, string);
5164 strcpy (ret, string);
5165 strcpy (ret + l, rep);
5170 ret = (char *)xmalloc (rsize = 64);
5173 for (replen = STRLEN (rep), rptr = 0, str = string;;)
5175 if (match_pattern (str, pat, mtype, &s, &e) == 0)
5178 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
5180 /* OK, now copy the leading unmatched portion of the string (from
5181 str to s) to ret starting at rptr (the current offset). Then copy
5182 the replacement string at ret + rptr + (s - str). Increment
5183 rptr (if necessary) and str and go on. */
5186 strncpy (ret + rptr, str, l);
5191 strncpy (ret + rptr, rep, replen);
5194 str = e; /* e == end of match */
5196 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
5200 e++, str++; /* avoid infinite recursion on zero-length match */
5203 /* Now copy the unmatched portion of the input string */
5206 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
5207 strcpy (ret + rptr, str);
5215 /* Do pattern match and replacement on the positional parameters. */
5217 pos_params_pat_subst (string, pat, rep, mflags)
5218 char *string, *pat, *rep;
5221 WORD_LIST *save, *params;
5225 save = params = list_rest_of_args ();
5227 return ((char *)NULL);
5229 for ( ; params; params = params->next)
5231 ret = pat_subst (params->word->word, pat, rep, mflags);
5232 w = make_bare_word (ret);
5233 dispose_word (params->word);
5238 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
5239 ret = string_list_dollar_star (quote_list (save));
5241 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
5242 dispose_words (save);
5247 /* Perform pattern substitution on VALUE, which is the expansion of
5248 VARNAME. PATSUB is an expression supplying the pattern to match
5249 and the string to substitute. QUOTED is a flags word containing
5250 the type of quoting currently in effect. */
5252 parameter_brace_patsub (varname, value, patsub, quoted)
5253 char *varname, *value, *patsub;
5256 int vtype, mflags, starsub;
5257 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
5261 return ((char *)NULL);
5263 this_command_name = varname;
5265 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5267 return ((char *)NULL);
5269 starsub = vtype & VT_STARSUB;
5270 vtype &= ~VT_STARSUB;
5275 mflags |= MATCH_GLOBREP;
5279 /* Malloc this because expand_string_if_necessary or one of the expansion
5280 functions in its call chain may free it on a substitution error. */
5281 lpatsub = savestring (patsub);
5283 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5284 mflags |= MATCH_QUOTED;
5287 mflags |= MATCH_STARSUB;
5289 if (rep = quoted_strchr (lpatsub, '/', ST_BACKSL))
5294 if (rep && *rep == '\0')
5298 /* Expand PAT and REP for command, variable and parameter, arithmetic,
5299 and process substitution. Also perform quote removal. Do not
5300 perform word splitting or filename generation. */
5301 pat = expand_string_if_necessary (lpatsub, (quoted & ~Q_DOUBLE_QUOTES), expand_string_unsplit);
5303 /* Perform the same expansions on the pattern as performed by the
5304 pattern removal expansions. */
5305 pat = getpattern (lpatsub, quoted, 1);
5310 if ((mflags & MATCH_QUOTED) == 0)
5311 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
5313 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
5317 if (pat && pat[0] == '#')
5319 mflags |= MATCH_BEG;
5322 else if (pat && pat[0] == '%')
5324 mflags |= MATCH_END;
5328 mflags |= MATCH_ANY;
5330 /* OK, we now want to substitute REP for PAT in VAL. If
5331 flags & MATCH_GLOBREP is non-zero, the substitution is done
5332 everywhere, otherwise only the first occurrence of PAT is
5333 replaced. The pattern matching code doesn't understand
5334 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5335 values passed in (VT_VARIABLE) so the pattern substitution
5336 code works right. We need to requote special chars after
5337 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5338 other cases if QUOTED == 0, since the posparams and arrays
5339 indexed by * or @ do special things when QUOTED != 0. */
5344 case VT_ARRAYMEMBER:
5345 temp = pat_subst (val, p, rep, mflags);
5346 if (vtype == VT_VARIABLE)
5350 tt = quote_escapes (temp);
5356 temp = pos_params_pat_subst (val, p, rep, mflags);
5357 if (temp && (mflags & MATCH_QUOTED) == 0)
5359 tt = quote_escapes (temp);
5364 #if defined (ARRAY_VARS)
5366 temp = array_patsub (array_cell (v), p, rep, mflags);
5367 if (temp && (mflags & MATCH_QUOTED) == 0)
5369 tt = quote_escapes (temp);
5384 /****************************************************************/
5386 /* Functions to perform parameter expansion on a string */
5388 /****************************************************************/
5390 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5392 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
5394 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
5396 int check_nullness, var_is_set, var_is_null, var_is_special;
5397 int want_substring, want_indir, want_patsub;
5398 char *name, *value, *temp, *temp1;
5399 int t_index, sindex, c;
5402 value = (char *)NULL;
5403 var_is_set = var_is_null = var_is_special = check_nullness = 0;
5404 want_substring = want_indir = want_patsub = 0;
5408 name = string_extract (string, &t_index, "#%:-=?+/}", EX_VARNAME);
5410 /* If the name really consists of a special variable, then make sure
5411 that we have the entire name. We don't allow indirect references
5412 to special variables except `#', `?', `@' and `*'. */
5413 if ((sindex == t_index &&
5414 (string[t_index] == '-' ||
5415 string[t_index] == '?' ||
5416 string[t_index] == '#')) ||
5417 (sindex == t_index - 1 && string[sindex] == '!' &&
5418 (string[t_index] == '#' ||
5419 string[t_index] == '?' ||
5420 string[t_index] == '@' ||
5421 string[t_index] == '*')))
5425 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
5426 name = (char *)xmalloc (3 + (strlen (temp1)));
5427 *name = string[sindex];
5428 if (string[sindex] == '!')
5430 /* indirect reference of $#, $?, $@, or $* */
5431 name[1] = string[sindex + 1];
5432 strcpy (name + 2, temp1);
5435 strcpy (name + 1, temp1);
5440 /* Find out what character ended the variable name. Then
5441 do the appropriate thing. */
5442 if (c = string[sindex])
5445 /* If c is followed by one of the valid parameter expansion
5446 characters, move past it as normal. If not, assume that
5447 a substring specification is being given, and do not move
5449 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
5452 if (c = string[sindex])
5455 else if (c == ':' && string[sindex] != RBRACE)
5457 else if (c == '/' && string[sindex] != RBRACE)
5460 /* Catch the valid and invalid brace expressions that made it through the
5462 /* ${#-} is a valid expansion and means to take the length of $-.
5463 Similarly for ${#?} and ${##}... */
5464 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
5465 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
5467 name = (char *)xrealloc (name, 3);
5470 c = string[sindex++];
5473 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
5474 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
5475 member (c, "%:=+/") && string[sindex] == RBRACE)
5477 temp = (char *)NULL;
5478 goto bad_substitution;
5481 /* Indirect expansion begins with a `!'. A valid indirect expansion is
5482 either a variable name, one of the positional parameters or a special
5483 variable that expands to one of the positional parameters. */
5484 want_indir = *name == '!' &&
5485 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
5486 || VALID_INDIR_PARAM (name[1]));
5488 /* Determine the value of this variable. */
5490 /* Check for special variables, directly referenced. */
5491 if (SPECIAL_VAR (name, want_indir))
5494 /* Check for special expansion things, like the length of a parameter */
5495 if (*name == '#' && name[1])
5497 /* If we are not pointing at the character just after the
5498 closing brace, then we haven't gotten all of the name.
5499 Since it begins with a special character, this is a bad
5500 substitution. Also check NAME for validity before trying
5502 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
5504 temp = (char *)NULL;
5505 goto bad_substitution;
5508 number = parameter_brace_expand_length (name);
5512 return ((number < 0) ? &expand_param_error : itos (number));
5515 /* ${@} is identical to $@. */
5516 if (name[0] == '@' && name[1] == '\0')
5518 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5519 *quoted_dollar_atp = 1;
5521 if (contains_dollar_at)
5522 *contains_dollar_at = 1;
5525 /* Process ${!PREFIX*} expansion. */
5526 if (want_indir && string[sindex - 1] == RBRACE &&
5527 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
5528 legal_variable_starter ((unsigned char) name[1]))
5533 temp1 = savestring (name + 1);
5534 number = strlen (temp1);
5535 temp1[number - 1] = '\0';
5536 x = all_variables_matching_prefix (temp1);
5537 xlist = strvec_to_word_list (x, 0, 0);
5538 if (string[sindex - 2] == '*')
5539 temp = string_list_dollar_star (xlist);
5542 temp = string_list_dollar_at (xlist, quoted);
5543 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5544 *quoted_dollar_atp = 1;
5545 if (contains_dollar_at)
5546 *contains_dollar_at = 1;
5555 #if defined (ARRAY_VARS)
5556 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
5557 if (want_indir && string[sindex - 1] == RBRACE &&
5558 string[sindex - 2] == ']' && valid_array_reference (name+1))
5562 temp1 = savestring (name + 1);
5563 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
5565 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
5567 temp = array_keys (temp1, quoted);
5570 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5571 *quoted_dollar_atp = 1;
5572 if (contains_dollar_at)
5573 *contains_dollar_at = 1;
5583 #endif /* ARRAY_VARS */
5585 /* Make sure that NAME is valid before trying to go on. */
5586 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
5587 var_is_special) == 0)
5589 temp = (char *)NULL;
5590 goto bad_substitution;
5594 temp = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
5596 temp = parameter_brace_expand_word (name, var_is_special, quoted);
5598 #if defined (ARRAY_VARS)
5599 if (valid_array_reference (name))
5600 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
5603 var_is_set = temp != (char *)0;
5604 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
5606 /* Get the rest of the stuff inside the braces. */
5607 if (c && c != RBRACE)
5609 /* Extract the contents of the ${ ... } expansion
5610 according to the Posix.2 rules. */
5611 value = extract_dollar_brace_string (string, &sindex, quoted, 0);
5612 if (string[sindex] == RBRACE)
5615 goto bad_substitution;
5618 value = (char *)NULL;
5622 /* If this is a substring spec, process it and add the result. */
5625 temp1 = parameter_brace_substring (name, temp, value, quoted);
5631 else if (want_patsub)
5633 temp1 = parameter_brace_patsub (name, temp, value, quoted);
5640 /* Do the right thing based on which character ended the variable name. */
5646 report_error (_("%s: bad substitution"), string ? string : "??");
5650 return &expand_param_error;
5653 if (var_is_set == 0 && unbound_vars_is_error)
5655 err_unboundvar (name);
5659 last_command_exit_value = EXECUTION_FAILURE;
5660 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5664 case '#': /* ${param#[#]pattern} */
5665 case '%': /* ${param%[%]pattern} */
5666 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
5671 temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
5681 if (var_is_set && var_is_null == 0)
5683 /* If the operator is `+', we don't want the value of the named
5684 variable for anything, just the value of the right hand side. */
5688 /* XXX -- if we're double-quoted and the named variable is "$@",
5689 we want to turn off any special handling of "$@" --
5690 we're not using it, so whatever is on the rhs applies. */
5691 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5692 *quoted_dollar_atp = 0;
5693 if (contains_dollar_at)
5694 *contains_dollar_at = 0;
5699 temp = parameter_brace_expand_rhs (name, value, c,
5702 contains_dollar_at);
5706 temp = (char *)NULL;
5712 /* Otherwise do nothing; just use the value in TEMP. */
5714 else /* VAR not set or VAR is NULL. */
5717 temp = (char *)NULL;
5718 if (c == '=' && var_is_special)
5720 report_error (_("$%s: cannot assign in this way"), name);
5723 return &expand_param_error;
5727 parameter_brace_expand_error (name, value);
5728 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5732 /* XXX -- if we're double-quoted and the named variable is "$@",
5733 we want to turn off any special handling of "$@" --
5734 we're not using it, so whatever is on the rhs applies. */
5735 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
5736 *quoted_dollar_atp = 0;
5737 if (contains_dollar_at)
5738 *contains_dollar_at = 0;
5740 temp = parameter_brace_expand_rhs (name, value, c, quoted,
5742 contains_dollar_at);
5753 /* Expand a single ${xxx} expansion. The braces are optional. When
5754 the braces are used, parameter_brace_expand() does the work,
5755 possibly calling param_expand recursively. */
5757 param_expand (string, sindex, quoted, expanded_something,
5758 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
5761 int *sindex, quoted, *expanded_something, *contains_dollar_at;
5762 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
5764 char *temp, *temp1, uerror[3];
5765 int zindex, t_index, expok;
5772 c = string[++zindex];
5774 temp = (char *)NULL;
5776 /* Do simple cases first. Switch on what follows '$'. */
5790 temp1 = dollar_vars[TODIGIT (c)];
5791 if (unbound_vars_is_error && temp1 == (char *)NULL)
5796 err_unboundvar (uerror);
5797 last_command_exit_value = EXECUTION_FAILURE;
5798 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5802 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
5803 ? quote_string (temp1)
5804 : quote_escapes (temp1);
5806 temp = (char *)NULL;
5808 temp = temp1 ? quote_escapes (temp1) : (char *)NULL;
5812 /* $$ -- pid of the invoking shell. */
5814 temp = itos (dollar_dollar_pid);
5817 /* $# -- number of positional parameters. */
5819 temp = itos (number_of_args ());
5822 /* $? -- return value of the last synchronous command. */
5824 temp = itos (last_command_exit_value);
5827 /* $- -- flags supplied to the shell on invocation or by `set'. */
5829 temp = which_set_flags ();
5832 /* $! -- Pid of the last asynchronous command. */
5834 /* If no asynchronous pids have been created, expand to nothing.
5835 If `set -u' has been executed, and no async processes have
5836 been created, this is an expansion error. */
5837 if (last_asynchronous_pid == NO_PID)
5839 if (expanded_something)
5840 *expanded_something = 0;
5841 temp = (char *)NULL;
5842 if (unbound_vars_is_error)
5847 err_unboundvar (uerror);
5848 last_command_exit_value = EXECUTION_FAILURE;
5849 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
5853 temp = itos (last_asynchronous_pid);
5856 /* The only difference between this and $@ is when the arg is quoted. */
5857 case '*': /* `$*' */
5858 list = list_rest_of_args ();
5860 /* If there are no command-line arguments, this should just
5861 disappear if there are other characters in the expansion,
5862 even if it's quoted. */
5863 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
5864 temp = (char *)NULL;
5865 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5867 /* If we have "$*" we want to make a string of the positional
5868 parameters, separated by the first character of $IFS, and
5869 quote the whole string, including the separators. If IFS
5870 is unset, the parameters are separated by ' '; if $IFS is
5871 null, the parameters are concatenated. */
5873 temp = string_list_dollar_star (list);
5875 temp = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (list) : string_list (list);
5877 temp1 = quote_string (temp);
5883 /* If the $* is not quoted it is identical to $@ */
5884 temp = string_list_dollar_at (list, quoted);
5885 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
5886 *contains_dollar_at = 1;
5889 dispose_words (list);
5892 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
5893 means that we have to turn quoting off after we split into
5894 the individually quoted arguments so that the final split
5895 on the first character of $IFS is still done. */
5896 case '@': /* `$@' */
5897 list = list_rest_of_args ();
5899 /* We want to flag the fact that we saw this. We can't turn
5900 off quoting entirely, because other characters in the
5901 string might need it (consider "\"$@\""), but we need some
5902 way to signal that the final split on the first character
5903 of $IFS should be done, even though QUOTED is 1. */
5904 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
5905 *quoted_dollar_at_p = 1;
5906 if (contains_dollar_at)
5907 *contains_dollar_at = 1;
5909 /* We want to separate the positional parameters with the first
5910 character of $IFS in case $IFS is something other than a space.
5911 We also want to make sure that splitting is done no matter what --
5912 according to POSIX.2, this expands to a list of the positional
5913 parameters no matter what IFS is set to. */
5914 temp = string_list_dollar_at (list, quoted);
5916 dispose_words (list);
5920 temp = parameter_brace_expand (string, &zindex, quoted,
5922 contains_dollar_at);
5923 if (temp == &expand_param_error || temp == &expand_param_fatal)
5927 /* Quoted nulls should be removed if there is anything else
5929 /* Note that we saw the quoted null so we can add one back at
5930 the end of this function if there are no other characters
5931 in the string, discard TEMP, and go on. The exception to
5932 this is when we have "${@}" and $1 is '', since $@ needs
5933 special handling. */
5934 if (temp && QUOTED_NULL (temp))
5936 if (had_quoted_null_p)
5937 *had_quoted_null_p = 1;
5938 if (*quoted_dollar_at_p == 0)
5941 temp = (char *)NULL;
5948 /* Do command or arithmetic substitution. */
5950 /* We have to extract the contents of this paren substitution. */
5951 t_index = zindex + 1;
5952 temp = extract_command_subst (string, &t_index);
5955 /* For Posix.2-style `$(( ))' arithmetic substitution,
5956 extract the expression and pass it to the evaluator. */
5957 if (temp && *temp == LPAREN)
5961 temp2 = savestring (temp1);
5962 t_index = strlen (temp2) - 1;
5964 if (temp2[t_index] != RPAREN)
5970 /* Cut off ending `)' */
5971 temp2[t_index] = '\0';
5973 /* Expand variables found inside the expression. */
5974 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
5978 /* No error messages. */
5979 this_command_name = (char *)NULL;
5980 number = evalexp (temp1, &expok);
5985 if (interactive_shell == 0 && posixly_correct)
5987 last_command_exit_value = EXECUTION_FAILURE;
5988 return (&expand_param_fatal);
5991 return (&expand_param_error);
5993 temp = itos (number);
5998 if (pflags & PF_NOCOMSUB)
5999 /* we need zindex+1 because string[zindex] == RPAREN */
6000 temp1 = substring (string, *sindex, zindex+1);
6002 temp1 = command_substitute (temp, quoted);
6007 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6008 away in a future bash release. */
6010 /* Extract the contents of this arithmetic substitution. */
6011 t_index = zindex + 1;
6012 temp = extract_arithmetic_subst (string, &t_index);
6015 /* Do initial variable expansion. */
6016 temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string);
6021 /* Find the variable in VARIABLE_LIST. */
6022 temp = (char *)NULL;
6024 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
6026 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
6028 /* If this isn't a variable name, then just output the `$'. */
6029 if (temp1 == 0 || *temp1 == '\0')
6032 temp = (char *)xmalloc (2);
6035 if (expanded_something)
6036 *expanded_something = 0;
6040 /* If the variable exists, return its value cell. */
6041 var = find_variable (temp1);
6043 if (var && invisible_p (var) == 0 && var_isset (var))
6045 #if defined (ARRAY_VARS)
6048 temp = array_reference (array_cell (var), 0);
6050 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6051 ? quote_string (temp)
6052 : quote_escapes (temp);
6053 else if (unbound_vars_is_error)
6054 goto unbound_variable;
6059 temp = value_cell (var);
6061 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6062 ? quote_string (temp)
6063 : quote_escapes (temp);
6071 temp = (char *)NULL;
6074 if (unbound_vars_is_error)
6075 err_unboundvar (temp1);
6083 last_command_exit_value = EXECUTION_FAILURE;
6084 return ((unbound_vars_is_error && interactive_shell == 0)
6085 ? &expand_param_fatal
6086 : &expand_param_error);
6097 /* Make a word list which is the result of parameter and variable
6098 expansion, command substitution, arithmetic substitution, and
6099 quote removal of WORD. Return a pointer to a WORD_LIST which is
6100 the result of the expansion. If WORD contains a null word, the
6101 word list returned is also null.
6103 QUOTED contains flag values defined in shell.h.
6105 ISEXP is used to tell expand_word_internal that the word should be
6106 treated as the result of an expansion. This has implications for
6107 how IFS characters in the word are treated.
6109 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6110 they point to an integer value which receives information about expansion.
6111 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6112 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6115 This only does word splitting in the case of $@ expansion. In that
6116 case, we split on ' '. */
6118 /* Values for the local variable quoted_state. */
6120 #define PARTIALLY_QUOTED 1
6121 #define WHOLLY_QUOTED 2
6124 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
6127 int *contains_dollar_at;
6128 int *expanded_something;
6133 /* The intermediate string that we build while expanding. */
6136 /* The current size of the above object. */
6139 /* Index into ISTRING. */
6142 /* Temporary string storage. */
6145 /* The text of WORD. */
6146 register char *string;
6148 /* The size of STRING. */
6151 /* The index into STRING. */
6154 /* This gets 1 if we see a $@ while quoted. */
6155 int quoted_dollar_at;
6157 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6158 whether WORD contains no quoting characters, a partially quoted
6159 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6162 int had_quoted_null;
6166 register unsigned char c; /* Current character. */
6167 int t_index; /* For calls to string_extract_xxx. */
6173 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
6174 istring[istring_index = 0] = '\0';
6175 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
6176 quoted_state = UNQUOTED;
6178 string = word->word;
6180 goto finished_with_string;
6181 string_size = strlen (string);
6183 if (contains_dollar_at)
6184 *contains_dollar_at = 0;
6186 /* Begin the expansion. */
6192 /* Case on toplevel character. */
6196 goto finished_with_string;
6200 #if HANDLE_MULTIBYTE
6201 if (MB_CUR_MAX > 1 && string[sindex])
6203 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6208 temp = (char *)xmalloc (3);
6210 temp[1] = c = string[sindex];
6221 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
6227 #if defined (PROCESS_SUBSTITUTION)
6228 /* Process substitution. */
6232 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || posixly_correct)
6234 sindex--; /* add_character: label increments sindex */
6238 t_index = sindex + 1; /* skip past both '<' and LPAREN */
6240 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
6243 /* If the process substitution specification is `<()', we want to
6244 open the pipe for writing in the child and produce output; if
6245 it is `>()', we want to open the pipe for reading in the child
6246 and consume input. */
6247 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
6251 goto dollar_add_string;
6253 #endif /* PROCESS_SUBSTITUTION */
6256 if (expanded_something)
6257 *expanded_something = 1;
6260 temp = param_expand (string, &sindex, quoted, expanded_something,
6261 &has_dollar_at, "ed_dollar_at,
6263 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
6265 if (temp == &expand_param_error || temp == &expand_param_fatal)
6269 return ((temp == &expand_param_error) ? &expand_word_error
6270 : &expand_word_fatal);
6272 if (contains_dollar_at && has_dollar_at)
6273 *contains_dollar_at = 1;
6277 case '`': /* Backquoted command substitution. */
6281 if (expanded_something)
6282 *expanded_something = 1;
6284 temp = string_extract (string, &sindex, "`", 0);
6285 if (word->flags & W_NOCOMSUB)
6286 /* sindex + 1 because string[sindex] == '`' */
6287 temp1 = substring (string, t_index, sindex + 1);
6290 de_backslash (temp);
6291 temp1 = command_substitute (temp, quoted);
6295 goto dollar_add_string;
6299 if (string[sindex + 1] == '\n')
6305 c = string[++sindex];
6307 if (quoted & Q_HERE_DOCUMENT)
6309 else if (quoted & Q_DOUBLE_QUOTES)
6314 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
6316 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
6321 sindex--; /* add_character: label increments sindex */
6326 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
6331 /* BEFORE jumping here, we need to increment sindex if appropriate */
6332 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
6333 DEFAULT_ARRAY_SIZE);
6334 istring[istring_index++] = twochars[0];
6335 istring[istring_index++] = twochars[1];
6336 istring[istring_index] = '\0';
6342 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_PATQUOTE))
6344 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6349 temp = string_extract_double_quoted (string, &sindex, 0);
6351 /* If the quotes surrounded the entire string, then the
6352 whole word was quoted. */
6353 quoted_state = (t_index == 1 && string[sindex] == '\0')
6359 tword = make_word (temp); /* XXX */
6361 temp = (char *)NULL;
6364 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
6366 if (list == &expand_word_error || list == &expand_word_fatal)
6370 /* expand_word_internal has already freed temp_word->word
6371 for us because of the way it prints error messages. */
6372 tword->word = (char *)NULL;
6373 dispose_word (tword);
6377 dispose_word (tword);
6379 /* "$@" (a double-quoted dollar-at) expands into nothing,
6380 not even a NULL word, when there are no positional
6382 if (list == 0 && has_dollar_at)
6388 /* If we get "$@", we know we have expanded something, so we
6389 need to remember it for the final split on $IFS. This is
6390 a special case; it's the only case where a quoted string
6391 can expand into more than one word. It's going to come back
6392 from the above call to expand_word_internal as a list with
6393 a single word, in which all characters are quoted and
6394 separated by blanks. What we want to do is to turn it back
6395 into a list for the next piece of code. */
6397 dequote_list (list);
6402 if (contains_dollar_at)
6403 *contains_dollar_at = 1;
6404 if (expanded_something)
6405 *expanded_something = 1;
6410 /* What we have is "". This is a minor optimization. */
6412 list = (WORD_LIST *)NULL;
6415 /* The code above *might* return a list (consider the case of "$@",
6416 where it returns "$1", "$2", etc.). We can't throw away the
6417 rest of the list, and we have to make sure each word gets added
6418 as quoted. We test on tresult->next: if it is non-NULL, we
6419 quote the whole list, save it to a string with string_list, and
6420 add that string. We don't need to quote the results of this
6421 (and it would be wrong, since that would quote the separators
6422 as well), so we go directly to add_string. */
6427 /* Testing quoted_dollar_at makes sure that "$@" is
6428 split correctly when $IFS does not contain a space. */
6429 temp = quoted_dollar_at
6430 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
6431 : string_list (quote_list (list));
6432 dispose_words (list);
6437 temp = savestring (list->word->word);
6438 dispose_words (list);
6440 /* If the string is not a quoted null string, we want
6441 to remove any embedded unquoted CTLNUL characters.
6442 We do not want to turn quoted null strings back into
6443 the empty string, though. We do this because we
6444 want to remove any quoted nulls from expansions that
6445 contain other characters. For example, if we have
6446 x"$*"y or "x$*y" and there are no positional parameters,
6447 the $* should expand into nothing. */
6448 /* HOWEVER, this fails if the string contains a literal
6449 CTLNUL or CTLNUL is contained in the (non-null) expansion
6450 of some variable. I'm not sure what to do about this
6451 yet. There has to be some way to indicate the difference
6452 between the two. An auxiliary data structure might be
6454 if (QUOTED_NULL (temp) == 0)
6455 remove_quoted_nulls (temp); /* XXX */
6460 temp = (char *)NULL;
6462 /* We do not want to add quoted nulls to strings that are only
6463 partially quoted; we can throw them away. */
6464 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
6472 temp = quote_string (temp);
6480 sindex--; /* add_character: label increments sindex */
6488 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_PATQUOTE))
6490 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
6495 temp = string_extract_single_quoted (string, &sindex);
6497 /* If the entire STRING was surrounded by single quotes,
6498 then the string is wholly quoted. */
6499 quoted_state = (t_index == 1 && string[sindex] == '\0')
6503 /* If all we had was '', it is a null expansion. */
6507 temp = (char *)NULL;
6510 remove_quoted_escapes (temp); /* ??? */
6512 /* We do not want to add quoted nulls to strings that are only
6513 partially quoted; such nulls are discarded. */
6514 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
6517 /* If we have a quoted null expansion, add a quoted NULL to istring. */
6521 sindex--; /* add_character: label increments sindex */
6525 goto add_quoted_string;
6530 /* This is the fix for " $@ " */
6531 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
6533 if (string[sindex]) /* from old goto dollar_add_string */
6542 #if HANDLE_MULTIBYTE
6548 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6553 twochars[0] = CTLESC;
6560 SADD_MBCHAR (temp, string, sindex, string_size);
6563 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
6564 DEFAULT_ARRAY_SIZE);
6565 istring[istring_index++] = c;
6566 istring[istring_index] = '\0';
6568 /* Next character. */
6573 finished_with_string:
6574 /* OK, we're ready to return. If we have a quoted string, and
6575 quoted_dollar_at is not set, we do no splitting at all; otherwise
6576 we split on ' '. The routines that call this will handle what to
6577 do if nothing has been expanded. */
6579 /* Partially and wholly quoted strings which expand to the empty
6580 string are retained as an empty arguments. Unquoted strings
6581 which expand to the empty string are discarded. The single
6582 exception is the case of expanding "$@" when there are no
6583 positional parameters. In that case, we discard the expansion. */
6585 /* Because of how the code that handles "" and '' in partially
6586 quoted strings works, we need to make ISTRING into a QUOTED_NULL
6587 if we saw quoting characters, but the expansion was empty.
6588 "" and '' are tossed away before we get to this point when
6589 processing partially quoted strings. This makes "" and $xxx""
6590 equivalent when xxx is unset. We also look to see whether we
6591 saw a quoted null from a ${} expansion and add one back if we
6594 /* If we expand to nothing and there were no single or double quotes
6595 in the word, we throw it away. Otherwise, we return a NULL word.
6596 The single exception is for $@ surrounded by double quotes when
6597 there are no positional parameters. In that case, we also throw
6600 if (*istring == '\0')
6602 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
6604 istring[0] = CTLNUL;
6606 tword = make_bare_word (istring);
6607 list = make_word_list (tword, (WORD_LIST *)NULL);
6608 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6609 tword->flags |= W_QUOTED;
6611 /* According to sh, ksh, and Posix.2, if a word expands into nothing
6612 and a double-quoted "$@" appears anywhere in it, then the entire
6614 else if (quoted_state == UNQUOTED || quoted_dollar_at)
6615 list = (WORD_LIST *)NULL;
6619 tword = make_bare_word (istring);
6620 list = make_word_list (tword, (WORD_LIST *)NULL);
6621 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6622 tword->flags |= W_QUOTED;
6626 list = (WORD_LIST *)NULL;
6629 else if (word->flags & W_NOSPLIT)
6631 tword = make_bare_word (istring);
6632 list = make_word_list (tword, (WORD_LIST *)NULL);
6633 if (word->flags & W_ASSIGNMENT)
6634 tword->flags |= W_ASSIGNMENT; /* XXX */
6635 if (word->flags & W_NOGLOB)
6636 tword->flags |= W_NOGLOB; /* XXX */
6637 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6638 tword->flags |= W_QUOTED;
6644 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
6646 /* If we have $@, we need to split the results no matter what. If
6647 IFS is unset or NULL, string_list_dollar_at has separated the
6648 positional parameters with a space, so we split on space (we have
6649 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
6650 string_list_dollar_at has separated the positional parameters
6651 with the first character of $IFS, so we split on $IFS. */
6652 if (has_dollar_at && ifs_chars)
6653 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
6656 tword = make_bare_word (istring);
6657 list = make_word_list (tword, (WORD_LIST *)NULL);
6658 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
6659 tword->flags |= W_QUOTED;
6660 if (word->flags & W_ASSIGNMENT)
6661 tword->flags |= W_ASSIGNMENT;
6662 if (word->flags & W_NOGLOB)
6663 tword->flags |= W_NOGLOB;
6671 /* **************************************************************** */
6673 /* Functions for Quote Removal */
6675 /* **************************************************************** */
6677 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
6678 backslash quoting rules for within double quotes or a here document. */
6680 string_quote_removal (string, quoted)
6685 char *r, *result_string, *temp, *send;
6686 int sindex, tindex, dquote;
6690 /* The result can be no longer than the original string. */
6691 slen = strlen (string);
6692 send = string + slen;
6694 r = result_string = (char *)xmalloc (slen + 1);
6696 for (dquote = sindex = 0; c = string[sindex];)
6701 c = string[++sindex];
6702 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
6707 SCOPY_CHAR_M (r, string, send, sindex);
6711 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
6717 tindex = sindex + 1;
6718 temp = string_extract_single_quoted (string, &tindex);
6729 dquote = 1 - dquote;
6735 return (result_string);
6740 /* Perform quote removal on word WORD. This allocates and returns a new
6743 word_quote_removal (word, quoted)
6750 t = string_quote_removal (word->word, quoted);
6751 w = make_bare_word (t);
6756 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
6757 the members of the list are treated as if they are surrounded by
6758 double quotes. Return a new list, or NULL if LIST is NULL. */
6760 word_list_quote_removal (list, quoted)
6764 WORD_LIST *result, *t, *tresult;
6766 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
6768 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
6769 result = (WORD_LIST *) list_append (result, tresult);
6775 /*******************************************
6777 * Functions to perform word splitting *
6779 *******************************************/
6789 ifs_value = v ? value_cell (v) : " \t\n";
6791 /* Should really merge ifs_cmap with sh_syntaxtab. */
6792 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
6793 for (t = ifs_value ; t && *t; t++)
6799 ifs_firstc = ifs_value ? *ifs_value : 0;
6808 /* This splits a single word into a WORD LIST on $IFS, but only if the word
6809 is not quoted. list_string () performs quote removal for us, even if we
6810 don't do any splitting. */
6812 word_split (w, ifs_chars)
6822 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
6823 result = list_string (w->word, xifs, w->flags & W_QUOTED);
6826 result = (WORD_LIST *)NULL;
6831 /* Perform word splitting on LIST and return the RESULT. It is possible
6832 to return (WORD_LIST *)NULL. */
6834 word_list_split (list)
6837 WORD_LIST *result, *t, *tresult;
6839 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
6841 tresult = word_split (t->word, ifs_value);
6842 result = (WORD_LIST *) list_append (result, tresult);
6847 /**************************************************
6849 * Functions to expand an entire WORD_LIST *
6851 **************************************************/
6853 /* Do any word-expansion-specific cleanup and jump to top_level */
6855 exp_jump_to_top_level (v)
6858 /* Cleanup code goes here. */
6859 expand_no_split_dollar_star = 0; /* XXX */
6860 expanding_redir = 0;
6862 jump_to_top_level (v);
6865 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
6866 ELIST, and set ELIST to the new list. */
6867 #define PREPEND_LIST(nlist, elist) \
6868 do { nlist->next = elist; elist = nlist; } while (0)
6870 /* Separate out any initial variable assignments from TLIST. If set -k has
6871 been executed, remove all assignment statements from TLIST. Initial
6872 variable assignments and other environment assignments are placed
6873 on SUBST_ASSIGN_VARLIST. */
6875 separate_out_assignments (tlist)
6878 register WORD_LIST *vp, *lp;
6881 return ((WORD_LIST *)NULL);
6883 if (subst_assign_varlist)
6884 dispose_words (subst_assign_varlist); /* Clean up after previous error */
6886 subst_assign_varlist = (WORD_LIST *)NULL;
6889 /* Separate out variable assignments at the start of the command.
6890 Loop invariant: vp->next == lp
6892 lp = list of words left after assignment statements skipped
6893 tlist = original list of words
6895 while (lp && (lp->word->flags & W_ASSIGNMENT))
6901 /* If lp != tlist, we have some initial assignment statements.
6902 We make SUBST_ASSIGN_VARLIST point to the list of assignment
6903 words and TLIST point to the remaining words. */
6906 subst_assign_varlist = tlist;
6907 /* ASSERT(vp->next == lp); */
6908 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
6909 tlist = lp; /* remainder of word list */
6912 /* vp == end of variable list */
6913 /* tlist == remainder of original word list without variable assignments */
6915 /* All the words in tlist were assignment statements */
6916 return ((WORD_LIST *)NULL);
6918 /* ASSERT(tlist != NULL); */
6919 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
6921 /* If the -k option is in effect, we need to go through the remaining
6922 words, separate out the assignment words, and place them on
6923 SUBST_ASSIGN_VARLIST. */
6924 if (place_keywords_in_env)
6926 WORD_LIST *tp; /* tp == running pointer into tlist */
6931 /* Loop Invariant: tp->next == lp */
6932 /* Loop postcondition: tlist == word list without assignment statements */
6935 if (lp->word->flags & W_ASSIGNMENT)
6937 /* Found an assignment statement, add this word to end of
6938 subst_assign_varlist (vp). */
6939 if (!subst_assign_varlist)
6940 subst_assign_varlist = vp = lp;
6947 /* Remove the word pointed to by LP from TLIST. */
6948 tp->next = lp->next;
6949 /* ASSERT(vp == lp); */
6950 lp->next = (WORD_LIST *)NULL;
6963 #define WEXP_VARASSIGN 0x001
6964 #define WEXP_BRACEEXP 0x002
6965 #define WEXP_TILDEEXP 0x004
6966 #define WEXP_PARAMEXP 0x008
6967 #define WEXP_PATHEXP 0x010
6969 /* All of the expansions, including variable assignments at the start of
6971 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6973 /* All of the expansions except variable assignments at the start of
6975 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6977 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
6978 expansion, command substitution, arithmetic expansion, word splitting, and
6980 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
6982 /* Take the list of words in LIST and do the various substitutions. Return
6983 a new list of words which is the expanded list, and without things like
6984 variable assignments. */
6990 return (expand_word_list_internal (list, WEXP_ALL));
6993 /* Same as expand_words (), but doesn't hack variable or environment
6996 expand_words_no_vars (list)
6999 return (expand_word_list_internal (list, WEXP_NOVARS));
7003 expand_words_shellexp (list)
7006 return (expand_word_list_internal (list, WEXP_SHELLEXP));
7010 glob_expand_word_list (tlist, eflags)
7014 char **glob_array, *temp_string;
7015 register int glob_index;
7016 WORD_LIST *glob_list, *output_list, *disposables, *next;
7019 output_list = disposables = (WORD_LIST *)NULL;
7020 glob_array = (char **)NULL;
7023 /* For each word, either globbing is attempted or the word is
7024 added to orig_list. If globbing succeeds, the results are
7025 added to orig_list and the word (tlist) is added to the list
7026 of disposable words. If globbing fails and failed glob
7027 expansions are left unchanged (the shell default), the
7028 original word is added to orig_list. If globbing fails and
7029 failed glob expansions are removed, the original word is
7030 added to the list of disposable words. orig_list ends up
7031 in reverse order and requires a call to REVERSE_LIST to
7032 be set right. After all words are examined, the disposable
7036 /* If the word isn't an assignment and contains an unquoted
7037 pattern matching character, then glob it. */
7038 if ((tlist->word->flags & W_NOGLOB) == 0 &&
7039 unquoted_glob_pattern_p (tlist->word->word))
7041 glob_array = shell_glob_filename (tlist->word->word);
7043 /* Handle error cases.
7044 I don't think we should report errors like "No such file
7045 or directory". However, I would like to report errors
7046 like "Read failed". */
7048 if (glob_array == 0 || GLOB_FAILED (glob_array))
7050 glob_array = (char **)xmalloc (sizeof (char *));
7051 glob_array[0] = (char *)NULL;
7054 /* Dequote the current word in case we have to use it. */
7055 if (glob_array[0] == NULL)
7057 temp_string = dequote_string (tlist->word->word);
7058 free (tlist->word->word);
7059 tlist->word->word = temp_string;
7062 /* Make the array into a word list. */
7063 glob_list = (WORD_LIST *)NULL;
7064 for (glob_index = 0; glob_array[glob_index]; glob_index++)
7066 tword = make_bare_word (glob_array[glob_index]);
7067 tword->flags |= W_GLOBEXP; /* XXX */
7068 glob_list = make_word_list (tword, glob_list);
7073 output_list = (WORD_LIST *)list_append (glob_list, output_list);
7074 PREPEND_LIST (tlist, disposables);
7076 else if (fail_glob_expansion != 0)
7078 report_error (_("no match: %s"), tlist->word->word);
7079 jump_to_top_level (DISCARD);
7081 else if (allow_null_glob_expansion == 0)
7083 /* Failed glob expressions are left unchanged. */
7084 PREPEND_LIST (tlist, output_list);
7088 /* Failed glob expressions are removed. */
7089 PREPEND_LIST (tlist, disposables);
7094 /* Dequote the string. */
7095 temp_string = dequote_string (tlist->word->word);
7096 free (tlist->word->word);
7097 tlist->word->word = temp_string;
7098 PREPEND_LIST (tlist, output_list);
7101 strvec_dispose (glob_array);
7102 glob_array = (char **)NULL;
7108 dispose_words (disposables);
7111 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7113 return (output_list);
7116 #if defined (BRACE_EXPANSION)
7118 brace_expand_word_list (tlist, eflags)
7122 register char **expansions;
7124 WORD_LIST *disposables, *output_list, *next;
7128 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
7132 /* Only do brace expansion if the word has a brace character. If
7133 not, just add the word list element to BRACES and continue. In
7134 the common case, at least when running shell scripts, this will
7135 degenerate to a bunch of calls to `xstrchr', and then what is
7136 basically a reversal of TLIST into BRACES, which is corrected
7137 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7139 if (xstrchr (tlist->word->word, LBRACE))
7141 expansions = brace_expand (tlist->word->word);
7143 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
7145 w = make_word (temp_string);
7146 /* If brace expansion didn't change the word, preserve
7147 the flags. We may want to preserve the flags
7148 unconditionally someday -- XXX */
7149 if (STREQ (temp_string, tlist->word->word))
7150 w->flags = tlist->word->flags;
7151 output_list = make_word_list (w, output_list);
7152 free (expansions[eindex]);
7156 /* Add TLIST to the list of words to be freed after brace
7157 expansion has been performed. */
7158 PREPEND_LIST (tlist, disposables);
7161 PREPEND_LIST (tlist, output_list);
7165 dispose_words (disposables);
7168 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7170 return (output_list);
7175 shell_expand_word_list (tlist, eflags)
7179 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
7180 int expanded_something, has_dollar_at;
7183 /* We do tilde expansion all the time. This is what 1003.2 says. */
7184 new_list = (WORD_LIST *)NULL;
7185 for (orig_list = tlist; tlist; tlist = next)
7187 temp_string = tlist->word->word;
7191 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7192 which are not assignment statements are not expanded. If the
7193 shell isn't in posix mode, though, we perform tilde expansion
7194 on `likely candidate' unquoted assignment statements (flags
7195 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7196 contains an unquoted :~ or =~. Something to think about: we
7197 now have a flag that says to perform tilde expansion on arguments
7198 to `assignment builtins' like declare and export that look like
7199 assignment statements. We now do tilde expansion on such words
7200 even in POSIX mode. */
7201 if (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
7202 (posixly_correct == 0 || (tlist->word->flags & W_TILDEEXP)) &&
7203 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string)))
7205 tlist->word->word = bash_tilde_expand (temp_string, 1);
7208 else if (temp_string[0] == '~')
7210 tlist->word->word = bash_tilde_expand (temp_string, 0);
7214 expanded_something = 0;
7215 expanded = expand_word_internal
7216 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
7218 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
7220 /* By convention, each time this error is returned,
7221 tlist->word->word has already been freed. */
7222 tlist->word->word = (char *)NULL;
7224 /* Dispose our copy of the original list. */
7225 dispose_words (orig_list);
7226 /* Dispose the new list we're building. */
7227 dispose_words (new_list);
7229 last_command_exit_value = EXECUTION_FAILURE;
7230 if (expanded == &expand_word_error)
7231 exp_jump_to_top_level (DISCARD);
7233 exp_jump_to_top_level (FORCE_EOF);
7236 /* Don't split words marked W_NOSPLIT. */
7237 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
7239 temp_list = word_list_split (expanded);
7240 dispose_words (expanded);
7244 /* If no parameter expansion, command substitution, process
7245 substitution, or arithmetic substitution took place, then
7246 do not do word splitting. We still have to remove quoted
7247 null characters from the result. */
7248 word_list_remove_quoted_nulls (expanded);
7249 temp_list = expanded;
7252 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
7253 new_list = (WORD_LIST *)list_append (expanded, new_list);
7257 dispose_words (orig_list);
7260 new_list = REVERSE_LIST (new_list, WORD_LIST *);
7265 /* The workhorse for expand_words () and expand_words_no_vars ().
7266 First arg is LIST, a WORD_LIST of words.
7267 Second arg EFLAGS is a flags word controlling which expansions are
7270 This does all of the substitutions: brace expansion, tilde expansion,
7271 parameter expansion, command substitution, arithmetic expansion,
7272 process substitution, word splitting, and pathname expansion, according
7273 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
7274 set, or for which no expansion is done, do not undergo word splitting.
7275 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
7277 expand_word_list_internal (list, eflags)
7281 WORD_LIST *new_list, *temp_list;
7285 return ((WORD_LIST *)NULL);
7287 garglist = new_list = copy_word_list (list);
7288 if (eflags & WEXP_VARASSIGN)
7290 garglist = new_list = separate_out_assignments (new_list);
7293 if (subst_assign_varlist)
7295 /* All the words were variable assignments, so they are placed
7296 into the shell's environment. */
7297 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
7299 this_command_name = (char *)NULL; /* no arithmetic errors */
7300 tint = do_assignment (temp_list->word->word);
7301 /* Variable assignment errors in non-interactive shells
7302 running in Posix.2 mode cause the shell to exit. */
7305 last_command_exit_value = EXECUTION_FAILURE;
7306 if (interactive_shell == 0 && posixly_correct)
7307 exp_jump_to_top_level (FORCE_EOF);
7309 exp_jump_to_top_level (DISCARD);
7312 dispose_words (subst_assign_varlist);
7313 subst_assign_varlist = (WORD_LIST *)NULL;
7315 return ((WORD_LIST *)NULL);
7319 /* Begin expanding the words that remain. The expansions take place on
7320 things that aren't really variable assignments. */
7322 #if defined (BRACE_EXPANSION)
7323 /* Do brace expansion on this word if there are any brace characters
7325 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
7326 new_list = brace_expand_word_list (new_list, eflags);
7327 #endif /* BRACE_EXPANSION */
7329 /* Perform the `normal' shell expansions: tilde expansion, parameter and
7330 variable substitution, command substitution, arithmetic expansion,
7331 and word splitting. */
7332 new_list = shell_expand_word_list (new_list, eflags);
7334 /* Okay, we're almost done. Now let's just do some filename
7338 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
7339 /* Glob expand the word list unless globbing has been disabled. */
7340 new_list = glob_expand_word_list (new_list, eflags);
7342 /* Dequote the words, because we're not performing globbing. */
7343 new_list = dequote_list (new_list);
7346 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
7348 sh_assign_func_t *assign_func;
7350 /* If the remainder of the words expand to nothing, Posix.2 requires
7351 that the variable and environment assignments affect the shell's
7353 assign_func = new_list ? assign_in_env : do_assignment;
7354 tempenv_assign_error = 0;
7356 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
7358 this_command_name = (char *)NULL;
7359 tint = (*assign_func) (temp_list->word->word);
7360 /* Variable assignment errors in non-interactive shells running
7361 in Posix.2 mode cause the shell to exit. */
7364 if (assign_func == do_assignment)
7366 last_command_exit_value = EXECUTION_FAILURE;
7367 if (interactive_shell == 0 && posixly_correct)
7368 exp_jump_to_top_level (FORCE_EOF);
7370 exp_jump_to_top_level (DISCARD);
7373 tempenv_assign_error++;
7377 dispose_words (subst_assign_varlist);
7378 subst_assign_varlist = (WORD_LIST *)NULL;
7382 tint = list_length (new_list) + 1;
7383 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
7384 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
7385 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
7386 glob_argv_flags[tint] = '\0';