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;
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 *, int));
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, 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, flags)
896 register int i = *sindex;
897 #if defined (HANDLE_MULTIBYTE)
905 if (charlist[0] == '\'' && charlist[1] == '\0')
907 temp = string_extract_single_quoted (string, sindex);
908 --*sindex; /* leave *sindex at separator character */
914 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
915 this only if MB_CUR_MAX > 1. */
916 slen = (MB_CUR_MAX > 1) ? strlen (string + *sindex) + *sindex : 1;
918 #if defined (HANDLE_MULTIBYTE)
919 clen = strlen (charlist);
922 while (c = string[i])
924 #if defined (HANDLE_MULTIBYTE)
933 #if defined (HANDLE_MULTIBYTE)
934 mblength = MBLEN (string + i, slen - i);
938 mblength = mbtowc (&wc, string + i, slen - i);
939 if (MB_INVALIDCH (mblength))
941 if (MEMBER (c, charlist))
949 len = mbstowcs (wcharlist, charlist, 0);
952 wcharlist = (wchar_t *)xmalloc (sizeof (wchar_t) * (len + 1));
953 mbstowcs (wcharlist, charlist, len + 1);
956 if (wcschr (wcharlist, wc))
962 if (MEMBER (c, charlist))
965 ADVANCE_CHAR (string, slen, i);
968 #if defined (HANDLE_MULTIBYTE)
972 temp = substring (string, *sindex, i);
978 /* Extract the $( construct in STRING, and return a new string.
979 Start extracting at (SINDEX) as if we had just seen "$(".
980 Make (SINDEX) get the position of the matching ")". ) */
982 extract_command_subst (string, sindex)
986 return (extract_delimited_string (string, sindex, "$(", "(", ")", EX_COMMAND)); /*)*/
989 /* Extract the $[ construct in STRING, and return a new string. (])
990 Start extracting at (SINDEX) as if we had just seen "$[".
991 Make (SINDEX) get the position of the matching "]". */
993 extract_arithmetic_subst (string, sindex)
997 return (extract_delimited_string (string, sindex, "$[", "[", "]", 0)); /*]*/
1000 #if defined (PROCESS_SUBSTITUTION)
1001 /* Extract the <( or >( construct in STRING, and return a new string.
1002 Start extracting at (SINDEX) as if we had just seen "<(".
1003 Make (SINDEX) get the position of the matching ")". */ /*))*/
1005 extract_process_subst (string, starter, sindex)
1010 return (extract_delimited_string (string, sindex, starter, "(", ")", 0));
1012 #endif /* PROCESS_SUBSTITUTION */
1014 #if defined (ARRAY_VARS)
1015 /* This can be fooled by unquoted right parens in the passed string. If
1016 each caller verifies that the last character in STRING is a right paren,
1017 we don't even need to call extract_delimited_string. */
1019 extract_array_assignment_list (string, sindex)
1026 slen = strlen (string); /* ( */
1027 if (string[slen - 1] == ')')
1029 ret = substring (string, *sindex, slen - 1);
1037 /* Extract and create a new string from the contents of STRING, a
1038 character string delimited with OPENER and CLOSER. SINDEX is
1039 the address of an int describing the current offset in STRING;
1040 it should point to just after the first OPENER found. On exit,
1041 SINDEX gets the position of the last character of the matching CLOSER.
1042 If OPENER is more than a single character, ALT_OPENER, if non-null,
1043 contains a character string that can also match CLOSER and thus
1044 needs to be skipped. */
1046 extract_delimited_string (string, sindex, opener, alt_opener, closer, flags)
1049 char *opener, *alt_opener, *closer;
1055 int pass_character, nesting_level, in_comment;
1056 int len_closer, len_opener, len_alt_opener;
1059 slen = strlen (string + *sindex) + *sindex;
1060 len_opener = STRLEN (opener);
1061 len_alt_opener = STRLEN (alt_opener);
1062 len_closer = STRLEN (closer);
1064 pass_character = in_comment = 0;
1069 while (nesting_level)
1080 ADVANCE_CHAR (string, slen, i);
1084 if (pass_character) /* previous char was backslash */
1087 ADVANCE_CHAR (string, slen, i);
1091 /* Not exactly right yet; should handle shell metacharacters and
1092 multibyte characters, too. */
1093 if ((flags & EX_COMMAND) && c == '#' && (i == 0 || string[i - 1] == '\n' || whitespace (string[i - 1])))
1096 ADVANCE_CHAR (string, slen, i);
1100 if (c == CTLESC || c == '\\')
1107 /* Process a nested OPENER. */
1108 if (STREQN (string + i, opener, len_opener))
1110 si = i + len_opener;
1111 t = extract_delimited_string (string, &si, opener, alt_opener, closer, flags|EX_NOALLOC);
1116 /* Process a nested ALT_OPENER */
1117 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
1119 si = i + len_alt_opener;
1120 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer, flags|EX_NOALLOC);
1125 /* If the current substring terminates the delimited string, decrement
1126 the nesting level. */
1127 if (STREQN (string + i, closer, len_closer))
1129 i += len_closer - 1; /* move to last byte of the closer */
1131 if (nesting_level == 0)
1135 /* Pass old-style command substitution through verbatim. */
1139 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1144 /* Pass single-quoted and double-quoted strings through verbatim. */
1145 if (c == '\'' || c == '"')
1148 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1149 : skip_double_quoted (string, slen, si);
1153 /* move past this character, which was not special. */
1154 ADVANCE_CHAR (string, slen, i);
1157 if (c == 0 && nesting_level)
1159 if (no_longjmp_on_fatal_error == 0)
1161 report_error (_("bad substitution: no closing `%s' in %s"), closer, string);
1162 last_command_exit_value = EXECUTION_FAILURE;
1163 exp_jump_to_top_level (DISCARD);
1168 return (char *)NULL;
1172 si = i - *sindex - len_closer + 1;
1173 if (flags & EX_NOALLOC)
1174 result = (char *)NULL;
1177 result = (char *)xmalloc (1 + si);
1178 strncpy (result, string + *sindex, si);
1186 /* Extract a parameter expansion expression within ${ and } from STRING.
1187 Obey the Posix.2 rules for finding the ending `}': count braces while
1188 skipping over enclosed quoted strings and command substitutions.
1189 SINDEX is the address of an int describing the current offset in STRING;
1190 it should point to just after the first `{' found. On exit, SINDEX
1191 gets the position of the matching `}'. QUOTED is non-zero if this
1192 occurs inside double quotes. */
1193 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1195 extract_dollar_brace_string (string, sindex, quoted, flags)
1197 int *sindex, quoted, flags;
1201 int pass_character, nesting_level, si;
1207 slen = strlen (string + *sindex) + *sindex;
1210 while (c = string[i])
1215 ADVANCE_CHAR (string, slen, i);
1219 /* CTLESCs and backslashes quote the next character. */
1220 if (c == CTLESC || c == '\\')
1227 if (string[i] == '$' && string[i+1] == LBRACE)
1237 if (nesting_level == 0)
1243 /* Pass the contents of old-style command substitutions through
1248 t = string_extract (string, &si, "`", flags|EX_NOALLOC);
1253 /* Pass the contents of new-style command substitutions and
1254 arithmetic substitutions through verbatim. */
1255 if (string[i] == '$' && string[i+1] == LPAREN)
1258 t = extract_delimited_string (string, &si, "$(", "(", ")", flags|EX_NOALLOC|EX_COMMAND); /*)*/
1263 /* Pass the contents of single-quoted and double-quoted strings
1264 through verbatim. */
1265 if (c == '\'' || c == '"')
1268 i = (c == '\'') ? skip_single_quoted (string, slen, si)
1269 : skip_double_quoted (string, slen, si);
1270 /* skip_XXX_quoted leaves index one past close quote */
1274 /* move past this character, which was not special. */
1275 ADVANCE_CHAR (string, slen, i);
1278 if (c == 0 && nesting_level)
1280 if (no_longjmp_on_fatal_error == 0)
1282 report_error (_("bad substitution: no closing `%s' in %s"), "}", string);
1283 last_command_exit_value = EXECUTION_FAILURE;
1284 exp_jump_to_top_level (DISCARD);
1289 return ((char *)NULL);
1293 result = (flags & EX_NOALLOC) ? (char *)NULL : substring (string, *sindex, i);
1299 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1300 STRING, and returns a pointer to it. */
1302 de_backslash (string)
1305 register size_t slen;
1306 register int i, j, prev_i;
1309 slen = strlen (string);
1312 /* Loop copying string[i] to string[j], i >= j. */
1315 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1316 string[i + 1] == '$'))
1319 ADVANCE_CHAR (string, slen, i);
1321 do string[j++] = string[prev_i++]; while (prev_i < i);
1332 /* Replace instances of \! in a string with !. */
1334 unquote_bang (string)
1338 register char *temp;
1340 temp = (char *)xmalloc (1 + strlen (string));
1342 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1344 if (string[i] == '\\' && string[i + 1] == '!')
1350 strcpy (string, temp);
1355 #if defined (READLINE)
1356 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1357 an unclosed quoted string), or if the character at EINDEX is quoted
1358 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1359 single and double-quoted string parsing functions should not return an
1360 error if there are unclosed quotes or braces. The characters that this
1361 recognizes need to be the same as the contents of
1362 rl_completer_quote_characters. */
1364 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1367 char_is_quoted (string, eindex)
1371 int i, pass_next, c;
1375 slen = strlen (string);
1376 no_longjmp_on_fatal_error = 1;
1385 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1387 ADVANCE_CHAR (string, slen, i);
1396 else if (c == '\'' || c == '"')
1398 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1399 : skip_double_quoted (string, slen, ++i);
1402 /* no increment, the skip_xxx functions go one past end */
1405 ADVANCE_CHAR (string, slen, i);
1412 unclosed_pair (string, eindex, openstr)
1417 int i, pass_next, openc, olen;
1421 slen = strlen (string);
1422 olen = strlen (openstr);
1423 i = pass_next = openc = 0;
1429 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1431 ADVANCE_CHAR (string, slen, i);
1434 else if (string[i] == '\\')
1440 else if (STREQN (string + i, openstr, olen))
1445 else if (string[i] == '\'' || string[i] == '"')
1447 i = (string[i] == '\'') ? skip_single_quoted (string, slen, i)
1448 : skip_double_quoted (string, slen, i);
1453 ADVANCE_CHAR (string, slen, i);
1458 /* Skip characters in STRING until we find a character in DELIMS, and return
1459 the index of that character. START is the index into string at which we
1460 begin. This is similar in spirit to strpbrk, but it returns an index into
1461 STRING and takes a starting index. This little piece of code knows quite
1462 a lot of shell syntax. It's very similar to skip_double_quoted and other
1463 functions of that ilk. */
1465 skip_to_delim (string, start, delims)
1470 int i, pass_next, backq, si, c;
1475 slen = strlen (string + start) + start;
1476 no_longjmp_on_fatal_error = 1;
1478 pass_next = backq = 0;
1479 while (c = string[i])
1486 ADVANCE_CHAR (string, slen, i);
1499 ADVANCE_CHAR (string, slen, i);
1508 else if (c == '\'' || c == '"')
1510 i = (c == '\'') ? skip_single_quoted (string, slen, ++i)
1511 : skip_double_quoted (string, slen, ++i);
1512 /* no increment, the skip functions increment past the closing quote. */
1514 else if (c == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1517 if (string[si] == '\0')
1520 if (string[i+1] == LPAREN)
1521 temp = extract_delimited_string (string, &si, "$(", "(", ")", EX_NOALLOC|EX_COMMAND); /* ) */
1523 temp = extract_dollar_brace_string (string, &si, 0, EX_NOALLOC);
1525 if (string[i] == '\0') /* don't increment i past EOS in loop */
1530 else if (member (c, delims))
1533 ADVANCE_CHAR (string, slen, i);
1539 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1540 individual words. If DELIMS is NULL, the current value of $IFS is used
1541 to split the string, and the function follows the shell field splitting
1542 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1543 gets the number of words in the returned list. CWP, if non-NULL, gets
1544 the index of the word containing SENTINEL. Non-whitespace chars in
1545 DELIMS delimit separate fields. */
1547 split_at_delims (string, slen, delims, sentinel, nwp, cwp)
1554 int ts, te, i, nw, cw, ifs_split;
1555 char *token, *d, *d2;
1556 WORD_LIST *ret, *tl;
1558 if (string == 0 || *string == '\0')
1564 return ((WORD_LIST *)NULL);
1567 d = (delims == 0) ? ifs_value : delims;
1568 ifs_split = delims == 0;
1570 /* Make d2 the non-whitespace characters in delims */
1575 #if defined (HANDLE_MULTIBYTE)
1576 size_t mblength = 1;
1580 slength = strlen (delims);
1581 d2 = (char *)xmalloc (slength + 1);
1585 #if defined (HANDLE_MULTIBYTE)
1586 mbstate_t state_bak;
1588 mblength = MBRLEN (delims + i, slength, &state);
1589 if (MB_INVALIDCH (mblength))
1591 else if (mblength > 1)
1593 memcpy (d2 + ts, delims + i, mblength);
1596 slength -= mblength;
1600 if (whitespace (delims[i]) == 0)
1601 d2[ts++] = delims[i];
1609 ret = (WORD_LIST *)NULL;
1611 /* Remove sequences of whitspace characters at the start of the string, as
1612 long as those characters are delimiters. */
1613 for (i = 0; member (string[i], d) && spctabnl (string[i]); i++)
1615 if (string[i] == '\0')
1623 te = skip_to_delim (string, ts, d);
1625 /* If we have a non-whitespace delimiter character, use it to make a
1626 separate field. This is just about what $IFS splitting does and
1627 is closer to the behavior of the shell parser. */
1628 if (ts == te && d2 && member (string[ts], d2))
1631 /* If we're using IFS splitting, the non-whitespace delimiter char
1632 and any additional IFS whitespace delimits a field. */
1634 while (member (string[te], d) && spctabnl (string[te]))
1637 while (member (string[te], d2))
1641 token = substring (string, ts, te);
1643 ret = add_string_to_list (token, ret);
1647 if (sentinel >= ts && sentinel <= te)
1650 /* If the cursor is at whitespace just before word start, set the
1651 sentinel word to the current word. */
1652 if (cwp && cw == -1 && sentinel == ts-1)
1655 /* If the cursor is at whitespace between two words, make a new, empty
1656 word, add it before (well, after, since the list is in reverse order)
1657 the word we just added, and set the current word to that one. */
1658 if (cwp && cw == -1 && sentinel < ts)
1660 tl = make_word_list (make_word (""), ret->next);
1666 if (string[te] == 0)
1670 while (member (string[i], d) && (ifs_split || spctabnl(string[i])))
1679 /* Special case for SENTINEL at the end of STRING. If we haven't found
1680 the word containing SENTINEL yet, and the index we're looking for is at
1681 the end of STRING, add an additional null argument and set the current
1682 word pointer to that. */
1683 if (cwp && cw == -1 && sentinel >= slen)
1685 if (whitespace (string[sentinel - 1]))
1688 ret = add_string_to_list (token, ret);
1699 return (REVERSE_LIST (ret, WORD_LIST *));
1701 #endif /* READLINE */
1705 /* Extract the name of the variable to bind to from the assignment string. */
1707 assignment_name (string)
1713 offset = assignment (string, 0);
1715 return (char *)NULL;
1716 temp = substring (string, 0, offset);
1721 /* **************************************************************** */
1723 /* Functions to convert strings to WORD_LISTs and vice versa */
1725 /* **************************************************************** */
1727 /* Return a single string of all the words in LIST. SEP is the separator
1728 to put between individual elements of LIST in the output string. */
1730 string_list_internal (list, sep)
1734 register WORD_LIST *t;
1736 int word_len, sep_len, result_size;
1739 return ((char *)NULL);
1741 /* Short-circuit quickly if we don't need to separate anything. */
1742 if (list->next == 0)
1743 return (savestring (list->word->word));
1745 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1746 sep_len = STRLEN (sep);
1749 for (t = list; t; t = t->next)
1752 result_size += sep_len;
1753 result_size += strlen (t->word->word);
1756 r = result = (char *)xmalloc (result_size + 1);
1758 for (t = list; t; t = t->next)
1760 if (t != list && sep_len)
1764 FASTCOPY (sep, r, sep_len);
1771 word_len = strlen (t->word->word);
1772 FASTCOPY (t->word->word, r, word_len);
1780 /* Return a single string of all the words present in LIST, separating
1781 each word with a space. */
1786 return (string_list_internal (list, " "));
1789 /* Return a single string of all the words present in LIST, obeying the
1790 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1791 expansion [of $*] appears within a double quoted string, it expands
1792 to a single field with the value of each parameter separated by the
1793 first character of the IFS variable, or by a <space> if IFS is unset." */
1795 string_list_dollar_star (list)
1799 #if defined (HANDLE_MULTIBYTE)
1800 # if defined (__GNUC__)
1801 char sep[MB_CUR_MAX + 1];
1809 #if defined (HANDLE_MULTIBYTE)
1810 # if !defined (__GNUC__)
1811 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1812 # endif /* !__GNUC__ */
1813 if (ifs_firstc_len == 1)
1815 sep[0] = ifs_firstc[0];
1820 memcpy (sep, ifs_firstc, ifs_firstc_len);
1821 sep[ifs_firstc_len] = '\0';
1824 sep[0] = ifs_firstc;
1828 ret = string_list_internal (list, sep);
1829 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1835 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1836 is non-zero, the $@ appears within double quotes, and we should quote
1837 the list before converting it into a string. If IFS is unset, and the
1838 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1839 in the words in the list, because the default value of $IFS is
1840 <space><tab><newline>, IFS characters in the words in the list should
1841 also be split. If IFS is null, and the word is not quoted, we need
1842 to quote the words in the list to preserve the positional parameters
1845 string_list_dollar_at (list, quoted)
1850 #if defined (HANDLE_MULTIBYTE)
1851 # if defined (__GNUC__)
1852 char sep[MB_CUR_MAX + 1];
1855 # endif /* !__GNUC__ */
1861 /* XXX this could just be ifs = ifs_value; */
1862 ifs = ifs_var ? value_cell (ifs_var) : (char *)0;
1864 #if defined (HANDLE_MULTIBYTE)
1865 # if !defined (__GNUC__)
1866 sep = (char *)xmalloc (MB_CUR_MAX + 1);
1867 # endif /* !__GNUC__ */
1870 if (ifs_firstc_len == 1)
1872 sep[0] = ifs_firstc[0];
1877 memcpy (sep, ifs_firstc, ifs_firstc_len);
1878 sep[ifs_firstc_len] = '\0';
1887 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1891 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
1892 it now that quote_escapes quotes spaces */
1894 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1896 tlist = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1899 : list_quote_escapes (list);
1901 ret = string_list_internal (tlist, sep);
1902 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1908 /* Return the list of words present in STRING. Separate the string into
1909 words at any of the characters found in SEPARATORS. If QUOTED is
1910 non-zero then word in the list will have its quoted flag set, otherwise
1911 the quoted flag is left as make_word () deemed fit.
1913 This obeys the P1003.2 word splitting semantics. If `separators' is
1914 exactly <space><tab><newline>, then the splitting algorithm is that of
1915 the Bourne shell, which treats any sequence of characters from `separators'
1916 as a delimiter. If IFS is unset, which results in `separators' being set
1917 to "", no splitting occurs. If separators has some other value, the
1918 following rules are applied (`IFS white space' means zero or more
1919 occurrences of <space>, <tab>, or <newline>, as long as those characters
1920 are in `separators'):
1922 1) IFS white space is ignored at the start and the end of the
1924 2) Each occurrence of a character in `separators' that is not
1925 IFS white space, along with any adjacent occurrences of
1926 IFS white space delimits a field.
1927 3) Any nonzero-length sequence of IFS white space delimits a field.
1930 /* BEWARE! list_string strips null arguments. Don't call it twice and
1931 expect to have "" preserved! */
1933 /* This performs word splitting and quoted null character removal on
1936 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1937 : (c) == (separators)[0]) \
1941 list_string (string, separators, quoted)
1942 register char *string, *separators;
1947 char *current_word, *s;
1948 int sindex, sh_style_split, whitesep;
1951 if (!string || !*string)
1952 return ((WORD_LIST *)NULL);
1954 sh_style_split = separators && separators[0] == ' ' &&
1955 separators[1] == '\t' &&
1956 separators[2] == '\n' &&
1957 separators[3] == '\0';
1960 /* Remove sequences of whitespace at the beginning of STRING, as
1961 long as those characters appear in IFS. Do not do this if
1962 STRING is quoted or if there are no separator characters. */
1963 if (!quoted || !separators || !*separators)
1965 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1968 return ((WORD_LIST *)NULL);
1973 /* OK, now STRING points to a word that does not begin with white space.
1974 The splitting algorithm is:
1975 extract a word, stopping at a separator
1976 skip sequences of spc, tab, or nl as long as they are separators
1977 This obeys the field splitting rules in Posix.2. */
1978 slen = (MB_CUR_MAX > 1) ? strlen (string) : 1;
1979 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1981 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
1982 unless multibyte chars are possible. */
1983 current_word = string_extract_verbatim (string, slen, &sindex, separators, 0);
1984 if (current_word == 0)
1987 /* If we have a quoted empty string, add a quoted null argument. We
1988 want to preserve the quoted null character iff this is a quoted
1989 empty string; otherwise the quoted null characters are removed
1991 if (QUOTED_NULL (current_word))
1993 t = alloc_word_desc ();
1994 t->word = make_quoted_char ('\0');
1995 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
1996 result = make_word_list (t, result);
1998 else if (current_word[0] != '\0')
2000 /* If we have something, then add it regardless. However,
2001 perform quoted null character removal on the current word. */
2002 remove_quoted_nulls (current_word);
2003 result = add_string_to_list (current_word, result);
2004 result->word->flags &= ~W_HASQUOTEDNULL; /* just to be sure */
2005 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
2006 result->word->flags |= W_QUOTED;
2009 /* If we're not doing sequences of separators in the traditional
2010 Bourne shell style, then add a quoted null argument. */
2011 else if (!sh_style_split && !spctabnl (string[sindex]))
2013 t = alloc_word_desc ();
2014 t->word = make_quoted_char ('\0');
2015 t->flags |= W_QUOTED|W_HASQUOTEDNULL;
2016 result = make_word_list (t, result);
2019 free (current_word);
2021 /* Note whether or not the separator is IFS whitespace, used later. */
2022 whitesep = string[sindex] && spctabnl (string[sindex]);
2024 /* Move past the current separator character. */
2028 ADVANCE_CHAR (string, slen, sindex);
2031 /* Now skip sequences of space, tab, or newline characters if they are
2032 in the list of separators. */
2033 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
2036 /* If the first separator was IFS whitespace and the current character
2037 is a non-whitespace IFS character, it should be part of the current
2038 field delimiter, not a separate delimiter that would result in an
2039 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2040 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
2043 /* An IFS character that is not IFS white space, along with any
2044 adjacent IFS white space, shall delimit a field. (SUSv3) */
2045 while (string[sindex] && spctabnl (string[sindex]) && isifs (string[sindex]))
2049 return (REVERSE_LIST (result, WORD_LIST *));
2052 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2053 ENDPTR is set to the first character after the word. This is used by
2054 the `read' builtin. This is never called with SEPARATORS != $IFS;
2055 it should be simplified.
2057 XXX - this function is very similar to list_string; they should be
2060 get_word_from_string (stringp, separators, endptr)
2061 char **stringp, *separators, **endptr;
2065 int sindex, sh_style_split, whitesep;
2068 if (!stringp || !*stringp || !**stringp)
2069 return ((char *)NULL);
2073 sh_style_split = separators && separators[0] == ' ' &&
2074 separators[1] == '\t' &&
2075 separators[2] == '\n' &&
2076 separators[3] == '\0';
2080 /* Remove sequences of whitespace at the beginning of STRING, as
2081 long as those characters appear in IFS. */
2082 if (sh_style_split || !separators || !*separators)
2084 for (; *s && spctabnl (*s) && isifs (*s); s++);
2086 /* If the string is nothing but whitespace, update it and return. */
2092 return ((char *)NULL);
2096 /* OK, S points to a word that does not begin with white space.
2097 Now extract a word, stopping at a separator, save a pointer to
2098 the first character after the word, then skip sequences of spc,
2099 tab, or nl as long as they are separators.
2101 This obeys the field splitting rules in Posix.2. */
2103 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2104 unless multibyte chars are possible. */
2105 slen = (MB_CUR_MAX > 1) ? strlen (s) : 1;
2106 current_word = string_extract_verbatim (s, slen, &sindex, separators, 0);
2108 /* Set ENDPTR to the first character after the end of the word. */
2110 *endptr = s + sindex;
2112 /* Note whether or not the separator is IFS whitespace, used later. */
2113 whitesep = s[sindex] && spctabnl (s[sindex]);
2115 /* Move past the current separator character. */
2119 ADVANCE_CHAR (s, slen, sindex);
2122 /* Now skip sequences of space, tab, or newline characters if they are
2123 in the list of separators. */
2124 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2127 /* If the first separator was IFS whitespace and the current character is
2128 a non-whitespace IFS character, it should be part of the current field
2129 delimiter, not a separate delimiter that would result in an empty field.
2130 Look at POSIX.2, 3.6.5, (3)(b). */
2131 if (s[sindex] && whitesep && isifs (s[sindex]) && !spctabnl (s[sindex]))
2134 /* An IFS character that is not IFS white space, along with any adjacent
2135 IFS white space, shall delimit a field. */
2136 while (s[sindex] && spctabnl (s[sindex]) && isifs (s[sindex]))
2140 /* Update STRING to point to the next field. */
2141 *stringp = s + sindex;
2142 return (current_word);
2145 /* Remove IFS white space at the end of STRING. Start at the end
2146 of the string and walk backwards until the beginning of the string
2147 or we find a character that's not IFS white space and not CTLESC.
2148 Only let CTLESC escape a white space character if SAW_ESCAPE is
2151 strip_trailing_ifs_whitespace (string, separators, saw_escape)
2152 char *string, *separators;
2157 s = string + STRLEN (string) - 1;
2158 while (s > string && ((spctabnl (*s) && isifs (*s)) ||
2159 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
2167 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2168 backslashes, single and double quotes. */
2170 list_string_with_quotes (string)
2176 int c, i, tokstart, len;
2178 for (s = string; s && *s && spctabnl (*s); s++)
2180 if (s == 0 || *s == 0)
2181 return ((WORD_LIST *)NULL);
2185 list = (WORD_LIST *)NULL;
2196 i = skip_single_quoted (s, s_len, ++i);
2198 i = skip_double_quoted (s, s_len, ++i);
2199 else if (c == 0 || spctabnl (c))
2201 /* We have found the end of a token. Make a word out of it and
2202 add it to the word list. */
2203 token = substring (s, tokstart, i);
2204 list = add_string_to_list (token, list);
2206 while (spctabnl (s[i]))
2214 i++; /* normal character */
2216 return (REVERSE_LIST (list, WORD_LIST *));
2220 /********************************************************/
2222 /* Functions to perform assignment statements */
2224 /********************************************************/
2226 #if defined (ARRAY_VARS)
2228 do_compound_assignment (name, value, flags)
2236 mklocal = flags & ASS_MKLOCAL;
2238 if (mklocal && variable_context)
2240 list = expand_compound_array_assignment (value, flags);
2241 v = find_variable (name);
2242 if (v == 0 || array_p (v) == 0 || v->context != variable_context)
2243 v = make_local_array_variable (name);
2244 assign_compound_array_list (v, list, flags);
2247 v = assign_array_from_string (name, value, flags);
2253 /* Given STRING, an assignment string, get the value of the right side
2254 of the `=', and bind it to the left side. If EXPAND is true, then
2255 perform parameter expansion, command substitution, and arithmetic
2256 expansion on the right-hand side. Perform tilde expansion in any
2257 case. Do not perform word splitting on the result of expansion. */
2259 do_assignment_internal (word, expand)
2260 const WORD_DESC *word;
2263 int offset, tlen, appendop, assign_list, aflags;
2266 #if defined (ARRAY_VARS)
2272 if (word == 0 || word->word == 0)
2275 appendop = assign_list = aflags = 0;
2276 string = word->word;
2277 offset = assignment (string, 0);
2278 name = savestring (string);
2279 value = (char *)NULL;
2281 if (name[offset] == '=')
2285 if (name[offset - 1] == '+')
2288 name[offset - 1] = '\0';
2291 name[offset] = 0; /* might need this set later */
2292 temp = name + offset + 1;
2293 tlen = STRLEN (temp);
2295 #if defined (ARRAY_VARS)
2296 if (expand && (word->flags & W_COMPASSIGN))
2298 assign_list = ni = 1;
2299 value = extract_array_assignment_list (temp, &ni);
2304 if (expand && temp[0])
2305 value = expand_string_if_necessary (temp, 0, expand_string_assignment);
2307 value = savestring (temp);
2312 value = (char *)xmalloc (1);
2316 if (echo_command_at_execute)
2319 name[offset - 1] = '+';
2320 xtrace_print_assignment (name, value, assign_list, 1);
2322 name[offset - 1] = '\0';
2325 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2328 aflags |= ASS_APPEND;
2330 #if defined (ARRAY_VARS)
2331 if (t = xstrchr (name, '[')) /*]*/
2335 report_error (_("%s: cannot assign list to array member"), name);
2338 entry = assign_array_element (name, value, aflags);
2342 else if (assign_list)
2344 if (word->flags & W_ASSIGNARG)
2345 aflags |= ASS_MKLOCAL;
2346 entry = do_compound_assignment (name, value, aflags);
2349 #endif /* ARRAY_VARS */
2350 entry = bind_variable (name, value, aflags);
2352 stupidly_hack_special_variables (name);
2355 VUNSETATTR (entry, att_invisible);
2357 /* Return 1 if the assignment seems to have been performed correctly. */
2358 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
2361 /* Perform the assignment statement in STRING, and expand the
2362 right side by doing tilde, command and parameter expansion. */
2364 do_assignment (string)
2369 td.flags = W_ASSIGNMENT;
2372 return do_assignment_internal (&td, 1);
2376 do_word_assignment (word)
2379 return do_assignment_internal (word, 1);
2382 /* Given STRING, an assignment string, get the value of the right side
2383 of the `=', and bind it to the left side. Do not perform any word
2384 expansions on the right hand side. */
2386 do_assignment_no_expand (string)
2391 td.flags = W_ASSIGNMENT;
2394 return (do_assignment_internal (&td, 0));
2397 /***************************************************
2399 * Functions to manage the positional parameters *
2401 ***************************************************/
2403 /* Return the word list that corresponds to `$*'. */
2405 list_rest_of_args ()
2407 register WORD_LIST *list, *args;
2410 /* Break out of the loop as soon as one of the dollar variables is null. */
2411 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
2412 list = make_word_list (make_bare_word (dollar_vars[i]), list);
2414 for (args = rest_of_args; args; args = args->next)
2415 list = make_word_list (make_bare_word (args->word->word), list);
2417 return (REVERSE_LIST (list, WORD_LIST *));
2423 register WORD_LIST *list;
2426 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
2428 for (list = rest_of_args; list; list = list->next)
2433 /* Return the value of a positional parameter. This handles values > 10. */
2435 get_dollar_var_value (ind)
2442 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
2443 else /* We want something like ${11} */
2446 for (p = rest_of_args; p && ind--; p = p->next)
2448 temp = p ? savestring (p->word->word) : (char *)NULL;
2453 /* Make a single large string out of the dollar digit variables,
2454 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2455 case of "$*" with respect to IFS. */
2457 string_rest_of_args (dollar_star)
2460 register WORD_LIST *list;
2463 list = list_rest_of_args ();
2464 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
2465 dispose_words (list);
2469 /* Return a string containing the positional parameters from START to
2470 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2471 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2472 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2473 no quoting chars are added. */
2475 pos_params (string, start, end, quoted)
2477 int start, end, quoted;
2479 WORD_LIST *save, *params, *h, *t;
2483 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2485 return ((char *)NULL);
2487 save = params = list_rest_of_args ();
2489 return ((char *)NULL);
2491 if (start == 0) /* handle ${@:0[:x]} specially */
2493 t = make_word_list (make_word (dollar_vars[0]), params);
2497 for (i = 1; params && i < start; i++)
2498 params = params->next;
2500 return ((char *)NULL);
2501 for (h = t = params; params && i < end; i++)
2504 params = params->next;
2507 t->next = (WORD_LIST *)NULL;
2508 if (string[0] == '*')
2510 if (quoted & Q_DOUBLE_QUOTES)
2511 ret = string_list_dollar_star (quote_list (h));
2512 else if (quoted & Q_HERE_DOCUMENT)
2513 ret = string_list (quote_list (h));
2515 ret = string_list (h);
2518 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
2522 dispose_words (save);
2526 /******************************************************************/
2528 /* Functions to expand strings to strings or WORD_LISTs */
2530 /******************************************************************/
2532 #if defined (PROCESS_SUBSTITUTION)
2533 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2535 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2538 /* If there are any characters in STRING that require full expansion,
2539 then call FUNC to expand STRING; otherwise just perform quote
2540 removal if necessary. This returns a new string. */
2542 expand_string_if_necessary (string, quoted, func)
2553 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2554 slen = (MB_CUR_MAX > 1) ? strlen (string) : 0;
2558 if (EXP_CHAR (string[i]))
2560 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
2562 ADVANCE_CHAR (string, slen, i);
2567 list = (*func) (string, quoted);
2570 ret = string_list (list);
2571 dispose_words (list);
2576 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
2577 ret = string_quote_removal (string, quoted);
2579 ret = savestring (string);
2584 static inline char *
2585 expand_string_to_string_internal (string, quoted, func)
2593 if (string == 0 || *string == '\0')
2594 return ((char *)NULL);
2596 list = (*func) (string, quoted);
2599 ret = string_list (list);
2600 dispose_words (list);
2609 expand_string_to_string (string, quoted)
2613 return (expand_string_to_string_internal (string, quoted, expand_string));
2617 expand_string_unsplit_to_string (string, quoted)
2621 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
2625 expand_assignment_string_to_string (string, quoted)
2629 return (expand_string_to_string_internal (string, quoted, expand_string_assignment));
2633 expand_arith_string (string, quoted)
2636 return (expand_string_if_necessary (string, quoted, expand_string));
2639 #if defined (COND_COMMAND)
2640 /* Just remove backslashes in STRING. Returns a new string. */
2642 remove_backslashes (string)
2647 r = ret = (char *)xmalloc (strlen (string) + 1);
2648 for (s = string; s && *s; )
2660 /* This needs better error handling. */
2661 /* Expand W for use as an argument to a unary or binary operator in a
2662 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2663 to the != or == operator, and should be treated as a pattern. In
2664 this case, we quote the string specially for the globbing code. If
2665 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2666 be quoted appropriately for regcomp/regexec. The caller is responsible
2667 for removing the backslashes if the unquoted word is needed later. */
2669 cond_expand_word (w, special)
2677 if (w->word == 0 || w->word[0] == '\0')
2678 return ((char *)NULL);
2680 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
2686 r = string_list (l);
2690 qflags = QGLOB_CVTNULL;
2692 qflags |= QGLOB_REGEXP;
2693 p = string_list (l);
2694 r = quote_string_for_globbing (p, qflags);
2706 /* Call expand_word_internal to expand W and handle error returns.
2707 A convenience function for functions that don't want to handle
2708 any errors or free any memory before aborting. */
2710 call_expand_word_internal (w, q, i, c, e)
2716 result = expand_word_internal (w, q, i, c, e);
2717 if (result == &expand_word_error || result == &expand_word_fatal)
2719 /* By convention, each time this error is returned, w->word has
2720 already been freed (it sometimes may not be in the fatal case,
2721 but that doesn't result in a memory leak because we're going
2722 to exit in most cases). */
2723 w->word = (char *)NULL;
2724 last_command_exit_value = EXECUTION_FAILURE;
2725 exp_jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
2732 /* Perform parameter expansion, command substitution, and arithmetic
2733 expansion on STRING, as if it were a word. Leave the result quoted. */
2735 expand_string_internal (string, quoted)
2742 if (string == 0 || *string == 0)
2743 return ((WORD_LIST *)NULL);
2746 td.word = savestring (string);
2748 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2754 /* Expand STRING by performing parameter expansion, command substitution,
2755 and arithmetic expansion. Dequote the resulting WORD_LIST before
2756 returning it, but do not perform word splitting. The call to
2757 remove_quoted_nulls () is in here because word splitting normally
2758 takes care of quote removal. */
2760 expand_string_unsplit (string, quoted)
2766 if (string == 0 || *string == '\0')
2767 return ((WORD_LIST *)NULL);
2769 expand_no_split_dollar_star = 1;
2770 value = expand_string_internal (string, quoted);
2771 expand_no_split_dollar_star = 0;
2777 remove_quoted_nulls (value->word->word);
2778 value->word->flags &= ~W_HASQUOTEDNULL;
2780 dequote_list (value);
2785 /* Expand the rhs of an assignment statement */
2787 expand_string_assignment (string, quoted)
2794 if (string == 0 || *string == '\0')
2795 return ((WORD_LIST *)NULL);
2797 expand_no_split_dollar_star = 1;
2799 td.flags = W_ASSIGNRHS;
2800 td.word = savestring (string);
2801 value = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2804 expand_no_split_dollar_star = 0;
2810 remove_quoted_nulls (value->word->word);
2811 value->word->flags &= ~W_HASQUOTEDNULL;
2813 dequote_list (value);
2819 /* Expand one of the PS? prompt strings. This is a sort of combination of
2820 expand_string_unsplit and expand_string_internal, but returns the
2821 passed string when an error occurs. Might want to trap other calls
2822 to jump_to_top_level here so we don't endlessly loop. */
2824 expand_prompt_string (string, quoted)
2831 if (string == 0 || *string == 0)
2832 return ((WORD_LIST *)NULL);
2835 td.word = savestring (string);
2837 no_longjmp_on_fatal_error = 1;
2838 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2839 no_longjmp_on_fatal_error = 0;
2841 if (value == &expand_word_error || value == &expand_word_fatal)
2843 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
2851 remove_quoted_nulls (value->word->word);
2852 value->word->flags &= ~W_HASQUOTEDNULL;
2854 dequote_list (value);
2859 /* Expand STRING just as if you were expanding a word, but do not dequote
2860 the resultant WORD_LIST. This is called only from within this file,
2861 and is used to correctly preserve quoted characters when expanding
2862 things like ${1+"$@"}. This does parameter expansion, command
2863 substitution, arithmetic expansion, and word splitting. */
2865 expand_string_leave_quoted (string, quoted)
2872 if (string == 0 || *string == '\0')
2873 return ((WORD_LIST *)NULL);
2875 tlist = expand_string_internal (string, quoted);
2879 tresult = word_list_split (tlist);
2880 dispose_words (tlist);
2883 return ((WORD_LIST *)NULL);
2886 /* This does not perform word splitting or dequote the WORD_LIST
2889 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
2891 int quoted, *dollar_at_p, *has_dollar_at;
2896 if (string == 0 || *string == '\0')
2897 return (WORD_LIST *)NULL;
2901 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
2905 /* Expand STRING just as if you were expanding a word. This also returns
2906 a list of words. Note that filename globbing is *NOT* done for word
2907 or string expansion, just when the shell is expanding a command. This
2908 does parameter expansion, command substitution, arithmetic expansion,
2909 and word splitting. Dequote the resultant WORD_LIST before returning. */
2911 expand_string (string, quoted)
2917 if (string == 0 || *string == '\0')
2918 return ((WORD_LIST *)NULL);
2920 result = expand_string_leave_quoted (string, quoted);
2921 return (result ? dequote_list (result) : result);
2924 /***************************************************
2926 * Functions to handle quoting chars *
2928 ***************************************************/
2932 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2933 The parser passes CTLNUL as CTLESC CTLNUL. */
2935 /* Quote escape characters in string s, but no other characters. This is
2936 used to protect CTLESC and CTLNUL in variable values from the rest of
2937 the word expansion process after the variable is expanded (word splitting
2938 and filename generation). If IFS is null, we quote spaces as well, just
2939 in case we split on spaces later (in the case of unquoted $@, we will
2940 eventually attempt to split the entire word on spaces). Corresponding
2941 code exists in dequote_escapes. Even if we don't end up splitting on
2942 spaces, quoting spaces is not a problem. This should never be called on
2943 a string that is quoted with single or double quotes or part of a here
2944 document (effectively double-quoted). */
2946 quote_escapes (string)
2949 register char *s, *t;
2951 char *result, *send;
2955 slen = strlen (string);
2956 send = string + slen;
2958 quote_spaces = (ifs_value && *ifs_value == 0);
2960 t = result = (char *)xmalloc ((slen * 2) + 1);
2965 if (*s == CTLESC || *s == CTLNUL || (quote_spaces && *s == ' '))
2967 COPY_CHAR_P (t, s, send);
2974 list_quote_escapes (list)
2977 register WORD_LIST *w;
2980 for (w = list; w; w = w->next)
2983 w->word->word = quote_escapes (t);
2989 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2991 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2992 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2993 data stream pass through properly.
2995 We need to remove doubled CTLESC characters inside quoted strings before
2996 quoting the entire string, so we do not double the number of CTLESC
2999 Also used by parts of the pattern substitution code. */
3001 dequote_escapes (string)
3004 register char *s, *t, *s1;
3006 char *result, *send;
3013 slen = strlen (string);
3014 send = string + slen;
3016 t = result = (char *)xmalloc (slen + 1);
3018 if (strchr (string, CTLESC) == 0)
3019 return (strcpy (result, string));
3021 quote_spaces = (ifs_value && *ifs_value == 0);
3026 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL || (quote_spaces && s[1] == ' ')))
3032 COPY_CHAR_P (t, s, send);
3038 /* Return a new string with the quoted representation of character C.
3039 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3040 set in any resultant WORD_DESC where this value is the word. */
3042 make_quoted_char (c)
3047 temp = (char *)xmalloc (3);
3062 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3063 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3064 this value is the word. */
3066 quote_string (string)
3071 char *result, *send;
3075 result = (char *)xmalloc (2);
3083 slen = strlen (string);
3084 send = string + slen;
3086 result = (char *)xmalloc ((slen * 2) + 1);
3088 for (t = result; string < send; )
3091 COPY_CHAR_P (t, string, send);
3098 /* De-quote quoted characters in STRING. */
3100 dequote_string (string)
3103 register char *s, *t;
3105 char *result, *send;
3108 slen = strlen (string);
3110 t = result = (char *)xmalloc (slen + 1);
3112 if (QUOTED_NULL (string))
3118 /* If no character in the string can be quoted, don't bother examining
3119 each character. Just return a copy of the string passed to us. */
3120 if (strchr (string, CTLESC) == NULL)
3121 return (strcpy (result, string));
3123 send = string + slen;
3133 COPY_CHAR_P (t, s, send);
3140 /* Quote the entire WORD_LIST list. */
3145 register WORD_LIST *w;
3148 for (w = list; w; w = w->next)
3151 w->word->word = quote_string (t);
3153 w->word->flags |= W_QUOTED;
3154 /* XXX - turn on W_HAVEQUOTEDNULL here? */
3159 /* De-quote quoted characters in each word in LIST. */
3165 register WORD_LIST *tlist;
3167 for (tlist = list; tlist; tlist = tlist->next)
3169 s = dequote_string (tlist->word->word);
3170 free (tlist->word->word);
3171 tlist->word->word = s;
3172 /* XXX - turn off W_HAVEQUOTEDNULL here? */
3177 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3180 remove_quoted_escapes (string)
3187 t = dequote_escapes (string);
3195 /* Perform quoted null character removal on STRING. We don't allow any
3196 quoted null characters in the middle or at the ends of strings because
3197 of how expand_word_internal works. remove_quoted_nulls () turns
3198 STRING into an empty string iff it only consists of a quoted null,
3199 and removes all unquoted CTLNUL characters. */
3201 remove_quoted_nulls (string)
3204 register size_t slen;
3205 register int i, j, prev_i;
3208 if (strchr (string, CTLNUL) == 0) /* XXX */
3209 return string; /* XXX */
3211 slen = strlen (string);
3216 if (string[i] == CTLESC)
3218 /* Old code had j++, but we cannot assume that i == j at this
3219 point -- what if a CTLNUL has already been removed from the
3220 string? We don't want to drop the CTLESC or recopy characters
3221 that we've already copied down. */
3222 i++; string[j++] = CTLESC;
3226 else if (string[i] == CTLNUL)
3230 ADVANCE_CHAR (string, slen, i);
3233 do string[j++] = string[prev_i++]; while (prev_i < i);
3243 /* Perform quoted null character removal on each element of LIST.
3244 This modifies LIST. */
3246 word_list_remove_quoted_nulls (list)
3249 register WORD_LIST *t;
3251 for (t = list; t; t = t->next)
3253 remove_quoted_nulls (t->word->word);
3254 t->word->flags &= ~W_HASQUOTEDNULL;
3258 /* **************************************************************** */
3260 /* Functions for Matching and Removing Patterns */
3262 /* **************************************************************** */
3264 #if defined (HANDLE_MULTIBYTE)
3265 #if 0 /* Currently unused */
3266 static unsigned char *
3267 mb_getcharlens (string, len)
3271 int i, offset, last;
3278 ret = (unsigned char *)xmalloc (len);
3279 memset (ret, 0, len);
3280 while (string[last])
3282 ADVANCE_CHAR (string, len, offset);
3283 ret[last] = offset - last;
3291 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3292 can have one of 4 values:
3293 RP_LONG_LEFT remove longest matching portion at start of PARAM
3294 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3295 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3296 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3299 #define RP_LONG_LEFT 1
3300 #define RP_SHORT_LEFT 2
3301 #define RP_LONG_RIGHT 3
3302 #define RP_SHORT_RIGHT 4
3305 remove_upattern (param, pattern, op)
3306 char *param, *pattern;
3311 register char *p, *ret, c;
3313 len = STRLEN (param);
3318 case RP_LONG_LEFT: /* remove longest match at start */
3319 for (p = end; p >= param; p--)
3322 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3325 return (savestring (p));
3332 case RP_SHORT_LEFT: /* remove shortest match at start */
3333 for (p = param; p <= end; p++)
3336 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3339 return (savestring (p));
3345 case RP_LONG_RIGHT: /* remove longest match at end */
3346 for (p = param; p <= end; p++)
3348 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3351 ret = savestring (param);
3358 case RP_SHORT_RIGHT: /* remove shortest match at end */
3359 for (p = end; p >= param; p--)
3361 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3364 ret = savestring (param);
3372 return (savestring (param)); /* no match, return original string */
3375 #if defined (HANDLE_MULTIBYTE)
3377 remove_wpattern (wparam, wstrlen, wpattern, op)
3388 case RP_LONG_LEFT: /* remove longest match at start */
3389 for (n = wstrlen; n >= 0; n--)
3391 wc = wparam[n]; wparam[n] = L'\0';
3392 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3395 return (wcsdup (wparam + n));
3401 case RP_SHORT_LEFT: /* remove shortest match at start */
3402 for (n = 0; n <= wstrlen; n++)
3404 wc = wparam[n]; wparam[n] = L'\0';
3405 if (wcsmatch (wpattern, wparam, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3408 return (wcsdup (wparam + n));
3414 case RP_LONG_RIGHT: /* remove longest match at end */
3415 for (n = 0; n <= wstrlen; n++)
3417 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3419 wc = wparam[n]; wparam[n] = L'\0';
3420 ret = wcsdup (wparam);
3427 case RP_SHORT_RIGHT: /* remove shortest match at end */
3428 for (n = wstrlen; n >= 0; n--)
3430 if (wcsmatch (wpattern, wparam + n, FNMATCH_EXTFLAG) != FNM_NOMATCH)
3432 wc = wparam[n]; wparam[n] = L'\0';
3433 ret = wcsdup (wparam);
3441 return (wcsdup (wparam)); /* no match, return original string */
3443 #endif /* HANDLE_MULTIBYTE */
3446 remove_pattern (param, pattern, op)
3447 char *param, *pattern;
3452 if (*param == '\0' || pattern == NULL || *pattern == '\0') /* minor optimization */
3453 return (savestring (param));
3455 #if defined (HANDLE_MULTIBYTE)
3458 wchar_t *ret, *oret;
3460 wchar_t *wparam, *wpattern;
3464 n = xdupmbstowcs (&wpattern, NULL, pattern);
3465 if (n == (size_t)-1)
3466 return (remove_upattern (param, pattern, op));
3467 n = xdupmbstowcs (&wparam, NULL, param);
3468 if (n == (size_t)-1)
3471 return (remove_upattern (param, pattern, op));
3473 oret = ret = remove_wpattern (wparam, n, wpattern, op);
3479 xret = (char *)xmalloc (n + 1);
3480 memset (&ps, '\0', sizeof (mbstate_t));
3481 n = wcsrtombs (xret, (const wchar_t **)&ret, n, &ps);
3482 xret[n] = '\0'; /* just to make sure */
3488 return (remove_upattern (param, pattern, op));
3491 /* Return 1 of the first character of STRING could match the first
3492 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3494 match_pattern_char (pat, string)
3505 return (*string == c);
3507 return (*string == *pat);
3509 return (*pat == LPAREN ? 1 : (*string != '\0'));
3515 return (*pat == LPAREN ? 1 : (*string == c));
3517 return (*string != '\0');
3521 /* Match PAT anywhere in STRING and return the match boundaries.
3522 This returns 1 in case of a successful match, 0 otherwise. SP
3523 and EP are pointers into the string where the match begins and
3524 ends, respectively. MTYPE controls what kind of match is attempted.
3525 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3526 of the string, respectively. The longest match is returned. */
3528 match_upattern (string, pat, mtype, sp, ep)
3534 register char *p, *p1, *npat;
3537 /* If the pattern doesn't match anywhere in the string, go ahead and
3538 short-circuit right away. A minor optimization, saves a bunch of
3539 unnecessary calls to strmatch (up to N calls for a string of N
3540 characters) if the match is unsuccessful. To preserve the semantics
3541 of the substring matches below, we make sure that the pattern has
3542 `*' as first and last character, making a new pattern if necessary. */
3543 /* XXX - check this later if I ever implement `**' with special meaning,
3544 since this will potentially result in `**' at the beginning or end */
3546 if (pat[0] != '*' || pat[len - 1] != '*')
3548 p = npat = (char *)xmalloc (len + 3);
3554 if (p1[-1] != '*' || p[-2] == '\\')
3560 c = strmatch (npat, string, FNMATCH_EXTFLAG);
3563 if (c == FNM_NOMATCH)
3566 len = STRLEN (string);
3572 for (p = string; p <= end; p++)
3574 if (match_pattern_char (pat, p))
3576 for (p1 = end; p1 >= p; p1--)
3578 c = *p1; *p1 = '\0';
3579 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3594 if (match_pattern_char (pat, string) == 0)
3597 for (p = end; p >= string; p--)
3600 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
3613 for (p = string; p <= end; p++)
3615 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
3630 #if defined (HANDLE_MULTIBYTE)
3631 /* Return 1 of the first character of WSTRING could match the first
3632 character of pattern WPAT. Wide character version. */
3634 match_pattern_wchar (wpat, wstring)
3635 wchar_t *wpat, *wstring;
3642 switch (wc = *wpat++)
3645 return (*wstring == wc);
3647 return (*wstring == *wpat);
3649 return (*wpat == LPAREN ? 1 : (*wstring != L'\0'));
3655 return (*wpat == LPAREN ? 1 : (*wstring == wc));
3657 return (*wstring != L'\0');
3661 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3662 This returns 1 in case of a successful match, 0 otherwise. Wide
3663 character version. */
3665 match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
3673 wchar_t wc, *wp, *nwpat, *wp1;
3676 size_t n, n1; /* Apple's gcc seems to miscompile this badly */
3681 /* If the pattern doesn't match anywhere in the string, go ahead and
3682 short-circuit right away. A minor optimization, saves a bunch of
3683 unnecessary calls to strmatch (up to N calls for a string of N
3684 characters) if the match is unsuccessful. To preserve the semantics
3685 of the substring matches below, we make sure that the pattern has
3686 `*' as first and last character, making a new pattern if necessary. */
3687 /* XXX - check this later if I ever implement `**' with special meaning,
3688 since this will potentially result in `**' at the beginning or end */
3689 len = wcslen (wpat);
3690 if (wpat[0] != L'*' || wpat[len - 1] != L'*')
3692 wp = nwpat = (wchar_t *)xmalloc ((len + 3) * sizeof (wchar_t));
3696 while (*wp1 != L'\0')
3698 if (wp1[-1] != L'*' || wp1[-2] == L'\\')
3704 len = wcsmatch (nwpat, wstring, FNMATCH_EXTFLAG);
3707 if (len == FNM_NOMATCH)
3713 for (n = 0; n <= wstrlen; n++)
3715 if (match_pattern_wchar (wpat, wstring + n))
3717 for (n1 = wstrlen; n1 >= n; n1--)
3719 wc = wstring[n1]; wstring[n1] = L'\0';
3720 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3735 if (match_pattern_wchar (wpat, wstring) == 0)
3738 for (n = wstrlen; n >= 0; n--)
3740 wc = wstring[n]; wstring[n] = L'\0';
3741 if (wcsmatch (wpat, wstring, FNMATCH_EXTFLAG) == 0)
3754 for (n = 0; n <= wstrlen; n++)
3756 if (wcsmatch (wpat, wstring + n, FNMATCH_EXTFLAG) == 0)
3759 *ep = indices[wstrlen];
3769 #endif /* HANDLE_MULTIBYTE */
3772 match_pattern (string, pat, mtype, sp, ep)
3777 #if defined (HANDLE_MULTIBYTE)
3780 wchar_t *wstring, *wpat;
3784 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
3787 #if defined (HANDLE_MULTIBYTE)
3790 n = xdupmbstowcs (&wpat, NULL, pat);
3791 if (n == (size_t)-1)
3792 return (match_upattern (string, pat, mtype, sp, ep));
3793 n = xdupmbstowcs (&wstring, &indices, string);
3794 if (n == (size_t)-1)
3797 return (match_upattern (string, pat, mtype, sp, ep));
3799 ret = match_wpattern (wstring, indices, n, wpat, mtype, sp, ep);
3809 return (match_upattern (string, pat, mtype, sp, ep));
3813 getpatspec (c, value)
3818 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
3820 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
3823 /* Posix.2 says that the WORD should be run through tilde expansion,
3824 parameter expansion, command substitution and arithmetic expansion.
3825 This leaves the result quoted, so quote_string_for_globbing () has
3826 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3827 it means that the entire expression was enclosed in double quotes.
3828 This means that quoting characters in the pattern do not make any
3829 special pattern characters quoted. For example, the `*' in the
3830 following retains its special meaning: "${foo#'*'}". */
3832 getpattern (value, quoted, expandpat)
3834 int quoted, expandpat;
3842 /* There is a problem here: how to handle single or double quotes in the
3843 pattern string when the whole expression is between double quotes?
3844 POSIX.2 says that enclosing double quotes do not cause the pattern to
3845 be quoted, but does that leave us a problem with @ and array[@] and their
3846 expansions inside a pattern? */
3848 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
3851 pat = string_extract_double_quoted (tword, &i, 1);
3857 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3859 l = *value ? expand_string_for_rhs (value,
3860 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_PATQUOTE : quoted,
3861 (int *)NULL, (int *)NULL)
3863 pat = string_list (l);
3867 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
3875 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3876 or ${name#[#]value}. */
3878 variable_remove_pattern (value, pattern, patspec, quoted)
3879 char *value, *pattern;
3880 int patspec, quoted;
3884 tword = remove_pattern (value, pattern, patspec);
3891 list_remove_pattern (list, pattern, patspec, itype, quoted)
3894 int patspec, itype, quoted;
3900 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
3902 tword = remove_pattern (l->word->word, pattern, patspec);
3903 w = alloc_word_desc ();
3904 w->word = tword ? tword : savestring ("");
3905 new = make_word_list (w, new);
3908 l = REVERSE_LIST (new, WORD_LIST *);
3910 tword = (quoted & Q_DOUBLE_QUOTES) ? string_list_dollar_star (l) : string_list (l);
3912 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
3919 parameter_list_remove_pattern (itype, pattern, patspec, quoted)
3922 int patspec, quoted;
3927 list = list_rest_of_args ();
3929 return ((char *)NULL);
3930 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3931 dispose_words (list);
3935 #if defined (ARRAY_VARS)
3937 array_remove_pattern (a, pattern, patspec, varname, quoted)
3941 char *varname; /* so we can figure out how it's indexed */
3949 /* compute itype from varname here */
3950 v = array_variable_part (varname, &ret, 0);
3953 list = array_to_word_list (a);
3955 return ((char *)NULL);
3956 ret = list_remove_pattern (list, pattern, patspec, itype, quoted);
3957 dispose_words (list);
3961 #endif /* ARRAY_VARS */
3964 parameter_brace_remove_pattern (varname, value, patstr, rtype, quoted)
3965 char *varname, *value, *patstr;
3968 int vtype, patspec, starsub;
3969 char *temp1, *val, *pattern;
3973 return ((char *)NULL);
3975 this_command_name = varname;
3977 vtype = get_var_and_type (varname, value, quoted, &v, &val);
3979 return ((char *)NULL);
3981 starsub = vtype & VT_STARSUB;
3982 vtype &= ~VT_STARSUB;
3984 patspec = getpatspec (rtype, patstr);
3985 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
3988 pattern = getpattern (patstr, quoted, 1);
3990 temp1 = (char *)NULL; /* shut up gcc */
3994 case VT_ARRAYMEMBER:
3995 temp1 = remove_pattern (val, pattern, patspec);
3996 if (vtype == VT_VARIABLE)
4000 val = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4001 ? quote_string (temp1)
4002 : quote_escapes (temp1);
4007 #if defined (ARRAY_VARS)
4009 temp1 = array_remove_pattern (array_cell (v), pattern, patspec, varname, quoted);
4010 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4012 val = quote_escapes (temp1);
4019 temp1 = parameter_list_remove_pattern (varname[0], pattern, patspec, quoted);
4020 if (temp1 && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
4022 val = quote_escapes (temp1);
4033 /*******************************************
4035 * Functions to expand WORD_DESCs *
4037 *******************************************/
4039 /* Expand WORD, performing word splitting on the result. This does
4040 parameter expansion, command substitution, arithmetic expansion,
4041 word splitting, and quote removal. */
4044 expand_word (word, quoted)
4048 WORD_LIST *result, *tresult;
4050 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4051 result = word_list_split (tresult);
4052 dispose_words (tresult);
4053 return (result ? dequote_list (result) : result);
4056 /* Expand WORD, but do not perform word splitting on the result. This
4057 does parameter expansion, command substitution, arithmetic expansion,
4058 and quote removal. */
4060 expand_word_unsplit (word, quoted)
4066 expand_no_split_dollar_star = 1;
4067 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
4068 expand_no_split_dollar_star = 0;
4070 return (result ? dequote_list (result) : result);
4073 /* Perform shell expansions on WORD, but do not perform word splitting or
4074 quote removal on the result. */
4076 expand_word_leave_quoted (word, quoted)
4080 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
4083 #if defined (PROCESS_SUBSTITUTION)
4085 /*****************************************************************/
4087 /* Hacking Process Substitution */
4089 /*****************************************************************/
4091 #if !defined (HAVE_DEV_FD)
4092 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4093 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4094 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4095 list. NFIFO is a count of the number of FIFOs in the list. */
4096 #define FIFO_INCR 20
4103 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
4105 static int fifo_list_size;
4108 add_fifo_list (pathname)
4111 if (nfifo >= fifo_list_size - 1)
4113 fifo_list_size += FIFO_INCR;
4114 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
4115 fifo_list_size * sizeof (struct temp_fifo));
4118 fifo_list[nfifo].file = savestring (pathname);
4130 for (i = saved = 0; i < nfifo; i++)
4132 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
4134 unlink (fifo_list[i].file);
4135 free (fifo_list[i].file);
4136 fifo_list[i].file = (char *)NULL;
4137 fifo_list[i].proc = -1;
4143 /* If we didn't remove some of the FIFOs, compact the list. */
4146 for (i = j = 0; i < nfifo; i++)
4147 if (fifo_list[i].file)
4149 fifo_list[j].file = fifo_list[i].file;
4150 fifo_list[j].proc = fifo_list[i].proc;
4170 tname = sh_mktmpname ("sh-np", MT_USERANDOM|MT_USETMPDIR);
4171 if (mkfifo (tname, 0600) < 0)
4174 return ((char *)NULL);
4177 add_fifo_list (tname);
4181 #else /* HAVE_DEV_FD */
4183 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4184 has open to children. NFDS is a count of the number of bits currently
4185 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4187 static char *dev_fd_list = (char *)NULL;
4189 static int totfds; /* The highest possible number of open files. */
4195 if (!dev_fd_list || fd >= totfds)
4200 totfds = getdtablesize ();
4201 if (totfds < 0 || totfds > 256)
4206 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
4207 memset (dev_fd_list + ofds, '\0', totfds - ofds);
4210 dev_fd_list[fd] = 1;
4217 return 0; /* used for cleanup; not needed with /dev/fd */
4228 for (i = 0; nfds && i < totfds; i++)
4239 #if defined (NOTDEF)
4240 print_dev_fd_list ()
4244 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
4247 for (i = 0; i < totfds; i++)
4250 fprintf (stderr, " %d", i);
4252 fprintf (stderr, "\n");
4257 make_dev_fd_filename (fd)
4260 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
4262 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 4);
4264 strcpy (ret, DEV_FD_PREFIX);
4265 p = inttostr (fd, intbuf, sizeof (intbuf));
4266 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
4272 #endif /* HAVE_DEV_FD */
4274 /* Return a filename that will open a connection to the process defined by
4275 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4276 a filename in /dev/fd corresponding to a descriptor that is one of the
4277 ends of the pipe. If not defined, we use named pipes on systems that have
4278 them. Systems without /dev/fd and named pipes are out of luck.
4280 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4281 use the read end of the pipe and dup that file descriptor to fd 0 in
4282 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4283 writing or use the write end of the pipe in the child, and dup that
4284 file descriptor to fd 1 in the child. The parent does the opposite. */
4287 process_substitute (string, open_for_read_in_child)
4289 int open_for_read_in_child;
4294 #if defined (HAVE_DEV_FD)
4295 int parent_pipe_fd, child_pipe_fd;
4297 #endif /* HAVE_DEV_FD */
4298 #if defined (JOB_CONTROL)
4299 pid_t old_pipeline_pgrp;
4302 if (!string || !*string || wordexp_only)
4303 return ((char *)NULL);
4305 #if !defined (HAVE_DEV_FD)
4306 pathname = make_named_pipe ();
4307 #else /* HAVE_DEV_FD */
4308 if (pipe (fildes) < 0)
4310 sys_error (_("cannot make pipe for process substitution"));
4311 return ((char *)NULL);
4313 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4314 the pipe in the parent, otherwise the read end. */
4315 parent_pipe_fd = fildes[open_for_read_in_child];
4316 child_pipe_fd = fildes[1 - open_for_read_in_child];
4317 /* Move the parent end of the pipe to some high file descriptor, to
4318 avoid clashes with FDs used by the script. */
4319 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
4321 pathname = make_dev_fd_filename (parent_pipe_fd);
4322 #endif /* HAVE_DEV_FD */
4326 sys_error (_("cannot make pipe for process substitution"));
4327 return ((char *)NULL);
4330 old_pid = last_made_pid;
4332 #if defined (JOB_CONTROL)
4333 old_pipeline_pgrp = pipeline_pgrp;
4334 pipeline_pgrp = shell_pgrp;
4336 #endif /* JOB_CONTROL */
4338 pid = make_child ((char *)NULL, 1);
4341 reset_terminating_signals (); /* XXX */
4342 free_pushed_string_input ();
4343 /* Cancel traps, in trap.c. */
4344 restore_original_signals ();
4345 setup_async_signals ();
4346 subshell_environment |= SUBSHELL_COMSUB|SUBSHELL_PROCSUB;
4349 #if defined (JOB_CONTROL)
4350 set_sigchld_handler ();
4351 stop_making_children ();
4352 pipeline_pgrp = old_pipeline_pgrp;
4353 #endif /* JOB_CONTROL */
4357 sys_error (_("cannot make child for process substitution"));
4359 #if defined (HAVE_DEV_FD)
4360 close (parent_pipe_fd);
4361 close (child_pipe_fd);
4362 #endif /* HAVE_DEV_FD */
4363 return ((char *)NULL);
4368 #if defined (JOB_CONTROL)
4369 restore_pipeline (1);
4372 #if !defined (HAVE_DEV_FD)
4373 fifo_list[nfifo-1].proc = pid;
4376 last_made_pid = old_pid;
4378 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4380 #endif /* JOB_CONTROL && PGRP_PIPE */
4382 #if defined (HAVE_DEV_FD)
4383 close (child_pipe_fd);
4384 #endif /* HAVE_DEV_FD */
4389 set_sigint_handler ();
4391 #if defined (JOB_CONTROL)
4392 set_job_control (0);
4393 #endif /* JOB_CONTROL */
4395 #if !defined (HAVE_DEV_FD)
4396 /* Open the named pipe in the child. */
4397 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
4400 /* Two separate strings for ease of translation. */
4401 if (open_for_read_in_child)
4402 sys_error (_("cannot open named pipe %s for reading"), pathname);
4404 sys_error (_("cannot open named pipe %s for writing"), pathname);
4408 if (open_for_read_in_child)
4410 if (sh_unset_nodelay_mode (fd) < 0)
4412 sys_error (_("cannot reset nodelay mode for fd %d"), fd);
4416 #else /* HAVE_DEV_FD */
4418 #endif /* HAVE_DEV_FD */
4420 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
4422 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname,
4423 open_for_read_in_child ? 0 : 1);
4427 if (fd != (open_for_read_in_child ? 0 : 1))
4430 /* Need to close any files that this process has open to pipes inherited
4432 if (current_fds_to_close)
4434 close_fd_bitmap (current_fds_to_close);
4435 current_fds_to_close = (struct fd_bitmap *)NULL;
4438 #if defined (HAVE_DEV_FD)
4439 /* Make sure we close the parent's end of the pipe and clear the slot
4440 in the fd list so it is not closed later, if reallocated by, for
4441 instance, pipe(2). */
4442 close (parent_pipe_fd);
4443 dev_fd_list[parent_pipe_fd] = 0;
4444 #endif /* HAVE_DEV_FD */
4446 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
4448 #if !defined (HAVE_DEV_FD)
4449 /* Make sure we close the named pipe in the child before we exit. */
4450 close (open_for_read_in_child ? 0 : 1);
4451 #endif /* !HAVE_DEV_FD */
4456 #endif /* PROCESS_SUBSTITUTION */
4458 /***********************************/
4460 /* Command Substitution */
4462 /***********************************/
4465 read_comsub (fd, quoted, rflag)
4469 char *istring, buf[128], *bufp;
4470 int istring_index, istring_size, c, tflag;
4473 istring = (char *)NULL;
4474 istring_index = istring_size = bufn = tflag = 0;
4477 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
4480 /* Read the output of the command through the pipe. This may need to be
4481 changed to understand multibyte characters in the future. */
4488 bufn = zread (fd, buf, sizeof (buf));
4498 internal_warning ("read_comsub: ignored null byte in input");
4503 /* Add the character to ISTRING, possibly after resizing it. */
4504 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
4506 /* This is essentially quote_string inline */
4507 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) /* || c == CTLESC || c == CTLNUL */)
4508 istring[istring_index++] = CTLESC;
4509 /* Escape CTLESC and CTLNUL in the output to protect those characters
4510 from the rest of the word expansions (word splitting and globbing.)
4511 This is essentially quote_escapes inline. */
4512 else if (c == CTLESC)
4514 tflag |= W_HASCTLESC;
4515 istring[istring_index++] = CTLESC;
4517 else if (c == CTLNUL || (c == ' ' && (ifs_value && *ifs_value == 0)))
4518 istring[istring_index++] = CTLESC;
4520 istring[istring_index++] = c;
4523 #if defined (__CYGWIN__)
4524 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
4527 istring[istring_index - 1] = '\n';
4534 istring[istring_index] = '\0';
4536 /* If we read no output, just return now and save ourselves some
4538 if (istring_index == 0)
4543 return (char *)NULL;
4546 /* Strip trailing newlines from the output of the command. */
4547 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4549 while (istring_index > 0)
4551 if (istring[istring_index - 1] == '\n')
4555 /* If the newline was quoted, remove the quoting char. */
4556 if (istring[istring_index - 1] == CTLESC)
4562 istring[istring_index] = '\0';
4565 strip_trailing (istring, istring_index - 1, 1);
4572 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
4573 contained string possibly quoted. */
4575 command_substitute (string, quoted)
4579 pid_t pid, old_pid, old_pipeline_pgrp, old_async_pid;
4581 int result, fildes[2], function_value, pflags, rc, tflag;
4584 istring = (char *)NULL;
4586 /* Don't fork () if there is no need to. In the case of no command to
4587 run, just return NULL. */
4588 if (!string || !*string || (string[0] == '\n' && !string[1]))
4589 return ((WORD_DESC *)NULL);
4591 if (wordexp_only && read_but_dont_execute)
4593 last_command_exit_value = 125;
4594 jump_to_top_level (EXITPROG);
4597 /* We're making the assumption here that the command substitution will
4598 eventually run a command from the file system. Since we'll run
4599 maybe_make_export_env in this subshell before executing that command,
4600 the parent shell and any other shells it starts will have to remake
4601 the environment. If we make it before we fork, other shells won't
4602 have to. Don't bother if we have any temporary variable assignments,
4603 though, because the export environment will be remade after this
4604 command completes anyway, but do it if all the words to be expanded
4605 are variable assignments. */
4606 if (subst_assign_varlist == 0 || garglist == 0)
4607 maybe_make_export_env (); /* XXX */
4609 /* Flags to pass to parse_and_execute() */
4610 pflags = interactive ? SEVAL_RESETLINE : 0;
4612 /* Pipe the output of executing STRING into the current shell. */
4613 if (pipe (fildes) < 0)
4615 sys_error (_("cannot make pipe for command substitution"));
4619 old_pid = last_made_pid;
4620 #if defined (JOB_CONTROL)
4621 old_pipeline_pgrp = pipeline_pgrp;
4622 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4623 if ((subshell_environment & SUBSHELL_PIPE) == 0)
4624 pipeline_pgrp = shell_pgrp;
4625 cleanup_the_pipeline ();
4626 #endif /* JOB_CONTROL */
4628 old_async_pid = last_asynchronous_pid;
4629 pid = make_child ((char *)NULL, subshell_environment&SUBSHELL_ASYNC);
4630 last_asynchronous_pid = old_async_pid;
4633 /* Reset the signal handlers in the child, but don't free the
4635 reset_signal_handlers ();
4637 #if defined (JOB_CONTROL)
4638 set_sigchld_handler ();
4639 stop_making_children ();
4640 pipeline_pgrp = old_pipeline_pgrp;
4642 stop_making_children ();
4643 #endif /* JOB_CONTROL */
4647 sys_error (_("cannot make child for command substitution"));
4653 return ((WORD_DESC *)NULL);
4658 set_sigint_handler (); /* XXX */
4660 free_pushed_string_input ();
4662 if (dup2 (fildes[1], 1) < 0)
4664 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4665 exit (EXECUTION_FAILURE);
4668 /* If standard output is closed in the parent shell
4669 (such as after `exec >&-'), file descriptor 1 will be
4670 the lowest available file descriptor, and end up in
4671 fildes[0]. This can happen for stdin and stderr as well,
4672 but stdout is more important -- it will cause no output
4673 to be generated from this command. */
4674 if ((fildes[1] != fileno (stdin)) &&
4675 (fildes[1] != fileno (stdout)) &&
4676 (fildes[1] != fileno (stderr)))
4679 if ((fildes[0] != fileno (stdin)) &&
4680 (fildes[0] != fileno (stdout)) &&
4681 (fildes[0] != fileno (stderr)))
4684 /* The currently executing shell is not interactive. */
4687 /* This is a subshell environment. */
4688 subshell_environment |= SUBSHELL_COMSUB;
4690 /* When not in POSIX mode, command substitution does not inherit
4692 if (posixly_correct == 0)
4693 exit_immediately_on_error = 0;
4695 remove_quoted_escapes (string);
4697 startup_state = 2; /* see if we can avoid a fork */
4698 /* Give command substitution a place to jump back to on failure,
4699 so we don't go back up to main (). */
4700 result = setjmp (top_level);
4702 /* If we're running a command substitution inside a shell function,
4703 trap `return' so we don't return from the function in the subshell
4704 and go off to never-never land. */
4705 if (result == 0 && return_catch_flag)
4706 function_value = setjmp (return_catch);
4710 if (result == ERREXIT)
4711 rc = last_command_exit_value;
4712 else if (result == EXITPROG)
4713 rc = last_command_exit_value;
4715 rc = EXECUTION_FAILURE;
4716 else if (function_value)
4717 rc = return_catch_value;
4721 rc = parse_and_execute (string, "command substitution", pflags|SEVAL_NOHIST);
4725 last_command_exit_value = rc;
4726 rc = run_exit_trap ();
4727 #if defined (PROCESS_SUBSTITUTION)
4728 unlink_fifo_list ();
4734 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4736 #endif /* JOB_CONTROL && PGRP_PIPE */
4741 istring = read_comsub (fildes[0], quoted, &tflag);
4745 current_command_subst_pid = pid;
4746 last_command_exit_value = wait_for (pid);
4747 last_command_subst_pid = pid;
4748 last_made_pid = old_pid;
4750 #if defined (JOB_CONTROL)
4751 /* If last_command_exit_value > 128, then the substituted command
4752 was terminated by a signal. If that signal was SIGINT, then send
4753 SIGINT to ourselves. This will break out of loops, for instance. */
4754 if (last_command_exit_value == (128 + SIGINT) && last_command_exit_signal == SIGINT)
4755 kill (getpid (), SIGINT);
4757 /* wait_for gives the terminal back to shell_pgrp. If some other
4758 process group should have it, give it away to that group here.
4759 pipeline_pgrp is non-zero only while we are constructing a
4760 pipline, so what we are concerned about is whether or not that
4761 pipeline was started in the background. A pipeline started in
4762 the background should never get the tty back here. */
4764 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
4766 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
4768 give_terminal_to (pipeline_pgrp, 0);
4769 #endif /* JOB_CONTROL */
4771 ret = alloc_word_desc ();
4772 ret->word = istring;
4779 /********************************************************
4781 * Utility functions for parameter expansion *
4783 ********************************************************/
4785 #if defined (ARRAY_VARS)
4788 array_length_reference (s)
4797 var = array_variable_part (s, &t, &len);
4799 /* If unbound variables should generate an error, report one and return
4801 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
4812 /* We support a couple of expansions for variables that are not arrays.
4813 We'll return the length of the value for v[0], and 1 for v[@] or
4814 v[*]. Return 0 for everything else. */
4816 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
4818 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
4819 return (array_p (var) ? array_num_elements (array) : 1);
4821 ind = array_expand_index (t, len);
4824 err_badarraysub (t);
4829 t = array_reference (array, ind);
4831 t = (ind == 0) ? value_cell (var) : (char *)NULL;
4836 #endif /* ARRAY_VARS */
4839 valid_brace_expansion_word (name, var_is_special)
4843 if (DIGIT (*name) && all_digits (name))
4845 else if (var_is_special)
4847 #if defined (ARRAY_VARS)
4848 else if (valid_array_reference (name))
4850 #endif /* ARRAY_VARS */
4851 else if (legal_identifier (name))
4858 chk_atstar (name, quoted, quoted_dollar_atp, contains_dollar_at)
4861 int *quoted_dollar_atp, *contains_dollar_at;
4867 if (quoted_dollar_atp)
4868 *quoted_dollar_atp = 0;
4869 if (contains_dollar_at)
4870 *contains_dollar_at = 0;
4874 /* check for $@ and $* */
4875 if (name[0] == '@' && name[1] == 0)
4877 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4878 *quoted_dollar_atp = 1;
4879 if (contains_dollar_at)
4880 *contains_dollar_at = 1;
4883 else if (name[0] == '*' && name[1] == '\0' && quoted == 0)
4885 if (contains_dollar_at)
4886 *contains_dollar_at = 1;
4890 /* Now check for ${array[@]} and ${array[*]} */
4891 #if defined (ARRAY_VARS)
4892 else if (valid_array_reference (name))
4894 temp1 = xstrchr (name, '[');
4895 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4897 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4898 *quoted_dollar_atp = 1;
4899 if (contains_dollar_at)
4900 *contains_dollar_at = 1;
4903 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4904 which should result in separate words even when IFS is unset. */
4905 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4907 if (contains_dollar_at)
4908 *contains_dollar_at = 1;
4916 /* Parameter expand NAME, and return a new string which is the expansion,
4917 or NULL if there was no expansion.
4918 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4919 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4920 NAME was found inside of a double-quoted expression. */
4922 parameter_brace_expand_word (name, var_is_special, quoted)
4924 int var_is_special, quoted;
4935 /* Handle multiple digit arguments, as in ${11}. */
4936 if (legal_number (name, &arg_index))
4938 tt = get_dollar_var_value (arg_index);
4940 temp = (*tt && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4942 : quote_escapes (tt);
4944 temp = (char *)NULL;
4947 else if (var_is_special) /* ${@} */
4950 tt = (char *)xmalloc (2 + strlen (name));
4951 tt[sindex = 0] = '$';
4952 strcpy (tt + 1, name);
4954 ret = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
4955 (int *)NULL, (int *)NULL, 0);
4958 #if defined (ARRAY_VARS)
4959 else if (valid_array_reference (name))
4961 temp = array_value (name, quoted, &atype);
4962 if (atype == 0 && temp)
4963 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4964 ? quote_string (temp)
4965 : quote_escapes (temp);
4968 else if (var = find_variable (name))
4970 if (var_isset (var) && invisible_p (var) == 0)
4972 #if defined (ARRAY_VARS)
4973 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
4975 temp = value_cell (var);
4979 temp = (*temp && (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
4980 ? quote_string (temp)
4981 : quote_escapes (temp);
4984 temp = (char *)NULL;
4987 temp = (char *)NULL;
4991 ret = alloc_word_desc ();
4997 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4998 value of the variable whose name is the value of NAME. */
5000 parameter_brace_expand_indir (name, var_is_special, quoted, quoted_dollar_atp, contains_dollar_at)
5002 int var_is_special, quoted;
5003 int *quoted_dollar_atp, *contains_dollar_at;
5008 w = parameter_brace_expand_word (name, var_is_special, quoted);
5010 /* Have to dequote here if necessary */
5013 temp = (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5014 ? dequote_string (t)
5015 : dequote_escapes (t);
5019 dispose_word_desc (w);
5021 chk_atstar (t, quoted, quoted_dollar_atp, contains_dollar_at);
5023 return (WORD_DESC *)NULL;
5025 w = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
5031 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5032 depending on the value of C, the separating character. C can be one of
5033 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5034 between double quotes. */
5036 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
5038 int c, quoted, *qdollaratp, *hasdollarat;
5042 char *t, *t1, *temp;
5045 /* If the entire expression is between double quotes, we want to treat
5046 the value as a double-quoted string, with the exception that we strip
5047 embedded unescaped double quotes (for sh backwards compatibility). */
5048 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *value)
5051 temp = string_extract_double_quoted (value, &hasdol, 1);
5056 w = alloc_word_desc ();
5058 /* XXX was 0 not quoted */
5059 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
5062 *hasdollarat = hasdol || (l && l->next);
5067 /* The expansion of TEMP returned something. We need to treat things
5068 slightly differently if HASDOL is non-zero. If we have "$@", the
5069 individual words have already been quoted. We need to turn them
5070 into a string with the words separated by the first character of
5071 $IFS without any additional quoting, so string_list_dollar_at won't
5072 do the right thing. We use string_list_dollar_star instead. */
5073 temp = (hasdol || l->next) ? string_list_dollar_star (l) : string_list (l);
5075 /* If l->next is not null, we know that TEMP contained "$@", since that
5076 is the only expansion that creates more than one word. */
5077 if (qdollaratp && ((hasdol && quoted) || l->next))
5081 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
5083 /* The brace expansion occurred between double quotes and there was
5084 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5085 it does not expand to anything. In this case, we want to return
5086 a quoted empty string. */
5087 temp = make_quoted_char ('\0');
5088 w->flags |= W_HASQUOTEDNULL;
5091 temp = (char *)NULL;
5093 if (c == '-' || c == '+')
5100 t = temp ? savestring (temp) : savestring ("");
5101 t1 = dequote_string (t);
5103 #if defined (ARRAY_VARS)
5104 if (valid_array_reference (name))
5105 assign_array_element (name, t1, 0);
5107 #endif /* ARRAY_VARS */
5108 bind_variable (name, t1, 0);
5115 /* Deal with the right hand side of a ${name:?value} expansion in the case
5116 that NAME is null or not set. If VALUE is non-null it is expanded and
5117 used as the error message to print, otherwise a standard message is
5120 parameter_brace_expand_error (name, value)
5126 if (value && *value)
5128 l = expand_string (value, 0);
5129 temp = string_list (l);
5130 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
5135 report_error (_("%s: parameter null or not set"), name);
5137 /* Free the data we have allocated during this expansion, since we
5138 are about to longjmp out. */
5143 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5146 valid_length_expression (name)
5149 return (name[1] == '\0' || /* ${#} */
5150 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
5151 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
5152 #if defined (ARRAY_VARS)
5153 valid_array_reference (name + 1) || /* ${#a[7]} */
5155 legal_identifier (name + 1)); /* ${#PS1} */
5158 #if defined (HANDLE_MULTIBYTE)
5164 mbstate_t mbs, mbsbak;
5167 memset (&mbs, 0, sizeof (mbs));
5169 while ((clen = mbrlen(s, MB_CUR_MAX, &mbs)) != 0)
5171 if (MB_INVALIDCH(clen))
5173 clen = 1; /* assume single byte */
5186 /* Handle the parameter brace expansion that requires us to return the
5187 length of a parameter. */
5189 parameter_brace_expand_length (name)
5193 intmax_t number, arg_index;
5195 #if defined (ARRAY_VARS)
5199 if (name[1] == '\0') /* ${#} */
5200 number = number_of_args ();
5201 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
5202 number = number_of_args ();
5203 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
5205 /* Take the lengths of some of the shell's special parameters. */
5209 t = which_set_flags ();
5212 t = itos (last_command_exit_value);
5215 t = itos (dollar_dollar_pid);
5218 if (last_asynchronous_pid == NO_PID)
5221 t = itos (last_asynchronous_pid);
5224 t = itos (number_of_args ());
5227 number = STRLEN (t);
5230 #if defined (ARRAY_VARS)
5231 else if (valid_array_reference (name + 1))
5232 number = array_length_reference (name + 1);
5233 #endif /* ARRAY_VARS */
5238 if (legal_number (name + 1, &arg_index)) /* ${#1} */
5240 t = get_dollar_var_value (arg_index);
5241 number = MB_STRLEN (t);
5244 #if defined (ARRAY_VARS)
5245 else if ((var = find_variable (name + 1)) && (invisible_p (var) == 0) && array_p (var))
5247 t = array_reference (array_cell (var), 0);
5248 number = MB_STRLEN (t);
5253 newname = savestring (name);
5255 list = expand_string (newname, Q_DOUBLE_QUOTES);
5256 t = list ? string_list (list) : (char *)NULL;
5259 dispose_words (list);
5261 number = MB_STRLEN (t);
5269 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5270 so we do some ad-hoc parsing of an arithmetic expression to find
5271 the first DELIM, instead of using strchr(3). Two rules:
5272 1. If the substring contains a `(', read until closing `)'.
5273 2. If the substring contains a `?', read past one `:' for each `?'.
5277 skiparith (substr, delim)
5282 int skipcol, pcount, i;
5285 sublen = strlen (substr);
5286 i = skipcol = pcount = 0;
5289 /* Balance parens */
5290 if (substr[i] == LPAREN)
5296 if (substr[i] == RPAREN && pcount)
5304 ADVANCE_CHAR (substr, sublen, i);
5308 /* Skip one `:' for each `?' */
5309 if (substr[i] == ':' && skipcol)
5315 if (substr[i] == delim)
5317 if (substr[i] == '?')
5323 ADVANCE_CHAR (substr, sublen, i);
5326 return (substr + i);
5329 /* Verify and limit the start and end of the desired substring. If
5330 VTYPE == 0, a regular shell variable is being used; if it is 1,
5331 then the positional parameters are being used; if it is 2, then
5332 VALUE is really a pointer to an array variable that should be used.
5333 Return value is 1 if both values were OK, 0 if there was a problem
5334 with an invalid expression, or -1 if the values were out of range. */
5336 verify_substring_values (value, substr, vtype, e1p, e2p)
5337 char *value, *substr;
5339 intmax_t *e1p, *e2p;
5341 char *t, *temp1, *temp2;
5344 #if defined (ARRAY_VARS)
5348 /* duplicate behavior of strchr(3) */
5349 t = skiparith (substr, ':');
5350 if (*t && *t == ':')
5355 temp1 = expand_arith_string (substr, Q_DOUBLE_QUOTES);
5356 *e1p = evalexp (temp1, &expok);
5361 len = -1; /* paranoia */
5365 case VT_ARRAYMEMBER:
5366 len = MB_STRLEN (value);
5369 len = number_of_args () + 1;
5371 len++; /* add one arg if counting from $0 */
5373 #if defined (ARRAY_VARS)
5376 /* For arrays, the first value deals with array indices. Negative
5377 offsets count from one past the array's maximum index. */
5378 len = array_max_index (a) + (*e1p < 0); /* arrays index from 0 to n - 1 */
5383 if (len == -1) /* paranoia */
5386 if (*e1p < 0) /* negative offsets count from end */
5389 if (*e1p > len || *e1p < 0)
5392 #if defined (ARRAY_VARS)
5393 /* For arrays, the second offset deals with the number of elements. */
5394 if (vtype == VT_ARRAYVAR)
5395 len = array_num_elements (a);
5401 temp2 = savestring (t);
5402 temp1 = expand_arith_string (temp2, Q_DOUBLE_QUOTES);
5405 *e2p = evalexp (temp1, &expok);
5411 internal_error (_("%s: substring expression < 0"), t);
5414 #if defined (ARRAY_VARS)
5415 /* In order to deal with sparse arrays, push the intelligence about how
5416 to deal with the number of elements desired down to the array-
5417 specific functions. */
5418 if (vtype != VT_ARRAYVAR)
5421 *e2p += *e1p; /* want E2 chars starting at E1 */
5432 /* Return the type of variable specified by VARNAME (simple variable,
5433 positional param, or array variable). Also return the value specified
5434 by VARNAME (value of a variable or a reference to an array element).
5435 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5436 characters in the value are quoted with CTLESC and takes appropriate
5437 steps. For convenience, *VALP is set to the dequoted VALUE. */
5439 get_var_and_type (varname, value, quoted, varp, valp)
5440 char *varname, *value;
5447 #if defined (ARRAY_VARS)
5451 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5452 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0';
5453 if (vtype == VT_POSPARMS && varname[0] == '*')
5454 vtype |= VT_STARSUB;
5455 *varp = (SHELL_VAR *)NULL;
5457 #if defined (ARRAY_VARS)
5458 if (valid_array_reference (varname))
5460 v = array_variable_part (varname, &temp, (int *)0);
5461 if (v && array_p (v))
5463 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
5465 vtype = VT_ARRAYVAR;
5467 vtype |= VT_STARSUB;
5468 *valp = (char *)array_cell (v);
5472 vtype = VT_ARRAYMEMBER;
5473 *valp = array_value (varname, 1, (int *)NULL);
5477 else if (v && (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']'))
5479 vtype = VT_VARIABLE;
5481 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5482 *valp = dequote_string (value);
5484 *valp = dequote_escapes (value);
5489 else if ((v = find_variable (varname)) && (invisible_p (v) == 0) && array_p (v))
5491 vtype = VT_ARRAYMEMBER;
5493 *valp = array_reference (array_cell (v), 0);
5498 if (value && vtype == VT_VARIABLE)
5500 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5501 *valp = dequote_string (value);
5503 *valp = dequote_escapes (value);
5512 /******************************************************/
5514 /* Functions to extract substrings of variable values */
5516 /******************************************************/
5518 #if defined (HANDLE_MULTIBYTE)
5519 /* Character-oriented rather than strictly byte-oriented substrings. S and
5520 E, rather being strict indices into STRING, indicate character (possibly
5521 multibyte character) positions that require calculation.
5522 Used by the ${param:offset[:length]} expansion. */
5524 mb_substring (string, s, e)
5529 int start, stop, i, slen;
5533 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5534 slen = (MB_CUR_MAX > 1) ? STRLEN (string) : 0;
5537 while (string[start] && i--)
5538 ADVANCE_CHAR (string, slen, start);
5541 while (string[stop] && i--)
5542 ADVANCE_CHAR (string, slen, stop);
5543 tt = substring (string, start, stop);
5548 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5549 is `@', use the positional parameters; otherwise, use the value of
5550 VARNAME. If VARNAME is an array variable, use the array elements. */
5553 parameter_brace_substring (varname, value, substr, quoted)
5554 char *varname, *value, *substr;
5558 int vtype, r, starsub;
5559 char *temp, *val, *tt, *oname;
5563 return ((char *)NULL);
5565 oname = this_command_name;
5566 this_command_name = varname;
5568 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5571 this_command_name = oname;
5572 return ((char *)NULL);
5575 starsub = vtype & VT_STARSUB;
5576 vtype &= ~VT_STARSUB;
5578 r = verify_substring_values (val, substr, vtype, &e1, &e2);
5579 this_command_name = oname;
5581 return ((r == 0) ? &expand_param_error : (char *)NULL);
5586 case VT_ARRAYMEMBER:
5587 #if defined (HANDLE_MULTIBYTE)
5589 tt = mb_substring (val, e1, e2);
5592 tt = substring (val, e1, e2);
5594 if (vtype == VT_VARIABLE)
5596 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
5597 temp = quote_string (tt);
5599 temp = tt ? quote_escapes (tt) : (char *)NULL;
5603 tt = pos_params (varname, e1, e2, quoted);
5604 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) == 0)
5606 temp = tt ? quote_escapes (tt) : (char *)NULL;
5612 #if defined (ARRAY_VARS)
5614 /* We want E2 to be the number of elements desired (arrays can be sparse,
5615 so verify_substring_values just returns the numbers specified and we
5616 rely on array_subrange to understand how to deal with them). */
5617 temp = array_subrange (array_cell (v), e1, e2, starsub, quoted);
5618 /* array_subrange now calls array_quote_escapes as appropriate, so the
5619 caller no longer needs to. */
5623 temp = (char *)NULL;
5629 /****************************************************************/
5631 /* Functions to perform pattern substitution on variable values */
5633 /****************************************************************/
5636 pat_subst (string, pat, rep, mflags)
5637 char *string, *pat, *rep;
5640 char *ret, *s, *e, *str;
5641 int rsize, rptr, l, replen, mtype;
5643 mtype = mflags & MATCH_TYPEMASK;
5646 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5647 * with REP and return the result.
5648 * 2. A null pattern with mtype == MATCH_END means to append REP to
5649 * STRING and return the result.
5651 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
5653 replen = STRLEN (rep);
5654 l = strlen (string);
5655 ret = (char *)xmalloc (replen + l + 2);
5657 strcpy (ret, string);
5658 else if (mtype == MATCH_BEG)
5661 strcpy (ret + replen, string);
5665 strcpy (ret, string);
5666 strcpy (ret + l, rep);
5671 ret = (char *)xmalloc (rsize = 64);
5674 for (replen = STRLEN (rep), rptr = 0, str = string;;)
5676 if (match_pattern (str, pat, mtype, &s, &e) == 0)
5679 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
5681 /* OK, now copy the leading unmatched portion of the string (from
5682 str to s) to ret starting at rptr (the current offset). Then copy
5683 the replacement string at ret + rptr + (s - str). Increment
5684 rptr (if necessary) and str and go on. */
5687 strncpy (ret + rptr, str, l);
5692 strncpy (ret + rptr, rep, replen);
5695 str = e; /* e == end of match */
5697 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
5701 e++, str++; /* avoid infinite recursion on zero-length match */
5704 /* Now copy the unmatched portion of the input string */
5707 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
5708 strcpy (ret + rptr, str);
5716 /* Do pattern match and replacement on the positional parameters. */
5718 pos_params_pat_subst (string, pat, rep, mflags)
5719 char *string, *pat, *rep;
5722 WORD_LIST *save, *params;
5726 save = params = list_rest_of_args ();
5728 return ((char *)NULL);
5730 for ( ; params; params = params->next)
5732 ret = pat_subst (params->word->word, pat, rep, mflags);
5733 w = alloc_word_desc ();
5734 w->word = ret ? ret : savestring ("");
5735 dispose_word (params->word);
5739 if ((mflags & (MATCH_QUOTED|MATCH_STARSUB)) == (MATCH_QUOTED|MATCH_STARSUB))
5740 ret = string_list_dollar_star (quote_list (save));
5742 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
5743 dispose_words (save);
5748 /* Perform pattern substitution on VALUE, which is the expansion of
5749 VARNAME. PATSUB is an expression supplying the pattern to match
5750 and the string to substitute. QUOTED is a flags word containing
5751 the type of quoting currently in effect. */
5753 parameter_brace_patsub (varname, value, patsub, quoted)
5754 char *varname, *value, *patsub;
5757 int vtype, mflags, starsub;
5758 char *val, *temp, *pat, *rep, *p, *lpatsub, *tt;
5762 return ((char *)NULL);
5764 this_command_name = varname;
5766 vtype = get_var_and_type (varname, value, quoted, &v, &val);
5768 return ((char *)NULL);
5770 starsub = vtype & VT_STARSUB;
5771 vtype &= ~VT_STARSUB;
5774 if (patsub && *patsub == '/')
5776 mflags |= MATCH_GLOBREP;
5780 /* Malloc this because expand_string_if_necessary or one of the expansion
5781 functions in its call chain may free it on a substitution error. */
5782 lpatsub = savestring (patsub);
5784 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5785 mflags |= MATCH_QUOTED;
5788 mflags |= MATCH_STARSUB;
5790 /* If the pattern starts with a `/', make sure we skip over it when looking
5791 for the replacement delimiter. */
5792 if (rep = quoted_strchr ((*patsub == '/') ? lpatsub+1 : lpatsub, '/', ST_BACKSL))
5797 if (rep && *rep == '\0')
5800 /* Perform the same expansions on the pattern as performed by the
5801 pattern removal expansions. */
5802 pat = getpattern (lpatsub, quoted, 1);
5806 if ((mflags & MATCH_QUOTED) == 0)
5807 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
5809 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
5812 /* ksh93 doesn't allow the match specifier to be a part of the expanded
5813 pattern. This is an extension. Make sure we don't anchor the pattern
5814 at the beginning or end of the string if we're doing global replacement,
5817 if (mflags & MATCH_GLOBREP)
5818 mflags |= MATCH_ANY;
5819 else if (pat && pat[0] == '#')
5821 mflags |= MATCH_BEG;
5824 else if (pat && pat[0] == '%')
5826 mflags |= MATCH_END;
5830 mflags |= MATCH_ANY;
5832 /* OK, we now want to substitute REP for PAT in VAL. If
5833 flags & MATCH_GLOBREP is non-zero, the substitution is done
5834 everywhere, otherwise only the first occurrence of PAT is
5835 replaced. The pattern matching code doesn't understand
5836 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5837 values passed in (VT_VARIABLE) so the pattern substitution
5838 code works right. We need to requote special chars after
5839 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5840 other cases if QUOTED == 0, since the posparams and arrays
5841 indexed by * or @ do special things when QUOTED != 0. */
5846 case VT_ARRAYMEMBER:
5847 temp = pat_subst (val, p, rep, mflags);
5848 if (vtype == VT_VARIABLE)
5852 tt = (mflags & MATCH_QUOTED) ? quote_string (temp) : quote_escapes (temp);
5858 temp = pos_params_pat_subst (val, p, rep, mflags);
5859 if (temp && (mflags & MATCH_QUOTED) == 0)
5861 tt = quote_escapes (temp);
5866 #if defined (ARRAY_VARS)
5868 temp = array_patsub (array_cell (v), p, rep, mflags);
5869 /* Don't call quote_escapes anymore; array_patsub calls
5870 array_quote_escapes as appropriate before adding the
5871 space separators. */
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);
6635 tdesc = command_substitute (temp, quoted);
6636 temp1 = tdesc ? tdesc->word : (char *)NULL;
6637 dispose_word_desc (tdesc);
6643 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6644 away in a future bash release. */
6646 /* Extract the contents of this arithmetic substitution. */
6647 t_index = zindex + 1;
6648 temp = extract_arithmetic_subst (string, &t_index);
6651 /* Do initial variable expansion. */
6652 temp1 = expand_arith_string (temp, Q_DOUBLE_QUOTES);
6657 /* Find the variable in VARIABLE_LIST. */
6658 temp = (char *)NULL;
6660 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
6662 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
6664 /* If this isn't a variable name, then just output the `$'. */
6665 if (temp1 == 0 || *temp1 == '\0')
6668 temp = (char *)xmalloc (2);
6671 if (expanded_something)
6672 *expanded_something = 0;
6676 /* If the variable exists, return its value cell. */
6677 var = find_variable (temp1);
6679 if (var && invisible_p (var) == 0 && var_isset (var))
6681 #if defined (ARRAY_VARS)
6684 temp = array_reference (array_cell (var), 0);
6686 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6687 ? quote_string (temp)
6688 : quote_escapes (temp);
6689 else if (unbound_vars_is_error)
6690 goto unbound_variable;
6695 temp = value_cell (var);
6697 temp = (*temp && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
6698 ? quote_string (temp)
6699 : quote_escapes (temp);
6707 temp = (char *)NULL;
6710 if (unbound_vars_is_error)
6711 err_unboundvar (temp1);
6719 last_command_exit_value = EXECUTION_FAILURE;
6720 return ((unbound_vars_is_error && interactive_shell == 0)
6721 ? &expand_wdesc_fatal
6722 : &expand_wdesc_error);
6733 ret = alloc_word_desc ();
6734 ret->flags = tflag; /* XXX */
6740 /* Make a word list which is the result of parameter and variable
6741 expansion, command substitution, arithmetic substitution, and
6742 quote removal of WORD. Return a pointer to a WORD_LIST which is
6743 the result of the expansion. If WORD contains a null word, the
6744 word list returned is also null.
6746 QUOTED contains flag values defined in shell.h.
6748 ISEXP is used to tell expand_word_internal that the word should be
6749 treated as the result of an expansion. This has implications for
6750 how IFS characters in the word are treated.
6752 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6753 they point to an integer value which receives information about expansion.
6754 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6755 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6758 This only does word splitting in the case of $@ expansion. In that
6759 case, we split on ' '. */
6761 /* Values for the local variable quoted_state. */
6763 #define PARTIALLY_QUOTED 1
6764 #define WHOLLY_QUOTED 2
6767 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
6770 int *contains_dollar_at;
6771 int *expanded_something;
6776 /* The intermediate string that we build while expanding. */
6779 /* The current size of the above object. */
6782 /* Index into ISTRING. */
6785 /* Temporary string storage. */
6788 /* The text of WORD. */
6789 register char *string;
6791 /* The size of STRING. */
6794 /* The index into STRING. */
6797 /* This gets 1 if we see a $@ while quoted. */
6798 int quoted_dollar_at;
6800 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6801 whether WORD contains no quoting characters, a partially quoted
6802 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6806 int had_quoted_null;
6810 int assignoff; /* If assignment, offset of `=' */
6812 register unsigned char c; /* Current character. */
6813 int t_index; /* For calls to string_extract_xxx. */
6819 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
6820 istring[istring_index = 0] = '\0';
6821 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
6822 quoted_state = UNQUOTED;
6824 string = word->word;
6826 goto finished_with_string;
6827 /* Don't need the string length for the SADD... and COPY_ macros unless
6828 multibyte characters are possible. */
6829 string_size = (MB_CUR_MAX > 1) ? strlen (string) : 1;
6831 if (contains_dollar_at)
6832 *contains_dollar_at = 0;
6836 /* Begin the expansion. */
6842 /* Case on toplevel character. */
6846 goto finished_with_string;
6850 #if HANDLE_MULTIBYTE
6851 if (MB_CUR_MAX > 1 && string[sindex])
6853 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
6858 temp = (char *)xmalloc (3);
6860 temp[1] = c = string[sindex];
6871 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
6877 #if defined (PROCESS_SUBSTITUTION)
6878 /* Process substitution. */
6882 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (word->flags & (W_DQUOTE|W_NOPROCSUB)) || posixly_correct)
6884 sindex--; /* add_character: label increments sindex */
6888 t_index = sindex + 1; /* skip past both '<' and LPAREN */
6890 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
6893 /* If the process substitution specification is `<()', we want to
6894 open the pipe for writing in the child and produce output; if
6895 it is `>()', we want to open the pipe for reading in the child
6896 and consume input. */
6897 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
6901 goto dollar_add_string;
6903 #endif /* PROCESS_SUBSTITUTION */
6906 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6907 which are not assignment statements are not expanded. If the
6908 shell isn't in posix mode, though, we perform tilde expansion
6909 on `likely candidate' unquoted assignment statements (flags
6910 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
6911 contains an unquoted :~ or =~. Something to think about: we
6912 now have a flag that says to perform tilde expansion on arguments
6913 to `assignment builtins' like declare and export that look like
6914 assignment statements. We now do tilde expansion on such words
6915 even in POSIX mode. */
6916 if (word->flags & (W_ASSIGNRHS|W_NOTILDE))
6918 /* If we're not in posix mode or forcing assignment-statement tilde
6919 expansion, note where the `=' appears in the word and prepare to
6920 do tilde expansion following the first `='. */
6921 if ((word->flags & W_ASSIGNMENT) &&
6922 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
6923 assignoff == -1 && sindex > 0)
6925 if (sindex == assignoff && string[sindex+1] == '~') /* XXX */
6926 word->flags |= W_ITILDE;
6928 else if ((word->flags & W_ASSIGNMENT) &&
6929 (posixly_correct == 0 || (word->flags & W_TILDEEXP)) &&
6930 string[sindex+1] == '~')
6931 word->flags |= W_ITILDE;
6936 if (word->flags & W_NOTILDE)
6939 if ((word->flags & (W_ASSIGNMENT|W_ASSIGNRHS|W_TILDEEXP)) &&
6940 string[sindex+1] == '~')
6941 word->flags |= W_ITILDE;
6945 /* If the word isn't supposed to be tilde expanded, or we're not
6946 at the start of a word or after an unquoted : or = in an
6947 assignment statement, we don't do tilde expansion. */
6948 if ((word->flags & (W_NOTILDE|W_DQUOTE)) ||
6949 (sindex > 0 && ((word->flags & W_ITILDE) == 0)) ||
6950 (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
6952 word->flags &= ~W_ITILDE;
6956 if (word->flags & W_ASSIGNRHS)
6958 else if (word->flags & (W_ASSIGNMENT|W_TILDEEXP))
6963 temp = bash_tilde_find_word (string + sindex, tflag, &t_index);
6965 word->flags &= ~W_ITILDE;
6967 if (temp && *temp && t_index > 0)
6969 temp1 = bash_tilde_expand (temp, tflag);
6970 if (temp1 && *temp1 == '~' && STREQ (temp, temp1))
6974 goto add_character; /* tilde expansion failed */
6988 if (expanded_something)
6989 *expanded_something = 1;
6992 tword = param_expand (string, &sindex, quoted, expanded_something,
6993 &has_dollar_at, "ed_dollar_at,
6995 (word->flags & W_NOCOMSUB) ? PF_NOCOMSUB : 0);
6997 if (tword == &expand_wdesc_error || tword == &expand_wdesc_fatal)
7001 return ((tword == &expand_wdesc_error) ? &expand_word_error
7002 : &expand_word_fatal);
7004 if (contains_dollar_at && has_dollar_at)
7005 *contains_dollar_at = 1;
7007 if (tword && (tword->flags & W_HASQUOTEDNULL))
7008 had_quoted_null = 1;
7011 dispose_word_desc (tword);
7016 case '`': /* Backquoted command substitution. */
7020 temp = string_extract (string, &sindex, "`", EX_REQMATCH);
7021 /* The test of sindex against t_index is to allow bare instances of
7022 ` to pass through, for backwards compatibility. */
7023 if (temp == &extract_string_error || temp == &extract_string_fatal)
7025 if (sindex - 1 == t_index)
7030 report_error (_("bad substitution: no closing \"`\" in %s") , string+t_index);
7033 return ((temp == &extract_string_error) ? &expand_word_error
7034 : &expand_word_fatal);
7037 if (expanded_something)
7038 *expanded_something = 1;
7040 if (word->flags & W_NOCOMSUB)
7041 /* sindex + 1 because string[sindex] == '`' */
7042 temp1 = substring (string, t_index, sindex + 1);
7045 de_backslash (temp);
7046 tword = command_substitute (temp, quoted);
7047 temp1 = tword ? tword->word : (char *)NULL;
7048 dispose_word_desc (tword);
7052 goto dollar_add_string;
7056 if (string[sindex + 1] == '\n')
7062 c = string[++sindex];
7064 if (quoted & Q_HERE_DOCUMENT)
7066 else if (quoted & Q_DOUBLE_QUOTES)
7071 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
7073 SCOPY_CHAR_I (twochars, '\\', c, string, sindex, string_size);
7078 sindex--; /* add_character: label increments sindex */
7083 SCOPY_CHAR_I (twochars, CTLESC, c, string, sindex, string_size);
7088 /* BEFORE jumping here, we need to increment sindex if appropriate */
7089 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
7090 DEFAULT_ARRAY_SIZE);
7091 istring[istring_index++] = twochars[0];
7092 istring[istring_index++] = twochars[1];
7093 istring[istring_index] = '\0';
7099 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7101 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7106 temp = string_extract_double_quoted (string, &sindex, 0);
7108 /* If the quotes surrounded the entire string, then the
7109 whole word was quoted. */
7110 quoted_state = (t_index == 1 && string[sindex] == '\0')
7116 tword = alloc_word_desc ();
7119 temp = (char *)NULL;
7122 /* Need to get W_HASQUOTEDNULL flag through this function. */
7123 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
7125 if (list == &expand_word_error || list == &expand_word_fatal)
7129 /* expand_word_internal has already freed temp_word->word
7130 for us because of the way it prints error messages. */
7131 tword->word = (char *)NULL;
7132 dispose_word (tword);
7136 dispose_word (tword);
7138 /* "$@" (a double-quoted dollar-at) expands into nothing,
7139 not even a NULL word, when there are no positional
7141 if (list == 0 && has_dollar_at)
7147 /* If we get "$@", we know we have expanded something, so we
7148 need to remember it for the final split on $IFS. This is
7149 a special case; it's the only case where a quoted string
7150 can expand into more than one word. It's going to come back
7151 from the above call to expand_word_internal as a list with
7152 a single word, in which all characters are quoted and
7153 separated by blanks. What we want to do is to turn it back
7154 into a list for the next piece of code. */
7156 dequote_list (list);
7158 if (list && list->word && (list->word->flags & W_HASQUOTEDNULL))
7159 had_quoted_null = 1;
7164 if (contains_dollar_at)
7165 *contains_dollar_at = 1;
7166 if (expanded_something)
7167 *expanded_something = 1;
7172 /* What we have is "". This is a minor optimization. */
7174 list = (WORD_LIST *)NULL;
7177 /* The code above *might* return a list (consider the case of "$@",
7178 where it returns "$1", "$2", etc.). We can't throw away the
7179 rest of the list, and we have to make sure each word gets added
7180 as quoted. We test on tresult->next: if it is non-NULL, we
7181 quote the whole list, save it to a string with string_list, and
7182 add that string. We don't need to quote the results of this
7183 (and it would be wrong, since that would quote the separators
7184 as well), so we go directly to add_string. */
7189 /* Testing quoted_dollar_at makes sure that "$@" is
7190 split correctly when $IFS does not contain a space. */
7191 temp = quoted_dollar_at
7192 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
7193 : string_list (quote_list (list));
7194 dispose_words (list);
7199 temp = savestring (list->word->word);
7200 tflag = list->word->flags;
7201 dispose_words (list);
7203 /* If the string is not a quoted null string, we want
7204 to remove any embedded unquoted CTLNUL characters.
7205 We do not want to turn quoted null strings back into
7206 the empty string, though. We do this because we
7207 want to remove any quoted nulls from expansions that
7208 contain other characters. For example, if we have
7209 x"$*"y or "x$*y" and there are no positional parameters,
7210 the $* should expand into nothing. */
7211 /* We use the W_HASQUOTEDNULL flag to differentiate the
7212 cases: a quoted null character as above and when
7213 CTLNUL is contained in the (non-null) expansion
7214 of some variable. We use the had_quoted_null flag to
7215 pass the value through this function to its caller. */
7216 if ((tflag & W_HASQUOTEDNULL) && QUOTED_NULL (temp) == 0)
7217 remove_quoted_nulls (temp); /* XXX */
7221 temp = (char *)NULL;
7223 /* We do not want to add quoted nulls to strings that are only
7224 partially quoted; we can throw them away. */
7225 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
7233 temp = quote_string (temp);
7241 sindex--; /* add_character: label increments sindex */
7249 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (word->flags & W_DQUOTE))
7251 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)))
7256 temp = string_extract_single_quoted (string, &sindex);
7258 /* If the entire STRING was surrounded by single quotes,
7259 then the string is wholly quoted. */
7260 quoted_state = (t_index == 1 && string[sindex] == '\0')
7264 /* If all we had was '', it is a null expansion. */
7268 temp = (char *)NULL;
7271 remove_quoted_escapes (temp); /* ??? */
7273 /* We do not want to add quoted nulls to strings that are only
7274 partially quoted; such nulls are discarded. */
7275 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
7278 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7282 sindex--; /* add_character: label increments sindex */
7286 goto add_quoted_string;
7291 /* This is the fix for " $@ " */
7292 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && isifs (c)))
7294 if (string[sindex]) /* from old goto dollar_add_string */
7303 #if HANDLE_MULTIBYTE
7309 SADD_MBQCHAR_BODY(temp, string, sindex, string_size);
7314 twochars[0] = CTLESC;
7321 SADD_MBCHAR (temp, string, sindex, string_size);
7324 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
7325 DEFAULT_ARRAY_SIZE);
7326 istring[istring_index++] = c;
7327 istring[istring_index] = '\0';
7329 /* Next character. */
7334 finished_with_string:
7335 /* OK, we're ready to return. If we have a quoted string, and
7336 quoted_dollar_at is not set, we do no splitting at all; otherwise
7337 we split on ' '. The routines that call this will handle what to
7338 do if nothing has been expanded. */
7340 /* Partially and wholly quoted strings which expand to the empty
7341 string are retained as an empty arguments. Unquoted strings
7342 which expand to the empty string are discarded. The single
7343 exception is the case of expanding "$@" when there are no
7344 positional parameters. In that case, we discard the expansion. */
7346 /* Because of how the code that handles "" and '' in partially
7347 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7348 if we saw quoting characters, but the expansion was empty.
7349 "" and '' are tossed away before we get to this point when
7350 processing partially quoted strings. This makes "" and $xxx""
7351 equivalent when xxx is unset. We also look to see whether we
7352 saw a quoted null from a ${} expansion and add one back if we
7355 /* If we expand to nothing and there were no single or double quotes
7356 in the word, we throw it away. Otherwise, we return a NULL word.
7357 The single exception is for $@ surrounded by double quotes when
7358 there are no positional parameters. In that case, we also throw
7361 if (*istring == '\0')
7363 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
7365 istring[0] = CTLNUL;
7367 tword = make_bare_word (istring);
7368 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7369 list = make_word_list (tword, (WORD_LIST *)NULL);
7370 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7371 tword->flags |= W_QUOTED;
7373 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7374 and a double-quoted "$@" appears anywhere in it, then the entire
7376 else if (quoted_state == UNQUOTED || quoted_dollar_at)
7377 list = (WORD_LIST *)NULL;
7381 tword = make_bare_word (istring);
7382 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7383 tword->flags |= W_QUOTED;
7384 list = make_word_list (tword, (WORD_LIST *)NULL);
7388 list = (WORD_LIST *)NULL;
7391 else if (word->flags & W_NOSPLIT)
7393 tword = make_bare_word (istring);
7394 if (word->flags & W_ASSIGNMENT)
7395 tword->flags |= W_ASSIGNMENT; /* XXX */
7396 if (word->flags & W_COMPASSIGN)
7397 tword->flags |= W_COMPASSIGN; /* XXX */
7398 if (word->flags & W_NOGLOB)
7399 tword->flags |= W_NOGLOB; /* XXX */
7400 if (word->flags & W_NOEXPAND)
7401 tword->flags |= W_NOEXPAND; /* XXX */
7402 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
7403 tword->flags |= W_QUOTED;
7404 if (had_quoted_null)
7405 tword->flags |= W_HASQUOTEDNULL;
7406 list = make_word_list (tword, (WORD_LIST *)NULL);
7412 ifs_chars = (quoted_dollar_at || has_dollar_at) ? ifs_value : (char *)NULL;
7414 /* If we have $@, we need to split the results no matter what. If
7415 IFS is unset or NULL, string_list_dollar_at has separated the
7416 positional parameters with a space, so we split on space (we have
7417 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7418 string_list_dollar_at has separated the positional parameters
7419 with the first character of $IFS, so we split on $IFS. */
7420 if (has_dollar_at && ifs_chars)
7421 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
7424 tword = make_bare_word (istring);
7425 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
7426 tword->flags |= W_QUOTED;
7427 if (word->flags & W_ASSIGNMENT)
7428 tword->flags |= W_ASSIGNMENT;
7429 if (word->flags & W_COMPASSIGN)
7430 tword->flags |= W_COMPASSIGN;
7431 if (word->flags & W_NOGLOB)
7432 tword->flags |= W_NOGLOB;
7433 if (word->flags & W_NOEXPAND)
7434 tword->flags |= W_NOEXPAND;
7435 if (had_quoted_null)
7436 tword->flags |= W_HASQUOTEDNULL; /* XXX */
7437 list = make_word_list (tword, (WORD_LIST *)NULL);
7445 /* **************************************************************** */
7447 /* Functions for Quote Removal */
7449 /* **************************************************************** */
7451 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7452 backslash quoting rules for within double quotes or a here document. */
7454 string_quote_removal (string, quoted)
7459 char *r, *result_string, *temp, *send;
7460 int sindex, tindex, dquote;
7464 /* The result can be no longer than the original string. */
7465 slen = strlen (string);
7466 send = string + slen;
7468 r = result_string = (char *)xmalloc (slen + 1);
7470 for (dquote = sindex = 0; c = string[sindex];)
7475 c = string[++sindex];
7476 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
7481 SCOPY_CHAR_M (r, string, send, sindex);
7485 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
7491 tindex = sindex + 1;
7492 temp = string_extract_single_quoted (string, &tindex);
7503 dquote = 1 - dquote;
7509 return (result_string);
7514 /* Perform quote removal on word WORD. This allocates and returns a new
7517 word_quote_removal (word, quoted)
7524 t = string_quote_removal (word->word, quoted);
7525 w = alloc_word_desc ();
7526 w->word = t ? t : savestring ("");
7530 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
7531 the members of the list are treated as if they are surrounded by
7532 double quotes. Return a new list, or NULL if LIST is NULL. */
7534 word_list_quote_removal (list, quoted)
7538 WORD_LIST *result, *t, *tresult, *e;
7540 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
7542 tresult = make_word_list (word_quote_removal (t->word, quoted), (WORD_LIST *)NULL);
7544 result = (WORD_LIST *) list_append (result, tresult);
7547 result = e = tresult;
7560 /*******************************************
7562 * Functions to perform word splitting *
7564 *******************************************/
7574 ifs_value = (v && value_cell (v)) ? value_cell (v) : " \t\n";
7576 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
7577 handle multibyte chars in IFS */
7578 memset (ifs_cmap, '\0', sizeof (ifs_cmap));
7579 for (t = ifs_value ; t && *t; t++)
7585 #if defined (HANDLE_MULTIBYTE)
7588 ifs_firstc[0] = '\0';
7594 ifs_len = strnlen (ifs_value, MB_CUR_MAX);
7595 ifs_firstc_len = MBLEN (ifs_value, ifs_len);
7596 if (ifs_firstc_len == 1 || ifs_firstc_len == 0 || MB_INVALIDCH (ifs_firstc_len))
7598 ifs_firstc[0] = ifs_value[0];
7599 ifs_firstc[1] = '\0';
7603 memcpy (ifs_firstc, ifs_value, ifs_firstc_len);
7606 ifs_firstc = ifs_value ? *ifs_value : 0;
7616 /* This splits a single word into a WORD LIST on $IFS, but only if the word
7617 is not quoted. list_string () performs quote removal for us, even if we
7618 don't do any splitting. */
7620 word_split (w, ifs_chars)
7630 xifs = ((w->flags & W_QUOTED) || ifs_chars == 0) ? "" : ifs_chars;
7631 result = list_string (w->word, xifs, w->flags & W_QUOTED);
7634 result = (WORD_LIST *)NULL;
7639 /* Perform word splitting on LIST and return the RESULT. It is possible
7640 to return (WORD_LIST *)NULL. */
7642 word_list_split (list)
7645 WORD_LIST *result, *t, *tresult, *e;
7647 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
7649 tresult = word_split (t->word, ifs_value);
7651 result = e = tresult;
7662 /**************************************************
7664 * Functions to expand an entire WORD_LIST *
7666 **************************************************/
7668 /* Do any word-expansion-specific cleanup and jump to top_level */
7670 exp_jump_to_top_level (v)
7673 /* Cleanup code goes here. */
7674 expand_no_split_dollar_star = 0; /* XXX */
7675 expanding_redir = 0;
7677 jump_to_top_level (v);
7680 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
7681 ELIST, and set ELIST to the new list. */
7682 #define PREPEND_LIST(nlist, elist) \
7683 do { nlist->next = elist; elist = nlist; } while (0)
7685 /* Separate out any initial variable assignments from TLIST. If set -k has
7686 been executed, remove all assignment statements from TLIST. Initial
7687 variable assignments and other environment assignments are placed
7688 on SUBST_ASSIGN_VARLIST. */
7690 separate_out_assignments (tlist)
7693 register WORD_LIST *vp, *lp;
7696 return ((WORD_LIST *)NULL);
7698 if (subst_assign_varlist)
7699 dispose_words (subst_assign_varlist); /* Clean up after previous error */
7701 subst_assign_varlist = (WORD_LIST *)NULL;
7704 /* Separate out variable assignments at the start of the command.
7705 Loop invariant: vp->next == lp
7707 lp = list of words left after assignment statements skipped
7708 tlist = original list of words
7710 while (lp && (lp->word->flags & W_ASSIGNMENT))
7716 /* If lp != tlist, we have some initial assignment statements.
7717 We make SUBST_ASSIGN_VARLIST point to the list of assignment
7718 words and TLIST point to the remaining words. */
7721 subst_assign_varlist = tlist;
7722 /* ASSERT(vp->next == lp); */
7723 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
7724 tlist = lp; /* remainder of word list */
7727 /* vp == end of variable list */
7728 /* tlist == remainder of original word list without variable assignments */
7730 /* All the words in tlist were assignment statements */
7731 return ((WORD_LIST *)NULL);
7733 /* ASSERT(tlist != NULL); */
7734 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
7736 /* If the -k option is in effect, we need to go through the remaining
7737 words, separate out the assignment words, and place them on
7738 SUBST_ASSIGN_VARLIST. */
7739 if (place_keywords_in_env)
7741 WORD_LIST *tp; /* tp == running pointer into tlist */
7746 /* Loop Invariant: tp->next == lp */
7747 /* Loop postcondition: tlist == word list without assignment statements */
7750 if (lp->word->flags & W_ASSIGNMENT)
7752 /* Found an assignment statement, add this word to end of
7753 subst_assign_varlist (vp). */
7754 if (!subst_assign_varlist)
7755 subst_assign_varlist = vp = lp;
7762 /* Remove the word pointed to by LP from TLIST. */
7763 tp->next = lp->next;
7764 /* ASSERT(vp == lp); */
7765 lp->next = (WORD_LIST *)NULL;
7778 #define WEXP_VARASSIGN 0x001
7779 #define WEXP_BRACEEXP 0x002
7780 #define WEXP_TILDEEXP 0x004
7781 #define WEXP_PARAMEXP 0x008
7782 #define WEXP_PATHEXP 0x010
7784 /* All of the expansions, including variable assignments at the start of
7786 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7788 /* All of the expansions except variable assignments at the start of
7790 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7792 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
7793 expansion, command substitution, arithmetic expansion, word splitting, and
7795 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7797 /* Take the list of words in LIST and do the various substitutions. Return
7798 a new list of words which is the expanded list, and without things like
7799 variable assignments. */
7805 return (expand_word_list_internal (list, WEXP_ALL));
7808 /* Same as expand_words (), but doesn't hack variable or environment
7811 expand_words_no_vars (list)
7814 return (expand_word_list_internal (list, WEXP_NOVARS));
7818 expand_words_shellexp (list)
7821 return (expand_word_list_internal (list, WEXP_SHELLEXP));
7825 glob_expand_word_list (tlist, eflags)
7829 char **glob_array, *temp_string;
7830 register int glob_index;
7831 WORD_LIST *glob_list, *output_list, *disposables, *next;
7834 output_list = disposables = (WORD_LIST *)NULL;
7835 glob_array = (char **)NULL;
7838 /* For each word, either globbing is attempted or the word is
7839 added to orig_list. If globbing succeeds, the results are
7840 added to orig_list and the word (tlist) is added to the list
7841 of disposable words. If globbing fails and failed glob
7842 expansions are left unchanged (the shell default), the
7843 original word is added to orig_list. If globbing fails and
7844 failed glob expansions are removed, the original word is
7845 added to the list of disposable words. orig_list ends up
7846 in reverse order and requires a call to REVERSE_LIST to
7847 be set right. After all words are examined, the disposable
7851 /* If the word isn't an assignment and contains an unquoted
7852 pattern matching character, then glob it. */
7853 if ((tlist->word->flags & W_NOGLOB) == 0 &&
7854 unquoted_glob_pattern_p (tlist->word->word))
7856 glob_array = shell_glob_filename (tlist->word->word);
7858 /* Handle error cases.
7859 I don't think we should report errors like "No such file
7860 or directory". However, I would like to report errors
7861 like "Read failed". */
7863 if (glob_array == 0 || GLOB_FAILED (glob_array))
7865 glob_array = (char **)xmalloc (sizeof (char *));
7866 glob_array[0] = (char *)NULL;
7869 /* Dequote the current word in case we have to use it. */
7870 if (glob_array[0] == NULL)
7872 temp_string = dequote_string (tlist->word->word);
7873 free (tlist->word->word);
7874 tlist->word->word = temp_string;
7877 /* Make the array into a word list. */
7878 glob_list = (WORD_LIST *)NULL;
7879 for (glob_index = 0; glob_array[glob_index]; glob_index++)
7881 tword = make_bare_word (glob_array[glob_index]);
7882 tword->flags |= W_GLOBEXP; /* XXX */
7883 glob_list = make_word_list (tword, glob_list);
7888 output_list = (WORD_LIST *)list_append (glob_list, output_list);
7889 PREPEND_LIST (tlist, disposables);
7891 else if (fail_glob_expansion != 0)
7893 report_error (_("no match: %s"), tlist->word->word);
7894 jump_to_top_level (DISCARD);
7896 else if (allow_null_glob_expansion == 0)
7898 /* Failed glob expressions are left unchanged. */
7899 PREPEND_LIST (tlist, output_list);
7903 /* Failed glob expressions are removed. */
7904 PREPEND_LIST (tlist, disposables);
7909 /* Dequote the string. */
7910 temp_string = dequote_string (tlist->word->word);
7911 free (tlist->word->word);
7912 tlist->word->word = temp_string;
7913 PREPEND_LIST (tlist, output_list);
7916 strvec_dispose (glob_array);
7917 glob_array = (char **)NULL;
7923 dispose_words (disposables);
7926 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7928 return (output_list);
7931 #if defined (BRACE_EXPANSION)
7933 brace_expand_word_list (tlist, eflags)
7937 register char **expansions;
7939 WORD_LIST *disposables, *output_list, *next;
7943 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
7947 /* Only do brace expansion if the word has a brace character. If
7948 not, just add the word list element to BRACES and continue. In
7949 the common case, at least when running shell scripts, this will
7950 degenerate to a bunch of calls to `xstrchr', and then what is
7951 basically a reversal of TLIST into BRACES, which is corrected
7952 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7954 if (xstrchr (tlist->word->word, LBRACE))
7956 expansions = brace_expand (tlist->word->word);
7958 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
7960 w = make_word (temp_string);
7961 /* If brace expansion didn't change the word, preserve
7962 the flags. We may want to preserve the flags
7963 unconditionally someday -- XXX */
7964 if (STREQ (temp_string, tlist->word->word))
7965 w->flags = tlist->word->flags;
7966 output_list = make_word_list (w, output_list);
7967 free (expansions[eindex]);
7971 /* Add TLIST to the list of words to be freed after brace
7972 expansion has been performed. */
7973 PREPEND_LIST (tlist, disposables);
7976 PREPEND_LIST (tlist, output_list);
7980 dispose_words (disposables);
7983 output_list = REVERSE_LIST (output_list, WORD_LIST *);
7985 return (output_list);
7990 shell_expand_word_list (tlist, eflags)
7994 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
7995 int expanded_something, has_dollar_at;
7998 /* We do tilde expansion all the time. This is what 1003.2 says. */
7999 new_list = (WORD_LIST *)NULL;
8000 for (orig_list = tlist; tlist; tlist = next)
8002 temp_string = tlist->word->word;
8006 #if defined (ARRAY_VARS)
8007 /* If this is a compound array assignment to a builtin that accepts
8008 such assignments (e.g., `declare'), take the assignment and perform
8009 it separately, handling the semantics of declarations inside shell
8010 functions. This avoids the double-evaluation of such arguments,
8011 because `declare' does some evaluation of compound assignments on
8013 if ((tlist->word->flags & (W_COMPASSIGN|W_ASSIGNARG)) == (W_COMPASSIGN|W_ASSIGNARG))
8017 t = do_word_assignment (tlist->word);
8020 last_command_exit_value = EXECUTION_FAILURE;
8021 exp_jump_to_top_level (DISCARD);
8024 /* Now transform the word as ksh93 appears to do and go on */
8025 t = assignment (tlist->word->word, 0);
8026 tlist->word->word[t] = '\0';
8027 tlist->word->flags &= ~(W_ASSIGNMENT|W_NOSPLIT|W_COMPASSIGN|W_ASSIGNARG);
8031 expanded_something = 0;
8032 expanded = expand_word_internal
8033 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
8035 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
8037 /* By convention, each time this error is returned,
8038 tlist->word->word has already been freed. */
8039 tlist->word->word = (char *)NULL;
8041 /* Dispose our copy of the original list. */
8042 dispose_words (orig_list);
8043 /* Dispose the new list we're building. */
8044 dispose_words (new_list);
8046 last_command_exit_value = EXECUTION_FAILURE;
8047 if (expanded == &expand_word_error)
8048 exp_jump_to_top_level (DISCARD);
8050 exp_jump_to_top_level (FORCE_EOF);
8053 /* Don't split words marked W_NOSPLIT. */
8054 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
8056 temp_list = word_list_split (expanded);
8057 dispose_words (expanded);
8061 /* If no parameter expansion, command substitution, process
8062 substitution, or arithmetic substitution took place, then
8063 do not do word splitting. We still have to remove quoted
8064 null characters from the result. */
8065 word_list_remove_quoted_nulls (expanded);
8066 temp_list = expanded;
8069 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
8070 new_list = (WORD_LIST *)list_append (expanded, new_list);
8074 dispose_words (orig_list);
8077 new_list = REVERSE_LIST (new_list, WORD_LIST *);
8082 /* The workhorse for expand_words () and expand_words_no_vars ().
8083 First arg is LIST, a WORD_LIST of words.
8084 Second arg EFLAGS is a flags word controlling which expansions are
8087 This does all of the substitutions: brace expansion, tilde expansion,
8088 parameter expansion, command substitution, arithmetic expansion,
8089 process substitution, word splitting, and pathname expansion, according
8090 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8091 set, or for which no expansion is done, do not undergo word splitting.
8092 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8094 expand_word_list_internal (list, eflags)
8098 WORD_LIST *new_list, *temp_list;
8102 return ((WORD_LIST *)NULL);
8104 garglist = new_list = copy_word_list (list);
8105 if (eflags & WEXP_VARASSIGN)
8107 garglist = new_list = separate_out_assignments (new_list);
8110 if (subst_assign_varlist)
8112 /* All the words were variable assignments, so they are placed
8113 into the shell's environment. */
8114 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8116 this_command_name = (char *)NULL; /* no arithmetic errors */
8117 tint = do_word_assignment (temp_list->word);
8118 /* Variable assignment errors in non-interactive shells
8119 running in Posix.2 mode cause the shell to exit. */
8122 last_command_exit_value = EXECUTION_FAILURE;
8123 if (interactive_shell == 0 && posixly_correct)
8124 exp_jump_to_top_level (FORCE_EOF);
8126 exp_jump_to_top_level (DISCARD);
8129 dispose_words (subst_assign_varlist);
8130 subst_assign_varlist = (WORD_LIST *)NULL;
8132 return ((WORD_LIST *)NULL);
8136 /* Begin expanding the words that remain. The expansions take place on
8137 things that aren't really variable assignments. */
8139 #if defined (BRACE_EXPANSION)
8140 /* Do brace expansion on this word if there are any brace characters
8142 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
8143 new_list = brace_expand_word_list (new_list, eflags);
8144 #endif /* BRACE_EXPANSION */
8146 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8147 variable substitution, command substitution, arithmetic expansion,
8148 and word splitting. */
8149 new_list = shell_expand_word_list (new_list, eflags);
8151 /* Okay, we're almost done. Now let's just do some filename
8155 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
8156 /* Glob expand the word list unless globbing has been disabled. */
8157 new_list = glob_expand_word_list (new_list, eflags);
8159 /* Dequote the words, because we're not performing globbing. */
8160 new_list = dequote_list (new_list);
8163 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
8165 sh_wassign_func_t *assign_func;
8167 /* If the remainder of the words expand to nothing, Posix.2 requires
8168 that the variable and environment assignments affect the shell's
8170 assign_func = new_list ? assign_in_env : do_word_assignment;
8171 tempenv_assign_error = 0;
8173 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
8175 this_command_name = (char *)NULL;
8176 tint = (*assign_func) (temp_list->word);
8177 /* Variable assignment errors in non-interactive shells running
8178 in Posix.2 mode cause the shell to exit. */
8181 if (assign_func == do_word_assignment)
8183 last_command_exit_value = EXECUTION_FAILURE;
8184 if (interactive_shell == 0 && posixly_correct)
8185 exp_jump_to_top_level (FORCE_EOF);
8187 exp_jump_to_top_level (DISCARD);
8190 tempenv_assign_error++;
8194 dispose_words (subst_assign_varlist);
8195 subst_assign_varlist = (WORD_LIST *)NULL;
8199 tint = list_length (new_list) + 1;
8200 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
8201 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
8202 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
8203 glob_argv_flags[tint] = '\0';