1 /* subst.c -- The part of the shell that does parameter, command, arithmetic,
2 and globbing substitutions. */
4 /* ``Have a little faith, there's magic in the night. You ain't a
5 beauty, but, hey, you're alright.'' */
7 /* Copyright (C) 1987-2007 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 () */
84 #define EX_REQMATCH 0x04 /* closing/matching delimiter required */
85 #define EX_COMMAND 0x08 /* extracting a shell script/command */
87 /* Flags for the `pflags' argument to param_expand() */
88 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 /* These defs make it easier to use the editor. */
96 /* Evaluates to 1 if C is one of the shell's special parameters whose length
97 can be taken, but is also one of the special expansion characters. */
98 #define VALID_SPECIAL_LENGTH_PARAM(c) \
99 ((c) == '-' || (c) == '?' || (c) == '#')
101 /* Evaluates to 1 if C is one of the shell's special parameters for which an
102 indirect variable reference may be made. */
103 #define VALID_INDIR_PARAM(c) \
104 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
106 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
107 in ${parameter[:]OPword}. */
108 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
110 /* Evaluates to 1 if this is one of the shell's special variables. */
111 #define SPECIAL_VAR(name, wi) \
112 ((DIGIT (*name) && all_digits (name)) || \
113 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
114 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
116 /* An expansion function that takes a string and a quoted flag and returns
117 a WORD_LIST *. Used as the type of the third argument to
118 expand_string_if_necessary(). */
119 typedef WORD_LIST *EXPFUNC __P((char *, int));
121 /* Process ID of the last command executed within command substitution. */
122 pid_t last_command_subst_pid = NO_PID;
123 pid_t current_command_subst_pid = NO_PID;
125 /* Variables used to keep track of the characters in IFS. */
128 unsigned char ifs_cmap[UCHAR_MAX + 1];
130 #if defined (HANDLE_MULTIBYTE)
131 unsigned char ifs_firstc[MB_LEN_MAX];
132 size_t ifs_firstc_len;
134 unsigned char ifs_firstc;
137 /* Extern functions and variables from different files. */
138 extern int last_command_exit_value, last_command_exit_signal;
139 extern int subshell_environment;
140 extern int subshell_level, parse_and_execute_level;
141 extern int eof_encountered;
142 extern int return_catch_flag, return_catch_value;
143 extern pid_t dollar_dollar_pid;
144 extern int posixly_correct;
145 extern char *this_command_name;
146 extern struct fd_bitmap *current_fds_to_close;
147 extern int wordexp_only;
148 extern int expanding_redir;
149 extern int tempenv_assign_error;
151 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
152 extern wchar_t *wcsdup __P((const wchar_t *));
155 /* Non-zero means to allow unmatched globbed filenames to expand to
157 int allow_null_glob_expansion;
159 /* Non-zero means to throw an error when globbing fails to match anything. */
160 int fail_glob_expansion;
163 /* Variables to keep track of which words in an expanded word list (the
164 output of expand_word_list_internal) are the result of globbing
165 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
166 (CURRENTLY UNUSED). */
167 char *glob_argv_flags;
168 static int glob_argv_flags_size;
171 static WORD_LIST expand_word_error, expand_word_fatal;
172 static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;
173 static char expand_param_error, expand_param_fatal;
174 static char extract_string_error, extract_string_fatal;
176 /* Tell the expansion functions to not longjmp back to top_level on fatal
177 errors. Enabled when doing completion and prompt string expansion. */
178 static int no_longjmp_on_fatal_error = 0;
180 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
181 $* on $IFS, primarily when doing assignment statements. */
182 static int expand_no_split_dollar_star = 0;
184 /* Used to hold a list of variable assignments preceding a command. Global
185 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
187 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
189 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
190 without any leading variable assignments. */
191 static WORD_LIST *garglist = (WORD_LIST *)NULL;
193 static char *quoted_substring __P((char *, int, int));
194 static int quoted_strlen __P((char *));
195 static char *quoted_strchr __P((char *, int, int));
197 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
198 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
199 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
200 static WORD_LIST *expand_string_internal __P((char *, int));
201 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
202 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
204 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
205 static char *dequote_escapes __P((char *));
206 static char *make_quoted_char __P((int));
207 static WORD_LIST *quote_list __P((WORD_LIST *));
208 static char *remove_quoted_escapes __P((char *));
209 static char *remove_quoted_nulls __P((char *));
211 static int unquoted_substring __P((char *, char *));
212 static int unquoted_member __P((int, char *));
214 #if defined (ARRAY_VARS)
215 static SHELL_VAR *do_compound_assignment __P((char *, char *, int));
217 static int do_assignment_internal __P((const WORD_DESC *, int));
219 static char *string_extract_verbatim __P((char *, size_t, int *, char *));
220 static char *string_extract __P((char *, int *, char *, int));
221 static char *string_extract_double_quoted __P((char *, int *, int));
222 static inline char *string_extract_single_quoted __P((char *, int *));
223 static inline int skip_single_quoted __P((const char *, size_t, int));
224 static int skip_double_quoted __P((char *, size_t, int));
225 static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));
226 static char *extract_dollar_brace_string __P((char *, int *, int, int));
228 static char *pos_params __P((char *, int, int, int));
230 static unsigned char *mb_getcharlens __P((char *, int));
232 static char *remove_upattern __P((char *, char *, int));
233 #if defined (HANDLE_MULTIBYTE)
234 static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));
236 static char *remove_pattern __P((char *, char *, int));
238 static int match_pattern_char __P((char *, char *));
239 static int match_upattern __P((char *, char *, int, char **, char **));
240 #if defined (HANDLE_MULTIBYTE)
241 static int match_pattern_wchar __P((wchar_t *, wchar_t *));
242 static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
244 static int match_pattern __P((char *, char *, int, char **, char **));
245 static int getpatspec __P((int, char *));
246 static char *getpattern __P((char *, int, int));
247 static char *variable_remove_pattern __P((char *, char *, int, int));
248 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
249 static char *parameter_list_remove_pattern __P((int, char *, int, int));
251 static char *array_remove_pattern __P((ARRAY *, char *, int, char *, int));
253 static char *parameter_brace_remove_pattern __P((char *, char *, char *, int, int));
255 static char *process_substitute __P((char *, int));
257 static char *read_comsub __P((int, int));
260 static arrayind_t array_length_reference __P((char *));
263 static int valid_brace_expansion_word __P((char *, int));
264 static int chk_atstar __P((char *, int, int *, int *));
265 static int chk_arithsub __P((const char *, int));
267 static WORD_DESC *parameter_brace_expand_word __P((char *, int, int));
268 static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));
269 static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
270 static void parameter_brace_expand_error __P((char *, char *));
272 static int valid_length_expression __P((char *));
273 static intmax_t parameter_brace_expand_length __P((char *));
275 static char *skiparith __P((char *, int));
276 static int verify_substring_values __P((char *, char *, int, intmax_t *, intmax_t *));
277 static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **));
278 static char *mb_substring __P((char *, int, int));
279 static char *parameter_brace_substring __P((char *, char *, char *, int));
281 static char *pos_params_pat_subst __P((char *, char *, char *, int));
283 static char *parameter_brace_patsub __P((char *, char *, char *, int));
285 static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int *, int *));
286 static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
288 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
290 static WORD_LIST *word_list_split __P((WORD_LIST *));
292 static void exp_jump_to_top_level __P((int));
294 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
295 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
296 #ifdef BRACE_EXPANSION
297 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
299 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
300 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
302 /* **************************************************************** */
304 /* Utility Functions */
306 /* **************************************************************** */
308 #ifdef INCLUDE_UNUSED
310 quoted_substring (string, start, end)
315 register char *result, *s, *r;
319 /* Move to string[start], skipping quoted characters. */
320 for (s = string, l = 0; *s && l < start; )
332 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
334 /* Copy LEN characters, including quote characters. */
336 for (l = 0; l < len; s++)
350 #ifdef INCLUDE_UNUSED
351 /* Return the length of S, skipping over quoted characters */
375 /* Find the first occurrence of character C in string S, obeying shell
376 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
377 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
378 escaped with CTLESC are skipped. */
380 quoted_strchr (s, c, flags)
388 if (((flags & ST_BACKSL) && *p == '\\')
389 || ((flags & ST_CTLESC) && *p == CTLESC))
393 return ((char *)NULL);
399 return ((char *)NULL);
402 /* Return 1 if CHARACTER appears in an unquoted portion of
403 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
405 unquoted_member (character, string)
413 slen = strlen (string);
415 while (c = string[sindex])
423 ADVANCE_CHAR (string, slen, sindex);
429 ADVANCE_CHAR (string, slen, sindex);
433 sindex = skip_single_quoted (string, slen, ++sindex);
437 sindex = skip_double_quoted (string, slen, ++sindex);
444 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
446 unquoted_substring (substr, string)
447 char *substr, *string;
450 int sindex, c, sublen;
453 if (substr == 0 || *substr == '\0')
456 slen = strlen (string);
457 sublen = strlen (substr);
458 for (sindex = 0; c = string[sindex]; )
460 if (STREQN (string + sindex, substr, sublen))
469 ADVANCE_CHAR (string, slen, sindex);
473 sindex = skip_single_quoted (string, slen, ++sindex);
477 sindex = skip_double_quoted (string, slen, ++sindex);
481 ADVANCE_CHAR (string, slen, sindex);
488 /* Most of the substitutions must be done in parallel. In order
489 to avoid using tons of unclear goto's, I have some functions
490 for manipulating malloc'ed strings. They all take INDX, a
491 pointer to an integer which is the offset into the string
492 where manipulation is taking place. They also take SIZE, a
493 pointer to an integer which is the current length of the
494 character array for this string. */
496 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
497 of space allocated to TARGET. SOURCE can be NULL, in which
498 case nothing happens. Gets rid of SOURCE by freeing it.
499 Returns TARGET in case the location has changed. */
501 sub_append_string (source, target, indx, size)
502 char *source, *target;
509 srclen = STRLEN (source);
510 if (srclen >= (int)(*size - *indx))
513 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
514 target = (char *)xrealloc (target, (*size = n));
517 FASTCOPY (source, target + *indx, srclen);
519 target[*indx] = '\0';
528 /* Append the textual representation of NUMBER to TARGET.
529 INDX and SIZE are as in SUB_APPEND_STRING. */
531 sub_append_number (number, target, indx, size)
538 temp = itos (number);
539 return (sub_append_string (temp, target, indx, size));
543 /* Extract a substring from STRING, starting at SINDEX and ending with
544 one of the characters in CHARLIST. Don't make the ending character
545 part of the string. Leave SINDEX pointing at the ending character.
546 Understand about backslashes in the string. If (flags & EX_VARNAME)
547 is non-zero, and array variables have been compiled into the shell,
548 everything between a `[' and a corresponding `]' is skipped over.
549 If (flags & EX_NOALLOC) is non-zero, don't return the substring, just
550 update SINDEX. If (flags & EX_REQMATCH) is non-zero, the string must
551 contain a closing character from CHARLIST. */
553 string_extract (string, sindex, charlist, flags)
565 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
568 while (c = string[i])
577 #if defined (ARRAY_VARS)
578 else if ((flags & EX_VARNAME) && c == '[')
581 /* If this is an array subscript, skip over it and continue. */
582 ni = skipsubscript (string, i);
583 if (string[ni] == ']')
587 else if (MEMBER (c, charlist))
593 ADVANCE_CHAR (string, slen, i);
596 /* If we had to have a matching delimiter and didn't find one, return an
597 error and let the caller deal with it. */
598 if ((flags & EX_REQMATCH) && found == 0)
601 return (&extract_string_error);
604 temp = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
610 /* Extract the contents of STRING as if it is enclosed in double quotes.
611 SINDEX, when passed in, is the offset of the character immediately
612 following the opening double quote; on exit, SINDEX is left pointing after
613 the closing double quote. If STRIPDQ is non-zero, unquoted double
614 quotes are stripped and the string is terminated by a null byte.
615 Backslashes between the embedded double quotes are processed. If STRIPDQ
616 is zero, an unquoted `"' terminates the string. */
618 string_extract_double_quoted (string, sindex, stripdq)
620 int *sindex, stripdq;
626 char *temp, *ret; /* The new string we return. */
627 int pass_next, backquote, si; /* State variables for the machine. */
631 slen = strlen (string + *sindex) + *sindex;
632 send = string + slen;
634 pass_next = backquote = dquote = 0;
635 temp = (char *)xmalloc (1 + slen - *sindex);
639 while (c = string[i])
641 /* Process a character that was quoted by a backslash. */
646 ``The backslash shall retain its special meaning as an escape
647 character only when followed by one of the characters:
650 If STRIPDQ is zero, we handle the double quotes here and let
651 expand_word_internal handle the rest. If STRIPDQ is non-zero,
652 we have already been through one round of backslash stripping,
653 and want to strip these backslashes only if DQUOTE is non-zero,
654 indicating that we are inside an embedded double-quoted string. */
656 /* If we are in an embedded quoted string, then don't strip
657 backslashes before characters for which the backslash
658 retains its special meaning, but remove backslashes in
659 front of other characters. If we are not in an
660 embedded quoted string, don't strip backslashes at all.
661 This mess is necessary because the string was already
662 surrounded by double quotes (and sh has some really weird
664 The returned string will be run through expansion as if
665 it were double-quoted. */
666 if ((stripdq == 0 && c != '"') ||
667 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
672 COPY_CHAR_I (temp, j, string, send, i);
676 /* A backslash protects the next character. The code just above
677 handles preserving the backslash in front of any character but
686 /* Inside backquotes, ``the portion of the quoted string from the
687 initial backquote and the characters up to the next backquote
688 that is not preceded by a backslash, having escape characters
689 removed, defines that command''. */
707 /* Pass everything between `$(' and the matching `)' or a quoted
708 ${ ... } pair through according to the Posix.2 specification. */
709 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
714 if (string[i + 1] == LPAREN)
715 ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_COMMAND); /*)*/
717 ret = extract_dollar_brace_string (string, &si, 1, 0);
720 temp[j++] = string[i + 1];
722 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
724 if (ret == 0 && no_longjmp_on_fatal_error)
727 ret = string + i + 2;
730 for (t = 0; ret[t]; t++, j++)
732 temp[j] = string[si];
747 /* Add any character but a double quote to the quoted string we're
750 goto add_one_character;
764 /* Point to after the closing quote. */
772 /* This should really be another option to string_extract_double_quoted. */
774 skip_double_quoted (string, slen, sind)
781 int pass_next, backquote, si;
784 pass_next = backquote = 0;
786 while (c = string[i])
791 ADVANCE_CHAR (string, slen, i);
804 ADVANCE_CHAR (string, slen, i);
813 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
816 if (string[i + 1] == LPAREN)
817 ret = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */
819 ret = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
826 ADVANCE_CHAR (string, slen, i);
839 /* Extract the contents of STRING as if it is enclosed in single quotes.
840 SINDEX, when passed in, is the offset of the character immediately
841 following the opening single quote; on exit, SINDEX is left pointing after
842 the closing single quote. */
844 string_extract_single_quoted (string, sindex)
853 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
854 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 0;
856 while (string[i] && string[i] != '\'')
857 ADVANCE_CHAR (string, slen, i);
859 t = substring (string, *sindex, i);
869 skip_single_quoted (string, slen, sind)
878 while (string[c] && string[c] != '\'')
879 ADVANCE_CHAR (string, slen, c);
886 /* Just like string_extract, but doesn't hack backslashes or any of
887 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
889 string_extract_verbatim (string, slen, sindex, charlist)
895 register int i = *sindex;
896 #if defined (HANDLE_MULTIBYTE)
904 if (charlist[0] == '\'' && charlist[1] == '\0')
906 temp = string_extract_single_quoted (string, sindex);
907 --*sindex; /* leave *sindex at separator character */
913 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
914 this only if MB_CUR_MAX > 1. */
915 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
917 #if defined (HANDLE_MULTIBYTE)
918 clen = strlen (charlist);
921 while (c = string[i])
923 #if defined (HANDLE_MULTIBYTE)
932 #if defined (HANDLE_MULTIBYTE)
933 mblength = MBLEN (string + i, slen - i);
937 mblength = mbtowc (&wc, string + i, slen - i);
938 if (MB_INVALIDCH (mblength))
940 if (MEMBER (c, charlist))
948 len = mbstowcs (wcharlist, charlist, 0);
951 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
952 mbstowcs (wcharlist, charlist, len + 1);
955 if (wcschr (wcharlist, wc))
961 if (MEMBER (c, charlist))
964 ADVANCE_CHAR (string, slen, i);
967 #if defined (HANDLE_MULTIBYTE)
971 temp = substring (string, *sindex, i);
977 /* Extract the $( construct in STRING, and return a new string.
978 Start extracting at (SINDEX) as if we had just seen "$(".
979 Make (SINDEX) get the position of the matching ")". ) */
981 extract_command_subst (string, sindex)
985 return (extract_delimited_string (string, sindex, "$(", "(", ")", EX_COMMAND)); /*)*/
988 /* Extract the $[ construct in STRING, and return a new string. (])
989 Start extracting at (SINDEX) as if we had just seen "$[".
990 Make (SINDEX) get the position of the matching "]". */
992 extract_arithmetic_subst (string, sindex)
996 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
999 #if defined (PROCESS_SUBSTITUTION)
1000 /* Extract the <( or >( construct in STRING, and return a new string.
1001 Start extracting at (SINDEX) as if we had just seen "<(".
1002 Make (SINDEX) get the position of the matching ")". */ /*))*/
1004 extract_process_subst (string, starter, sindex)
1009 return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
1011 #endif /* PROCESS_SUBSTITUTION */
1013 #if defined (ARRAY_VARS)
1014 /* This can be fooled by unquoted right parens in the passed string. If
1015 each caller verifies that the last character in STRING is a right paren,
1016 we don't even need to call extract_delimited_string. */
1018 extract_array_assignment_list (string, sindex)
1025 slen = strlen (string); /* ( */
1026 if (string[slen - 1] == ')')
1028 ret = substring (string, *sindex, slen - 1);
1036 /* Extract and create a new string from the contents of STRING, a
1037 character string delimited with OPENER and CLOSER. SINDEX is
1038 the address of an int describing the current offset in STRING;
1039 it should point to just after the first OPENER found. On exit,
1040 SINDEX gets the position of the last character of the matching CLOSER.
1041 If OPENER is more than a single character, ALT_OPENER, if non-null,
1042 contains a character string that can also match CLOSER and thus
1043 needs to be skipped. */
1045 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
1048 char *opener, *alt_opener, *closer;
1054 int pass_character, nesting_level, in_comment;
1055 int len_closer, len_opener, len_alt_opener;
1058 slen = strlen (string + *sindex) + *sindex;
1059 len_opener = STRLEN (opener);
1060 len_alt_opener = STRLEN (alt_opener);
1061 len_closer = STRLEN (closer);
1063 pass_character = in_comment = 0;
1068 while (nesting_level)
1079 ADVANCE_CHAR (string, slen, i);
1083 if (pass_character) /* previous char was backslash */
1086 ADVANCE_CHAR (string, slen, i);
1090 /* Not exactly right yet; should handle shell metacharacters and
1091 multibyte characters, too. */
1092 if ((flags & EX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || whitespace (string[i - 1])))
1095 ADVANCE_CHAR (string, slen, i);
1099 if (c == CTLESC || c == '\\')
1106 /* Process a nested OPENER. */
1107 if (STREQN (string + i, opener, len_opener))
1109 si = i + len_opener;
1110 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|EX_NOALLOC);
1115 /* Process a nested ALT_OPENER */
1116 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1118 si = i + len_alt_opener;
1119 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|EX_NOALLOC);
1124 /* If the current substring terminates the delimited string, decrement
1125 the nesting level. */
1126 if (STREQN (string + i, closer, len_closer))
1128 i += len_closer - 1; /* move to last byte of the closer */
1130 if (nesting_level == 0)
1134 /* Pass old-style command substitution through verbatim. */
1138 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1143 /* Pass single-quoted and double-quoted strings through verbatim. */
1144 if (c == '\'' || c == '"')
1147 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1148 : skip_double_quoted (string, slen, si);
1152 /* move past this character, which was not special. */
1153 ADVANCE_CHAR (string, slen, i);
1156 if (c == 0 && nesting_level)
1158 if (no_longjmp_on_fatal_error == 0)
1160 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1161 last_command_exit_value = EXECUTION_FAILURE;
1162 exp_jump_to_top_level (DISCARD);
1167 return (char *)NULL;
1171 si = i - *sindex - len_closer + 1;
1172 if (flags & EX_NOALLOC)
1173 result = (char *)NULL;
1176 result = (char *)xmalloc (1 + si);
1177 strncpy (result, string + *sindex, si);
1185 /* Extract a parameter expansion expression within ${ and } from STRING.
1186 Obey the Posix.2 rules for finding the ending `}': count braces while
1187 skipping over enclosed quoted strings and command substitutions.
1188 SINDEX is the address of an int describing the current offset in STRING;
1189 it should point to just after the first `{' found. On exit, SINDEX
1190 gets the position of the matching `}'. QUOTED is non-zero if this
1191 occurs inside double quotes. */
1192 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1194 extract_dollar_brace_string (string, sindex, quoted, flags)
1196 int *sindex, quoted, flags;
1200 int pass_character, nesting_level, si;
1206 slen = strlen (string + *sindex) + *sindex;
1209 while (c = string[i])
1214 ADVANCE_CHAR (string, slen, i);
1218 /* CTLESCs and backslashes quote the next character. */
1219 if (c == CTLESC || c == '\\')
1226 if (string[i] == '$' && string[i+1] == LBRACE)
1236 if (nesting_level == 0)
1242 /* Pass the contents of old-style command substitutions through
1247 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1252 /* Pass the contents of new-style command substitutions and
1253 arithmetic substitutions through verbatim. */
1254 if (string[i] == '$' && string[i+1] == LPAREN)
1257 t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC|EX_COMMAND); /*)*/
1262 /* Pass the contents of single-quoted and double-quoted strings
1263 through verbatim. */
1264 if (c == '\'' || c == '"')
1267 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1268 : skip_double_quoted (string, slen, si);
1269 /* skip_XXX_quoted leaves index one past close quote */
1273 /* move past this character, which was not special. */
1274 ADVANCE_CHAR (string, slen, i);
1277 if (c == 0 && nesting_level)
1279 if (no_longjmp_on_fatal_error == 0)
1281 report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1282 last_command_exit_value = EXECUTION_FAILURE;
1283 exp_jump_to_top_level (DISCARD);
1288 return ((char *)NULL);
1292 result = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1298 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1299 STRING, and returns a pointer to it. */
1301 de_backslash (string)
1304 register size_t slen;
1305 register int i, j, prev_i;
1308 slen = strlen (string);
1311 /* Loop copying string[i] to string[j], i >= j. */
1314 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1315 string[i + 1] == '$'))
1318 ADVANCE_CHAR (string, slen, i);
1320 do string[j++] = string[prev_i++]; while (prev_i < i);
1331 /* Replace instances of \! in a string with !. */
1333 unquote_bang (string)
1337 register char *temp;
1339 temp = (char *)xmalloc (1 + strlen (string));
1341 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1343 if (string[i] == '\\' && string[i + 1] == '!')
1349 strcpy (string, temp);
1354 #if defined (READLINE)
1355 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1356 an unclosed quoted string), or if the character at EINDEX is quoted
1357 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1358 single and double-quoted string parsing functions should not return an
1359 error if there are unclosed quotes or braces. The characters that this
1360 recognizes need to be the same as the contents of
1361 rl_completer_quote_characters. */
1363 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1366 char_is_quoted (string, eindex)
1370 int i, pass_next, c;
1374 slen = strlen (string);
1375 no_longjmp_on_fatal_error = 1;
1384 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1386 ADVANCE_CHAR (string, slen, i);
1395 else if (c == '\'' || c == '"')
1397 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1398 : skip_double_quoted (string, slen, ++i);
1401 /* no increment, the skip_xxx functions go one past end */
1404 ADVANCE_CHAR (string, slen, i);
1411 unclosed_pair (string, eindex, openstr)
1416 int i, pass_next, openc, olen;
1420 slen = strlen (string);
1421 olen = strlen (openstr);
1422 i = pass_next = openc = 0;
1428 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1430 ADVANCE_CHAR (string, slen, i);
1433 else if (string[i] == '\\')
1439 else if (STREQN (string + i, openstr, olen))
1444 else if (string[i] == '\'' || string[i] == '"')
1446 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1447 : skip_double_quoted (string, slen, i);
1452 ADVANCE_CHAR (string, slen, i);
1457 /* Skip characters in STRING until we find a character in DELIMS, and return
1458 the index of that character. START is the index into string at which we
1459 begin. This is similar in spirit to strpbrk, but it returns an index into
1460 STRING and takes a starting index. This little piece of code knows quite
1461 a lot of shell syntax. It's very similar to skip_double_quoted and other
1462 functions of that ilk. */
1464 skip_to_delim (string, start, delims)
1469 int i, pass_next, backq, si, c;
1474 slen = strlen (string + start) + start;
1475 no_longjmp_on_fatal_error = 1;
1477 pass_next = backq = 0;
1478 while (c = string[i])
1485 ADVANCE_CHAR (string, slen, i);
1498 ADVANCE_CHAR (string, slen, i);
1507 else if (c == '\'' || c == '"')
1509 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1510 : skip_double_quoted (string, slen, ++i);
1511 /* no increment, the skip functions increment past the closing quote. */
1513 else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1516 if (string[si] == '\0')
1519 if (string[i+1] == LPAREN)
1520 temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */
1522 temp = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
1524 if (string[i] == '\0') /* don't increment i past EOS in loop */
1529 else if (member (c, delims))
1532 ADVANCE_CHAR (string, slen, i);
1538 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1539 individual words. If DELIMS is NULL, the current value of $IFS is used
1540 to split the string, and the function follows the shell field splitting
1541 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1542 gets the number of words in the returned list. CWP, if non-NULL, gets
1543 the index of the word containing SENTINEL. Non-whitespace chars in
1544 DELIMS delimit separate fields. */
1546 split_at_delims (string, slen, delims, sentinel, nwp, cwp)
1553 int ts, te, i, nw, cw, ifs_split;
1554 char *token, *d, *d2;
1555 WORD_LIST *ret, *tl;
1557 if (string == 0 || *string == '\0')
1563 return ((WORD_LIST *)NULL);
1566 d = (delims == 0) ? ifs_value : delims;
1567 ifs_split = delims == 0;
1569 /* Make d2 the non-whitespace characters in delims */
1574 #if defined (HANDLE_MULTIBYTE)
1575 size_t mblength = 1;
1579 slength = strlen (delims);
1580 d2 = (char *)xmalloc (slength + 1);
1584 #if defined (HANDLE_MULTIBYTE)
1585 mbstate_t state_bak;
1587 mblength = MBRLEN (delims + i, slength, &state);
1588 if (MB_INVALIDCH (mblength))
1590 else if (mblength > 1)
1592 memcpy (d2 + ts, delims + i, mblength);
1595 slength -= mblength;
1599 if (whitespace (delims[i]) == 0)
1600 d2[ts++] = delims[i];
1608 ret = (WORD_LIST *)NULL;
1610 /* Remove sequences of whitspace characters at the start of the string, as
1611 long as those characters are delimiters. */
1612 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1614 if (string[i] == '\0')
1622 te = skip_to_delim (string, ts, d);
1624 /* If we have a non-whitespace delimiter character, use it to make a
1625 separate field. This is just about what $IFS splitting does and
1626 is closer to the behavior of the shell parser. */
1627 if (ts == te && d2 && member (string[ts], d2))
1630 /* If we're using IFS splitting, the non-whitespace delimiter char
1631 and any additional IFS whitespace delimits a field. */
1633 while (member (string[te], d) && spctabnl (string[te]))
1636 while (member (string[te], d2))
1640 token = substring (string, ts, te);
1642 ret = add_string_to_list (token, ret);
1646 if (sentinel >= ts && sentinel <= te)
1649 /* If the cursor is at whitespace just before word start, set the
1650 sentinel word to the current word. */
1651 if (cwp && cw == -1 && sentinel == ts-1)
1654 /* If the cursor is at whitespace between two words, make a new, empty
1655 word, add it before (well, after, since the list is in reverse order)
1656 the word we just added, and set the current word to that one. */
1657 if (cwp && cw == -1 && sentinel < ts)
1659 tl = make_word_list (make_word (""), ret->next);
1665 if (string[te] == 0)
1669 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
1678 /* Special case for SENTINEL at the end of STRING. If we haven't found
1679 the word containing SENTINEL yet, and the index we're looking for is at
1680 the end of STRING, add an additional null argument and set the current
1681 word pointer to that. */
1682 if (cwp && cw == -1 && sentinel >= slen)
1684 if (whitespace (string[sentinel - 1]))
1687 ret = add_string_to_list (token, ret);
1698 return (REVERSE_LIST (ret, WORD_LIST *));
1700 #endif /* READLINE */
1704 /* Extract the name of the variable to bind to from the assignment string. */
1706 assignment_name (string)
1712 offset = assignment (string, 0);
1714 return (char *)NULL;
1715 temp = substring (string, 0, offset);
1720 /* **************************************************************** */
1722 /* Functions to convert strings to WORD_LISTs and vice versa */
1724 /* **************************************************************** */
1726 /* Return a single string of all the words in LIST. SEP is the separator
1727 to put between individual elements of LIST in the output string. */
1729 string_list_internal (list, sep)
1733 register WORD_LIST *t;
1735 int word_len, sep_len, result_size;
1738 return ((char *)NULL);
1740 /* Short-circuit quickly if we don't need to separate anything. */
1741 if (list->next == 0)
1742 return (savestring (list->word->word));
1744 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1745 sep_len = STRLEN (sep);
1748 for (t = list; t; t = t->next)
1751 result_size += sep_len;
1752 result_size += strlen (t->word->word);
1755 r = result = (char *)xmalloc (result_size + 1);
1757 for (t = list; t; t = t->next)
1759 if (t != list && sep_len)
1763 FASTCOPY (sep, r, sep_len);
1770 word_len = strlen (t->word->word);
1771 FASTCOPY (t->word->word, r, word_len);
1779 /* Return a single string of all the words present in LIST, separating
1780 each word with a space. */
1785 return (string_list_internal (list, " "));
1788 /* Return a single string of all the words present in LIST, obeying the
1789 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1790 expansion [of $*] appears within a double quoted string, it expands
1791 to a single field with the value of each parameter separated by the
1792 first character of the IFS variable, or by a <space> if IFS is unset." */
1794 string_list_dollar_star (list)
1798 #if defined (HANDLE_MULTIBYTE)
1799 # if defined (__GNUC__)
1800 char sep[MB_CUR_MAX + 1];
1808 #if defined (HANDLE_MULTIBYTE)
1809 # if !defined (__GNUC__)
1810 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1811 # endif /* !__GNUC__ */
1812 if (ifs_firstc_len == 1)
1814 sep[0] = ifs_firstc[0];
1819 memcpy (sep, ifs_firstc, ifs_firstc_len);
1820 sep[ifs_firstc_len] = '\0';
1823 sep[0] = ifs_firstc;
1827 ret = string_list_internal (list, sep);
1828 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1834 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1835 is non-zero, the $@ appears within double quotes, and we should quote
1836 the list before converting it into a string. If IFS is unset, and the
1837 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1838 in the words in the list, because the default value of $IFS is
1839 <space><tab><newline>, IFS characters in the words in the list should
1840 also be split. If IFS is null, and the word is not quoted, we need
1841 to quote the words in the list to preserve the positional parameters
1844 string_list_dollar_at (list, quoted)
1849 #if defined (HANDLE_MULTIBYTE)
1850 # if defined (__GNUC__)
1851 char sep[MB_CUR_MAX + 1];
1854 # endif /* !__GNUC__ */
1860 /* XXX this could just be ifs = ifs_value; */
1861 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
1863 #if defined (HANDLE_MULTIBYTE)
1864 # if !defined (__GNUC__)
1865 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1866 # endif /* !__GNUC__ */
1869 if (ifs_firstc_len == 1)
1871 sep[0] = ifs_firstc[0];
1876 memcpy (sep, ifs_firstc, ifs_firstc_len);
1877 sep[ifs_firstc_len] = '\0';
1886 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1890 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
1891 it now that quote_escapes quotes spaces */
1893 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1895 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1898 : list_quote_escapes (list);
1900 ret = string_list_internal (tlist, sep);
1901 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1907 /* Return the list of words present in STRING. Separate the string into
1908 words at any of the characters found in SEPARATORS. If QUOTED is
1909 non-zero then word in the list will have its quoted flag set, otherwise
1910 the quoted flag is left as make_word () deemed fit.
1912 This obeys the P1003.2 word splitting semantics. If `separators' is
1913 exactly <space><tab><newline>, then the splitting algorithm is that of
1914 the Bourne shell, which treats any sequence of characters from `separators'
1915 as a delimiter. If IFS is unset, which results in `separators' being set
1916 to "", no splitting occurs. If separators has some other value, the
1917 following rules are applied (`IFS white space' means zero or more
1918 occurrences of <space>, <tab>, or <newline>, as long as those characters
1919 are in `separators'):
1921 1) IFS white space is ignored at the start and the end of the
1923 2) Each occurrence of a character in `separators' that is not
1924 IFS white space, along with any adjacent occurrences of
1925 IFS white space delimits a field.
1926 3) Any nonzero-length sequence of IFS white space delimits a field.
1929 /* BEWARE! list_string strips null arguments. Don't call it twice and
1930 expect to have "" preserved! */
1932 /* This performs word splitting and quoted null character removal on
1935 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1936 : (c) == (separators)[0]) \
1940 list_string (string, separators, quoted)
1941 register char *string, *separators;
1946 char *current_word, *s;
1947 int sindex, sh_style_split, whitesep;
1950 if (!string || !*string)
1951 return ((WORD_LIST *)NULL);
1953 sh_style_split = separators && separators[0] == ' ' &&
1954 separators[1] == '\t' &&
1955 separators[2] == '\n' &&
1956 separators[3] == '\0';
1959 /* Remove sequences of whitespace at the beginning of STRING, as
1960 long as those characters appear in IFS. Do not do this if
1961 STRING is quoted or if there are no separator characters. */
1962 if (!quoted || !separators || !*separators)
1964 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1967 return ((WORD_LIST *)NULL);
1972 /* OK, now STRING points to a word that does not begin with white space.
1973 The splitting algorithm is:
1974 extract a word, stopping at a separator
1975 skip sequences of spc, tab, or nl as long as they are separators
1976 This obeys the field splitting rules in Posix.2. */
1977 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
1978 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1980 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
1981 unless multibyte chars are possible. */
1982 current_word = string_extract_verbatim (string, slen, &sindex, separators);
1983 if (current_word == 0)
1986 /* If we have a quoted empty string, add a quoted null argument. We
1987 want to preserve the quoted null character iff this is a quoted
1988 empty string; otherwise the quoted null characters are removed
1990 if (QUOTED_NULL (current_word))
1992 t = alloc_word_desc ();
1993 t->word = make_quoted_char ('\0');
1994 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
1995 result = make_word_list (t, result);
1997 else if (current_word[0] != '\0')
1999 /* If we have something, then add it regardless. However,
2000 perform quoted null character removal on the current word. */
2001 remove_quoted_nulls (current_word);
2002 result = add_string_to_list (current_word, result);
2003 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
2004 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
2005 result->word->flags |= W_QUOTED;
2008 /* If we're not doing sequences of separators in the traditional
2009 Bourne shell style, then add a quoted null argument. */
2010 else if (!sh_style_split && !spctabnl (string[sindex]))
2012 t = alloc_word_desc ();
2013 t->word = make_quoted_char ('\0');
2014 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2015 result = make_word_list (t, result);
2018 free (current_word);
2020 /* Note whether or not the separator is IFS whitespace, used later. */
2021 whitesep = string[sindex] && spctabnl (string[sindex]);
2023 /* Move past the current separator character. */
2027 ADVANCE_CHAR (string, slen, sindex);
2030 /* Now skip sequences of space, tab, or newline characters if they are
2031 in the list of separators. */
2032 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
2035 /* If the first separator was IFS whitespace and the current character
2036 is a non-whitespace IFS character, it should be part of the current
2037 field delimiter, not a separate delimiter that would result in an
2038 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2039 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
2042 /* An IFS character that is not IFS white space, along with any
2043 adjacent IFS white space, shall delimit a field. (SUSv3) */
2044 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
2048 return (REVERSE_LIST (result, WORD_LIST *));
2051 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2052 ENDPTR is set to the first character after the word. This is used by
2053 the `read' builtin. This is never called with SEPARATORS != $IFS;
2054 it should be simplified.
2056 XXX - this function is very similar to list_string; they should be
2059 get_word_from_string (stringp, separators, endptr)
2060 char **stringp, *separators, **endptr;
2064 int sindex, sh_style_split, whitesep;
2067 if (!stringp || !*stringp || !**stringp)
2068 return ((char *)NULL);
2072 sh_style_split = separators && separators[0] == ' ' &&
2073 separators[1] == '\t' &&
2074 separators[2] == '\n' &&
2075 separators[3] == '\0';
2079 /* Remove sequences of whitespace at the beginning of STRING, as
2080 long as those characters appear in IFS. */
2081 if (sh_style_split || !separators || !*separators)
2083 for (; *s && spctabnl (*s) && isifs (*s); s++);
2085 /* If the string is nothing but whitespace, update it and return. */
2091 return ((char *)NULL);
2095 /* OK, S points to a word that does not begin with white space.
2096 Now extract a word, stopping at a separator, save a pointer to
2097 the first character after the word, then skip sequences of spc,
2098 tab, or nl as long as they are separators.
2100 This obeys the field splitting rules in Posix.2. */
2102 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2103 unless multibyte chars are possible. */
2104 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
2105 current_word = string_extract_verbatim (s, slen, &sindex, separators);
2107 /* Set ENDPTR to the first character after the end of the word. */
2109 *endptr = s + sindex;
2111 /* Note whether or not the separator is IFS whitespace, used later. */
2112 whitesep = s[sindex] && spctabnl (s[sindex]);
2114 /* Move past the current separator character. */
2118 ADVANCE_CHAR (s, slen, sindex);
2121 /* Now skip sequences of space, tab, or newline characters if they are
2122 in the list of separators. */
2123 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2126 /* If the first separator was IFS whitespace and the current character is
2127 a non-whitespace IFS character, it should be part of the current field
2128 delimiter, not a separate delimiter that would result in an empty field.
2129 Look at POSIX.2, 3.6.5, (3)(b). */
2130 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
2133 /* An IFS character that is not IFS white space, along with any adjacent
2134 IFS white space, shall delimit a field. */
2135 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2139 /* Update STRING to point to the next field. */
2140 *stringp = s + sindex;
2141 return (current_word);
2144 /* Remove IFS white space at the end of STRING. Start at the end
2145 of the string and walk backwards until the beginning of the string
2146 or we find a character that's not IFS white space and not CTLESC.
2147 Only let CTLESC escape a white space character if SAW_ESCAPE is
2150 strip_trailing_ifs_whitespace (string, separators, saw_escape)
2151 char *string, *separators;
2156 s = string + STRLEN (string) - 1;
2157 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
2158 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
2166 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2167 backslashes, single and double quotes. */
2169 list_string_with_quotes (string)
2175 int c, i, tokstart, len;
2177 for (s = string; s && *s && spctabnl (*s); s++)
2179 if (s == 0 || *s == 0)
2180 return ((WORD_LIST *)NULL);
2184 list = (WORD_LIST *)NULL;
2195 i = skip_single_quoted (s, s_len, ++i);
2197 i = skip_double_quoted (s, s_len, ++i);
2198 else if (c == 0 || spctabnl (c))
2200 /* We have found the end of a token. Make a word out of it and
2201 add it to the word list. */
2202 token = substring (s, tokstart, i);
2203 list = add_string_to_list (token, list);
2205 while (spctabnl (s[i]))
2213 i++; /* normal character */
2215 return (REVERSE_LIST (list, WORD_LIST *));
2219 /********************************************************/
2221 /* Functions to perform assignment statements */
2223 /********************************************************/
2225 #if defined (ARRAY_VARS)
2227 do_compound_assignment (name, value, flags)
2235 mklocal = flags & ASS_MKLOCAL;
2237 if (mklocal && variable_context)
2239 list = expand_compound_array_assignment (value, flags);
2240 v = find_variable (name);
2241 if (v == 0 || array_p (v) == 0 || v->context != variable_context)
2242 v = make_local_array_variable (name);
2243 assign_compound_array_list (v, list, flags);
2246 v = assign_array_from_string (name, value, flags);
2252 /* Given STRING, an assignment string, get the value of the right side
2253 of the `=', and bind it to the left side. If EXPAND is true, then
2254 perform parameter expansion, command substitution, and arithmetic
2255 expansion on the right-hand side. Perform tilde expansion in any
2256 case. Do not perform word splitting on the result of expansion. */
2258 do_assignment_internal (word, expand)
2259 const WORD_DESC *word;
2262 int offset, tlen, appendop, assign_list, aflags;
2265 #if defined (ARRAY_VARS)
2271 if (word == 0 || word->word == 0)
2274 appendop = assign_list = aflags = 0;
2275 string = word->word;
2276 offset = assignment (string, 0);
2277 name = savestring (string);
2278 value = (char *)NULL;
2280 if (name[offset] == '=')
2284 if (name[offset - 1] == '+')
2287 name[offset - 1] = '\0';
2290 name[offset] = 0; /* might need this set later */
2291 temp = name + offset + 1;
2292 tlen = STRLEN (temp);
2294 #if defined (ARRAY_VARS)
2295 if (expand && (word->flags & W_COMPASSIGN))
2297 assign_list = ni = 1;
2298 value = extract_array_assignment_list (temp, &ni);
2303 if (expand && temp[0])
2304 value = expand_string_if_necessary (temp, 0, expand_string_assignment);
2306 value = savestring (temp);
2311 value = (char *)xmalloc (1);
2315 if (echo_command_at_execute)
2318 name[offset - 1] = '+';
2319 xtrace_print_assignment (name, value, assign_list, 1);
2321 name[offset - 1] = '\0';
2324 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2327 aflags |= ASS_APPEND;
2329 #if defined (ARRAY_VARS)
2330 if (t = xstrchr (name, '[')) /*]*/
2334 report_error (_("%s: cannot assign list to array member"), name);
2337 entry = assign_array_element (name, value, aflags);
2341 else if (assign_list)
2343 if (word->flags & W_ASSIGNARG)
2344 aflags |= ASS_MKLOCAL;
2345 entry = do_compound_assignment (name, value, aflags);
2348 #endif /* ARRAY_VARS */
2349 entry = bind_variable (name, value, aflags);
2351 stupidly_hack_special_variables (name);
2354 VUNSETATTR (entry, att_invisible);
2356 /* Return 1 if the assignment seems to have been performed correctly. */
2357 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
2360 /* Perform the assignment statement in STRING, and expand the
2361 right side by doing tilde, command and parameter expansion. */
2363 do_assignment (string)
2368 td.flags = W_ASSIGNMENT;
2371 return do_assignment_internal (&td, 1);
2375 do_word_assignment (word)
2378 return do_assignment_internal (word, 1);
2381 /* Given STRING, an assignment string, get the value of the right side
2382 of the `=', and bind it to the left side. Do not perform any word
2383 expansions on the right hand side. */
2385 do_assignment_no_expand (string)
2390 td.flags = W_ASSIGNMENT;
2393 return (do_assignment_internal (&td, 0));
2396 /***************************************************
2398 * Functions to manage the positional parameters *
2400 ***************************************************/
2402 /* Return the word list that corresponds to `$*'. */
2404 list_rest_of_args ()
2406 register WORD_LIST *list, *args;
2409 /* Break out of the loop as soon as one of the dollar variables is null. */
2410 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2411 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2413 for (args = rest_of_args; args; args = args->next)
2414 list = make_word_list (make_bare_word (args->word->word), list);
2416 return (REVERSE_LIST (list, WORD_LIST *));
2422 register WORD_LIST *list;
2425 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2427 for (list = rest_of_args; list; list = list->next)
2432 /* Return the value of a positional parameter. This handles values > 10. */
2434 get_dollar_var_value (ind)
2441 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2442 else /* We want something like ${11} */
2445 for (p = rest_of_args; p && ind--; p = p->next)
2447 temp = p ? savestring (p->word->word) : (char *)NULL;
2452 /* Make a single large string out of the dollar digit variables,
2453 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2454 case of "$*" with respect to IFS. */
2456 string_rest_of_args (dollar_star)
2459 register WORD_LIST *list;
2462 list = list_rest_of_args ();
2463 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2464 dispose_words (list);
2468 /* Return a string containing the positional parameters from START to
2469 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2470 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2471 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2472 no quoting chars are added. */
2474 pos_params (string, start, end, quoted)
2476 int start, end, quoted;
2478 WORD_LIST *save, *params, *h, *t;
2482 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2484 return ((char *)NULL);
2486 save = params = list_rest_of_args ();
2488 return ((char *)NULL);
2490 for (i = 1; params && i < start; i++)
2491 params = params->next;
2493 return ((char *)NULL);
2494 for (h = t = params; params && i < end; i++)
2497 params = params->next;
2500 t->next = (WORD_LIST *)NULL;
2501 if (string[0] == '*')
2503 if (quoted & Q_DOUBLE_QUOTES)
2504 ret = string_list_dollar_star (quote_list (h));
2505 else if (quoted & Q_HERE_DOCUMENT)
2506 ret = string_list (quote_list (h));
2508 ret = string_list (h);
2511 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
2515 dispose_words (save);
2519 /******************************************************************/
2521 /* Functions to expand strings to strings or WORD_LISTs */
2523 /******************************************************************/
2525 #if defined (PROCESS_SUBSTITUTION)
2526 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2528 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2531 /* If there are any characters in STRING that require full expansion,
2532 then call FUNC to expand STRING; otherwise just perform quote
2533 removal if necessary. This returns a new string. */
2535 expand_string_if_necessary (string, quoted, func)
2546 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2547 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
2551 if (EXP_CHAR (string[i]))
2553 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
2555 ADVANCE_CHAR (string, slen, i);
2560 list = (*func) (string, quoted);
2563 ret = string_list (list);
2564 dispose_words (list);
2569 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
2570 ret = string_quote_removal (string, quoted);
2572 ret = savestring (string);
2577 static inline char *
2578 expand_string_to_string_internal (string, quoted, func)
2586 if (string == 0 || *string == '\0')
2587 return ((char *)NULL);
2589 list = (*func) (string, quoted);
2592 ret = string_list (list);
2593 dispose_words (list);
2602 expand_string_to_string (string, quoted)
2606 return (expand_string_to_string_internal (string, quoted, expand_string));
2610 expand_string_unsplit_to_string (string, quoted)
2614 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
2618 expand_assignment_string_to_string (string, quoted)
2622 return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
2626 expand_arith_string (string, quoted)
2629 return (expand_string_if_necessary (string, quoted, expand_string));
2632 #if defined (COND_COMMAND)
2633 /* Just remove backslashes in STRING. Returns a new string. */
2635 remove_backslashes (string)
2640 r = ret = (char *)xmalloc (strlen (string) + 1);
2641 for (s = string; s && *s; )
2653 /* This needs better error handling. */
2654 /* Expand W for use as an argument to a unary or binary operator in a
2655 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2656 to the != or == operator, and should be treated as a pattern. In
2657 this case, we quote the string specially for the globbing code. If
2658 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2659 be quoted appropriately for regcomp/regexec. The caller is responsible
2660 for removing the backslashes if the unquoted word is needed later. */
2662 cond_expand_word (w, special)
2670 if (w->word == 0 || w->word[0] == '\0')
2671 return ((char *)NULL);
2673 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
2679 r = string_list (l);
2683 qflags = QGLOB_CVTNULL;
2685 qflags |= QGLOB_REGEXP;
2686 p = string_list (l);
2687 r = quote_string_for_globbing (p, qflags);
2699 /* Call expand_word_internal to expand W and handle error returns.
2700 A convenience function for functions that don't want to handle
2701 any errors or free any memory before aborting. */
2703 call_expand_word_internal (w, q, i, c, e)
2709 result = expand_word_internal (w, q, i, c, e);
2710 if (result == &expand_word_error || result == &expand_word_fatal)
2712 /* By convention, each time this error is returned, w->word has
2713 already been freed (it sometimes may not be in the fatal case,
2714 but that doesn't result in a memory leak because we're going
2715 to exit in most cases). */
2716 w->word = (char *)NULL;
2717 last_command_exit_value = EXECUTION_FAILURE;
2718 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
2725 /* Perform parameter expansion, command substitution, and arithmetic
2726 expansion on STRING, as if it were a word. Leave the result quoted. */
2728 expand_string_internal (string, quoted)
2735 if (string == 0 || *string == 0)
2736 return ((WORD_LIST *)NULL);
2739 td.word = savestring (string);
2741 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2747 /* Expand STRING by performing parameter expansion, command substitution,
2748 and arithmetic expansion. Dequote the resulting WORD_LIST before
2749 returning it, but do not perform word splitting. The call to
2750 remove_quoted_nulls () is in here because word splitting normally
2751 takes care of quote removal. */
2753 expand_string_unsplit (string, quoted)
2759 if (string == 0 || *string == '\0')
2760 return ((WORD_LIST *)NULL);
2762 expand_no_split_dollar_star = 1;
2763 value = expand_string_internal (string, quoted);
2764 expand_no_split_dollar_star = 0;
2770 remove_quoted_nulls (value->word->word);
2771 value->word->flags &= ~W_HASQUOTEDNULL;
2773 dequote_list (value);
2778 /* Expand the rhs of an assignment statement */
2780 expand_string_assignment (string, quoted)
2787 if (string == 0 || *string == '\0')
2788 return ((WORD_LIST *)NULL);
2790 expand_no_split_dollar_star = 1;
2792 td.flags = W_ASSIGNRHS;
2793 td.word = savestring (string);
2794 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2797 expand_no_split_dollar_star = 0;
2803 remove_quoted_nulls (value->word->word);
2804 value->word->flags &= ~W_HASQUOTEDNULL;
2806 dequote_list (value);
2812 /* Expand one of the PS? prompt strings. This is a sort of combination of
2813 expand_string_unsplit and expand_string_internal, but returns the
2814 passed string when an error occurs. Might want to trap other calls
2815 to jump_to_top_level here so we don't endlessly loop. */
2817 expand_prompt_string (string, quoted, wflags)
2825 if (string == 0 || *string == 0)
2826 return ((WORD_LIST *)NULL);
2829 td.word = savestring (string);
2831 no_longjmp_on_fatal_error = 1;
2832 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2833 no_longjmp_on_fatal_error = 0;
2835 if (value == &expand_word_error || value == &expand_word_fatal)
2837 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
2845 remove_quoted_nulls (value->word->word);
2846 value->word->flags &= ~W_HASQUOTEDNULL;
2848 dequote_list (value);
2853 /* Expand STRING just as if you were expanding a word, but do not dequote
2854 the resultant WORD_LIST. This is called only from within this file,
2855 and is used to correctly preserve quoted characters when expanding
2856 things like ${1+"$@"}. This does parameter expansion, command
2857 substitution, arithmetic expansion, and word splitting. */
2859 expand_string_leave_quoted (string, quoted)
2866 if (string == 0 || *string == '\0')
2867 return ((WORD_LIST *)NULL);
2869 tlist = expand_string_internal (string, quoted);
2873 tresult = word_list_split (tlist);
2874 dispose_words (tlist);
2877 return ((WORD_LIST *)NULL);
2880 /* This does not perform word splitting or dequote the WORD_LIST
2883 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
2885 int quoted, *dollar_at_p, *has_dollar_at;
2890 if (string == 0 || *string == '\0')
2891 return (WORD_LIST *)NULL;
2895 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
2899 /* Expand STRING just as if you were expanding a word. This also returns
2900 a list of words. Note that filename globbing is *NOT* done for word
2901 or string expansion, just when the shell is expanding a command. This
2902 does parameter expansion, command substitution, arithmetic expansion,
2903 and word splitting. Dequote the resultant WORD_LIST before returning. */
2905 expand_string (string, quoted)
2911 if (string == 0 || *string == '\0')
2912 return ((WORD_LIST *)NULL);
2914 result = expand_string_leave_quoted (string, quoted);
2915 return (result ? dequote_list (result) : result);
2918 /***************************************************
2920 * Functions to handle quoting chars *
2922 ***************************************************/
2926 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2927 The parser passes CTLNUL as CTLESC CTLNUL. */
2929 /* Quote escape characters in string s, but no other characters. This is
2930 used to protect CTLESC and CTLNUL in variable values from the rest of
2931 the word expansion process after the variable is expanded. If IFS is
2932 null, we quote spaces as well, just in case we split on spaces later
2933 (in the case of unquoted $@, we will eventually attempt to split the
2934 entire word on spaces). Corresponding code exists in dequote_escapes.
2935 Even if we don't end up splitting on spaces, quoting spaces is not a
2938 quote_escapes (string)
2941 register char *s, *t;
2943 char *result, *send;
2947 slen = strlen (string);
2948 send = string + slen;
2950 quote_spaces = (ifs_value && *ifs_value == 0);
2951 t = result = (char *)xmalloc ((slen * 2) + 1);
2956 if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
2958 COPY_CHAR_P (t, s, send);
2965 list_quote_escapes (list)
2968 register WORD_LIST *w;
2971 for (w = list; w; w = w->next)
2974 w->word->word = quote_escapes (t);
2980 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2982 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2983 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2984 data stream pass through properly.
2986 We need to remove doubled CTLESC characters inside quoted strings before
2987 quoting the entire string, so we do not double the number of CTLESC
2990 Also used by parts of the pattern substitution code. */
2992 dequote_escapes (string)
2995 register char *s, *t;
2997 char *result, *send;
3004 slen = strlen (string);
3005 send = string + slen;
3007 t = result = (char *)xmalloc (slen + 1);
3010 if (strchr (string, CTLESC) == 0)
3011 return (strcpy (result, s));
3013 quote_spaces = (ifs_value && *ifs_value == 0);
3016 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
3022 COPY_CHAR_P (t, s, send);
3028 /* Return a new string with the quoted representation of character C.
3029 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3030 set in any resultant WORD_DESC where this value is the word. */
3032 make_quoted_char (c)
3037 temp = (char *)xmalloc (3);
3052 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3053 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3054 this value is the word. */
3056 quote_string (string)
3061 char *result, *send;
3065 result = (char *)xmalloc (2);
3073 slen = strlen (string);
3074 send = string + slen;
3076 result = (char *)xmalloc ((slen * 2) + 1);
3078 for (t = result; string < send; )
3081 COPY_CHAR_P (t, string, send);
3088 /* De-quote quoted characters in STRING. */
3090 dequote_string (string)
3093 register char *s, *t;
3095 char *result, *send;
3098 slen = strlen (string);
3100 t = result = (char *)xmalloc (slen + 1);
3102 if (QUOTED_NULL (string))
3108 /* If no character in the string can be quoted, don't bother examining
3109 each character. Just return a copy of the string passed to us. */
3110 if (strchr (string, CTLESC) == NULL)
3111 return (strcpy (result, string));
3113 send = string + slen;
3123 COPY_CHAR_P (t, s, send);
3130 /* Quote the entire WORD_LIST list. */
3135 register WORD_LIST *w;
3138 for (w = list; w; w = w->next)
3141 w->word->word = quote_string (t);
3143 w->word->flags |= W_QUOTED;
3144 /* XXX - turn on W_HAVEQUOTEDNULL here? */
3149 /* De-quote quoted characters in each word in LIST. */
3155 register WORD_LIST *tlist;
3157 for (tlist = list; tlist; tlist = tlist->next)
3159 s = dequote_string (tlist->word->word);
3160 free (tlist->word->word);
3161 tlist->word->word = s;
3162 /* XXX - turn off W_HAVEQUOTEDNULL here? */
3167 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3170 remove_quoted_escapes (string)
3177 t = dequote_escapes (string);
3185 /* Perform quoted null character removal on STRING. We don't allow any
3186 quoted null characters in the middle or at the ends of strings because
3187 of how expand_word_internal works. remove_quoted_nulls () turns
3188 STRING into an empty string iff it only consists of a quoted null,
3189 and removes all unquoted CTLNUL characters. */
3191 remove_quoted_nulls (string)
3194 register size_t slen;
3195 register int i, j, prev_i;
3198 if (strchr (string, CTLNUL) == 0) /* XXX */
3199 return string; /* XXX */
3201 slen = strlen (string);
3206 if (string[i] == CTLESC)
3208 /* Old code had j++, but we cannot assume that i == j at this
3209 point -- what if a CTLNUL has already been removed from the
3210 string? We don't want to drop the CTLESC or recopy characters
3211 that we've already copied down. */
3212 i++; string[j++] = CTLESC;
3216 else if (string[i] == CTLNUL)
3220 ADVANCE_CHAR (string, slen, i);
3223 do string[j++] = string[prev_i++]; while (prev_i < i);
3233 /* Perform quoted null character removal on each element of LIST.
3234 This modifies LIST. */
3236 word_list_remove_quoted_nulls (list)
3239 register WORD_LIST *t;
3241 for (t = list; t; t = t->next)
3243 remove_quoted_nulls (t->word->word);
3244 t->word->flags &= ~W_HASQUOTEDNULL;
3248 /* **************************************************************** */
3250 /* Functions for Matching and Removing Patterns */
3252 /* **************************************************************** */
3254 #if defined (HANDLE_MULTIBYTE)
3255 #if 0 /* Currently unused */
3256 static unsigned char *
3257 mb_getcharlens (string, len)
3261 int i, offset, last;
3268 ret = (unsigned char *)xmalloc (len);
3269 memset (ret, 0, len);
3270 while (string[last])
3272 ADVANCE_CHAR (string, len, offset);
3273 ret[last] = offset - last;
3281 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3282 can have one of 4 values:
3283 RP_LONG_LEFT remove longest matching portion at start of PARAM
3284 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3285 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3286 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3289 #define RP_LONG_LEFT 1
3290 #define RP_SHORT_LEFT 2
3291 #define RP_LONG_RIGHT 3
3292 #define RP_SHORT_RIGHT 4
3295 remove_upattern (param, pattern, op)
3296 char *param, *pattern;
3301 register char *p, *ret, c;
3303 len = STRLEN (param);
3308 case RP_LONG_LEFT: /* remove longest match at start */
3309 for (p = end; p >= param; p--)
3312 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3315 return (savestring (p));
3322 case RP_SHORT_LEFT: /* remove shortest match at start */
3323 for (p = param; p <= end; p++)
3326 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3329 return (savestring (p));
3335 case RP_LONG_RIGHT: /* remove longest match at end */
3336 for (p = param; p <= end; p++)
3338 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3341 ret = savestring (param);
3348 case RP_SHORT_RIGHT: /* remove shortest match at end */
3349 for (p = end; p >= param; p--)
3351 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3354 ret = savestring (param);
3362 return (savestring (param)); /* no match, return original string */
3365 #if defined (HANDLE_MULTIBYTE)
3367 remove_wpattern (wparam, wstrlen, wpattern, op)
3378 case RP_LONG_LEFT: /* remove longest match at start */
3379 for (n = wstrlen; n >= 0; n--)
3381 wc = wparam[n]; wparam[n] = L'\0';
3382 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3385 return (wcsdup (wparam + n));
3391 case RP_SHORT_LEFT: /* remove shortest match at start */
3392 for (n = 0; n <= wstrlen; n++)
3394 wc = wparam[n]; wparam[n] = L'\0';
3395 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3398 return (wcsdup (wparam + n));
3404 case RP_LONG_RIGHT: /* remove longest match at end */
3405 for (n = 0; n <= wstrlen; n++)
3407 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3409 wc = wparam[n]; wparam[n] = L'\0';
3410 ret = wcsdup (wparam);
3417 case RP_SHORT_RIGHT: /* remove shortest match at end */
3418 for (n = wstrlen; n >= 0; n--)
3420 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3422 wc = wparam[n]; wparam[n] = L'\0';
3423 ret = wcsdup (wparam);
3431 return (wcsdup (wparam)); /* no match, return original string */
3433 #endif /* HANDLE_MULTIBYTE */
3436 remove_pattern (param, pattern, op)
3437 char *param, *pattern;
3442 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3443 return (savestring (param));
3445 #if defined (HANDLE_MULTIBYTE)
3448 wchar_t *ret, *oret;
3450 wchar_t *wparam, *wpattern;
3454 n = xdupmbstowcs (&wpattern, NULL, pattern);
3455 if (n == (size_t)-1)
3456 return (remove_upattern (param, pattern, op));
3457 n = xdupmbstowcs (&wparam, NULL, param);
3458 if (n == (size_t)-1)
3461 return (remove_upattern (param, pattern, op));
3463 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3469 xret = (char *)xmalloc (n + 1);
3470 memset (&ps, '\0', sizeof (mbstate_t));
3471 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3472 xret[n] = '\0'; /* just to make sure */
3478 return (remove_upattern (param, pattern, op));
3481 /* Return 1 of the first character of STRING could match the first
3482 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3484 match_pattern_char (pat, string)
3495 return (*string == c);
3497 return (*string == *pat);
3499 return (*pat == LPAREN ? 1 : (*string != '\0'));
3505 return (*pat == LPAREN ? 1 : (*string == c));
3507 return (*string != '\0');
3511 /* Match PAT anywhere in STRING and return the match boundaries.
3512 This returns 1 in case of a successful match, 0 otherwise. SP
3513 and EP are pointers into the string where the match begins and
3514 ends, respectively. MTYPE controls what kind of match is attempted.
3515 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3516 of the string, respectively. The longest match is returned. */
3518 match_upattern (string, pat, mtype, sp, ep)
3524 register char *p, *p1, *npat;
3527 /* If the pattern doesn't match anywhere in the string, go ahead and
3528 short-circuit right away. A minor optimization, saves a bunch of
3529 unnecessary calls to strmatch (up to N calls for a string of N
3530 characters) if the match is unsuccessful. To preserve the semantics
3531 of the substring matches below, we make sure that the pattern has
3532 `*' as first and last character, making a new pattern if necessary. */
3533 /* XXX - check this later if I ever implement `**' with special meaning,
3534 since this will potentially result in `**' at the beginning or end */
3536 if (pat[0] != '*' || pat[len - 1] != '*')
3538 p = npat = (char *)xmalloc (len + 3);
3544 if (p1[-1] != '*' || p[-2] == '\\')
3550 c = strmatch (npat, string, FNMATCH_EXTFLAG);
3553 if (c == FNM_NOMATCH)
3556 len = STRLEN (string);
3562 for (p = string; p <= end; p++)
3564 if (match_pattern_char (pat, p))
3566 for (p1 = end; p1 >= p; p1--)
3568 c = *p1; *p1 = '\0';
3569 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3584 if (match_pattern_char (pat, string) == 0)
3587 for (p = end; p >= string; p--)
3590 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
3603 for (p = string; p <= end; p++)
3605 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3620 #if defined (HANDLE_MULTIBYTE)
3621 /* Return 1 of the first character of WSTRING could match the first
3622 character of pattern WPAT. Wide character version. */
3624 match_pattern_wchar (wpat, wstring)
3625 wchar_t *wpat, *wstring;
3632 switch (wc = *wpat++)
3635 return (*wstring == wc);
3637 return (*wstring == *wpat);
3639 return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
3645 return (*wpat == LPAREN ? 1 : (*wstring == wc));
3647 return (*wstring != L'\0');
3651 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3652 This returns 1 in case of a successful match, 0 otherwise. Wide
3653 character version. */
3655 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
3663 wchar_t wc, *wp, *nwpat, *wp1;
3666 size_t n, n1; /* Apple's gcc seems to miscompile this badly */
3671 /* If the pattern doesn't match anywhere in the string, go ahead and
3672 short-circuit right away. A minor optimization, saves a bunch of
3673 unnecessary calls to strmatch (up to N calls for a string of N
3674 characters) if the match is unsuccessful. To preserve the semantics
3675 of the substring matches below, we make sure that the pattern has
3676 `*' as first and last character, making a new pattern if necessary. */
3677 /* XXX - check this later if I ever implement `**' with special meaning,
3678 since this will potentially result in `**' at the beginning or end */
3679 len = wcslen (wpat);
3680 if (wpat[0] != L'*' || wpat[len - 1] != L'*')
3682 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
3686 while (*wp1 != L'\0')
3688 if (wp1[-1] != L'*' || wp1[-2] == L'\\')
3694 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
3697 if (len == FNM_NOMATCH)
3703 for (n = 0; n <= wstrlen; n++)
3705 if (match_pattern_wchar (wpat, wstring + n))
3707 for (n1 = wstrlen; n1 >= n; n1--)
3709 wc = wstring[n1]; wstring[n1] = L'\0';
3710 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3725 if (match_pattern_wchar (wpat, wstring) == 0)
3728 for (n = wstrlen; n >= 0; n--)
3730 wc = wstring[n]; wstring[n] = L'\0';
3731 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
3744 for (n = 0; n <= wstrlen; n++)
3746 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3749 *ep = indices[wstrlen];
3759 #endif /* HANDLE_MULTIBYTE */
3762 match_pattern (string, pat, mtype, sp, ep)
3767 #if defined (HANDLE_MULTIBYTE)
3770 wchar_t *wstring, *wpat;
3774 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
3777 #if defined (HANDLE_MULTIBYTE)
3780 n = xdupmbstowcs (&wpat, NULL, pat);
3781 if (n == (size_t)-1)
3782 return (match_upattern (string, pat, mtype, sp, ep));
3783 n = xdupmbstowcs (&wstring, &indices, string);
3784 if (n == (size_t)-1)
3787 return (match_upattern (string, pat, mtype, sp, ep));
3789 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
3799 return (match_upattern (string, pat, mtype, sp, ep));
3803 getpatspec (c, value)
3808 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
3810 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
3813 /* Posix.2 says that the WORD should be run through tilde expansion,
3814 parameter expansion, command substitution and arithmetic expansion.
3815 This leaves the result quoted, so quote_string_for_globbing () has
3816 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3817 it means that the entire expression was enclosed in double quotes.
3818 This means that quoting characters in the pattern do not make any
3819 special pattern characters quoted. For example, the `*' in the
3820 following retains its special meaning: "${foo#'*'}". */
3822 getpattern (value, quoted, expandpat)
3824 int quoted, expandpat;
3832 /* There is a problem here: how to handle single or double quotes in the
3833 pattern string when the whole expression is between double quotes?
3834 POSIX.2 says that enclosing double quotes do not cause the pattern to
3835 be quoted, but does that leave us a problem with @ and array[@] and their
3836 expansions inside a pattern? */
3838 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
3841 pat = string_extract_double_quoted (tword, &i, 1);
3847 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3849 l = *value ? expand_string_for_rhs (value,
3850 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
3851 (int *)NULL, (int *)NULL)
3853 pat = string_list (l);
3857 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
3865 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3866 or ${name#[#]value}. */
3868 variable_remove_pattern (value, pattern, patspec, quoted)
3869 char *value, *pattern;
3870 int patspec, quoted;
3874 tword = remove_pattern (value, pattern, patspec);
3881 list_remove_pattern (list, pattern, patspec, itype, quoted)
3884 int patspec, itype, quoted;
3890 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
3892 tword = remove_pattern (l->word->word, pattern, patspec);
3893 w = alloc_word_desc ();
3894 w->word = tword ? tword : savestring ("");
3895 new = make_word_list (w, new);
3898 l = REVERSE_LIST (new, WORD_LIST *);
3900 tword = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (l) : string_list (l);
3902 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
3909 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
3912 int patspec, quoted;
3917 list = list_rest_of_args ();
3919 return ((char *)NULL);
3920 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3921 dispose_words (list);
3925 #if defined (ARRAY_VARS)
3927 array_remove_pattern (a, pattern, patspec, varname, quoted)
3931 char *varname; /* so we can figure out how it's indexed */
3939 /* compute itype from varname here */
3940 v = array_variable_part (varname, &ret, 0);
3943 list = array_to_word_list (a);
3945 return ((char *)NULL);
3946 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3947 dispose_words (list);
3951 #endif /* ARRAY_VARS */
3954 parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
3955 char *varname, *value, *patstr;
3958 int vtype, patspec, starsub;
3959 char *temp1, *val, *pattern;
3963 return ((char *)NULL);
3965 this_command_name = varname;
3967 vtype = get_var_and_type (varname, value, quoted, &v, &val);
3969 return ((char *)NULL);
3971 starsub = vtype & VT_STARSUB;
3972 vtype &= ~VT_STARSUB;
3974 patspec = getpatspec (rtype, patstr);
3975 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
3978 /* Need to pass getpattern newly-allocated memory in case of expansion --
3979 the expansion code will free the passed string on an error. */
3980 temp1 = savestring (patstr);
3981 pattern = getpattern (temp1, quoted, 1);
3984 temp1 = (char *)NULL; /* shut up gcc */
3988 case VT_ARRAYMEMBER:
3989 temp1 = remove_pattern (val, pattern, patspec);
3990 if (vtype == VT_VARIABLE)
3994 val = quote_escapes (temp1);
3999 #if defined (ARRAY_VARS)
4001 temp1 = array_remove_pattern (array_cell (v), pattern, patspec, varname, quoted);
4002 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4004 val = quote_escapes (temp1);
4011 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
4012 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4014 val = quote_escapes (temp1);
4025 /*******************************************
4027 * Functions to expand WORD_DESCs *
4029 *******************************************/
4031 /* Expand WORD, performing word splitting on the result. This does
4032 parameter expansion, command substitution, arithmetic expansion,
4033 word splitting, and quote removal. */
4036 expand_word (word, quoted)
4040 WORD_LIST *result, *tresult;
4042 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4043 result = word_list_split (tresult);
4044 dispose_words (tresult);
4045 return (result ? dequote_list (result) : result);
4048 /* Expand WORD, but do not perform word splitting on the result. This
4049 does parameter expansion, command substitution, arithmetic expansion,
4050 and quote removal. */
4052 expand_word_unsplit (word, quoted)
4058 expand_no_split_dollar_star = 1;
4059 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4060 expand_no_split_dollar_star = 0;
4062 return (result ? dequote_list (result) : result);
4065 /* Perform shell expansions on WORD, but do not perform word splitting or
4066 quote removal on the result. */
4068 expand_word_leave_quoted (word, quoted)
4072 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
4075 #if defined (PROCESS_SUBSTITUTION)
4077 /*****************************************************************/
4079 /* Hacking Process Substitution */
4081 /*****************************************************************/
4083 #if !defined (HAVE_DEV_FD)
4084 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4085 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4086 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4087 list. NFIFO is a count of the number of FIFOs in the list. */
4088 #define FIFO_INCR 20
4095 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
4097 static int fifo_list_size;
4100 add_fifo_list (pathname)
4103 if (nfifo >= fifo_list_size - 1)
4105 fifo_list_size += FIFO_INCR;
4106 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
4107 fifo_list_size * sizeof (struct temp_fifo));
4110 fifo_list[nfifo].file = savestring (pathname);
4122 for (i = saved = 0; i < nfifo; i++)
4124 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4126 unlink (fifo_list[i].file);
4127 free (fifo_list[i].file);
4128 fifo_list[i].file = (char *)NULL;
4129 fifo_list[i].proc = -1;
4135 /* If we didn't remove some of the FIFOs, compact the list. */
4138 for (i = j = 0; i < nfifo; i++)
4139 if (fifo_list[i].file)
4141 fifo_list[j].file = fifo_list[i].file;
4142 fifo_list[j].proc = fifo_list[i].proc;
4162 tname = sh_mktmpname ("sh-np", MT_USERANDOM);
4163 if (mkfifo (tname, 0600) < 0)
4166 return ((char *)NULL);
4169 add_fifo_list (tname);
4173 #else /* HAVE_DEV_FD */
4175 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4176 has open to children. NFDS is a count of the number of bits currently
4177 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4179 static char *dev_fd_list = (char *)NULL;
4181 static int totfds; /* The highest possible number of open files. */
4187 if (!dev_fd_list || fd >= totfds)
4192 totfds = getdtablesize ();
4193 if (totfds < 0 || totfds > 256)
4198 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
4199 memset (dev_fd_list + ofds, '\0', totfds - ofds);
4202 dev_fd_list[fd] = 1;
4209 return 0; /* used for cleanup; not needed with /dev/fd */
4220 for (i = 0; nfds && i < totfds; i++)
4231 #if defined (NOTDEF)
4232 print_dev_fd_list ()
4236 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
4239 for (i = 0; i < totfds; i++)
4242 fprintf (stderr, " %d", i);
4244 fprintf (stderr, "\n");
4249 make_dev_fd_filename (fd)
4252 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
4254 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 4);
4256 strcpy (ret, DEV_FD_PREFIX);
4257 p = inttostr (fd, intbuf, sizeof (intbuf));
4258 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
4264 #endif /* HAVE_DEV_FD */
4266 /* Return a filename that will open a connection to the process defined by
4267 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4268 a filename in /dev/fd corresponding to a descriptor that is one of the
4269 ends of the pipe. If not defined, we use named pipes on systems that have
4270 them. Systems without /dev/fd and named pipes are out of luck.
4272 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4273 use the read end of the pipe and dup that file descriptor to fd 0 in
4274 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4275 writing or use the write end of the pipe in the child, and dup that
4276 file descriptor to fd 1 in the child. The parent does the opposite. */
4279 process_substitute (string, open_for_read_in_child)
4281 int open_for_read_in_child;
4286 #if defined (HAVE_DEV_FD)
4287 int parent_pipe_fd, child_pipe_fd;
4289 #endif /* HAVE_DEV_FD */
4290 #if defined (JOB_CONTROL)
4291 pid_t old_pipeline_pgrp;
4294 if (!string || !*string || wordexp_only)
4295 return ((char *)NULL);
4297 #if !defined (HAVE_DEV_FD)
4298 pathname = make_named_pipe ();
4299 #else /* HAVE_DEV_FD */
4300 if (pipe (fildes) < 0)
4302 sys_error (_("cannot make pipe for process substitution"));
4303 return ((char *)NULL);
4305 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4306 the pipe in the parent, otherwise the read end. */
4307 parent_pipe_fd = fildes[open_for_read_in_child];
4308 child_pipe_fd = fildes[1 - open_for_read_in_child];
4309 /* Move the parent end of the pipe to some high file descriptor, to
4310 avoid clashes with FDs used by the script. */
4311 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
4313 pathname = make_dev_fd_filename (parent_pipe_fd);
4314 #endif /* HAVE_DEV_FD */
4318 sys_error (_("cannot make pipe for process substitution"));
4319 return ((char *)NULL);
4322 old_pid = last_made_pid;
4324 #if defined (JOB_CONTROL)
4325 old_pipeline_pgrp = pipeline_pgrp;
4326 pipeline_pgrp = shell_pgrp;
4328 #endif /* JOB_CONTROL */
4330 pid = make_child ((char *)NULL, 1);
4333 reset_terminating_signals (); /* XXX */
4334 free_pushed_string_input ();
4335 /* Cancel traps, in trap.c. */
4336 restore_original_signals ();
4337 setup_async_signals ();
4338 subshell_environment |= SUBSHELL_COMSUB;
4341 #if defined (JOB_CONTROL)
4342 set_sigchld_handler ();
4343 stop_making_children ();
4344 pipeline_pgrp = old_pipeline_pgrp;
4345 #endif /* JOB_CONTROL */
4349 sys_error (_("cannot make child for process substitution"));
4351 #if defined (HAVE_DEV_FD)
4352 close (parent_pipe_fd);
4353 close (child_pipe_fd);
4354 #endif /* HAVE_DEV_FD */
4355 return ((char *)NULL);
4360 #if defined (JOB_CONTROL)
4361 restore_pipeline (1);
4364 #if !defined (HAVE_DEV_FD)
4365 fifo_list[nfifo-1].proc = pid;
4368 last_made_pid = old_pid;
4370 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4372 #endif /* JOB_CONTROL && PGRP_PIPE */
4374 #if defined (HAVE_DEV_FD)
4375 close (child_pipe_fd);
4376 #endif /* HAVE_DEV_FD */
4381 set_sigint_handler ();
4383 #if defined (JOB_CONTROL)
4384 set_job_control (0);
4385 #endif /* JOB_CONTROL */
4387 #if !defined (HAVE_DEV_FD)
4388 /* Open the named pipe in the child. */
4389 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
4392 /* Two separate strings for ease of translation. */
4393 if (open_for_read_in_child)
4394 sys_error (_("cannot open named pipe %s for reading"), pathname);
4396 sys_error (_("cannot open named pipe %s for writing"), pathname);
4400 if (open_for_read_in_child)
4402 if (sh_unset_nodelay_mode (fd) < 0)
4404 sys_error (_("cannout reset nodelay mode for fd %d"), fd);
4408 #else /* HAVE_DEV_FD */
4410 #endif /* HAVE_DEV_FD */
4412 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
4414 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
4415 open_for_read_in_child ? 0 : 1);
4419 if (fd != (open_for_read_in_child ? 0 : 1))
4422 /* Need to close any files that this process has open to pipes inherited
4424 if (current_fds_to_close)
4426 close_fd_bitmap (current_fds_to_close);
4427 current_fds_to_close = (struct fd_bitmap *)NULL;
4430 #if defined (HAVE_DEV_FD)
4431 /* Make sure we close the parent's end of the pipe and clear the slot
4432 in the fd list so it is not closed later, if reallocated by, for
4433 instance, pipe(2). */
4434 close (parent_pipe_fd);
4435 dev_fd_list[parent_pipe_fd] = 0;
4436 #endif /* HAVE_DEV_FD */
4438 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
4440 #if !defined (HAVE_DEV_FD)
4441 /* Make sure we close the named pipe in the child before we exit. */
4442 close (open_for_read_in_child ? 0 : 1);
4443 #endif /* !HAVE_DEV_FD */
4448 #endif /* PROCESS_SUBSTITUTION */
4450 /***********************************/
4452 /* Command Substitution */
4454 /***********************************/
4457 read_comsub (fd, quoted)
4460 char *istring, buf[128], *bufp;
4461 int istring_index, istring_size, c;
4464 istring = (char *)NULL;
4465 istring_index = istring_size = bufn = 0;
4468 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
4471 /* Read the output of the command through the pipe. */
4478 bufn = zread (fd, buf, sizeof (buf));
4488 internal_warning ("read_comsub: ignored null byte in input");
4493 /* Add the character to ISTRING, possibly after resizing it. */
4494 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
4496 /* This is essentially quote_string inline */
4497 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
4498 istring[istring_index++] = CTLESC;
4499 /* Escape CTLESC and CTLNUL in the output to protect those characters
4500 from the rest of the word expansions (word splitting and globbing.)
4501 This is essentially quote_escapes inline. */
4502 else if (c == CTLESC)
4503 istring[istring_index++] = CTLESC;
4504 else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
4505 istring[istring_index++] = CTLESC;
4507 istring[istring_index++] = c;
4510 #if defined (__CYGWIN__)
4511 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
4514 istring[istring_index - 1] = '\n';
4521 istring[istring_index] = '\0';
4523 /* If we read no output, just return now and save ourselves some
4525 if (istring_index == 0)
4528 return (char *)NULL;
4531 /* Strip trailing newlines from the output of the command. */
4532 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4534 while (istring_index > 0)
4536 if (istring[istring_index - 1] == '\n')
4540 /* If the newline was quoted, remove the quoting char. */
4541 if (istring[istring_index - 1] == CTLESC)
4547 istring[istring_index] = '\0';
4550 strip_trailing (istring, istring_index - 1, 1);
4555 /* Perform command substitution on STRING. This returns a string,
4558 command_substitute (string, quoted)
4562 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
4564 int result, fildes[2], function_value, pflags, rc;
4566 istring = (char *)NULL;
4568 /* Don't fork () if there is no need to. In the case of no command to
4569 run, just return NULL. */
4570 if (!string || !*string || (string[0] == '\n' && !string[1]))
4571 return ((char *)NULL);
4573 if (wordexp_only && read_but_dont_execute)
4575 last_command_exit_value = 125;
4576 jump_to_top_level (EXITPROG);
4579 /* We're making the assumption here that the command substitution will
4580 eventually run a command from the file system. Since we'll run
4581 maybe_make_export_env in this subshell before executing that command,
4582 the parent shell and any other shells it starts will have to remake
4583 the environment. If we make it before we fork, other shells won't
4584 have to. Don't bother if we have any temporary variable assignments,
4585 though, because the export environment will be remade after this
4586 command completes anyway, but do it if all the words to be expanded
4587 are variable assignments. */
4588 if (subst_assign_varlist == 0 || garglist == 0)
4589 maybe_make_export_env (); /* XXX */
4591 /* Flags to pass to parse_and_execute() */
4592 pflags = interactive ? SEVAL_RESETLINE : 0;
4594 /* Pipe the output of executing STRING into the current shell. */
4595 if (pipe (fildes) < 0)
4597 sys_error (_("cannot make pipe for command substitution"));
4601 old_pid = last_made_pid;
4602 #if defined (JOB_CONTROL)
4603 old_pipeline_pgrp = pipeline_pgrp;
4604 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4605 if ((subshell_environment & SUBSHELL_PIPE) == 0)
4606 pipeline_pgrp = shell_pgrp;
4607 cleanup_the_pipeline ();
4608 #endif /* JOB_CONTROL */
4610 old_async_pid = last_asynchronous_pid;
4612 pid = make_child ((char *)NULL, 0);
4614 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
4616 last_asynchronous_pid = old_async_pid;
4619 /* Reset the signal handlers in the child, but don't free the
4621 reset_signal_handlers ();
4623 #if defined (JOB_CONTROL)
4624 set_sigchld_handler ();
4625 stop_making_children ();
4627 pipeline_pgrp = old_pipeline_pgrp;
4629 stop_making_children ();
4630 #endif /* JOB_CONTROL */
4634 sys_error (_("cannot make child for command substitution"));
4640 return ((char *)NULL);
4645 set_sigint_handler (); /* XXX */
4647 free_pushed_string_input ();
4649 if (dup2 (fildes[1], 1) < 0)
4651 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4652 exit (EXECUTION_FAILURE);
4655 /* If standard output is closed in the parent shell
4656 (such as after `exec >&-'), file descriptor 1 will be
4657 the lowest available file descriptor, and end up in
4658 fildes[0]. This can happen for stdin and stderr as well,
4659 but stdout is more important -- it will cause no output
4660 to be generated from this command. */
4661 if ((fildes[1] != fileno (stdin)) &&
4662 (fildes[1] != fileno (stdout)) &&
4663 (fildes[1] != fileno (stderr)))
4666 if ((fildes[0] != fileno (stdin)) &&
4667 (fildes[0] != fileno (stdout)) &&
4668 (fildes[0] != fileno (stderr)))
4671 /* The currently executing shell is not interactive. */
4674 /* This is a subshell environment. */
4675 subshell_environment |= SUBSHELL_COMSUB;
4677 /* When not in POSIX mode, command substitution does not inherit
4679 if (posixly_correct == 0)
4680 exit_immediately_on_error = 0;
4682 remove_quoted_escapes (string);
4684 startup_state = 2; /* see if we can avoid a fork */
4685 /* Give command substitution a place to jump back to on failure,
4686 so we don't go back up to main (). */
4687 result = setjmp (top_level);
4689 /* If we're running a command substitution inside a shell function,
4690 trap `return' so we don't return from the function in the subshell
4691 and go off to never-never land. */
4692 if (result == 0 && return_catch_flag)
4693 function_value = setjmp (return_catch);
4697 if (result == ERREXIT)
4698 rc = last_command_exit_value;
4699 else if (result == EXITPROG)
4700 rc = last_command_exit_value;
4702 rc = EXECUTION_FAILURE;
4703 else if (function_value)
4704 rc = return_catch_value;
4708 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
4712 last_command_exit_value = rc;
4713 rc = run_exit_trap ();
4714 #if defined (PROCESS_SUBSTITUTION)
4715 unlink_fifo_list ();
4721 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4723 #endif /* JOB_CONTROL && PGRP_PIPE */
4727 istring = read_comsub (fildes[0], quoted);
4731 current_command_subst_pid = pid;
4732 last_command_exit_value = wait_for (pid);
4733 last_command_subst_pid = pid;
4734 last_made_pid = old_pid;
4736 #if defined (JOB_CONTROL)
4737 /* If last_command_exit_value > 128, then the substituted command
4738 was terminated by a signal. If that signal was SIGINT, then send
4739 SIGINT to ourselves. This will break out of loops, for instance. */
4740 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
4741 kill (getpid (), SIGINT);
4743 /* wait_for gives the terminal back to shell_pgrp. If some other
4744 process group should have it, give it away to that group here.
4745 pipeline_pgrp is non-zero only while we are constructing a
4746 pipline, so what we are concerned about is whether or not that
4747 pipeline was started in the background. A pipeline started in
4748 the background should never get the tty back here. */
4750 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
4752 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
4754 give_terminal_to (pipeline_pgrp, 0);
4755 #endif /* JOB_CONTROL */
4761 /********************************************************
4763 * Utility functions for parameter expansion *
4765 ********************************************************/
4767 #if defined (ARRAY_VARS)
4770 array_length_reference (s)
4779 var = array_variable_part (s, &t, &len);
4781 /* If unbound variables should generate an error, report one and return
4783 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
4794 /* We support a couple of expansions for variables that are not arrays.
4795 We'll return the length of the value for v[0], and 1 for v[@] or
4796 v[*]. Return 0 for everything else. */
4798 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
4800 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
4801 return (array_p (var) ? array_num_elements (array) : 1);
4803 ind = array_expand_index (t, len);
4806 err_badarraysub (t);
4811 t = array_reference (array, ind);
4813 t = (ind == 0) ? value_cell (var) : (char *)NULL;
4815 len = MB_STRLEN (t);
4818 #endif /* ARRAY_VARS */
4821 valid_brace_expansion_word (name, var_is_special)
4825 if (DIGIT (*name) && all_digits (name))
4827 else if (var_is_special)
4829 #if defined (ARRAY_VARS)
4830 else if (valid_array_reference (name))
4832 #endif /* ARRAY_VARS */
4833 else if (legal_identifier (name))
4840 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
4843 int *quoted_dollar_atp, *contains_dollar_at;
4849 if (quoted_dollar_atp)
4850 *quoted_dollar_atp = 0;
4851 if (contains_dollar_at)
4852 *contains_dollar_at = 0;
4856 /* check for $@ and $* */
4857 if (name[0] == '@' && name[1] == 0)
4859 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4860 *quoted_dollar_atp = 1;
4861 if (contains_dollar_at)
4862 *contains_dollar_at = 1;
4865 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
4867 if (contains_dollar_at)
4868 *contains_dollar_at = 1;
4872 /* Now check for ${array[@]} and ${array[*]} */
4873 #if defined (ARRAY_VARS)
4874 else if (valid_array_reference (name))
4876 temp1 = xstrchr (name, '[');
4877 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4879 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4880 *quoted_dollar_atp = 1;
4881 if (contains_dollar_at)
4882 *contains_dollar_at = 1;
4885 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4886 which should result in separate words even when IFS is unset. */
4887 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4889 if (contains_dollar_at)
4890 *contains_dollar_at = 1;
4898 /* Parameter expand NAME, and return a new string which is the expansion,
4899 or NULL if there was no expansion.
4900 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4901 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4902 NAME was found inside of a double-quoted expression. */
4904 parameter_brace_expand_word (name, var_is_special, quoted)
4906 int var_is_special, quoted;
4918 /* Handle multiple digit arguments, as in ${11}. */
4919 if (legal_number (name, &arg_index))
4921 tt = get_dollar_var_value (arg_index);
4923 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4925 : quote_escapes (tt);
4927 temp = (char *)NULL;
4930 else if (var_is_special) /* ${@} */
4933 tt = (char *)xmalloc (2 + strlen (name));
4934 tt[sindex = 0] = '$';
4935 strcpy (tt + 1, name);
4937 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
4938 (int *)NULL, (int *)NULL, 0);
4941 #if defined (ARRAY_VARS)
4942 else if (valid_array_reference (name))
4944 temp = array_value (name, quoted, &atype);
4945 if (atype == 0 && temp)
4946 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4947 ? quote_string (temp)
4948 : quote_escapes (temp);
4949 else if (atype == 1 && temp && QUOTED_NULL (temp) && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4950 rflags |= W_HASQUOTEDNULL;
4953 else if (var = find_variable (name))
4955 if (var_isset (var) && invisible_p (var) == 0)
4957 #if defined (ARRAY_VARS)
4958 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
4960 temp = value_cell (var);
4964 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4965 ? quote_string (temp)
4966 : quote_escapes (temp);
4969 temp = (char *)NULL;
4972 temp = (char *)NULL;
4976 ret = alloc_word_desc ();
4978 ret->flags |= rflags;
4983 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4984 value of the variable whose name is the value of NAME. */
4986 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
4988 int var_is_special, quoted;
4989 int *quoted_dollar_atp, *contains_dollar_at;
4994 w = parameter_brace_expand_word (name, var_is_special, quoted);
4996 /* Have to dequote here if necessary */
4999 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5000 ? dequote_string (t)
5001 : dequote_escapes (t);
5005 dispose_word_desc (w);
5007 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
5009 return (WORD_DESC *)NULL;
5011 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
5017 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5018 depending on the value of C, the separating character. C can be one of
5019 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5020 between double quotes. */
5022 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
5024 int c, quoted, *qdollaratp, *hasdollarat;
5028 char *t, *t1, *temp;
5031 /* If the entire expression is between double quotes, we want to treat
5032 the value as a double-quoted string, with the exception that we strip
5033 embedded unescaped double quotes. */
5034 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
5037 temp = string_extract_double_quoted (value, &hasdol, 1);
5042 w = alloc_word_desc ();
5044 /* XXX was 0 not quoted */
5045 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
5048 *hasdollarat = hasdol || (l && l->next);
5053 /* The expansion of TEMP returned something. We need to treat things
5054 slightly differently if HASDOL is non-zero. If we have "$@", the
5055 individual words have already been quoted. We need to turn them
5056 into a string with the words separated by the first character of
5057 $IFS without any additional quoting, so string_list_dollar_at won't
5058 do the right thing. We use string_list_dollar_star instead. */
5059 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
5061 /* If l->next is not null, we know that TEMP contained "$@", since that
5062 is the only expansion that creates more than one word. */
5063 if (qdollaratp && ((hasdol && quoted) || l->next))
5067 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
5069 /* The brace expansion occurred between double quotes and there was
5070 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5071 it does not expand to anything. In this case, we want to return
5072 a quoted empty string. */
5073 temp = make_quoted_char ('\0');
5074 w->flags |= W_HASQUOTEDNULL;
5077 temp = (char *)NULL;
5079 if (c == '-' || c == '+')
5086 t = temp ? savestring (temp) : savestring ("");
5087 t1 = dequote_string (t);
5089 #if defined (ARRAY_VARS)
5090 if (valid_array_reference (name))
5091 assign_array_element (name, t1, 0);
5093 #endif /* ARRAY_VARS */
5094 bind_variable (name, t1, 0);
5101 /* Deal with the right hand side of a ${name:?value} expansion in the case
5102 that NAME is null or not set. If VALUE is non-null it is expanded and
5103 used as the error message to print, otherwise a standard message is
5106 parameter_brace_expand_error (name, value)
5112 if (value && *value)
5114 l = expand_string (value, 0);
5115 temp = string_list (l);
5116 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
5121 report_error (_("%s: parameter null or not set"), name);
5123 /* Free the data we have allocated during this expansion, since we
5124 are about to longjmp out. */
5129 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5132 valid_length_expression (name)
5135 return (name[1] == '\0' || /* ${#} */
5136 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
5137 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
5138 #if defined (ARRAY_VARS)
5139 valid_array_reference (name + 1) || /* ${#a[7]} */
5141 legal_identifier (name + 1)); /* ${#PS1} */
5144 #if defined (HANDLE_MULTIBYTE)
5150 mbstate_t mbs, mbsbak;
5153 memset (&mbs, 0, sizeof (mbs));
5155 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
5157 if (MB_INVALIDCH(clen))
5159 clen = 1; /* assume single byte */
5172 /* Handle the parameter brace expansion that requires us to return the
5173 length of a parameter. */
5175 parameter_brace_expand_length (name)
5179 intmax_t number, arg_index;
5181 #if defined (ARRAY_VARS)
5185 if (name[1] == '\0') /* ${#} */
5186 number = number_of_args ();
5187 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
5188 number = number_of_args ();
5189 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
5191 /* Take the lengths of some of the shell's special parameters. */
5195 t = which_set_flags ();
5198 t = itos (last_command_exit_value);
5201 t = itos (dollar_dollar_pid);
5204 if (last_asynchronous_pid == NO_PID)
5207 t = itos (last_asynchronous_pid);
5210 t = itos (number_of_args ());
5213 number = STRLEN (t);
5216 #if defined (ARRAY_VARS)
5217 else if (valid_array_reference (name + 1))
5218 number = array_length_reference (name + 1);
5219 #endif /* ARRAY_VARS */
5224 if (legal_number (name + 1, &arg_index)) /* ${#1} */
5226 t = get_dollar_var_value (arg_index);
5227 number = MB_STRLEN (t);
5230 #if defined (ARRAY_VARS)
5231 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var))
5233 t = array_reference (array_cell (var), 0);
5234 number = MB_STRLEN (t);
5239 newname = savestring (name);
5241 list = expand_string (newname, Q_DOUBLE_QUOTES);
5242 t = list ? string_list (list) : (char *)NULL;
5245 dispose_words (list);
5247 number = MB_STRLEN (t);
5255 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5256 so we do some ad-hoc parsing of an arithmetic expression to find
5257 the first DELIM, instead of using strchr(3). Two rules:
5258 1. If the substring contains a `(', read until closing `)'.
5259 2. If the substring contains a `?', read past one `:' for each `?'.
5263 skiparith (substr, delim)
5268 int skipcol, pcount, i;
5271 sublen = strlen (substr);
5272 i = skipcol = pcount = 0;
5275 /* Balance parens */
5276 if (substr[i] == LPAREN)
5282 if (substr[i] == RPAREN && pcount)
5290 ADVANCE_CHAR (substr, sublen, i);
5294 /* Skip one `:' for each `?' */
5295 if (substr[i] == ':' && skipcol)
5301 if (substr[i] == delim)
5303 if (substr[i] == '?')
5309 ADVANCE_CHAR (substr, sublen, i);
5312 return (substr + i);
5315 /* Verify and limit the start and end of the desired substring. If
5316 VTYPE == 0, a regular shell variable is being used; if it is 1,
5317 then the positional parameters are being used; if it is 2, then
5318 VALUE is really a pointer to an array variable that should be used.
5319 Return value is 1 if both values were OK, 0 if there was a problem
5320 with an invalid expression, or -1 if the values were out of range. */
5322 verify_substring_values (value, substr, vtype, e1p, e2p)
5323 char *value, *substr;
5325 intmax_t *e1p, *e2p;
5327 char *t, *temp1, *temp2;
5330 #if defined (ARRAY_VARS)
5334 /* duplicate behavior of strchr(3) */
5335 t = skiparith (substr, ':');
5336 if (*t && *t == ':')
5341 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
5342 *e1p = evalexp (temp1, &expok);
5347 len = -1; /* paranoia */
5351 case VT_ARRAYMEMBER:
5352 len = MB_STRLEN (value);
5355 len = number_of_args () + 1;
5357 #if defined (ARRAY_VARS)
5360 /* For arrays, the first value deals with array indices. Negative
5361 offsets count from one past the array's maximum index. */
5362 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
5367 if (len == -1) /* paranoia */
5370 if (*e1p < 0) /* negative offsets count from end */
5373 if (*e1p > len || *e1p < 0)
5376 #if defined (ARRAY_VARS)
5377 /* For arrays, the second offset deals with the number of elements. */
5378 if (vtype == VT_ARRAYVAR)
5379 len = array_num_elements (a);
5385 temp2 = savestring (t);
5386 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
5389 *e2p = evalexp (temp1, &expok);
5395 internal_error (_("%s: substring expression < 0"), t);
5398 #if defined (ARRAY_VARS)
5399 /* In order to deal with sparse arrays, push the intelligence about how
5400 to deal with the number of elements desired down to the array-
5401 specific functions. */
5402 if (vtype != VT_ARRAYVAR)
5405 *e2p += *e1p; /* want E2 chars starting at E1 */
5416 /* Return the type of variable specified by VARNAME (simple variable,
5417 positional param, or array variable). Also return the value specified
5418 by VARNAME (value of a variable or a reference to an array element).
5419 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5420 characters in the value are quoted with CTLESC and takes appropriate
5421 steps. For convenience, *VALP is set to the dequoted VALUE. */
5423 get_var_and_type (varname, value, quoted, varp, valp)
5424 char *varname, *value;
5431 #if defined (ARRAY_VARS)
5435 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5436 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
5437 if (vtype == VT_POSPARMS && varname[0] == '*')
5438 vtype |= VT_STARSUB;
5439 *varp = (SHELL_VAR *)NULL;
5441 #if defined (ARRAY_VARS)
5442 if (valid_array_reference (varname))
5444 v = array_variable_part (varname, &temp, (int *)0);
5445 if (v && array_p (v))
5447 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
5449 vtype = VT_ARRAYVAR;
5451 vtype |= VT_STARSUB;
5452 *valp = (char *)array_cell (v);
5456 vtype = VT_ARRAYMEMBER;
5457 *valp = array_value (varname, 1, (int *)NULL);
5461 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
5463 vtype = VT_VARIABLE;
5465 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5466 *valp = dequote_string (value);
5468 *valp = dequote_escapes (value);
5473 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v))
5475 vtype = VT_ARRAYMEMBER;
5477 *valp = array_reference (array_cell (v), 0);
5482 if (value && vtype == VT_VARIABLE)
5484 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5485 *valp = dequote_string (value);
5487 *valp = dequote_escapes (value);
5496 /******************************************************/
5498 /* Functions to extract substrings of variable values */
5500 /******************************************************/
5502 #if defined (HANDLE_MULTIBYTE)
5503 /* Character-oriented rather than strictly byte-oriented substrings. S and
5504 E, rather being strict indices into STRING, indicate character (possibly
5505 multibyte character) positions that require calculation.
5506 Used by the ${param:offset[:length]} expansion. */
5508 mb_substring (string, s, e)
5513 int start, stop, i, slen;
5517 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5518 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
5521 while (string[start] && i--)
5522 ADVANCE_CHAR (string, slen, start);
5525 while (string[stop] && i--)
5526 ADVANCE_CHAR (string, slen, stop);
5527 tt = substring (string, start, stop);
5532 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5533 is `@', use the positional parameters; otherwise, use the value of
5534 VARNAME. If VARNAME is an array variable, use the array elements. */
5537 parameter_brace_substring (varname, value, substr, quoted)
5538 char *varname, *value, *substr;
5542 int vtype, r, starsub;
5543 char *temp, *val, *tt, *oname;
5547 return ((char *)NULL);
5549 oname = this_command_name;
5550 this_command_name = varname;
5552 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5555 this_command_name = oname;
5556 return ((char *)NULL);
5559 starsub = vtype & VT_STARSUB;
5560 vtype &= ~VT_STARSUB;
5562 r = verify_substring_values (val, substr, vtype, &e1, &e2);
5563 this_command_name = oname;
5565 return ((r == 0) ? &expand_param_error : (char *)NULL);
5570 case VT_ARRAYMEMBER:
5571 #if defined (HANDLE_MULTIBYTE)
5573 tt = mb_substring (val, e1, e2);
5576 tt = substring (val, e1, e2);
5578 if (vtype == VT_VARIABLE)
5580 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5581 temp = quote_string (tt);
5583 temp = tt ? quote_escapes (tt) : (char *)NULL;
5587 tt = pos_params (varname, e1, e2, quoted);
5588 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5590 temp = tt ? quote_escapes (tt) : (char *)NULL;
5596 #if defined (ARRAY_VARS)
5598 /* We want E2 to be the number of elements desired (arrays can be sparse,
5599 so verify_substring_values just returns the numbers specified and we
5600 rely on array_subrange to understand how to deal with them). */
5601 tt = array_subrange (array_cell (v), e1, e2, starsub, quoted);
5603 /* array_subrange now calls array_quote_escapes as appropriate, so the
5604 caller no longer needs to. */
5605 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5607 temp = tt ? quote_escapes (tt) : (char *)NULL;
5616 temp = (char *)NULL;
5622 /****************************************************************/
5624 /* Functions to perform pattern substitution on variable values */
5626 /****************************************************************/
5629 pat_subst (string, pat, rep, mflags)
5630 char *string, *pat, *rep;
5633 char *ret, *s, *e, *str;
5634 int rsize, rptr, l, replen, mtype;
5636 mtype = mflags & MATCH_TYPEMASK;
5639 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5640 * with REP and return the result.
5641 * 2. A null pattern with mtype == MATCH_END means to append REP to
5642 * STRING and return the result.
5644 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
5646 replen = STRLEN (rep);
5647 l = strlen (string);
5648 ret = (char *)xmalloc (replen + l + 2);
5650 strcpy (ret, string);
5651 else if (mtype == MATCH_BEG)
5654 strcpy (ret + replen, string);
5658 strcpy (ret, string);
5659 strcpy (ret + l, rep);
5664 ret = (char *)xmalloc (rsize = 64);
5667 for (replen = STRLEN (rep), rptr = 0, str = string;;)
5669 if (match_pattern (str, pat, mtype, &s, &e) == 0)
5672 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
5674 /* OK, now copy the leading unmatched portion of the string (from
5675 str to s) to ret starting at rptr (the current offset). Then copy
5676 the replacement string at ret + rptr + (s - str). Increment
5677 rptr (if necessary) and str and go on. */
5680 strncpy (ret + rptr, str, l);
5685 strncpy (ret + rptr, rep, replen);
5688 str = e; /* e == end of match */
5690 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
5694 e++, str++; /* avoid infinite recursion on zero-length match */
5697 /* Now copy the unmatched portion of the input string */
5700 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
5701 strcpy (ret + rptr, str);
5709 /* Do pattern match and replacement on the positional parameters. */
5711 pos_params_pat_subst (string, pat, rep, mflags)
5712 char *string, *pat, *rep;
5715 WORD_LIST *save, *params;
5719 save = params = list_rest_of_args ();
5721 return ((char *)NULL);
5723 for ( ; params; params = params->next)
5725 ret = pat_subst (params->word->word, pat, rep, mflags);
5726 w = alloc_word_desc ();
5727 w->word = ret ? ret : savestring ("");
5728 dispose_word (params->word);
5732 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
5733 ret = string_list_dollar_star (quote_list (save));
5735 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
5736 dispose_words (save);
5741 /* Perform pattern substitution on VALUE, which is the expansion of
5742 VARNAME. PATSUB is an expression supplying the pattern to match
5743 and the string to substitute. QUOTED is a flags word containing
5744 the type of quoting currently in effect. */
5746 parameter_brace_patsub (varname, value, patsub, quoted)
5747 char *varname, *value, *patsub;
5750 int vtype, mflags, starsub;
5751 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
5755 return ((char *)NULL);
5757 this_command_name = varname;
5759 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5761 return ((char *)NULL);
5763 starsub = vtype & VT_STARSUB;
5764 vtype &= ~VT_STARSUB;
5767 if (patsub && *patsub == '/')
5769 mflags |= MATCH_GLOBREP;
5773 /* Malloc this because expand_string_if_necessary or one of the expansion
5774 functions in its call chain may free it on a substitution error. */
5775 lpatsub = savestring (patsub);
5777 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5778 mflags |= MATCH_QUOTED;
5781 mflags |= MATCH_STARSUB;
5783 /* If the pattern starts with a `/', make sure we skip over it when looking
5784 for the replacement delimiter. */
5785 if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
5790 if (rep && *rep == '\0')
5793 /* Perform the same expansions on the pattern as performed by the
5794 pattern removal expansions. */
5795 pat = getpattern (lpatsub, quoted, 1);
5799 if ((mflags & MATCH_QUOTED) == 0)
5800 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
5802 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
5805 /* ksh93 doesn't allow the match specifier to be a part of the expanded
5806 pattern. This is an extension. Make sure we don't anchor the pattern
5807 at the beginning or end of the string if we're doing global replacement,
5810 if (mflags & MATCH_GLOBREP)
5811 mflags |= MATCH_ANY;
5812 else if (pat && pat[0] == '#')
5814 mflags |= MATCH_BEG;
5817 else if (pat && pat[0] == '%')
5819 mflags |= MATCH_END;
5823 mflags |= MATCH_ANY;
5825 /* OK, we now want to substitute REP for PAT in VAL. If
5826 flags & MATCH_GLOBREP is non-zero, the substitution is done
5827 everywhere, otherwise only the first occurrence of PAT is
5828 replaced. The pattern matching code doesn't understand
5829 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5830 values passed in (VT_VARIABLE) so the pattern substitution
5831 code works right. We need to requote special chars after
5832 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5833 other cases if QUOTED == 0, since the posparams and arrays
5834 indexed by * or @ do special things when QUOTED != 0. */
5839 case VT_ARRAYMEMBER:
5840 temp = pat_subst (val, p, rep, mflags);
5841 if (vtype == VT_VARIABLE)
5845 tt = quote_escapes (temp);
5851 temp = pos_params_pat_subst (val, p, rep, mflags);
5852 if (temp && (mflags & MATCH_QUOTED) == 0)
5854 tt = quote_escapes (temp);
5859 #if defined (ARRAY_VARS)
5861 temp = array_patsub (array_cell (v), p, rep, mflags);
5863 /* Don't need to do this anymore; array_patsub calls array_quote_escapes
5864 as appropriate before adding the space separators. */
5865 if (temp && (mflags & MATCH_QUOTED) == 0)
5867 tt = quote_escapes (temp);
5883 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
5884 any occur, this must be a nested command substitution, so return 0.
5885 Otherwise, return 1. A valid arithmetic expression must always have a
5886 ( before a matching ), so any cases where there are more right parens
5887 means that this must not be an arithmetic expression, though the parser
5888 will not accept it without a balanced total number of parens. */
5890 chk_arithsub (s, len)
5902 else if (s[i] == ')')
5912 ADVANCE_CHAR (s, len, i);
5918 ADVANCE_CHAR (s, len, i);
5922 i = skip_single_quoted (s, len, ++i);
5926 i = skip_double_quoted ((char *)s, len, ++i);
5931 return (count == 0);
5934 /****************************************************************/
5936 /* Functions to perform parameter expansion on a string */
5938 /****************************************************************/
5940 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5942 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
5944 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
5946 int check_nullness, var_is_set, var_is_null, var_is_special;
5947 int want_substring, want_indir, want_patsub;
5948 char *name, *value, *temp, *temp1;
5949 WORD_DESC *tdesc, *ret;
5950 int t_index, sindex, c, tflag;
5953 value = (char *)NULL;
5954 var_is_set = var_is_null = var_is_special = check_nullness = 0;
5955 want_substring = want_indir = want_patsub = 0;
5959 /* ${#var} doesn't have any of the other parameter expansions on it. */
5960 if (string[t_index] == '#' && legal_variable_starter (string[t_index+1])) /* {{ */
5961 name = string_extract (string, &t_index, "}", EX_VARNAME);
5963 name = string_extract (string, &t_index, "#%:-=?+/}", EX_VARNAME);
5968 /* If the name really consists of a special variable, then make sure
5969 that we have the entire name. We don't allow indirect references
5970 to special variables except `#', `?', `@' and `*'. */
5971 if ((sindex == t_index &&
5972 (string[t_index] == '-' ||
5973 string[t_index] == '?' ||
5974 string[t_index] == '#')) ||
5975 (sindex == t_index - 1 && string[sindex] == '!' &&
5976 (string[t_index] == '#' ||
5977 string[t_index] == '?' ||
5978 string[t_index] == '@' ||
5979 string[t_index] == '*')))
5983 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
5984 name = (char *)xmalloc (3 + (strlen (temp1)));
5985 *name = string[sindex];
5986 if (string[sindex] == '!')
5988 /* indirect reference of $#, $?, $@, or $* */
5989 name[1] = string[sindex + 1];
5990 strcpy (name + 2, temp1);
5993 strcpy (name + 1, temp1);
5998 /* Find out what character ended the variable name. Then
5999 do the appropriate thing. */
6000 if (c = string[sindex])
6003 /* If c is followed by one of the valid parameter expansion
6004 characters, move past it as normal. If not, assume that
6005 a substring specification is being given, and do not move
6007 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
6010 if (c = string[sindex])
6013 else if (c == ':' && string[sindex] != RBRACE)
6015 else if (c == '/' && string[sindex] != RBRACE)
6018 /* Catch the valid and invalid brace expressions that made it through the
6020 /* ${#-} is a valid expansion and means to take the length of $-.
6021 Similarly for ${#?} and ${##}... */
6022 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6023 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
6025 name = (char *)xrealloc (name, 3);
6028 c = string[sindex++];
6031 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6032 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
6033 member (c, "%:=+/") && string[sindex] == RBRACE)
6035 temp = (char *)NULL;
6036 goto bad_substitution;
6039 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6040 either a variable name, one of the positional parameters or a special
6041 variable that expands to one of the positional parameters. */
6042 want_indir = *name == '!' &&
6043 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
6044 || VALID_INDIR_PARAM (name[1]));
6046 /* Determine the value of this variable. */
6048 /* Check for special variables, directly referenced. */
6049 if (SPECIAL_VAR (name, want_indir))
6052 /* Check for special expansion things, like the length of a parameter */
6053 if (*name == '#' && name[1])
6055 /* If we are not pointing at the character just after the
6056 closing brace, then we haven't gotten all of the name.
6057 Since it begins with a special character, this is a bad
6058 substitution. Also check NAME for validity before trying
6060 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
6062 temp = (char *)NULL;
6063 goto bad_substitution;
6066 number = parameter_brace_expand_length (name);
6071 return (&expand_wdesc_error);
6074 ret = alloc_word_desc ();
6075 ret->word = itos (number);
6080 /* ${@} is identical to $@. */
6081 if (name[0] == '@' && name[1] == '\0')
6083 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6084 *quoted_dollar_atp = 1;
6086 if (contains_dollar_at)
6087 *contains_dollar_at = 1;
6090 /* Process ${!PREFIX*} expansion. */
6091 if (want_indir && string[sindex - 1] == RBRACE &&
6092 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
6093 legal_variable_starter ((unsigned char) name[1]))
6098 temp1 = savestring (name + 1);
6099 number = strlen (temp1);
6100 temp1[number - 1] = '\0';
6101 x = all_variables_matching_prefix (temp1);
6102 xlist = strvec_to_word_list (x, 0, 0);
6103 if (string[sindex - 2] == '*')
6104 temp = string_list_dollar_star (xlist);
6107 temp = string_list_dollar_at (xlist, quoted);
6108 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6109 *quoted_dollar_atp = 1;
6110 if (contains_dollar_at)
6111 *contains_dollar_at = 1;
6118 ret = alloc_word_desc ();
6123 #if defined (ARRAY_VARS)
6124 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6125 if (want_indir && string[sindex - 1] == RBRACE &&
6126 string[sindex - 2] == ']' && valid_array_reference (name+1))
6130 temp1 = savestring (name + 1);
6131 x = array_variable_name (temp1, &x1, (int *)0); /* [ */
6133 if (ALL_ELEMENT_SUB (x1[0]) && x1[1] == ']')
6135 temp = array_keys (temp1, quoted);
6138 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6139 *quoted_dollar_atp = 1;
6140 if (contains_dollar_at)
6141 *contains_dollar_at = 1;
6147 ret = alloc_word_desc ();
6154 #endif /* ARRAY_VARS */
6156 /* Make sure that NAME is valid before trying to go on. */
6157 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
6158 var_is_special) == 0)
6160 temp = (char *)NULL;
6161 goto bad_substitution;
6165 tdesc = parameter_brace_expand_indir (name + 1, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at);
6167 tdesc = parameter_brace_expand_word (name, var_is_special, quoted);
6172 tflag = tdesc->flags;
6173 dispose_word_desc (tdesc);
6178 #if defined (ARRAY_VARS)
6179 if (valid_array_reference (name))
6180 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at);
6183 var_is_set = temp != (char *)0;
6184 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
6186 /* Get the rest of the stuff inside the braces. */
6187 if (c && c != RBRACE)
6189 /* Extract the contents of the ${ ... } expansion
6190 according to the Posix.2 rules. */
6191 value = extract_dollar_brace_string (string, &sindex, quoted, 0);
6192 if (string[sindex] == RBRACE)
6195 goto bad_substitution;
6198 value = (char *)NULL;
6202 /* If this is a substring spec, process it and add the result. */
6205 temp1 = parameter_brace_substring (name, temp, value, quoted);
6210 if (temp1 == &expand_param_error)
6211 return (&expand_wdesc_error);
6212 else if (temp1 == &expand_param_fatal)
6213 return (&expand_wdesc_fatal);
6215 ret = alloc_word_desc ();
6217 if (temp1 && QUOTED_NULL (temp1) && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6218 ret->flags |= W_QUOTED|W_HASQUOTEDNULL;
6221 else if (want_patsub)
6223 temp1 = parameter_brace_patsub (name, temp, value, quoted);
6228 if (temp1 == &expand_param_error)
6229 return (&expand_wdesc_error);
6230 else if (temp1 == &expand_param_fatal)
6231 return (&expand_wdesc_fatal);
6233 ret = alloc_word_desc ();
6238 /* Do the right thing based on which character ended the variable name. */
6244 report_error (_("%s: bad substitution"), string ? string : "??");
6248 return &expand_wdesc_error;
6251 if (var_is_set == 0 && unbound_vars_is_error)
6253 err_unboundvar (name);
6257 last_command_exit_value = EXECUTION_FAILURE;
6258 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6262 case '#': /* ${param#[#]pattern} */
6263 case '%': /* ${param%[%]pattern} */
6264 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
6269 temp1 = parameter_brace_remove_pattern (name, temp, value, c, quoted);
6279 if (var_is_set && var_is_null == 0)
6281 /* If the operator is `+', we don't want the value of the named
6282 variable for anything, just the value of the right hand side. */
6286 /* XXX -- if we're double-quoted and the named variable is "$@",
6287 we want to turn off any special handling of "$@" --
6288 we're not using it, so whatever is on the rhs applies. */
6289 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6290 *quoted_dollar_atp = 0;
6291 if (contains_dollar_at)
6292 *contains_dollar_at = 0;
6297 ret = parameter_brace_expand_rhs (name, value, c,
6300 contains_dollar_at);
6301 /* XXX - fix up later, esp. noting presence of
6302 W_HASQUOTEDNULL in ret->flags */
6306 temp = (char *)NULL;
6312 /* Otherwise do nothing; just use the value in TEMP. */
6314 else /* VAR not set or VAR is NULL. */
6317 temp = (char *)NULL;
6318 if (c == '=' && var_is_special)
6320 report_error (_("$%s: cannot assign in this way"), name);
6323 return &expand_wdesc_error;
6327 parameter_brace_expand_error (name, value);
6328 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6332 /* XXX -- if we're double-quoted and the named variable is "$@",
6333 we want to turn off any special handling of "$@" --
6334 we're not using it, so whatever is on the rhs applies. */
6335 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
6336 *quoted_dollar_atp = 0;
6337 if (contains_dollar_at)
6338 *contains_dollar_at = 0;
6340 ret = parameter_brace_expand_rhs (name, value, c, quoted,
6342 contains_dollar_at);
6343 /* XXX - fix up later, esp. noting presence of
6344 W_HASQUOTEDNULL in tdesc->flags */
6355 ret = alloc_word_desc ();
6362 /* Expand a single ${xxx} expansion. The braces are optional. When
6363 the braces are used, parameter_brace_expand() does the work,
6364 possibly calling param_expand recursively. */
6366 param_expand (string, sindex, quoted, expanded_something,
6367 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
6370 int *sindex, quoted, *expanded_something, *contains_dollar_at;
6371 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
6373 char *temp, *temp1, uerror[3];
6374 int zindex, t_index, expok;
6379 WORD_DESC *tdesc, *ret;
6383 c = string[++zindex];
6385 temp = (char *)NULL;
6386 ret = tdesc = (WORD_DESC *)NULL;
6389 /* Do simple cases first. Switch on what follows '$'. */
6403 temp1 = dollar_vars[TODIGIT (c)];
6404 if (unbound_vars_is_error && temp1 == (char *)NULL)
6409 err_unboundvar (uerror);
6410 last_command_exit_value = EXECUTION_FAILURE;
6411 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6414 temp = (*temp1 && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6415 ? quote_string (temp1)
6416 : quote_escapes (temp1);
6418 temp = (char *)NULL;
6422 /* $$ -- pid of the invoking shell. */
6424 temp = itos (dollar_dollar_pid);
6427 /* $# -- number of positional parameters. */
6429 temp = itos (number_of_args ());
6432 /* $? -- return value of the last synchronous command. */
6434 temp = itos (last_command_exit_value);
6437 /* $- -- flags supplied to the shell on invocation or by `set'. */
6439 temp = which_set_flags ();
6442 /* $! -- Pid of the last asynchronous command. */
6444 /* If no asynchronous pids have been created, expand to nothing.
6445 If `set -u' has been executed, and no async processes have
6446 been created, this is an expansion error. */
6447 if (last_asynchronous_pid == NO_PID)
6449 if (expanded_something)
6450 *expanded_something = 0;
6451 temp = (char *)NULL;
6452 if (unbound_vars_is_error)
6457 err_unboundvar (uerror);
6458 last_command_exit_value = EXECUTION_FAILURE;
6459 return (interactive_shell ? &expand_wdesc_error : &expand_wdesc_fatal);
6463 temp = itos (last_asynchronous_pid);
6466 /* The only difference between this and $@ is when the arg is quoted. */
6467 case '*': /* `$*' */
6468 list = list_rest_of_args ();
6470 /* If there are no command-line arguments, this should just
6471 disappear if there are other characters in the expansion,
6472 even if it's quoted. */
6473 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
6474 temp = (char *)NULL;
6475 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6477 /* If we have "$*" we want to make a string of the positional
6478 parameters, separated by the first character of $IFS, and
6479 quote the whole string, including the separators. If IFS
6480 is unset, the parameters are separated by ' '; if $IFS is
6481 null, the parameters are concatenated. */
6482 temp = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (list) : string_list (list);
6483 temp1 = quote_string (temp);
6485 tflag |= W_HASQUOTEDNULL;
6491 /* We check whether or not we're eventually going to split $* here,
6492 for example when IFS is empty and we are processing the rhs of
6493 an assignment statement. In that case, we don't separate the
6494 arguments at all. Otherwise, if the $* is not quoted it is
6497 # if defined (HANDLE_MULTIBYTE)
6498 if (expand_no_split_dollar_star && ifs_firstc[0] == 0)
6500 if (expand_no_split_dollar_star && ifs_firstc == 0)
6502 temp = string_list_dollar_star (list);
6504 temp = string_list_dollar_at (list, quoted);
6506 temp = string_list_dollar_at (list, quoted);
6508 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
6509 *contains_dollar_at = 1;
6512 dispose_words (list);
6515 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
6516 means that we have to turn quoting off after we split into
6517 the individually quoted arguments so that the final split
6518 on the first character of $IFS is still done. */
6519 case '@': /* `$@' */
6520 list = list_rest_of_args ();
6522 /* We want to flag the fact that we saw this. We can't turn
6523 off quoting entirely, because other characters in the
6524 string might need it (consider "\"$@\""), but we need some
6525 way to signal that the final split on the first character
6526 of $IFS should be done, even though QUOTED is 1. */
6527 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6528 *quoted_dollar_at_p = 1;
6529 if (contains_dollar_at)
6530 *contains_dollar_at = 1;
6532 /* We want to separate the positional parameters with the first
6533 character of $IFS in case $IFS is something other than a space.
6534 We also want to make sure that splitting is done no matter what --
6535 according to POSIX.2, this expands to a list of the positional
6536 parameters no matter what IFS is set to. */
6537 temp = string_list_dollar_at (list, quoted);
6539 dispose_words (list);
6543 tdesc = parameter_brace_expand (string, &zindex, quoted,
6545 contains_dollar_at);
6547 if (tdesc == &expand_wdesc_error || tdesc == &expand_wdesc_fatal)
6549 temp = tdesc ? tdesc->word : (char *)0;
6552 /* Quoted nulls should be removed if there is anything else
6554 /* Note that we saw the quoted null so we can add one back at
6555 the end of this function if there are no other characters
6556 in the string, discard TEMP, and go on. The exception to
6557 this is when we have "${@}" and $1 is '', since $@ needs
6558 special handling. */
6559 if (tdesc && tdesc->word && (tdesc->flags & W_HASQUOTEDNULL) && QUOTED_NULL (temp))
6561 if (had_quoted_null_p)
6562 *had_quoted_null_p = 1;
6563 if (*quoted_dollar_at_p == 0)
6566 tdesc->word = temp = (char *)NULL;
6574 /* Do command or arithmetic substitution. */
6576 /* We have to extract the contents of this paren substitution. */
6577 t_index = zindex + 1;
6578 temp = extract_command_subst (string, &t_index);
6581 /* For Posix.2-style `$(( ))' arithmetic substitution,
6582 extract the expression and pass it to the evaluator. */
6583 if (temp && *temp == LPAREN)
6587 temp2 = savestring (temp1);
6588 t_index = strlen (temp2) - 1;
6590 if (temp2[t_index] != RPAREN)
6596 /* Cut off ending `)' */
6597 temp2[t_index] = '\0';
6599 if (chk_arithsub (temp2, t_index) == 0)
6605 /* Expand variables found inside the expression. */
6606 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
6610 /* No error messages. */
6611 this_command_name = (char *)NULL;
6612 number = evalexp (temp1, &expok);
6617 if (interactive_shell == 0 && posixly_correct)
6619 last_command_exit_value = EXECUTION_FAILURE;
6620 return (&expand_wdesc_fatal);
6623 return (&expand_wdesc_error);
6625 temp = itos (number);
6630 if (pflags & PF_NOCOMSUB)
6631 /* we need zindex+1 because string[zindex] == RPAREN */
6632 temp1 = substring (string, *sindex, zindex+1);
6634 temp1 = command_substitute (temp, quoted);
6639 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6640 away in a future bash release. */
6642 /* Extract the contents of this arithmetic substitution. */
6643 t_index = zindex + 1;
6644 temp = extract_arithmetic_subst (string, &t_index);
6647 /* Do initial variable expansion. */
6648 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
6653 /* Find the variable in VARIABLE_LIST. */
6654 temp = (char *)NULL;
6656 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
6658 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
6660 /* If this isn't a variable name, then just output the `$'. */
6661 if (temp1 == 0 || *temp1 == '\0')
6664 temp = (char *)xmalloc (2);
6667 if (expanded_something)
6668 *expanded_something = 0;
6672 /* If the variable exists, return its value cell. */
6673 var = find_variable (temp1);
6675 if (var && invisible_p (var) == 0 && var_isset (var))
6677 #if defined (ARRAY_VARS)
6680 temp = array_reference (array_cell (var), 0);
6682 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6683 ? quote_string (temp)
6684 : quote_escapes (temp);
6685 else if (unbound_vars_is_error)
6686 goto unbound_variable;
6691 temp = value_cell (var);
6693 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6694 ? quote_string (temp)
6695 : quote_escapes (temp);
6703 temp = (char *)NULL;
6706 if (unbound_vars_is_error)
6707 err_unboundvar (temp1);
6715 last_command_exit_value = EXECUTION_FAILURE;
6716 return ((unbound_vars_is_error && interactive_shell == 0)
6717 ? &expand_wdesc_fatal
6718 : &expand_wdesc_error);
6729 ret = alloc_word_desc ();
6730 ret->flags = tflag; /* XXX */
6736 /* Make a word list which is the result of parameter and variable
6737 expansion, command substitution, arithmetic substitution, and
6738 quote removal of WORD. Return a pointer to a WORD_LIST which is
6739 the result of the expansion. If WORD contains a null word, the
6740 word list returned is also null.
6742 QUOTED contains flag values defined in shell.h.
6744 ISEXP is used to tell expand_word_internal that the word should be
6745 treated as the result of an expansion. This has implications for
6746 how IFS characters in the word are treated.
6748 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6749 they point to an integer value which receives information about expansion.
6750 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6751 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6754 This only does word splitting in the case of $@ expansion. In that
6755 case, we split on ' '. */
6757 /* Values for the local variable quoted_state. */
6759 #define PARTIALLY_QUOTED 1
6760 #define WHOLLY_QUOTED 2
6763 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
6766 int *contains_dollar_at;
6767 int *expanded_something;
6772 /* The intermediate string that we build while expanding. */
6775 /* The current size of the above object. */
6778 /* Index into ISTRING. */
6781 /* Temporary string storage. */
6784 /* The text of WORD. */
6785 register char *string;
6787 /* The size of STRING. */
6790 /* The index into STRING. */
6793 /* This gets 1 if we see a $@ while quoted. */
6794 int quoted_dollar_at;
6796 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6797 whether WORD contains no quoting characters, a partially quoted
6798 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6802 int had_quoted_null;
6806 int assignoff; /* If assignment, offset of `=' */
6808 register unsigned char c; /* Current character. */
6809 int t_index; /* For calls to string_extract_xxx. */
6815 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
6816 istring[istring_index = 0] = '\0';
6817 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
6818 quoted_state = UNQUOTED;
6820 string = word->word;
6822 goto finished_with_string;
6823 /* Don't need the string length for the SADD... and COPY_ macros unless
6824 multibyte characters are possible. */
6825 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
6827 if (contains_dollar_at)
6828 *contains_dollar_at = 0;
6832 /* Begin the expansion. */
6838 /* Case on toplevel character. */
6842 goto finished_with_string;
6846 #if HANDLE_MULTIBYTE
6847 if (MB_CUR_MAX > 1 && string[sindex])
6849 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6854 temp = (char *)xmalloc (3);
6856 temp[1] = c = string[sindex];
6867 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
6873 #if defined (PROCESS_SUBSTITUTION)
6874 /* Process substitution. */
6878 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
6880 sindex--; /* add_character: label increments sindex */
6884 t_index = sindex + 1; /* skip past both '<' and LPAREN */
6886 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
6889 /* If the process substitution specification is `<()', we want to
6890 open the pipe for writing in the child and produce output; if
6891 it is `>()', we want to open the pipe for reading in the child
6892 and consume input. */
6893 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
6897 goto dollar_add_string;
6899 #endif /* PROCESS_SUBSTITUTION */
6902 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6903 which are not assignment statements are not expanded. If the
6904 shell isn't in posix mode, though, we perform tilde expansion
6905 on `likely candidate' unquoted assignment statements (flags
6906 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
6907 contains an unquoted :~ or =~. Something to think about: we
6908 now have a flag that says to perform tilde expansion on arguments
6909 to `assignment builtins' like declare and export that look like
6910 assignment statements. We now do tilde expansion on such words
6911 even in POSIX mode. */
6912 if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
6914 /* If we're not in posix mode or forcing assignment-statement tilde
6915 expansion, note where the `=' appears in the word and prepare to
6916 do tilde expansion following the first `='. */
6917 if ((word->flags & W_ASSIGNMENT) &&
6918 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
6919 assignoff == -1 && sindex > 0)
6921 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */
6922 word->flags |= W_ITILDE;
6924 else if ((word->flags & W_ASSIGNMENT) &&
6925 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
6926 string[sindex+1] == '~')
6927 word->flags |= W_ITILDE;
6932 if (word->flags & W_NOTILDE)
6935 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
6936 string[sindex+1] == '~')
6937 word->flags |= W_ITILDE;
6941 /* If the word isn't supposed to be tilde expanded, or we're not
6942 at the start of a word or after an unquoted : or = in an
6943 assignment statement, we don't do tilde expansion. */
6944 if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
6945 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
6946 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
6948 word->flags &= ~W_ITILDE;
6952 if (word->flags & W_ASSIGNRHS)
6954 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
6959 temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
6961 word->flags &= ~W_ITILDE;
6963 if (temp && *temp && t_index > 0)
6965 temp1 = bash_tilde_expand (temp, tflag);
6966 if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
6970 goto add_character; /* tilde expansion failed */
6984 if (expanded_something)
6985 *expanded_something = 1;
6988 tword = param_expand (string, &sindex, quoted, expanded_something,
6989 &has_dollar_at, "ed_dollar_at,
6991 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
6993 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
6997 return ((tword == &expand_wdesc_error) ? &expand_word_error
6998 : &expand_word_fatal);
7000 if (contains_dollar_at && has_dollar_at)
7001 *contains_dollar_at = 1;
7003 if (tword && (tword->flags & W_HASQUOTEDNULL))
7004 had_quoted_null = 1;
7007 dispose_word_desc (tword);
7012 case '`': /* Backquoted command substitution. */
7016 temp = string_extract (string, &sindex, "`", EX_REQMATCH);
7017 /* The test of sindex against t_index is to allow bare instances of
7018 ` to pass through, for backwards compatibility. */
7019 if (temp == &extract_string_error || temp == &extract_string_fatal)
7021 if (sindex - 1 == t_index)
7026 report_error ("bad substitution: no closing \"`\" in %s", string+t_index);
7029 return ((temp == &extract_string_error) ? &expand_word_error
7030 : &expand_word_fatal);
7033 if (expanded_something)
7034 *expanded_something = 1;
7036 if (word->flags & W_NOCOMSUB)
7037 /* sindex + 1 because string[sindex] == '`' */
7038 temp1 = substring (string, t_index, sindex + 1);
7041 de_backslash (temp);
7042 temp1 = command_substitute (temp, quoted);
7046 goto dollar_add_string;
7050 if (string[sindex + 1] == '\n')
7056 c = string[++sindex];
7058 if (quoted & Q_HERE_DOCUMENT)
7060 else if (quoted & Q_DOUBLE_QUOTES)
7065 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
7067 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
7072 sindex--; /* add_character: label increments sindex */
7077 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
7082 /* BEFORE jumping here, we need to increment sindex if appropriate */
7083 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
7084 DEFAULT_ARRAY_SIZE);
7085 istring[istring_index++] = twochars[0];
7086 istring[istring_index++] = twochars[1];
7087 istring[istring_index] = '\0';
7093 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7095 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7100 temp = string_extract_double_quoted (string, &sindex, 0);
7102 /* If the quotes surrounded the entire string, then the
7103 whole word was quoted. */
7104 quoted_state = (t_index == 1 && string[sindex] == '\0')
7110 tword = alloc_word_desc ();
7113 temp = (char *)NULL;
7116 /* Need to get W_HASQUOTEDNULL flag through this function. */
7117 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
7119 if (list == &expand_word_error || list == &expand_word_fatal)
7123 /* expand_word_internal has already freed temp_word->word
7124 for us because of the way it prints error messages. */
7125 tword->word = (char *)NULL;
7126 dispose_word (tword);
7130 dispose_word (tword);
7132 /* "$@" (a double-quoted dollar-at) expands into nothing,
7133 not even a NULL word, when there are no positional
7135 if (list == 0 && has_dollar_at)
7141 /* If we get "$@", we know we have expanded something, so we
7142 need to remember it for the final split on $IFS. This is
7143 a special case; it's the only case where a quoted string
7144 can expand into more than one word. It's going to come back
7145 from the above call to expand_word_internal as a list with
7146 a single word, in which all characters are quoted and
7147 separated by blanks. What we want to do is to turn it back
7148 into a list for the next piece of code. */
7150 dequote_list (list);
7152 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
7153 had_quoted_null = 1;
7158 if (contains_dollar_at)
7159 *contains_dollar_at = 1;
7160 if (expanded_something)
7161 *expanded_something = 1;
7166 /* What we have is "". This is a minor optimization. */
7168 list = (WORD_LIST *)NULL;
7171 /* The code above *might* return a list (consider the case of "$@",
7172 where it returns "$1", "$2", etc.). We can't throw away the
7173 rest of the list, and we have to make sure each word gets added
7174 as quoted. We test on tresult->next: if it is non-NULL, we
7175 quote the whole list, save it to a string with string_list, and
7176 add that string. We don't need to quote the results of this
7177 (and it would be wrong, since that would quote the separators
7178 as well), so we go directly to add_string. */
7183 /* Testing quoted_dollar_at makes sure that "$@" is
7184 split correctly when $IFS does not contain a space. */
7185 temp = quoted_dollar_at
7186 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
7187 : string_list (quote_list (list));
7188 dispose_words (list);
7193 temp = savestring (list->word->word);
7194 tflag = list->word->flags;
7195 dispose_words (list);
7197 /* If the string is not a quoted null string, we want
7198 to remove any embedded unquoted CTLNUL characters.
7199 We do not want to turn quoted null strings back into
7200 the empty string, though. We do this because we
7201 want to remove any quoted nulls from expansions that
7202 contain other characters. For example, if we have
7203 x"$*"y or "x$*y" and there are no positional parameters,
7204 the $* should expand into nothing. */
7205 /* We use the W_HASQUOTEDNULL flag to differentiate the
7206 cases: a quoted null character as above and when
7207 CTLNUL is contained in the (non-null) expansion
7208 of some variable. We use the had_quoted_null flag to
7209 pass the value through this function to its caller. */
7210 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
7211 remove_quoted_nulls (temp); /* XXX */
7215 temp = (char *)NULL;
7217 /* We do not want to add quoted nulls to strings that are only
7218 partially quoted; we can throw them away. */
7219 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
7227 temp = quote_string (temp);
7235 sindex--; /* add_character: label increments sindex */
7243 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7245 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7250 temp = string_extract_single_quoted (string, &sindex);
7252 /* If the entire STRING was surrounded by single quotes,
7253 then the string is wholly quoted. */
7254 quoted_state = (t_index == 1 && string[sindex] == '\0')
7258 /* If all we had was '', it is a null expansion. */
7262 temp = (char *)NULL;
7265 remove_quoted_escapes (temp); /* ??? */
7267 /* We do not want to add quoted nulls to strings that are only
7268 partially quoted; such nulls are discarded. */
7269 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
7272 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7276 sindex--; /* add_character: label increments sindex */
7280 goto add_quoted_string;
7285 /* This is the fix for " $@ " */
7286 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
7288 if (string[sindex]) /* from old goto dollar_add_string */
7297 #if HANDLE_MULTIBYTE
7303 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
7308 twochars[0] = CTLESC;
7315 SADD_MBCHAR (temp, string, sindex, string_size);
7318 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
7319 DEFAULT_ARRAY_SIZE);
7320 istring[istring_index++] = c;
7321 istring[istring_index] = '\0';
7323 /* Next character. */
7328 finished_with_string:
7329 /* OK, we're ready to return. If we have a quoted string, and
7330 quoted_dollar_at is not set, we do no splitting at all; otherwise
7331 we split on ' '. The routines that call this will handle what to
7332 do if nothing has been expanded. */
7334 /* Partially and wholly quoted strings which expand to the empty
7335 string are retained as an empty arguments. Unquoted strings
7336 which expand to the empty string are discarded. The single
7337 exception is the case of expanding "$@" when there are no
7338 positional parameters. In that case, we discard the expansion. */
7340 /* Because of how the code that handles "" and '' in partially
7341 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7342 if we saw quoting characters, but the expansion was empty.
7343 "" and '' are tossed away before we get to this point when
7344 processing partially quoted strings. This makes "" and $xxx""
7345 equivalent when xxx is unset. We also look to see whether we
7346 saw a quoted null from a ${} expansion and add one back if we
7349 /* If we expand to nothing and there were no single or double quotes
7350 in the word, we throw it away. Otherwise, we return a NULL word.
7351 The single exception is for $@ surrounded by double quotes when
7352 there are no positional parameters. In that case, we also throw
7355 if (*istring == '\0')
7357 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
7359 istring[0] = CTLNUL;
7361 tword = make_bare_word (istring);
7362 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7363 list = make_word_list (tword, (WORD_LIST *)NULL);
7364 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7365 tword->flags |= W_QUOTED;
7367 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7368 and a double-quoted "$@" appears anywhere in it, then the entire
7370 else if (quoted_state == UNQUOTED || quoted_dollar_at)
7371 list = (WORD_LIST *)NULL;
7375 tword = make_bare_word (istring);
7376 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7377 tword->flags |= W_QUOTED;
7378 list = make_word_list (tword, (WORD_LIST *)NULL);
7382 list = (WORD_LIST *)NULL;
7385 else if (word->flags & W_NOSPLIT)
7387 tword = make_bare_word (istring);
7388 if (word->flags & W_ASSIGNMENT)
7389 tword->flags |= W_ASSIGNMENT; /* XXX */
7390 if (word->flags & W_COMPASSIGN)
7391 tword->flags |= W_COMPASSIGN; /* XXX */
7392 if (word->flags & W_NOGLOB)
7393 tword->flags |= W_NOGLOB; /* XXX */
7394 if (word->flags & W_NOEXPAND)
7395 tword->flags |= W_NOEXPAND; /* XXX */
7396 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7397 tword->flags |= W_QUOTED;
7398 if (had_quoted_null)
7399 tword->flags |= W_HASQUOTEDNULL;
7400 list = make_word_list (tword, (WORD_LIST *)NULL);
7406 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
7408 /* If we have $@, we need to split the results no matter what. If
7409 IFS is unset or NULL, string_list_dollar_at has separated the
7410 positional parameters with a space, so we split on space (we have
7411 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7412 string_list_dollar_at has separated the positional parameters
7413 with the first character of $IFS, so we split on $IFS. */
7414 if (has_dollar_at && ifs_chars)
7415 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
7418 tword = make_bare_word (istring);
7419 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
7420 tword->flags |= W_QUOTED;
7421 if (word->flags & W_ASSIGNMENT)
7422 tword->flags |= W_ASSIGNMENT;
7423 if (word->flags & W_COMPASSIGN)
7424 tword->flags |= W_COMPASSIGN;
7425 if (word->flags & W_NOGLOB)
7426 tword->flags |= W_NOGLOB;
7427 if (word->flags & W_NOEXPAND)
7428 tword->flags |= W_NOEXPAND;
7429 if (had_quoted_null)
7430 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7431 list = make_word_list (tword, (WORD_LIST *)NULL);
7439 /* **************************************************************** */
7441 /* Functions for Quote Removal */
7443 /* **************************************************************** */
7445 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7446 backslash quoting rules for within double quotes or a here document. */
7448 string_quote_removal (string, quoted)
7453 char *r, *result_string, *temp, *send;
7454 int sindex, tindex, dquote;
7458 /* The result can be no longer than the original string. */
7459 slen = strlen (string);
7460 send = string + slen;
7462 r = result_string = (char *)xmalloc (slen + 1);
7464 for (dquote = sindex = 0; c = string[sindex];)
7469 c = string[++sindex];
7470 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
7475 SCOPY_CHAR_M (r, string, send, sindex);
7479 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
7485 tindex = sindex + 1;
7486 temp = string_extract_single_quoted (string, &tindex);
7497 dquote = 1 - dquote;
7503 return (result_string);
7508 /* Perform quote removal on word WORD. This allocates and returns a new
7511 word_quote_removal (word, quoted)
7518 t = string_quote_removal (word->word, quoted);
7519 w = alloc_word_desc ();
7520 w->word = t ? t : savestring ("");
7524 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
7525 the members of the list are treated as if they are surrounded by
7526 double quotes. Return a new list, or NULL if LIST is NULL. */
7528 word_list_quote_removal (list, quoted)
7532 WORD_LIST *result, *t, *tresult, *e;
7534 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
7536 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
7538 result = (WORD_LIST *) list_append (result, tresult);
7541 result = e = tresult;
7554 /*******************************************
7556 * Functions to perform word splitting *
7558 *******************************************/
7569 ifs_value = v ? value_cell (v) : " \t\n";
7571 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
7574 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
7575 handle multibyte chars in IFS */
7576 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
7577 for (t = ifs_value ; t && *t; t++)
7583 #if defined (HANDLE_MULTIBYTE)
7586 ifs_firstc[0] = '\0';
7592 ifs_len = strnlen (ifs_value, MB_CUR_MAX);
7593 ifs_firstc_len = MBLEN (ifs_value, ifs_len);
7594 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
7596 ifs_firstc[0] = ifs_value[0];
7597 ifs_firstc[1] = '\0';
7601 memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
7604 ifs_firstc = ifs_value ? *ifs_value : 0;
7614 /* This splits a single word into a WORD LIST on $IFS, but only if the word
7615 is not quoted. list_string () performs quote removal for us, even if we
7616 don't do any splitting. */
7618 word_split (w, ifs_chars)
7628 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
7629 result = list_string (w->word, xifs, w->flags & W_QUOTED);
7632 result = (WORD_LIST *)NULL;
7637 /* Perform word splitting on LIST and return the RESULT. It is possible
7638 to return (WORD_LIST *)NULL. */
7640 word_list_split (list)
7643 WORD_LIST *result, *t, *tresult, *e;
7645 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
7647 tresult = word_split (t->word, ifs_value);
7649 result = e = tresult;
7660 /**************************************************
7662 * Functions to expand an entire WORD_LIST *
7664 **************************************************/
7666 /* Do any word-expansion-specific cleanup and jump to top_level */
7668 exp_jump_to_top_level (v)
7671 /* Cleanup code goes here. */
7672 expand_no_split_dollar_star = 0; /* XXX */
7673 expanding_redir = 0;
7675 if (parse_and_execute_level == 0)
7676 top_level_cleanup (); /* from sig.c */
7679 jump_to_top_level (v);
7682 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
7683 ELIST, and set ELIST to the new list. */
7684 #define PREPEND_LIST(nlist, elist) \
7685 do { nlist->next = elist; elist = nlist; } while (0)
7687 /* Separate out any initial variable assignments from TLIST. If set -k has
7688 been executed, remove all assignment statements from TLIST. Initial
7689 variable assignments and other environment assignments are placed
7690 on SUBST_ASSIGN_VARLIST. */
7692 separate_out_assignments (tlist)
7695 register WORD_LIST *vp, *lp;
7698 return ((WORD_LIST *)NULL);
7700 if (subst_assign_varlist)
7701 dispose_words (subst_assign_varlist); /* Clean up after previous error */
7703 subst_assign_varlist = (WORD_LIST *)NULL;
7706 /* Separate out variable assignments at the start of the command.
7707 Loop invariant: vp->next == lp
7709 lp = list of words left after assignment statements skipped
7710 tlist = original list of words
7712 while (lp && (lp->word->flags & W_ASSIGNMENT))
7718 /* If lp != tlist, we have some initial assignment statements.
7719 We make SUBST_ASSIGN_VARLIST point to the list of assignment
7720 words and TLIST point to the remaining words. */
7723 subst_assign_varlist = tlist;
7724 /* ASSERT(vp->next == lp); */
7725 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
7726 tlist = lp; /* remainder of word list */
7729 /* vp == end of variable list */
7730 /* tlist == remainder of original word list without variable assignments */
7732 /* All the words in tlist were assignment statements */
7733 return ((WORD_LIST *)NULL);
7735 /* ASSERT(tlist != NULL); */
7736 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
7738 /* If the -k option is in effect, we need to go through the remaining
7739 words, separate out the assignment words, and place them on
7740 SUBST_ASSIGN_VARLIST. */
7741 if (place_keywords_in_env)
7743 WORD_LIST *tp; /* tp == running pointer into tlist */
7748 /* Loop Invariant: tp->next == lp */
7749 /* Loop postcondition: tlist == word list without assignment statements */
7752 if (lp->word->flags & W_ASSIGNMENT)
7754 /* Found an assignment statement, add this word to end of
7755 subst_assign_varlist (vp). */
7756 if (!subst_assign_varlist)
7757 subst_assign_varlist = vp = lp;
7764 /* Remove the word pointed to by LP from TLIST. */
7765 tp->next = lp->next;
7766 /* ASSERT(vp == lp); */
7767 lp->next = (WORD_LIST *)NULL;
7780 #define WEXP_VARASSIGN 0x001
7781 #define WEXP_BRACEEXP 0x002
7782 #define WEXP_TILDEEXP 0x004
7783 #define WEXP_PARAMEXP 0x008
7784 #define WEXP_PATHEXP 0x010
7786 /* All of the expansions, including variable assignments at the start of
7788 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7790 /* All of the expansions except variable assignments at the start of
7792 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7794 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
7795 expansion, command substitution, arithmetic expansion, word splitting, and
7797 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7799 /* Take the list of words in LIST and do the various substitutions. Return
7800 a new list of words which is the expanded list, and without things like
7801 variable assignments. */
7807 return (expand_word_list_internal (list, WEXP_ALL));
7810 /* Same as expand_words (), but doesn't hack variable or environment
7813 expand_words_no_vars (list)
7816 return (expand_word_list_internal (list, WEXP_NOVARS));
7820 expand_words_shellexp (list)
7823 return (expand_word_list_internal (list, WEXP_SHELLEXP));
7827 glob_expand_word_list (tlist, eflags)
7831 char **glob_array, *temp_string;
7832 register int glob_index;
7833 WORD_LIST *glob_list, *output_list, *disposables, *next;
7836 output_list = disposables = (WORD_LIST *)NULL;
7837 glob_array = (char **)NULL;
7840 /* For each word, either globbing is attempted or the word is
7841 added to orig_list. If globbing succeeds, the results are
7842 added to orig_list and the word (tlist) is added to the list
7843 of disposable words. If globbing fails and failed glob
7844 expansions are left unchanged (the shell default), the
7845 original word is added to orig_list. If globbing fails and
7846 failed glob expansions are removed, the original word is
7847 added to the list of disposable words. orig_list ends up
7848 in reverse order and requires a call to REVERSE_LIST to
7849 be set right. After all words are examined, the disposable
7853 /* If the word isn't an assignment and contains an unquoted
7854 pattern matching character, then glob it. */
7855 if ((tlist->word->flags & W_NOGLOB) == 0 &&
7856 unquoted_glob_pattern_p (tlist->word->word))
7858 glob_array = shell_glob_filename (tlist->word->word);
7860 /* Handle error cases.
7861 I don't think we should report errors like "No such file
7862 or directory". However, I would like to report errors
7863 like "Read failed". */
7865 if (glob_array == 0 || GLOB_FAILED (glob_array))
7867 glob_array = (char **)xmalloc (sizeof (char *));
7868 glob_array[0] = (char *)NULL;
7871 /* Dequote the current word in case we have to use it. */
7872 if (glob_array[0] == NULL)
7874 temp_string = dequote_string (tlist->word->word);
7875 free (tlist->word->word);
7876 tlist->word->word = temp_string;
7879 /* Make the array into a word list. */
7880 glob_list = (WORD_LIST *)NULL;
7881 for (glob_index = 0; glob_array[glob_index]; glob_index++)
7883 tword = make_bare_word (glob_array[glob_index]);
7884 tword->flags |= W_GLOBEXP; /* XXX */
7885 glob_list = make_word_list (tword, glob_list);
7890 output_list = (WORD_LIST *)list_append (glob_list, output_list);
7891 PREPEND_LIST (tlist, disposables);
7893 else if (fail_glob_expansion != 0)
7895 report_error (_("no match: %s"), tlist->word->word);
7896 exp_jump_to_top_level (DISCARD);
7898 else if (allow_null_glob_expansion == 0)
7900 /* Failed glob expressions are left unchanged. */
7901 PREPEND_LIST (tlist, output_list);
7905 /* Failed glob expressions are removed. */
7906 PREPEND_LIST (tlist, disposables);
7911 /* Dequote the string. */
7912 temp_string = dequote_string (tlist->word->word);
7913 free (tlist->word->word);
7914 tlist->word->word = temp_string;
7915 PREPEND_LIST (tlist, output_list);
7918 strvec_dispose (glob_array);
7919 glob_array = (char **)NULL;
7925 dispose_words (disposables);
7928 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7930 return (output_list);
7933 #if defined (BRACE_EXPANSION)
7935 brace_expand_word_list (tlist, eflags)
7939 register char **expansions;
7941 WORD_LIST *disposables, *output_list, *next;
7945 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
7949 /* Only do brace expansion if the word has a brace character. If
7950 not, just add the word list element to BRACES and continue. In
7951 the common case, at least when running shell scripts, this will
7952 degenerate to a bunch of calls to `xstrchr', and then what is
7953 basically a reversal of TLIST into BRACES, which is corrected
7954 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7956 if (xstrchr (tlist->word->word, LBRACE))
7958 expansions = brace_expand (tlist->word->word);
7960 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
7962 w = make_word (temp_string);
7963 /* If brace expansion didn't change the word, preserve
7964 the flags. We may want to preserve the flags
7965 unconditionally someday -- XXX */
7966 if (STREQ (temp_string, tlist->word->word))
7967 w->flags = tlist->word->flags;
7968 output_list = make_word_list (w, output_list);
7969 free (expansions[eindex]);
7973 /* Add TLIST to the list of words to be freed after brace
7974 expansion has been performed. */
7975 PREPEND_LIST (tlist, disposables);
7978 PREPEND_LIST (tlist, output_list);
7982 dispose_words (disposables);
7985 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7987 return (output_list);
7992 shell_expand_word_list (tlist, eflags)
7996 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
7997 int expanded_something, has_dollar_at;
8000 /* We do tilde expansion all the time. This is what 1003.2 says. */
8001 new_list = (WORD_LIST *)NULL;
8002 for (orig_list = tlist; tlist; tlist = next)
8004 temp_string = tlist->word->word;
8008 #if defined (ARRAY_VARS)
8009 /* If this is a compound array assignment to a builtin that accepts
8010 such assignments (e.g., `declare'), take the assignment and perform
8011 it separately, handling the semantics of declarations inside shell
8012 functions. This avoids the double-evaluation of such arguments,
8013 because `declare' does some evaluation of compound assignments on
8015 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
8019 t = do_word_assignment (tlist->word);
8022 last_command_exit_value = EXECUTION_FAILURE;
8023 exp_jump_to_top_level (DISCARD);
8026 /* Now transform the word as ksh93 appears to do and go on */
8027 t = assignment (tlist->word->word, 0);
8028 tlist->word->word[t] = '\0';
8029 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG);
8033 expanded_something = 0;
8034 expanded = expand_word_internal
8035 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
8037 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
8039 /* By convention, each time this error is returned,
8040 tlist->word->word has already been freed. */
8041 tlist->word->word = (char *)NULL;
8043 /* Dispose our copy of the original list. */
8044 dispose_words (orig_list);
8045 /* Dispose the new list we're building. */
8046 dispose_words (new_list);
8048 last_command_exit_value = EXECUTION_FAILURE;
8049 if (expanded == &expand_word_error)
8050 exp_jump_to_top_level (DISCARD);
8052 exp_jump_to_top_level (FORCE_EOF);
8055 /* Don't split words marked W_NOSPLIT. */
8056 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
8058 temp_list = word_list_split (expanded);
8059 dispose_words (expanded);
8063 /* If no parameter expansion, command substitution, process
8064 substitution, or arithmetic substitution took place, then
8065 do not do word splitting. We still have to remove quoted
8066 null characters from the result. */
8067 word_list_remove_quoted_nulls (expanded);
8068 temp_list = expanded;
8071 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
8072 new_list = (WORD_LIST *)list_append (expanded, new_list);
8076 dispose_words (orig_list);
8079 new_list = REVERSE_LIST (new_list, WORD_LIST *);
8084 /* The workhorse for expand_words () and expand_words_no_vars ().
8085 First arg is LIST, a WORD_LIST of words.
8086 Second arg EFLAGS is a flags word controlling which expansions are
8089 This does all of the substitutions: brace expansion, tilde expansion,
8090 parameter expansion, command substitution, arithmetic expansion,
8091 process substitution, word splitting, and pathname expansion, according
8092 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8093 set, or for which no expansion is done, do not undergo word splitting.
8094 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8096 expand_word_list_internal (list, eflags)
8100 WORD_LIST *new_list, *temp_list;
8104 return ((WORD_LIST *)NULL);
8106 garglist = new_list = copy_word_list (list);
8107 if (eflags & WEXP_VARASSIGN)
8109 garglist = new_list = separate_out_assignments (new_list);
8112 if (subst_assign_varlist)
8114 /* All the words were variable assignments, so they are placed
8115 into the shell's environment. */
8116 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8118 this_command_name = (char *)NULL; /* no arithmetic errors */
8119 tint = do_word_assignment (temp_list->word);
8120 /* Variable assignment errors in non-interactive shells
8121 running in Posix.2 mode cause the shell to exit. */
8124 last_command_exit_value = EXECUTION_FAILURE;
8125 if (interactive_shell == 0 && posixly_correct)
8126 exp_jump_to_top_level (FORCE_EOF);
8128 exp_jump_to_top_level (DISCARD);
8131 dispose_words (subst_assign_varlist);
8132 subst_assign_varlist = (WORD_LIST *)NULL;
8134 return ((WORD_LIST *)NULL);
8138 /* Begin expanding the words that remain. The expansions take place on
8139 things that aren't really variable assignments. */
8141 #if defined (BRACE_EXPANSION)
8142 /* Do brace expansion on this word if there are any brace characters
8144 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
8145 new_list = brace_expand_word_list (new_list, eflags);
8146 #endif /* BRACE_EXPANSION */
8148 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8149 variable substitution, command substitution, arithmetic expansion,
8150 and word splitting. */
8151 new_list = shell_expand_word_list (new_list, eflags);
8153 /* Okay, we're almost done. Now let's just do some filename
8157 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
8158 /* Glob expand the word list unless globbing has been disabled. */
8159 new_list = glob_expand_word_list (new_list, eflags);
8161 /* Dequote the words, because we're not performing globbing. */
8162 new_list = dequote_list (new_list);
8165 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
8167 sh_wassign_func_t *assign_func;
8169 /* If the remainder of the words expand to nothing, Posix.2 requires
8170 that the variable and environment assignments affect the shell's
8172 assign_func = new_list ? assign_in_env : do_word_assignment;
8173 tempenv_assign_error = 0;
8175 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8177 this_command_name = (char *)NULL;
8178 tint = (*assign_func) (temp_list->word);
8179 /* Variable assignment errors in non-interactive shells running
8180 in Posix.2 mode cause the shell to exit. */
8183 if (assign_func == do_word_assignment)
8185 last_command_exit_value = EXECUTION_FAILURE;
8186 if (interactive_shell == 0 && posixly_correct)
8187 exp_jump_to_top_level (FORCE_EOF);
8189 exp_jump_to_top_level (DISCARD);
8192 tempenv_assign_error++;
8196 dispose_words (subst_assign_varlist);
8197 subst_assign_varlist = (WORD_LIST *)NULL;
8201 tint = list_length (new_list) + 1;
8202 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
8203 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
8204 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
8205 glob_argv_flags[tint] = '\0';