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-2014 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
48 #include "execute_cmd.h"
52 #include "mailcheck.h"
55 #if defined (HAVE_MBSTR_H) && defined (HAVE_MBSCHR)
56 # include <mbstr.h> /* mbschr */
60 #include "builtins/getopt.h"
61 #include "builtins/common.h"
63 #include "builtins/builtext.h"
65 #include <tilde/tilde.h>
66 #include <glob/strmatch.h>
72 /* The size that strings change by. */
73 #define DEFAULT_INITIAL_ARRAY_SIZE 112
74 #define DEFAULT_ARRAY_SIZE 128
80 #define VT_ARRAYMEMBER 3
83 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
85 /* Flags for quoted_strchr */
86 #define ST_BACKSL 0x01
87 #define ST_CTLESC 0x02
88 #define ST_SQUOTE 0x04 /* unused yet */
89 #define ST_DQUOTE 0x08 /* unused yet */
91 /* Flags for the `pflags' argument to param_expand() */
92 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
93 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
94 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
95 #define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */
97 /* These defs make it easier to use the editor. */
105 #if defined (HANDLE_MULTIBYTE)
110 /* Evaluates to 1 if C is one of the shell's special parameters whose length
111 can be taken, but is also one of the special expansion characters. */
112 #define VALID_SPECIAL_LENGTH_PARAM(c) \
113 ((c) == '-' || (c) == '?' || (c) == '#' || (c) == '@')
115 /* Evaluates to 1 if C is one of the shell's special parameters for which an
116 indirect variable reference may be made. */
117 #define VALID_INDIR_PARAM(c) \
118 ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
120 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
121 in ${parameter[:]OPword}. */
122 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
124 /* Evaluates to 1 if this is one of the shell's special variables. */
125 #define SPECIAL_VAR(name, wi) \
126 ((DIGIT (*name) && all_digits (name)) || \
127 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
128 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
130 /* An expansion function that takes a string and a quoted flag and returns
131 a WORD_LIST *. Used as the type of the third argument to
132 expand_string_if_necessary(). */
133 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
135 /* Process ID of the last command executed within command substitution. */
136 pid_t last_command_subst_pid
= NO_PID
;
137 pid_t current_command_subst_pid
= NO_PID
;
139 /* Variables used to keep track of the characters in IFS. */
142 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
143 int ifs_is_set
, ifs_is_null
;
145 #if defined (HANDLE_MULTIBYTE)
146 unsigned char ifs_firstc
[MB_LEN_MAX
];
147 size_t ifs_firstc_len
;
149 unsigned char ifs_firstc
;
152 /* Sentinel to tell when we are performing variable assignments preceding a
153 command name and putting them into the environment. Used to make sure
154 we use the temporary environment when looking up variable values. */
155 int assigning_in_environment
;
157 /* Used to hold a list of variable assignments preceding a command. Global
158 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
159 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
160 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
162 /* Extern functions and variables from different files. */
163 extern int last_command_exit_value
, last_command_exit_signal
;
164 extern int subshell_environment
, line_number
;
165 extern int subshell_level
, parse_and_execute_level
, sourcelevel
;
166 extern int eof_encountered
;
167 extern int return_catch_flag
, return_catch_value
;
168 extern pid_t dollar_dollar_pid
;
169 extern int posixly_correct
;
170 extern char *this_command_name
;
171 extern struct fd_bitmap
*current_fds_to_close
;
172 extern int wordexp_only
;
173 extern int expanding_redir
;
174 extern int tempenv_assign_error
;
175 extern int builtin_ignoring_errexit
;
177 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
178 extern wchar_t *wcsdup
__P((const wchar_t *));
181 /* Non-zero means to allow unmatched globbed filenames to expand to
183 int allow_null_glob_expansion
;
185 /* Non-zero means to throw an error when globbing fails to match anything. */
186 int fail_glob_expansion
;
189 /* Variables to keep track of which words in an expanded word list (the
190 output of expand_word_list_internal) are the result of globbing
191 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
192 (CURRENTLY UNUSED). */
193 char *glob_argv_flags
;
194 static int glob_argv_flags_size
;
197 static WORD_LIST
*cached_quoted_dollar_at
= 0;
199 static WORD_LIST expand_word_error
, expand_word_fatal
;
200 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
201 static char expand_param_error
, expand_param_fatal
;
202 static char extract_string_error
, extract_string_fatal
;
204 /* Tell the expansion functions to not longjmp back to top_level on fatal
205 errors. Enabled when doing completion and prompt string expansion. */
206 static int no_longjmp_on_fatal_error
= 0;
208 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
209 $* on $IFS, primarily when doing assignment statements. */
210 static int expand_no_split_dollar_star
= 0;
212 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
213 without any leading variable assignments. */
214 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
216 static char *quoted_substring
__P((char *, int, int));
217 static int quoted_strlen
__P((char *));
218 static char *quoted_strchr
__P((char *, int, int));
220 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
221 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
222 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
223 static WORD_LIST
*expand_string_internal
__P((char *, int));
224 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
225 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
227 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
228 static WORD_LIST
*list_dequote_escapes
__P((WORD_LIST
*));
230 static char *make_quoted_char
__P((int));
231 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
233 static int unquoted_substring
__P((char *, char *));
234 static int unquoted_member
__P((int, char *));
236 #if defined (ARRAY_VARS)
237 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
239 static int do_assignment_internal
__P((const WORD_DESC
*, int));
241 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
242 static char *string_extract
__P((char *, int *, char *, int));
243 static char *string_extract_double_quoted
__P((char *, int *, int));
244 static inline char *string_extract_single_quoted
__P((char *, int *));
245 static inline int skip_single_quoted
__P((const char *, size_t, int));
246 static int skip_double_quoted
__P((char *, size_t, int));
247 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
248 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
249 static int skip_matched_pair
__P((const char *, int, int, int, int));
251 static char *pos_params
__P((char *, int, int, int));
253 static unsigned char *mb_getcharlens
__P((char *, int));
255 static char *remove_upattern
__P((char *, char *, int));
256 #if defined (HANDLE_MULTIBYTE)
257 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
259 static char *remove_pattern
__P((char *, char *, int));
261 static int match_upattern
__P((char *, char *, int, char **, char **));
262 #if defined (HANDLE_MULTIBYTE)
263 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
265 static int match_pattern
__P((char *, char *, int, char **, char **));
266 static int getpatspec
__P((int, char *));
267 static char *getpattern
__P((char *, int, int));
268 static char *variable_remove_pattern
__P((char *, char *, int, int));
269 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
270 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
272 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
274 static char *parameter_brace_remove_pattern
__P((char *, char *, int, char *, int, int, int));
276 static char *string_var_assignment
__P((SHELL_VAR
*, char *));
277 #if defined (ARRAY_VARS)
278 static char *array_var_assignment
__P((SHELL_VAR
*, int, int));
280 static char *pos_params_assignment
__P((WORD_LIST
*, int, int));
281 static char *string_transform
__P((int, SHELL_VAR
*, char *));
282 static char *list_transform
__P((int, SHELL_VAR
*, WORD_LIST
*, int, int));
283 static char *parameter_list_transform
__P((int, int, int));
284 #if defined ARRAY_VARS
285 static char *array_transform
__P((int, SHELL_VAR
*, char *, int));
287 static char *parameter_brace_transform
__P((char *, char *, int, char *, int, int, int));
289 static char *process_substitute
__P((char *, int));
291 static char *read_comsub
__P((int, int, int *));
294 static arrayind_t array_length_reference
__P((char *));
297 static int valid_brace_expansion_word
__P((char *, int));
298 static int chk_atstar
__P((char *, int, int *, int *));
299 static int chk_arithsub
__P((const char *, int));
301 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int, arrayind_t
*));
302 static char *parameter_brace_find_indir
__P((char *, int, int, int));
303 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
304 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
305 static void parameter_brace_expand_error
__P((char *, char *));
307 static int valid_length_expression
__P((char *));
308 static intmax_t parameter_brace_expand_length
__P((char *));
310 static char *skiparith
__P((char *, int));
311 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
312 static int get_var_and_type
__P((char *, char *, arrayind_t
, int, int, SHELL_VAR
**, char **));
313 static char *mb_substring
__P((char *, int, int));
314 static char *parameter_brace_substring
__P((char *, char *, int, char *, int, int));
316 static int shouldexp_replacement
__P((char *));
318 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
320 static char *parameter_brace_patsub
__P((char *, char *, int, char *, int, int));
322 static char *pos_params_casemod
__P((char *, char *, int, int));
323 static char *parameter_brace_casemod
__P((char *, char *, int, int, char *, int, int));
325 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int, int *, int *));
326 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
328 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
330 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
332 static void exp_jump_to_top_level
__P((int));
334 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
335 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
336 #ifdef BRACE_EXPANSION
337 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
339 #if defined (ARRAY_VARS)
340 static int make_internal_declare
__P((char *, char *));
342 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
343 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
345 /* **************************************************************** */
347 /* Utility Functions */
349 /* **************************************************************** */
353 dump_word_flags (flags
)
359 fprintf (stderr
, "%d -> ", f
);
363 fprintf (stderr
, "W_ARRAYIND%s", f
? "|" : "");
365 if (f
& W_ASSIGNASSOC
)
368 fprintf (stderr
, "W_ASSIGNASSOC%s", f
? "|" : "");
370 if (f
& W_ASSIGNARRAY
)
373 fprintf (stderr
, "W_ASSIGNARRAY%s", f
? "|" : "");
378 fprintf (stderr
, "W_HASCTLESC%s", f
? "|" : "");
383 fprintf (stderr
, "W_NOPROCSUB%s", f
? "|" : "");
388 fprintf (stderr
, "W_DQUOTE%s", f
? "|" : "");
390 if (f
& W_HASQUOTEDNULL
)
392 f
&= ~W_HASQUOTEDNULL
;
393 fprintf (stderr
, "W_HASQUOTEDNULL%s", f
? "|" : "");
398 fprintf (stderr
, "W_ASSIGNARG%s", f
? "|" : "");
403 fprintf (stderr
, "W_ASSNBLTIN%s", f
? "|" : "");
405 if (f
& W_ASSNGLOBAL
)
408 fprintf (stderr
, "W_ASSNGLOBAL%s", f
? "|" : "");
410 if (f
& W_COMPASSIGN
)
413 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
418 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
423 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
428 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
433 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
438 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
440 if (f
& W_DOLLARSTAR
)
443 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
448 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
453 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
458 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
463 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
468 fprintf (stderr
, "W_NOBRACE%s", f
? "|" : "");
473 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
475 if (f
& W_SPLITSPACE
)
478 fprintf (stderr
, "W_SPLITSPACE%s", f
? "|" : "");
480 if (f
& W_ASSIGNMENT
)
483 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
488 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
493 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
495 fprintf (stderr
, "\n");
500 #ifdef INCLUDE_UNUSED
502 quoted_substring (string
, start
, end
)
507 register char *result
, *s
, *r
;
511 /* Move to string[start], skipping quoted characters. */
512 for (s
= string
, l
= 0; *s
&& l
< start
; )
524 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
526 /* Copy LEN characters, including quote characters. */
528 for (l
= 0; l
< len
; s
++)
542 #ifdef INCLUDE_UNUSED
543 /* Return the length of S, skipping over quoted characters */
567 /* Find the first occurrence of character C in string S, obeying shell
568 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
569 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
570 escaped with CTLESC are skipped. */
572 quoted_strchr (s
, c
, flags
)
580 if (((flags
& ST_BACKSL
) && *p
== '\\')
581 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
585 return ((char *)NULL
);
591 return ((char *)NULL
);
594 /* Return 1 if CHARACTER appears in an unquoted portion of
595 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
597 unquoted_member (character
, string
)
605 slen
= strlen (string
);
607 while (c
= string
[sindex
])
615 ADVANCE_CHAR (string
, slen
, sindex
);
621 ADVANCE_CHAR (string
, slen
, sindex
);
625 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
629 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
636 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
638 unquoted_substring (substr
, string
)
639 char *substr
, *string
;
642 int sindex
, c
, sublen
;
645 if (substr
== 0 || *substr
== '\0')
648 slen
= strlen (string
);
649 sublen
= strlen (substr
);
650 for (sindex
= 0; c
= string
[sindex
]; )
652 if (STREQN (string
+ sindex
, substr
, sublen
))
660 ADVANCE_CHAR (string
, slen
, sindex
);
664 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
668 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
672 ADVANCE_CHAR (string
, slen
, sindex
);
679 /* Most of the substitutions must be done in parallel. In order
680 to avoid using tons of unclear goto's, I have some functions
681 for manipulating malloc'ed strings. They all take INDX, a
682 pointer to an integer which is the offset into the string
683 where manipulation is taking place. They also take SIZE, a
684 pointer to an integer which is the current length of the
685 character array for this string. */
687 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
688 of space allocated to TARGET. SOURCE can be NULL, in which
689 case nothing happens. Gets rid of SOURCE by freeing it.
690 Returns TARGET in case the location has changed. */
692 sub_append_string (source
, target
, indx
, size
)
693 char *source
, *target
;
700 srclen
= STRLEN (source
);
701 if (srclen
>= (int)(*size
- *indx
))
704 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
705 target
= (char *)xrealloc (target
, (*size
= n
));
708 FASTCOPY (source
, target
+ *indx
, srclen
);
710 target
[*indx
] = '\0';
719 /* Append the textual representation of NUMBER to TARGET.
720 INDX and SIZE are as in SUB_APPEND_STRING. */
722 sub_append_number (number
, target
, indx
, size
)
729 temp
= itos (number
);
730 return (sub_append_string (temp
, target
, indx
, size
));
734 /* Extract a substring from STRING, starting at SINDEX and ending with
735 one of the characters in CHARLIST. Don't make the ending character
736 part of the string. Leave SINDEX pointing at the ending character.
737 Understand about backslashes in the string. If (flags & SX_VARNAME)
738 is non-zero, and array variables have been compiled into the shell,
739 everything between a `[' and a corresponding `]' is skipped over.
740 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
741 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
742 contain a closing character from CHARLIST. */
744 string_extract (string
, sindex
, charlist
, flags
)
756 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
759 while (c
= string
[i
])
768 #if defined (ARRAY_VARS)
769 else if ((flags
& SX_VARNAME
) && c
== '[')
772 /* If this is an array subscript, skip over it and continue. */
773 ni
= skipsubscript (string
, i
, 0);
774 if (string
[ni
] == ']')
778 else if (MEMBER (c
, charlist
))
784 ADVANCE_CHAR (string
, slen
, i
);
787 /* If we had to have a matching delimiter and didn't find one, return an
788 error and let the caller deal with it. */
789 if ((flags
& SX_REQMATCH
) && found
== 0)
792 return (&extract_string_error
);
795 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
801 /* Extract the contents of STRING as if it is enclosed in double quotes.
802 SINDEX, when passed in, is the offset of the character immediately
803 following the opening double quote; on exit, SINDEX is left pointing after
804 the closing double quote. If STRIPDQ is non-zero, unquoted double
805 quotes are stripped and the string is terminated by a null byte.
806 Backslashes between the embedded double quotes are processed. If STRIPDQ
807 is zero, an unquoted `"' terminates the string. */
809 string_extract_double_quoted (string
, sindex
, stripdq
)
811 int *sindex
, stripdq
;
817 char *temp
, *ret
; /* The new string we return. */
818 int pass_next
, backquote
, si
; /* State variables for the machine. */
822 slen
= strlen (string
+ *sindex
) + *sindex
;
823 send
= string
+ slen
;
825 pass_next
= backquote
= dquote
= 0;
826 temp
= (char *)xmalloc (1 + slen
- *sindex
);
830 while (c
= string
[i
])
832 /* Process a character that was quoted by a backslash. */
835 /* XXX - take another look at this in light of Interp 221 */
838 ``The backslash shall retain its special meaning as an escape
839 character only when followed by one of the characters:
842 If STRIPDQ is zero, we handle the double quotes here and let
843 expand_word_internal handle the rest. If STRIPDQ is non-zero,
844 we have already been through one round of backslash stripping,
845 and want to strip these backslashes only if DQUOTE is non-zero,
846 indicating that we are inside an embedded double-quoted string. */
848 /* If we are in an embedded quoted string, then don't strip
849 backslashes before characters for which the backslash
850 retains its special meaning, but remove backslashes in
851 front of other characters. If we are not in an
852 embedded quoted string, don't strip backslashes at all.
853 This mess is necessary because the string was already
854 surrounded by double quotes (and sh has some really weird
856 The returned string will be run through expansion as if
857 it were double-quoted. */
858 if ((stripdq
== 0 && c
!= '"') ||
859 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
864 COPY_CHAR_I (temp
, j
, string
, send
, i
);
868 /* A backslash protects the next character. The code just above
869 handles preserving the backslash in front of any character but
878 /* Inside backquotes, ``the portion of the quoted string from the
879 initial backquote and the characters up to the next backquote
880 that is not preceded by a backslash, having escape characters
881 removed, defines that command''. */
899 /* Pass everything between `$(' and the matching `)' or a quoted
900 ${ ... } pair through according to the Posix.2 specification. */
901 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
906 if (string
[i
+ 1] == LPAREN
)
907 ret
= extract_command_subst (string
, &si
, 0);
909 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, 0);
912 temp
[j
++] = string
[i
+ 1];
914 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
916 if (ret
== 0 && no_longjmp_on_fatal_error
)
919 ret
= string
+ i
+ 2;
922 for (t
= 0; ret
[t
]; t
++, j
++)
924 temp
[j
] = string
[si
];
939 /* Add any character but a double quote to the quoted string we're
942 goto add_one_character
;
956 /* Point to after the closing quote. */
964 /* This should really be another option to string_extract_double_quoted. */
966 skip_double_quoted (string
, slen
, sind
)
973 int pass_next
, backquote
, si
;
976 pass_next
= backquote
= 0;
978 while (c
= string
[i
])
983 ADVANCE_CHAR (string
, slen
, i
);
996 ADVANCE_CHAR (string
, slen
, i
);
1005 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
1008 if (string
[i
+ 1] == LPAREN
)
1009 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
1011 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, SX_NOALLOC
);
1018 ADVANCE_CHAR (string
, slen
, i
);
1031 /* Extract the contents of STRING as if it is enclosed in single quotes.
1032 SINDEX, when passed in, is the offset of the character immediately
1033 following the opening single quote; on exit, SINDEX is left pointing after
1034 the closing single quote. */
1035 static inline char *
1036 string_extract_single_quoted (string
, sindex
)
1045 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1046 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
1048 while (string
[i
] && string
[i
] != '\'')
1049 ADVANCE_CHAR (string
, slen
, i
);
1051 t
= substring (string
, *sindex
, i
);
1061 skip_single_quoted (string
, slen
, sind
)
1070 while (string
[c
] && string
[c
] != '\'')
1071 ADVANCE_CHAR (string
, slen
, c
);
1078 /* Just like string_extract, but doesn't hack backslashes or any of
1079 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1081 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1089 #if defined (HANDLE_MULTIBYTE)
1097 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1099 temp
= string_extract_single_quoted (string
, sindex
);
1100 --*sindex
; /* leave *sindex at separator character */
1106 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1107 this only if MB_CUR_MAX > 1. */
1108 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1110 #if defined (HANDLE_MULTIBYTE)
1111 clen
= strlen (charlist
);
1114 while (c
= string
[i
])
1116 #if defined (HANDLE_MULTIBYTE)
1119 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1124 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1125 through, to protect the CTLNULs from later calls to
1126 remove_quoted_nulls. */
1127 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1133 #if defined (HANDLE_MULTIBYTE)
1134 mblength
= MBLEN (string
+ i
, slen
- i
);
1138 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1139 if (MB_INVALIDCH (mblength
))
1141 if (MEMBER (c
, charlist
))
1149 len
= mbstowcs (wcharlist
, charlist
, 0);
1152 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1153 mbstowcs (wcharlist
, charlist
, len
+ 1);
1156 if (wcschr (wcharlist
, wc
))
1162 if (MEMBER (c
, charlist
))
1165 ADVANCE_CHAR (string
, slen
, i
);
1168 #if defined (HANDLE_MULTIBYTE)
1172 temp
= substring (string
, *sindex
, i
);
1178 /* Extract the $( construct in STRING, and return a new string.
1179 Start extracting at (SINDEX) as if we had just seen "$(".
1180 Make (SINDEX) get the position of the matching ")". )
1181 XFLAGS is additional flags to pass to other extraction functions. */
1183 extract_command_subst (string
, sindex
, xflags
)
1188 if (string
[*sindex
] == LPAREN
)
1189 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1192 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1193 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1197 /* Extract the $[ construct in STRING, and return a new string. (])
1198 Start extracting at (SINDEX) as if we had just seen "$[".
1199 Make (SINDEX) get the position of the matching "]". */
1201 extract_arithmetic_subst (string
, sindex
)
1205 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1208 #if defined (PROCESS_SUBSTITUTION)
1209 /* Extract the <( or >( construct in STRING, and return a new string.
1210 Start extracting at (SINDEX) as if we had just seen "<(".
1211 Make (SINDEX) get the position of the matching ")". */ /*))*/
1213 extract_process_subst (string
, starter
, sindex
, xflags
)
1220 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", SX_COMMAND
));
1222 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1223 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1226 #endif /* PROCESS_SUBSTITUTION */
1228 #if defined (ARRAY_VARS)
1229 /* This can be fooled by unquoted right parens in the passed string. If
1230 each caller verifies that the last character in STRING is a right paren,
1231 we don't even need to call extract_delimited_string. */
1233 extract_array_assignment_list (string
, sindex
)
1240 slen
= strlen (string
); /* ( */
1241 if (string
[slen
- 1] == ')')
1243 ret
= substring (string
, *sindex
, slen
- 1);
1251 /* Extract and create a new string from the contents of STRING, a
1252 character string delimited with OPENER and CLOSER. SINDEX is
1253 the address of an int describing the current offset in STRING;
1254 it should point to just after the first OPENER found. On exit,
1255 SINDEX gets the position of the last character of the matching CLOSER.
1256 If OPENER is more than a single character, ALT_OPENER, if non-null,
1257 contains a character string that can also match CLOSER and thus
1258 needs to be skipped. */
1260 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1263 char *opener
, *alt_opener
, *closer
;
1269 int pass_character
, nesting_level
, in_comment
;
1270 int len_closer
, len_opener
, len_alt_opener
;
1273 slen
= strlen (string
+ *sindex
) + *sindex
;
1274 len_opener
= STRLEN (opener
);
1275 len_alt_opener
= STRLEN (alt_opener
);
1276 len_closer
= STRLEN (closer
);
1278 pass_character
= in_comment
= 0;
1283 while (nesting_level
)
1294 ADVANCE_CHAR (string
, slen
, i
);
1298 if (pass_character
) /* previous char was backslash */
1301 ADVANCE_CHAR (string
, slen
, i
);
1305 /* Not exactly right yet; should handle shell metacharacters and
1306 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1307 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1310 ADVANCE_CHAR (string
, slen
, i
);
1314 if (c
== CTLESC
|| c
== '\\')
1321 /* Process a nested command substitution, but only if we're parsing an
1322 arithmetic substitution. */
1323 if ((flags
& SX_COMMAND
) && string
[i
] == '$' && string
[i
+1] == LPAREN
)
1326 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1331 /* Process a nested OPENER. */
1332 if (STREQN (string
+ i
, opener
, len_opener
))
1334 si
= i
+ len_opener
;
1335 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1340 /* Process a nested ALT_OPENER */
1341 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1343 si
= i
+ len_alt_opener
;
1344 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1349 /* If the current substring terminates the delimited string, decrement
1350 the nesting level. */
1351 if (STREQN (string
+ i
, closer
, len_closer
))
1353 i
+= len_closer
- 1; /* move to last byte of the closer */
1355 if (nesting_level
== 0)
1359 /* Pass old-style command substitution through verbatim. */
1363 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1368 /* Pass single-quoted and double-quoted strings through verbatim. */
1369 if (c
== '\'' || c
== '"')
1372 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1373 : skip_double_quoted (string
, slen
, si
);
1377 /* move past this character, which was not special. */
1378 ADVANCE_CHAR (string
, slen
, i
);
1381 if (c
== 0 && nesting_level
)
1383 if (no_longjmp_on_fatal_error
== 0)
1385 last_command_exit_value
= EXECUTION_FAILURE
;
1386 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1387 exp_jump_to_top_level (DISCARD
);
1392 return (char *)NULL
;
1396 si
= i
- *sindex
- len_closer
+ 1;
1397 if (flags
& SX_NOALLOC
)
1398 result
= (char *)NULL
;
1401 result
= (char *)xmalloc (1 + si
);
1402 strncpy (result
, string
+ *sindex
, si
);
1410 /* Extract a parameter expansion expression within ${ and } from STRING.
1411 Obey the Posix.2 rules for finding the ending `}': count braces while
1412 skipping over enclosed quoted strings and command substitutions.
1413 SINDEX is the address of an int describing the current offset in STRING;
1414 it should point to just after the first `{' found. On exit, SINDEX
1415 gets the position of the matching `}'. QUOTED is non-zero if this
1416 occurs inside double quotes. */
1417 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1419 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1421 int *sindex
, quoted
, flags
;
1425 int pass_character
, nesting_level
, si
, dolbrace_state
;
1431 slen
= strlen (string
+ *sindex
) + *sindex
;
1433 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1434 parse_matched_pair(). The different initial value is to handle the
1435 case where this function is called to parse the word in
1436 ${param op word} (SX_WORD). */
1437 dolbrace_state
= (flags
& SX_WORD
) ? DOLBRACE_WORD
: DOLBRACE_PARAM
;
1438 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && (flags
& SX_POSIXEXP
))
1439 dolbrace_state
= DOLBRACE_QUOTE
;
1442 while (c
= string
[i
])
1447 ADVANCE_CHAR (string
, slen
, i
);
1451 /* CTLESCs and backslashes quote the next character. */
1452 if (c
== CTLESC
|| c
== '\\')
1459 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1469 if (nesting_level
== 0)
1475 /* Pass the contents of old-style command substitutions through
1480 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1485 /* Pass the contents of new-style command substitutions and
1486 arithmetic substitutions through verbatim. */
1487 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1490 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1495 /* Pass the contents of double-quoted strings through verbatim. */
1499 i
= skip_double_quoted (string
, slen
, si
);
1500 /* skip_XXX_quoted leaves index one past close quote */
1506 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1507 if (posixly_correct
&& shell_compatibility_level
> 42 && dolbrace_state
!= DOLBRACE_QUOTE
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1508 ADVANCE_CHAR (string
, slen
, i
);
1512 i
= skip_single_quoted (string
, slen
, si
);
1518 /* move past this character, which was not special. */
1519 ADVANCE_CHAR (string
, slen
, i
);
1521 /* This logic must agree with parse.y:parse_matched_pair, since they
1522 share the same defines. */
1523 if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '%' && (i
- *sindex
) > 1)
1524 dolbrace_state
= DOLBRACE_QUOTE
;
1525 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '#' && (i
- *sindex
) > 1)
1526 dolbrace_state
= DOLBRACE_QUOTE
;
1527 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '/' && (i
- *sindex
) > 1)
1528 dolbrace_state
= DOLBRACE_QUOTE2
; /* XXX */
1529 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '^' && (i
- *sindex
) > 1)
1530 dolbrace_state
= DOLBRACE_QUOTE
;
1531 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== ',' && (i
- *sindex
) > 1)
1532 dolbrace_state
= DOLBRACE_QUOTE
;
1533 else if (dolbrace_state
== DOLBRACE_PARAM
&& strchr ("#%^,~:-=?+/", c
) != 0)
1534 dolbrace_state
= DOLBRACE_OP
;
1535 else if (dolbrace_state
== DOLBRACE_OP
&& strchr ("#%^,~:-=?+/", c
) == 0)
1536 dolbrace_state
= DOLBRACE_WORD
;
1539 if (c
== 0 && nesting_level
)
1541 if (no_longjmp_on_fatal_error
== 0)
1543 last_command_exit_value
= EXECUTION_FAILURE
;
1544 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1545 exp_jump_to_top_level (DISCARD
);
1550 return ((char *)NULL
);
1554 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1560 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1561 STRING, and returns a pointer to it. */
1563 de_backslash (string
)
1566 register size_t slen
;
1567 register int i
, j
, prev_i
;
1570 slen
= strlen (string
);
1573 /* Loop copying string[i] to string[j], i >= j. */
1576 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1577 string
[i
+ 1] == '$'))
1580 ADVANCE_CHAR (string
, slen
, i
);
1582 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1593 /* Replace instances of \! in a string with !. */
1595 unquote_bang (string
)
1599 register char *temp
;
1601 temp
= (char *)xmalloc (1 + strlen (string
));
1603 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1605 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1611 strcpy (string
, temp
);
1616 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1618 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1619 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1620 matched pairs of quotes or backquotes, or skip word expansions; it is
1621 intended to be used after expansion has been performed and during final
1622 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1624 skip_matched_pair (string
, start
, open
, close
, flags
)
1626 int start
, open
, close
, flags
;
1628 int i
, pass_next
, backq
, si
, c
, count
;
1633 slen
= strlen (string
+ start
) + start
;
1634 no_longjmp_on_fatal_error
= 1;
1636 i
= start
+ 1; /* skip over leading bracket */
1638 pass_next
= backq
= 0;
1639 ss
= (char *)string
;
1640 while (c
= string
[i
])
1647 ADVANCE_CHAR (string
, slen
, i
);
1660 ADVANCE_CHAR (string
, slen
, i
);
1663 else if ((flags
& 1) == 0 && c
== '`')
1669 else if ((flags
& 1) == 0 && c
== open
)
1675 else if (c
== close
)
1683 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1685 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1686 : skip_double_quoted (ss
, slen
, ++i
);
1687 /* no increment, the skip functions increment past the closing quote. */
1689 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1692 if (string
[si
] == '\0')
1695 if (string
[i
+1] == LPAREN
)
1696 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1698 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1700 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1706 ADVANCE_CHAR (string
, slen
, i
);
1712 #if defined (ARRAY_VARS)
1714 skipsubscript (string
, start
, flags
)
1718 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1722 /* Skip characters in STRING until we find a character in DELIMS, and return
1723 the index of that character. START is the index into string at which we
1724 begin. This is similar in spirit to strpbrk, but it returns an index into
1725 STRING and takes a starting index. This little piece of code knows quite
1726 a lot of shell syntax. It's very similar to skip_double_quoted and other
1727 functions of that ilk. */
1729 skip_to_delim (string
, start
, delims
, flags
)
1735 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
, skipcmd
, noprocsub
;
1737 char *temp
, open
[3];
1740 slen
= strlen (string
+ start
) + start
;
1741 if (flags
& SD_NOJMP
)
1742 no_longjmp_on_fatal_error
= 1;
1743 invert
= (flags
& SD_INVERT
);
1744 skipcmd
= (flags
& SD_NOSKIPCMD
) == 0;
1745 noprocsub
= (flags
& SD_NOPROCSUB
);
1748 pass_next
= backq
= 0;
1749 while (c
= string
[i
])
1751 /* If this is non-zero, we should not let quote characters be delimiters
1752 and the current character is a single or double quote. We should not
1753 test whether or not it's a delimiter until after we skip single- or
1754 double-quoted strings. */
1755 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1761 ADVANCE_CHAR (string
, slen
, i
);
1774 ADVANCE_CHAR (string
, slen
, i
);
1783 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1785 else if (c
== '\'' || c
== '"')
1787 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1788 : skip_double_quoted (string
, slen
, ++i
);
1789 /* no increment, the skip functions increment past the closing quote. */
1791 else if (c
== '$' && ((skipcmd
&& string
[i
+1] == LPAREN
) || string
[i
+1] == LBRACE
))
1794 if (string
[si
] == '\0')
1797 if (string
[i
+1] == LPAREN
)
1798 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1800 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1802 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1807 #if defined (PROCESS_SUBSTITUTION)
1808 else if (skipcmd
&& noprocsub
== 0 && (c
== '<' || c
== '>') && string
[i
+1] == LPAREN
)
1811 if (string
[si
] == '\0')
1814 temp
= extract_delimited_string (string
, &si
, (c
== '<') ? "<(" : ">(", "(", ")", SX_COMMAND
|SX_NOALLOC
); /* )) */
1816 temp
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &si
, 0);
1817 free (temp
); /* XXX - not using SX_NOALLOC here yet */
1820 if (string
[i
] == '\0')
1825 #endif /* PROCESS_SUBSTITUTION */
1826 #if defined (EXTENDED_GLOB)
1827 else if ((flags
& SD_EXTGLOB
) && extended_glob
&& string
[i
+1] == LPAREN
&& member (c
, "?*+!@"))
1830 if (string
[si
] == '\0')
1836 temp
= extract_delimited_string (string
, &si
, open
, "(", ")", SX_NOALLOC
); /* ) */
1839 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1845 else if ((flags
& SD_GLOB
) && c
== LBRACK
)
1848 if (string
[si
] == '\0')
1851 temp
= extract_delimited_string (string
, &si
, "[", "[", "]", SX_NOALLOC
); /* ] */
1854 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1859 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1862 ADVANCE_CHAR (string
, slen
, i
);
1868 #if defined (READLINE)
1869 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1870 an unclosed quoted string), or if the character at EINDEX is quoted
1871 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1872 single and double-quoted string parsing functions should not return an
1873 error if there are unclosed quotes or braces. The characters that this
1874 recognizes need to be the same as the contents of
1875 rl_completer_quote_characters. */
1878 char_is_quoted (string
, eindex
)
1882 int i
, pass_next
, c
;
1886 slen
= strlen (string
);
1887 no_longjmp_on_fatal_error
= 1;
1896 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1898 ADVANCE_CHAR (string
, slen
, i
);
1907 else if (c
== '\'' || c
== '"')
1909 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1910 : skip_double_quoted (string
, slen
, ++i
);
1913 /* no increment, the skip_xxx functions go one past end */
1916 ADVANCE_CHAR (string
, slen
, i
);
1923 unclosed_pair (string
, eindex
, openstr
)
1928 int i
, pass_next
, openc
, olen
;
1932 slen
= strlen (string
);
1933 olen
= strlen (openstr
);
1934 i
= pass_next
= openc
= 0;
1940 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1942 ADVANCE_CHAR (string
, slen
, i
);
1945 else if (string
[i
] == '\\')
1951 else if (STREQN (string
+ i
, openstr
, olen
))
1956 else if (string
[i
] == '\'' || string
[i
] == '"')
1958 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1959 : skip_double_quoted (string
, slen
, i
);
1964 ADVANCE_CHAR (string
, slen
, i
);
1969 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1970 individual words. If DELIMS is NULL, the current value of $IFS is used
1971 to split the string, and the function follows the shell field splitting
1972 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1973 gets the number of words in the returned list. CWP, if non-NULL, gets
1974 the index of the word containing SENTINEL. Non-whitespace chars in
1975 DELIMS delimit separate fields. */
1977 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1981 int sentinel
, flags
;
1984 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1985 char *token
, *d
, *d2
;
1986 WORD_LIST
*ret
, *tl
;
1988 if (string
== 0 || *string
== '\0')
1994 return ((WORD_LIST
*)NULL
);
1997 d
= (delims
== 0) ? ifs_value
: delims
;
1998 ifs_split
= delims
== 0;
2000 /* Make d2 the non-whitespace characters in delims */
2005 #if defined (HANDLE_MULTIBYTE)
2006 size_t mblength
= 1;
2010 slength
= strlen (delims
);
2011 d2
= (char *)xmalloc (slength
+ 1);
2015 #if defined (HANDLE_MULTIBYTE)
2016 mbstate_t state_bak
;
2018 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
2019 if (MB_INVALIDCH (mblength
))
2021 else if (mblength
> 1)
2023 memcpy (d2
+ ts
, delims
+ i
, mblength
);
2026 slength
-= mblength
;
2030 if (whitespace (delims
[i
]) == 0)
2031 d2
[ts
++] = delims
[i
];
2039 ret
= (WORD_LIST
*)NULL
;
2041 /* Remove sequences of whitespace characters at the start of the string, as
2042 long as those characters are delimiters. */
2043 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
2045 if (string
[i
] == '\0')
2051 dflags
= flags
|SD_NOJMP
;
2054 te
= skip_to_delim (string
, ts
, d
, dflags
);
2056 /* If we have a non-whitespace delimiter character, use it to make a
2057 separate field. This is just about what $IFS splitting does and
2058 is closer to the behavior of the shell parser. */
2059 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
2062 /* If we're using IFS splitting, the non-whitespace delimiter char
2063 and any additional IFS whitespace delimits a field. */
2065 while (member (string
[te
], d
) && spctabnl (string
[te
]))
2068 while (member (string
[te
], d2
))
2072 token
= substring (string
, ts
, te
);
2074 ret
= add_string_to_list (token
, ret
);
2078 if (sentinel
>= ts
&& sentinel
<= te
)
2081 /* If the cursor is at whitespace just before word start, set the
2082 sentinel word to the current word. */
2083 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
2086 /* If the cursor is at whitespace between two words, make a new, empty
2087 word, add it before (well, after, since the list is in reverse order)
2088 the word we just added, and set the current word to that one. */
2089 if (cwp
&& cw
== -1 && sentinel
< ts
)
2091 tl
= make_word_list (make_word (""), ret
->next
);
2097 if (string
[te
] == 0)
2101 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
2110 /* Special case for SENTINEL at the end of STRING. If we haven't found
2111 the word containing SENTINEL yet, and the index we're looking for is at
2112 the end of STRING (or past the end of the previously-found token,
2113 possible if the end of the line is composed solely of IFS whitespace)
2114 add an additional null argument and set the current word pointer to that. */
2115 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
2117 if (whitespace (string
[sentinel
- 1]))
2120 ret
= add_string_to_list (token
, ret
);
2133 return (REVERSE_LIST (ret
, WORD_LIST
*));
2135 #endif /* READLINE */
2139 /* Extract the name of the variable to bind to from the assignment string. */
2141 assignment_name (string
)
2147 offset
= assignment (string
, 0);
2149 return (char *)NULL
;
2150 temp
= substring (string
, 0, offset
);
2155 /* **************************************************************** */
2157 /* Functions to convert strings to WORD_LISTs and vice versa */
2159 /* **************************************************************** */
2161 /* Return a single string of all the words in LIST. SEP is the separator
2162 to put between individual elements of LIST in the output string. */
2164 string_list_internal (list
, sep
)
2168 register WORD_LIST
*t
;
2170 int word_len
, sep_len
, result_size
;
2173 return ((char *)NULL
);
2175 /* Short-circuit quickly if we don't need to separate anything. */
2176 if (list
->next
== 0)
2177 return (savestring (list
->word
->word
));
2179 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2180 sep_len
= STRLEN (sep
);
2183 for (t
= list
; t
; t
= t
->next
)
2186 result_size
+= sep_len
;
2187 result_size
+= strlen (t
->word
->word
);
2190 r
= result
= (char *)xmalloc (result_size
+ 1);
2192 for (t
= list
; t
; t
= t
->next
)
2194 if (t
!= list
&& sep_len
)
2198 FASTCOPY (sep
, r
, sep_len
);
2205 word_len
= strlen (t
->word
->word
);
2206 FASTCOPY (t
->word
->word
, r
, word_len
);
2214 /* Return a single string of all the words present in LIST, separating
2215 each word with a space. */
2220 return (string_list_internal (list
, " "));
2223 /* An external interface that can be used by the rest of the shell to
2224 obtain a string containing the first character in $IFS. Handles all
2225 the multibyte complications. If LENP is non-null, it is set to the
2226 length of the returned string. */
2228 ifs_firstchar (lenp
)
2234 ret
= xmalloc (MB_LEN_MAX
+ 1);
2235 #if defined (HANDLE_MULTIBYTE)
2236 if (ifs_firstc_len
== 1)
2238 ret
[0] = ifs_firstc
[0];
2240 len
= ret
[0] ? 1 : 0;
2244 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2245 ret
[len
= ifs_firstc_len
] = '\0';
2248 ret
[0] = ifs_firstc
;
2250 len
= ret
[0] ? 0 : 1;
2259 /* Return a single string of all the words present in LIST, obeying the
2260 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2261 expansion [of $*] appears within a double quoted string, it expands
2262 to a single field with the value of each parameter separated by the
2263 first character of the IFS variable, or by a <space> if IFS is unset." */
2265 string_list_dollar_star (list
)
2269 #if defined (HANDLE_MULTIBYTE)
2270 # if defined (__GNUC__)
2271 char sep
[MB_CUR_MAX
+ 1];
2279 #if defined (HANDLE_MULTIBYTE)
2280 # if !defined (__GNUC__)
2281 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2282 # endif /* !__GNUC__ */
2283 if (ifs_firstc_len
== 1)
2285 sep
[0] = ifs_firstc
[0];
2290 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2291 sep
[ifs_firstc_len
] = '\0';
2294 sep
[0] = ifs_firstc
;
2298 ret
= string_list_internal (list
, sep
);
2299 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2305 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2306 is non-zero, the $@ appears within double quotes, and we should quote
2307 the list before converting it into a string. If IFS is unset, and the
2308 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2309 in the words in the list, because the default value of $IFS is
2310 <space><tab><newline>, IFS characters in the words in the list should
2311 also be split. If IFS is null, and the word is not quoted, we need
2312 to quote the words in the list to preserve the positional parameters
2315 string_list_dollar_at (list
, quoted
)
2320 #if defined (HANDLE_MULTIBYTE)
2321 # if defined (__GNUC__)
2322 char sep
[MB_CUR_MAX
+ 1];
2325 # endif /* !__GNUC__ */
2331 /* XXX this could just be ifs = ifs_value; */
2332 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2334 #if defined (HANDLE_MULTIBYTE)
2335 # if !defined (__GNUC__)
2336 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2337 # endif /* !__GNUC__ */
2340 if (ifs_firstc_len
== 1)
2342 sep
[0] = ifs_firstc
[0];
2347 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2348 sep
[ifs_firstc_len
] = '\0';
2357 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2361 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2362 it now that quote_escapes quotes spaces */
2363 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2365 : list_quote_escapes (list
);
2367 ret
= string_list_internal (tlist
, sep
);
2368 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2374 /* Turn the positional parameters into a string, understanding quoting and
2375 the various subtleties of using the first character of $IFS as the
2376 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2377 string_list as appropriate. */
2379 string_list_pos_params (pchar
, list
, quoted
)
2387 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2389 tlist
= quote_list (list
);
2390 word_list_remove_quoted_nulls (tlist
);
2391 ret
= string_list_dollar_star (tlist
);
2393 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2395 tlist
= quote_list (list
);
2396 word_list_remove_quoted_nulls (tlist
);
2397 ret
= string_list (tlist
);
2399 else if (pchar
== '*')
2401 /* Even when unquoted, string_list_dollar_star does the right thing
2402 making sure that the first character of $IFS is used as the
2404 ret
= string_list_dollar_star (list
);
2406 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2407 /* We use string_list_dollar_at, but only if the string is quoted, since
2408 that quotes the escapes if it's not, which we don't want. We could
2409 use string_list (the old code did), but that doesn't do the right
2410 thing if the first character of $IFS is not a space. We use
2411 string_list_dollar_star if the string is unquoted so we make sure that
2412 the elements of $@ are separated by the first character of $IFS for
2414 ret
= string_list_dollar_at (list
, quoted
);
2415 else if (pchar
== '@')
2416 ret
= string_list_dollar_star (list
);
2418 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2423 /* Return the list of words present in STRING. Separate the string into
2424 words at any of the characters found in SEPARATORS. If QUOTED is
2425 non-zero then word in the list will have its quoted flag set, otherwise
2426 the quoted flag is left as make_word () deemed fit.
2428 This obeys the P1003.2 word splitting semantics. If `separators' is
2429 exactly <space><tab><newline>, then the splitting algorithm is that of
2430 the Bourne shell, which treats any sequence of characters from `separators'
2431 as a delimiter. If IFS is unset, which results in `separators' being set
2432 to "", no splitting occurs. If separators has some other value, the
2433 following rules are applied (`IFS white space' means zero or more
2434 occurrences of <space>, <tab>, or <newline>, as long as those characters
2435 are in `separators'):
2437 1) IFS white space is ignored at the start and the end of the
2439 2) Each occurrence of a character in `separators' that is not
2440 IFS white space, along with any adjacent occurrences of
2441 IFS white space delimits a field.
2442 3) Any nonzero-length sequence of IFS white space delimits a field.
2445 /* BEWARE! list_string strips null arguments. Don't call it twice and
2446 expect to have "" preserved! */
2448 /* This performs word splitting and quoted null character removal on
2451 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2452 : (c) == (separators)[0]) \
2456 list_string (string
, separators
, quoted
)
2457 register char *string
, *separators
;
2462 char *current_word
, *s
;
2463 int sindex
, sh_style_split
, whitesep
, xflags
;
2466 if (!string
|| !*string
)
2467 return ((WORD_LIST
*)NULL
);
2469 sh_style_split
= separators
&& separators
[0] == ' ' &&
2470 separators
[1] == '\t' &&
2471 separators
[2] == '\n' &&
2472 separators
[3] == '\0';
2473 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2475 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2476 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2480 /* Remove sequences of whitespace at the beginning of STRING, as
2481 long as those characters appear in IFS. Do not do this if
2482 STRING is quoted or if there are no separator characters. */
2483 if (!quoted
|| !separators
|| !*separators
)
2485 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2488 return ((WORD_LIST
*)NULL
);
2493 /* OK, now STRING points to a word that does not begin with white space.
2494 The splitting algorithm is:
2495 extract a word, stopping at a separator
2496 skip sequences of spc, tab, or nl as long as they are separators
2497 This obeys the field splitting rules in Posix.2. */
2498 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2499 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2501 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2502 unless multibyte chars are possible. */
2503 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2504 if (current_word
== 0)
2507 /* If we have a quoted empty string, add a quoted null argument. We
2508 want to preserve the quoted null character iff this is a quoted
2509 empty string; otherwise the quoted null characters are removed
2511 if (QUOTED_NULL (current_word
))
2513 t
= alloc_word_desc ();
2514 t
->word
= make_quoted_char ('\0');
2515 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2516 result
= make_word_list (t
, result
);
2518 else if (current_word
[0] != '\0')
2520 /* If we have something, then add it regardless. However,
2521 perform quoted null character removal on the current word. */
2522 remove_quoted_nulls (current_word
);
2523 result
= add_string_to_list (current_word
, result
);
2524 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2525 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2526 result
->word
->flags
|= W_QUOTED
;
2529 /* If we're not doing sequences of separators in the traditional
2530 Bourne shell style, then add a quoted null argument. */
2531 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2533 t
= alloc_word_desc ();
2534 t
->word
= make_quoted_char ('\0');
2535 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2536 result
= make_word_list (t
, result
);
2539 free (current_word
);
2541 /* Note whether or not the separator is IFS whitespace, used later. */
2542 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2544 /* Move past the current separator character. */
2548 ADVANCE_CHAR (string
, slen
, sindex
);
2551 /* Now skip sequences of space, tab, or newline characters if they are
2552 in the list of separators. */
2553 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2556 /* If the first separator was IFS whitespace and the current character
2557 is a non-whitespace IFS character, it should be part of the current
2558 field delimiter, not a separate delimiter that would result in an
2559 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2560 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2563 /* An IFS character that is not IFS white space, along with any
2564 adjacent IFS white space, shall delimit a field. (SUSv3) */
2565 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2569 return (REVERSE_LIST (result
, WORD_LIST
*));
2572 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2573 ENDPTR is set to the first character after the word. This is used by
2574 the `read' builtin. This is never called with SEPARATORS != $IFS;
2575 it should be simplified.
2577 XXX - this function is very similar to list_string; they should be
2580 get_word_from_string (stringp
, separators
, endptr
)
2581 char **stringp
, *separators
, **endptr
;
2585 int sindex
, sh_style_split
, whitesep
, xflags
;
2588 if (!stringp
|| !*stringp
|| !**stringp
)
2589 return ((char *)NULL
);
2591 sh_style_split
= separators
&& separators
[0] == ' ' &&
2592 separators
[1] == '\t' &&
2593 separators
[2] == '\n' &&
2594 separators
[3] == '\0';
2595 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2597 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2598 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2604 /* Remove sequences of whitespace at the beginning of STRING, as
2605 long as those characters appear in IFS. */
2606 if (sh_style_split
|| !separators
|| !*separators
)
2608 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2610 /* If the string is nothing but whitespace, update it and return. */
2616 return ((char *)NULL
);
2620 /* OK, S points to a word that does not begin with white space.
2621 Now extract a word, stopping at a separator, save a pointer to
2622 the first character after the word, then skip sequences of spc,
2623 tab, or nl as long as they are separators.
2625 This obeys the field splitting rules in Posix.2. */
2627 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2628 unless multibyte chars are possible. */
2629 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2630 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2632 /* Set ENDPTR to the first character after the end of the word. */
2634 *endptr
= s
+ sindex
;
2636 /* Note whether or not the separator is IFS whitespace, used later. */
2637 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2639 /* Move past the current separator character. */
2643 ADVANCE_CHAR (s
, slen
, sindex
);
2646 /* Now skip sequences of space, tab, or newline characters if they are
2647 in the list of separators. */
2648 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2651 /* If the first separator was IFS whitespace and the current character is
2652 a non-whitespace IFS character, it should be part of the current field
2653 delimiter, not a separate delimiter that would result in an empty field.
2654 Look at POSIX.2, 3.6.5, (3)(b). */
2655 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2658 /* An IFS character that is not IFS white space, along with any adjacent
2659 IFS white space, shall delimit a field. */
2660 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2664 /* Update STRING to point to the next field. */
2665 *stringp
= s
+ sindex
;
2666 return (current_word
);
2669 /* Remove IFS white space at the end of STRING. Start at the end
2670 of the string and walk backwards until the beginning of the string
2671 or we find a character that's not IFS white space and not CTLESC.
2672 Only let CTLESC escape a white space character if SAW_ESCAPE is
2675 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2676 char *string
, *separators
;
2681 s
= string
+ STRLEN (string
) - 1;
2682 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2683 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2691 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2692 backslashes, single and double quotes. */
2694 list_string_with_quotes (string
)
2700 int c
, i
, tokstart
, len
;
2702 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2704 if (s
== 0 || *s
== 0)
2705 return ((WORD_LIST
*)NULL
);
2709 list
= (WORD_LIST
*)NULL
;
2720 i
= skip_single_quoted (s
, s_len
, ++i
);
2722 i
= skip_double_quoted (s
, s_len
, ++i
);
2723 else if (c
== 0 || spctabnl (c
))
2725 /* We have found the end of a token. Make a word out of it and
2726 add it to the word list. */
2727 token
= substring (s
, tokstart
, i
);
2728 list
= add_string_to_list (token
, list
);
2730 while (spctabnl (s
[i
]))
2738 i
++; /* normal character */
2740 return (REVERSE_LIST (list
, WORD_LIST
*));
2744 /********************************************************/
2746 /* Functions to perform assignment statements */
2748 /********************************************************/
2750 #if defined (ARRAY_VARS)
2752 do_compound_assignment (name
, value
, flags
)
2757 int mklocal
, mkassoc
, mkglobal
;
2760 mklocal
= flags
& ASS_MKLOCAL
;
2761 mkassoc
= flags
& ASS_MKASSOC
;
2762 mkglobal
= flags
& ASS_MKGLOBAL
;
2764 if (mklocal
&& variable_context
)
2766 v
= find_variable (name
);
2767 list
= expand_compound_array_assignment (v
, value
, flags
);
2769 v
= make_local_assoc_variable (name
);
2770 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2771 v
= make_local_array_variable (name
, 0);
2773 assign_compound_array_list (v
, list
, flags
);
2775 /* In a function but forcing assignment in global context */
2776 else if (mkglobal
&& variable_context
)
2778 v
= find_global_variable (name
);
2779 list
= expand_compound_array_assignment (v
, value
, flags
);
2780 if (v
== 0 && mkassoc
)
2781 v
= make_new_assoc_variable (name
);
2782 else if (v
&& mkassoc
&& assoc_p (v
) == 0)
2783 v
= convert_var_to_assoc (v
);
2785 v
= make_new_array_variable (name
);
2786 else if (v
&& mkassoc
== 0 && array_p (v
) == 0)
2787 v
= convert_var_to_array (v
);
2789 assign_compound_array_list (v
, list
, flags
);
2792 v
= assign_array_from_string (name
, value
, flags
);
2798 /* Given STRING, an assignment string, get the value of the right side
2799 of the `=', and bind it to the left side. If EXPAND is true, then
2800 perform parameter expansion, command substitution, and arithmetic
2801 expansion on the right-hand side. Perform tilde expansion in any
2802 case. Do not perform word splitting on the result of expansion. */
2804 do_assignment_internal (word
, expand
)
2805 const WORD_DESC
*word
;
2808 int offset
, appendop
, assign_list
, aflags
, retval
;
2809 char *name
, *value
, *temp
;
2811 #if defined (ARRAY_VARS)
2817 if (word
== 0 || word
->word
== 0)
2820 appendop
= assign_list
= aflags
= 0;
2821 string
= word
->word
;
2822 offset
= assignment (string
, 0);
2823 name
= savestring (string
);
2824 value
= (char *)NULL
;
2826 if (name
[offset
] == '=')
2828 if (name
[offset
- 1] == '+')
2831 name
[offset
- 1] = '\0';
2834 name
[offset
] = 0; /* might need this set later */
2835 temp
= name
+ offset
+ 1;
2837 #if defined (ARRAY_VARS)
2838 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2840 assign_list
= ni
= 1;
2841 value
= extract_array_assignment_list (temp
, &ni
);
2845 if (expand
&& temp
[0])
2846 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2848 value
= savestring (temp
);
2853 value
= (char *)xmalloc (1);
2857 if (echo_command_at_execute
)
2860 name
[offset
- 1] = '+';
2861 xtrace_print_assignment (name
, value
, assign_list
, 1);
2863 name
[offset
- 1] = '\0';
2866 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2869 aflags
|= ASS_APPEND
;
2871 #if defined (ARRAY_VARS)
2872 if (t
= mbschr (name
, '[')) /*]*/
2876 report_error (_("%s: cannot assign list to array member"), name
);
2879 entry
= assign_array_element (name
, value
, aflags
);
2883 else if (assign_list
)
2885 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
) == 0)
2886 aflags
|= ASS_MKLOCAL
;
2887 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
))
2888 aflags
|= ASS_MKGLOBAL
;
2889 if (word
->flags
& W_ASSIGNASSOC
)
2890 aflags
|= ASS_MKASSOC
;
2891 entry
= do_compound_assignment (name
, value
, aflags
);
2894 #endif /* ARRAY_VARS */
2895 entry
= bind_variable (name
, value
, aflags
);
2897 stupidly_hack_special_variables (name
);
2899 /* Return 1 if the assignment seems to have been performed correctly. */
2900 if (entry
== 0 || readonly_p (entry
))
2901 retval
= 0; /* assignment failure */
2902 else if (noassign_p (entry
))
2904 last_command_exit_value
= EXECUTION_FAILURE
;
2905 retval
= 1; /* error status, but not assignment failure */
2910 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2911 VUNSETATTR (entry
, att_invisible
);
2913 ASSIGN_RETURN (retval
);
2916 /* Perform the assignment statement in STRING, and expand the
2917 right side by doing tilde, command and parameter expansion. */
2919 do_assignment (string
)
2924 td
.flags
= W_ASSIGNMENT
;
2927 return do_assignment_internal (&td
, 1);
2931 do_word_assignment (word
, flags
)
2935 return do_assignment_internal (word
, 1);
2938 /* Given STRING, an assignment string, get the value of the right side
2939 of the `=', and bind it to the left side. Do not perform any word
2940 expansions on the right hand side. */
2942 do_assignment_no_expand (string
)
2947 td
.flags
= W_ASSIGNMENT
;
2950 return (do_assignment_internal (&td
, 0));
2953 /***************************************************
2955 * Functions to manage the positional parameters *
2957 ***************************************************/
2959 /* Return the word list that corresponds to `$*'. */
2961 list_rest_of_args ()
2963 register WORD_LIST
*list
, *args
;
2966 /* Break out of the loop as soon as one of the dollar variables is null. */
2967 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2968 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2970 for (args
= rest_of_args
; args
; args
= args
->next
)
2971 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2973 return (REVERSE_LIST (list
, WORD_LIST
*));
2979 register WORD_LIST
*list
;
2982 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2984 for (list
= rest_of_args
; list
; list
= list
->next
)
2989 /* Return the value of a positional parameter. This handles values > 10. */
2991 get_dollar_var_value (ind
)
2998 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2999 else /* We want something like ${11} */
3002 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
3004 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
3009 /* Make a single large string out of the dollar digit variables,
3010 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
3011 case of "$*" with respect to IFS. */
3013 string_rest_of_args (dollar_star
)
3016 register WORD_LIST
*list
;
3019 list
= list_rest_of_args ();
3020 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
3021 dispose_words (list
);
3025 /* Return a string containing the positional parameters from START to
3026 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
3027 which only makes a difference if QUOTED is non-zero. If QUOTED includes
3028 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
3029 no quoting chars are added. */
3031 pos_params (string
, start
, end
, quoted
)
3033 int start
, end
, quoted
;
3035 WORD_LIST
*save
, *params
, *h
, *t
;
3039 /* see if we can short-circuit. if start == end, we want 0 parameters. */
3041 return ((char *)NULL
);
3043 save
= params
= list_rest_of_args ();
3044 if (save
== 0 && start
> 0)
3045 return ((char *)NULL
);
3047 if (start
== 0) /* handle ${@:0[:x]} specially */
3049 t
= make_word_list (make_word (dollar_vars
[0]), params
);
3053 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
3054 params
= params
->next
;
3057 dispose_words (save
);
3058 return ((char *)NULL
);
3060 for (h
= t
= params
; params
&& i
< end
; i
++)
3063 params
= params
->next
;
3066 t
->next
= (WORD_LIST
*)NULL
;
3068 ret
= string_list_pos_params (string
[0], h
, quoted
);
3073 dispose_words (save
);
3077 /******************************************************************/
3079 /* Functions to expand strings to strings or WORD_LISTs */
3081 /******************************************************************/
3083 #if defined (PROCESS_SUBSTITUTION)
3084 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3086 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3089 /* If there are any characters in STRING that require full expansion,
3090 then call FUNC to expand STRING; otherwise just perform quote
3091 removal if necessary. This returns a new string. */
3093 expand_string_if_necessary (string
, quoted
, func
)
3104 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3105 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3109 if (EXP_CHAR (string
[i
]))
3111 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3113 ADVANCE_CHAR (string
, slen
, i
);
3118 list
= (*func
) (string
, quoted
);
3121 ret
= string_list (list
);
3122 dispose_words (list
);
3127 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3128 ret
= string_quote_removal (string
, quoted
);
3130 ret
= savestring (string
);
3135 static inline char *
3136 expand_string_to_string_internal (string
, quoted
, func
)
3144 if (string
== 0 || *string
== '\0')
3145 return ((char *)NULL
);
3147 list
= (*func
) (string
, quoted
);
3150 ret
= string_list (list
);
3151 dispose_words (list
);
3160 expand_string_to_string (string
, quoted
)
3164 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
3168 expand_string_unsplit_to_string (string
, quoted
)
3172 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3176 expand_assignment_string_to_string (string
, quoted
)
3180 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3184 expand_arith_string (string
, quoted
)
3189 WORD_LIST
*list
, *tlist
;
3195 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3196 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3200 if (EXP_CHAR (string
[i
]))
3202 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3204 ADVANCE_CHAR (string
, slen
, i
);
3209 /* This is expanded version of expand_string_internal as it's called by
3210 expand_string_leave_quoted */
3211 td
.flags
= W_NOPROCSUB
; /* don't want process substitution */
3212 td
.word
= savestring (string
);
3213 list
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3214 /* This takes care of the calls from expand_string_leave_quoted and
3218 tlist
= word_list_split (list
);
3219 dispose_words (list
);
3222 dequote_list (list
);
3224 /* This comes from expand_string_if_necessary */
3227 ret
= string_list (list
);
3228 dispose_words (list
);
3234 else if (saw_quote
&& (quoted
& Q_ARITH
))
3235 ret
= string_quote_removal (string
, quoted
);
3236 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3237 ret
= string_quote_removal (string
, quoted
);
3239 ret
= savestring (string
);
3244 #if defined (COND_COMMAND)
3245 /* Just remove backslashes in STRING. Returns a new string. */
3247 remove_backslashes (string
)
3252 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3253 for (s
= string
; s
&& *s
; )
3265 /* This needs better error handling. */
3266 /* Expand W for use as an argument to a unary or binary operator in a
3267 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3268 to the != or == operator, and should be treated as a pattern. In
3269 this case, we quote the string specially for the globbing code. If
3270 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3271 be quoted appropriately for regcomp/regexec. The caller is responsible
3272 for removing the backslashes if the unquoted word is needed later. */
3274 cond_expand_word (w
, special
)
3282 if (w
->word
== 0 || w
->word
[0] == '\0')
3283 return ((char *)NULL
);
3285 expand_no_split_dollar_star
= 1;
3286 w
->flags
|= W_NOSPLIT2
;
3287 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3288 expand_no_split_dollar_star
= 0;
3291 if (special
== 0) /* LHS */
3294 r
= string_list (l
);
3298 /* Need to figure out whether or not we should call dequote_escapes
3299 or a new dequote_ctlnul function here, and under what
3301 qflags
= QGLOB_CVTNULL
;
3303 qflags
|= QGLOB_REGEXP
;
3304 p
= string_list (l
);
3305 r
= quote_string_for_globbing (p
, qflags
);
3317 /* Call expand_word_internal to expand W and handle error returns.
3318 A convenience function for functions that don't want to handle
3319 any errors or free any memory before aborting. */
3321 call_expand_word_internal (w
, q
, i
, c
, e
)
3327 result
= expand_word_internal (w
, q
, i
, c
, e
);
3328 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3330 /* By convention, each time this error is returned, w->word has
3331 already been freed (it sometimes may not be in the fatal case,
3332 but that doesn't result in a memory leak because we're going
3333 to exit in most cases). */
3334 w
->word
= (char *)NULL
;
3335 last_command_exit_value
= EXECUTION_FAILURE
;
3336 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3344 /* Perform parameter expansion, command substitution, and arithmetic
3345 expansion on STRING, as if it were a word. Leave the result quoted.
3346 Since this does not perform word splitting, it leaves quoted nulls
3349 expand_string_internal (string
, quoted
)
3356 if (string
== 0 || *string
== 0)
3357 return ((WORD_LIST
*)NULL
);
3360 td
.word
= savestring (string
);
3362 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3368 /* Expand STRING by performing parameter expansion, command substitution,
3369 and arithmetic expansion. Dequote the resulting WORD_LIST before
3370 returning it, but do not perform word splitting. The call to
3371 remove_quoted_nulls () is in here because word splitting normally
3372 takes care of quote removal. */
3374 expand_string_unsplit (string
, quoted
)
3380 if (string
== 0 || *string
== '\0')
3381 return ((WORD_LIST
*)NULL
);
3383 expand_no_split_dollar_star
= 1;
3384 value
= expand_string_internal (string
, quoted
);
3385 expand_no_split_dollar_star
= 0;
3391 remove_quoted_nulls (value
->word
->word
);
3392 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3394 dequote_list (value
);
3399 /* Expand the rhs of an assignment statement */
3401 expand_string_assignment (string
, quoted
)
3408 if (string
== 0 || *string
== '\0')
3409 return ((WORD_LIST
*)NULL
);
3411 expand_no_split_dollar_star
= 1;
3413 td
.flags
= W_ASSIGNRHS
;
3414 td
.word
= savestring (string
);
3415 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3418 expand_no_split_dollar_star
= 0;
3424 remove_quoted_nulls (value
->word
->word
);
3425 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3427 dequote_list (value
);
3433 /* Expand one of the PS? prompt strings. This is a sort of combination of
3434 expand_string_unsplit and expand_string_internal, but returns the
3435 passed string when an error occurs. Might want to trap other calls
3436 to jump_to_top_level here so we don't endlessly loop. */
3438 expand_prompt_string (string
, quoted
, wflags
)
3446 if (string
== 0 || *string
== 0)
3447 return ((WORD_LIST
*)NULL
);
3450 td
.word
= savestring (string
);
3452 no_longjmp_on_fatal_error
= 1;
3453 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3454 no_longjmp_on_fatal_error
= 0;
3456 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3458 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3466 remove_quoted_nulls (value
->word
->word
);
3467 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3469 dequote_list (value
);
3474 /* Expand STRING just as if you were expanding a word, but do not dequote
3475 the resultant WORD_LIST. This is called only from within this file,
3476 and is used to correctly preserve quoted characters when expanding
3477 things like ${1+"$@"}. This does parameter expansion, command
3478 substitution, arithmetic expansion, and word splitting. */
3480 expand_string_leave_quoted (string
, quoted
)
3487 if (string
== 0 || *string
== '\0')
3488 return ((WORD_LIST
*)NULL
);
3490 tlist
= expand_string_internal (string
, quoted
);
3494 tresult
= word_list_split (tlist
);
3495 dispose_words (tlist
);
3498 return ((WORD_LIST
*)NULL
);
3501 /* This does not perform word splitting or dequote the WORD_LIST
3504 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3506 int quoted
, *dollar_at_p
, *has_dollar_at
;
3511 if (string
== 0 || *string
== '\0')
3512 return (WORD_LIST
*)NULL
;
3514 expand_no_split_dollar_star
= 1;
3515 td
.flags
= W_NOSPLIT2
; /* no splitting, remove "" and '' */
3517 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3518 expand_no_split_dollar_star
= 0;
3523 /* Expand STRING just as if you were expanding a word. This also returns
3524 a list of words. Note that filename globbing is *NOT* done for word
3525 or string expansion, just when the shell is expanding a command. This
3526 does parameter expansion, command substitution, arithmetic expansion,
3527 and word splitting. Dequote the resultant WORD_LIST before returning. */
3529 expand_string (string
, quoted
)
3535 if (string
== 0 || *string
== '\0')
3536 return ((WORD_LIST
*)NULL
);
3538 result
= expand_string_leave_quoted (string
, quoted
);
3539 return (result
? dequote_list (result
) : result
);
3542 /***************************************************
3544 * Functions to handle quoting chars *
3546 ***************************************************/
3550 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3551 The parser passes CTLNUL as CTLESC CTLNUL. */
3553 /* Quote escape characters in string s, but no other characters. This is
3554 used to protect CTLESC and CTLNUL in variable values from the rest of
3555 the word expansion process after the variable is expanded (word splitting
3556 and filename generation). If IFS is null, we quote spaces as well, just
3557 in case we split on spaces later (in the case of unquoted $@, we will
3558 eventually attempt to split the entire word on spaces). Corresponding
3559 code exists in dequote_escapes. Even if we don't end up splitting on
3560 spaces, quoting spaces is not a problem. This should never be called on
3561 a string that is quoted with single or double quotes or part of a here
3562 document (effectively double-quoted). */
3564 quote_escapes (string
)
3567 register char *s
, *t
;
3569 char *result
, *send
;
3570 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3573 slen
= strlen (string
);
3574 send
= string
+ slen
;
3576 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3578 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3579 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3581 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3586 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3588 COPY_CHAR_P (t
, s
, send
);
3596 list_quote_escapes (list
)
3599 register WORD_LIST
*w
;
3602 for (w
= list
; w
; w
= w
->next
)
3605 w
->word
->word
= quote_escapes (t
);
3611 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3613 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3614 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3615 data stream pass through properly.
3617 We need to remove doubled CTLESC characters inside quoted strings before
3618 quoting the entire string, so we do not double the number of CTLESC
3621 Also used by parts of the pattern substitution code. */
3623 dequote_escapes (string
)
3626 register char *s
, *t
, *s1
;
3628 char *result
, *send
;
3635 slen
= strlen (string
);
3636 send
= string
+ slen
;
3638 t
= result
= (char *)xmalloc (slen
+ 1);
3640 if (strchr (string
, CTLESC
) == 0)
3641 return (strcpy (result
, string
));
3643 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3648 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3654 COPY_CHAR_P (t
, s
, send
);
3662 list_dequote_escapes (list
)
3665 register WORD_LIST
*w
;
3668 for (w
= list
; w
; w
= w
->next
)
3671 w
->word
->word
= dequote_escapes (t
);
3677 /* Return a new string with the quoted representation of character C.
3678 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3679 set in any resultant WORD_DESC where this value is the word. */
3681 make_quoted_char (c
)
3686 temp
= (char *)xmalloc (3);
3701 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3702 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3703 this value is the word. */
3705 quote_string (string
)
3710 char *result
, *send
;
3714 result
= (char *)xmalloc (2);
3722 slen
= strlen (string
);
3723 send
= string
+ slen
;
3725 result
= (char *)xmalloc ((slen
* 2) + 1);
3727 for (t
= result
; string
< send
; )
3730 COPY_CHAR_P (t
, string
, send
);
3737 /* De-quote quoted characters in STRING. */
3739 dequote_string (string
)
3742 register char *s
, *t
;
3744 char *result
, *send
;
3747 slen
= strlen (string
);
3749 t
= result
= (char *)xmalloc (slen
+ 1);
3751 if (QUOTED_NULL (string
))
3757 /* If no character in the string can be quoted, don't bother examining
3758 each character. Just return a copy of the string passed to us. */
3759 if (strchr (string
, CTLESC
) == NULL
)
3760 return (strcpy (result
, string
));
3762 send
= string
+ slen
;
3772 COPY_CHAR_P (t
, s
, send
);
3779 /* Quote the entire WORD_LIST list. */
3784 register WORD_LIST
*w
;
3787 for (w
= list
; w
; w
= w
->next
)
3790 w
->word
->word
= quote_string (t
);
3792 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3793 w
->word
->flags
|= W_QUOTED
;
3799 /* De-quote quoted characters in each word in LIST. */
3805 register WORD_LIST
*tlist
;
3807 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3809 s
= dequote_string (tlist
->word
->word
);
3810 if (QUOTED_NULL (tlist
->word
->word
))
3811 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3812 free (tlist
->word
->word
);
3813 tlist
->word
->word
= s
;
3818 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3821 remove_quoted_escapes (string
)
3828 t
= dequote_escapes (string
);
3836 /* Perform quoted null character removal on STRING. We don't allow any
3837 quoted null characters in the middle or at the ends of strings because
3838 of how expand_word_internal works. remove_quoted_nulls () turns
3839 STRING into an empty string iff it only consists of a quoted null,
3840 and removes all unquoted CTLNUL characters. */
3842 remove_quoted_nulls (string
)
3845 register size_t slen
;
3846 register int i
, j
, prev_i
;
3849 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3850 return string
; /* XXX */
3852 slen
= strlen (string
);
3857 if (string
[i
] == CTLESC
)
3859 /* Old code had j++, but we cannot assume that i == j at this
3860 point -- what if a CTLNUL has already been removed from the
3861 string? We don't want to drop the CTLESC or recopy characters
3862 that we've already copied down. */
3863 i
++; string
[j
++] = CTLESC
;
3867 else if (string
[i
] == CTLNUL
)
3874 ADVANCE_CHAR (string
, slen
, i
);
3877 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3887 /* Perform quoted null character removal on each element of LIST.
3888 This modifies LIST. */
3890 word_list_remove_quoted_nulls (list
)
3893 register WORD_LIST
*t
;
3895 for (t
= list
; t
; t
= t
->next
)
3897 remove_quoted_nulls (t
->word
->word
);
3898 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3902 /* **************************************************************** */
3904 /* Functions for Matching and Removing Patterns */
3906 /* **************************************************************** */
3908 #if defined (HANDLE_MULTIBYTE)
3909 #if 0 /* Currently unused */
3910 static unsigned char *
3911 mb_getcharlens (string
, len
)
3915 int i
, offset
, last
;
3922 ret
= (unsigned char *)xmalloc (len
);
3923 memset (ret
, 0, len
);
3924 while (string
[last
])
3926 ADVANCE_CHAR (string
, len
, offset
);
3927 ret
[last
] = offset
- last
;
3935 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3936 can have one of 4 values:
3937 RP_LONG_LEFT remove longest matching portion at start of PARAM
3938 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3939 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3940 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3943 #define RP_LONG_LEFT 1
3944 #define RP_SHORT_LEFT 2
3945 #define RP_LONG_RIGHT 3
3946 #define RP_SHORT_RIGHT 4
3948 /* Returns its first argument if nothing matched; new memory otherwise */
3950 remove_upattern (param
, pattern
, op
)
3951 char *param
, *pattern
;
3956 register char *p
, *ret
, c
;
3958 len
= STRLEN (param
);
3963 case RP_LONG_LEFT
: /* remove longest match at start */
3964 for (p
= end
; p
>= param
; p
--)
3967 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3970 return (savestring (p
));
3977 case RP_SHORT_LEFT
: /* remove shortest match at start */
3978 for (p
= param
; p
<= end
; p
++)
3981 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3984 return (savestring (p
));
3990 case RP_LONG_RIGHT
: /* remove longest match at end */
3991 for (p
= param
; p
<= end
; p
++)
3993 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3996 ret
= savestring (param
);
4003 case RP_SHORT_RIGHT
: /* remove shortest match at end */
4004 for (p
= end
; p
>= param
; p
--)
4006 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4009 ret
= savestring (param
);
4017 return (param
); /* no match, return original string */
4020 #if defined (HANDLE_MULTIBYTE)
4021 /* Returns its first argument if nothing matched; new memory otherwise */
4023 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
4034 case RP_LONG_LEFT
: /* remove longest match at start */
4035 for (n
= wstrlen
; n
>= 0; n
--)
4037 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
4038 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4041 return (wcsdup (wparam
+ n
));
4047 case RP_SHORT_LEFT
: /* remove shortest match at start */
4048 for (n
= 0; n
<= wstrlen
; n
++)
4050 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
4051 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4054 return (wcsdup (wparam
+ n
));
4060 case RP_LONG_RIGHT
: /* remove longest match at end */
4061 for (n
= 0; n
<= wstrlen
; n
++)
4063 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4065 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
4066 ret
= wcsdup (wparam
);
4073 case RP_SHORT_RIGHT
: /* remove shortest match at end */
4074 for (n
= wstrlen
; n
>= 0; n
--)
4076 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4078 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
4079 ret
= wcsdup (wparam
);
4087 return (wparam
); /* no match, return original string */
4089 #endif /* HANDLE_MULTIBYTE */
4092 remove_pattern (param
, pattern
, op
)
4093 char *param
, *pattern
;
4100 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
4101 return (savestring (param
));
4103 #if defined (HANDLE_MULTIBYTE)
4106 wchar_t *ret
, *oret
;
4108 wchar_t *wparam
, *wpattern
;
4111 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
4112 if (n
== (size_t)-1)
4114 xret
= remove_upattern (param
, pattern
, op
);
4115 return ((xret
== param
) ? savestring (param
) : xret
);
4117 n
= xdupmbstowcs (&wparam
, NULL
, param
);
4119 if (n
== (size_t)-1)
4122 xret
= remove_upattern (param
, pattern
, op
);
4123 return ((xret
== param
) ? savestring (param
) : xret
);
4125 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
4126 /* Don't bother to convert wparam back to multibyte string if nothing
4127 matched; just return copy of original string */
4132 return (savestring (param
));
4139 xret
= (char *)xmalloc (n
+ 1);
4140 memset (&ps
, '\0', sizeof (mbstate_t));
4141 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
4142 xret
[n
] = '\0'; /* just to make sure */
4149 xret
= remove_upattern (param
, pattern
, op
);
4150 return ((xret
== param
) ? savestring (param
) : xret
);
4154 /* Match PAT anywhere in STRING and return the match boundaries.
4155 This returns 1 in case of a successful match, 0 otherwise. SP
4156 and EP are pointers into the string where the match begins and
4157 ends, respectively. MTYPE controls what kind of match is attempted.
4158 MATCH_BEG and MATCH_END anchor the match at the beginning and end
4159 of the string, respectively. The longest match is returned. */
4161 match_upattern (string
, pat
, mtype
, sp
, ep
)
4167 register char *p
, *p1
, *npat
;
4171 /* If the pattern doesn't match anywhere in the string, go ahead and
4172 short-circuit right away. A minor optimization, saves a bunch of
4173 unnecessary calls to strmatch (up to N calls for a string of N
4174 characters) if the match is unsuccessful. To preserve the semantics
4175 of the substring matches below, we make sure that the pattern has
4176 `*' as first and last character, making a new pattern if necessary. */
4177 /* XXX - check this later if I ever implement `**' with special meaning,
4178 since this will potentially result in `**' at the beginning or end */
4180 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == LPAREN
&& extended_glob
) || pat
[len
- 1] != '*')
4182 p
= npat
= (char *)xmalloc (len
+ 3);
4184 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == LPAREN
&& extended_glob
))
4188 if (p1
[-1] != '*' || p
[-2] == '\\')
4194 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
);
4197 if (c
== FNM_NOMATCH
)
4200 len
= STRLEN (string
);
4203 mlen
= umatchlen (pat
, len
);
4208 for (p
= string
; p
<= end
; p
++)
4210 if (match_pattern_char (pat
, p
, FNMATCH_IGNCASE
))
4212 p1
= (mlen
== -1) ? end
: p
+ mlen
;
4213 /* p1 - p = length of portion of string to be considered
4214 p = current position in string
4215 mlen = number of characters consumed by match (-1 for entire string)
4217 we want to break immediately if the potential match len
4218 is greater than the number of characters remaining in the
4223 for ( ; p1
>= p
; p1
--)
4225 c
= *p1
; *p1
= '\0';
4226 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4235 /* If MLEN != -1, we have a fixed length pattern. */
4246 if (match_pattern_char (pat
, string
, FNMATCH_IGNCASE
) == 0)
4249 for (p
= (mlen
== -1) ? end
: string
+ mlen
; p
>= string
; p
--)
4252 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4260 /* If MLEN != -1, we have a fixed length pattern. */
4268 for (p
= end
- ((mlen
== -1) ? len
: mlen
); p
<= end
; p
++)
4270 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4276 /* If MLEN != -1, we have a fixed length pattern. */
4287 #if defined (HANDLE_MULTIBYTE)
4289 #define WFOLD(c) (match_ignore_case && iswupper (c) ? towlower (c) : (c))
4291 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4292 This returns 1 in case of a successful match, 0 otherwise. Wide
4293 character version. */
4295 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4303 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4306 int n
, n1
, n2
, simple
;
4308 simple
= (wpat
[0] != L
'\\' && wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'[');
4309 #if defined (EXTENDED_GLOB)
4311 simple
&= (wpat
[1] != L
'(' || (wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'+' && wpat
[0] != L
'!' && wpat
[0] != L
'@')); /*)*/
4314 /* If the pattern doesn't match anywhere in the string, go ahead and
4315 short-circuit right away. A minor optimization, saves a bunch of
4316 unnecessary calls to strmatch (up to N calls for a string of N
4317 characters) if the match is unsuccessful. To preserve the semantics
4318 of the substring matches below, we make sure that the pattern has
4319 `*' as first and last character, making a new pattern if necessary. */
4320 len
= wcslen (wpat
);
4321 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == WLPAREN
&& extended_glob
) || wpat
[len
- 1] != L
'*')
4323 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4325 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == WLPAREN
&& extended_glob
))
4327 while (*wp1
!= L
'\0')
4329 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4335 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
);
4338 if (len
== FNM_NOMATCH
)
4341 mlen
= wmatchlen (wpat
, wstrlen
);
4343 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4347 for (n
= 0; n
<= wstrlen
; n
++)
4349 n2
= simple
? (WFOLD(*wpat
) == WFOLD(wstring
[n
])) : match_pattern_wchar (wpat
, wstring
+ n
, FNMATCH_IGNCASE
);
4352 n1
= (mlen
== -1) ? wstrlen
: n
+ mlen
;
4356 for ( ; n1
>= n
; n1
--)
4358 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4359 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4367 /* If MLEN != -1, we have a fixed length pattern. */
4377 if (match_pattern_wchar (wpat
, wstring
, FNMATCH_IGNCASE
) == 0)
4380 for (n
= (mlen
== -1) ? wstrlen
: mlen
; n
>= 0; n
--)
4382 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4383 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4391 /* If MLEN != -1, we have a fixed length pattern. */
4399 for (n
= wstrlen
- ((mlen
== -1) ? wstrlen
: mlen
); n
<= wstrlen
; n
++)
4401 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
| FNMATCH_IGNCASE
) == 0)
4404 *ep
= indices
[wstrlen
];
4407 /* If MLEN != -1, we have a fixed length pattern. */
4418 #endif /* HANDLE_MULTIBYTE */
4421 match_pattern (string
, pat
, mtype
, sp
, ep
)
4426 #if defined (HANDLE_MULTIBYTE)
4429 wchar_t *wstring
, *wpat
;
4431 size_t slen
, plen
, mslen
, mplen
;
4434 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4437 #if defined (HANDLE_MULTIBYTE)
4440 if (mbsmbchar (string
) == 0 && mbsmbchar (pat
) == 0)
4441 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4443 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4444 if (n
== (size_t)-1)
4445 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4446 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4447 if (n
== (size_t)-1)
4450 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4452 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4462 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4466 getpatspec (c
, value
)
4471 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4473 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4476 /* Posix.2 says that the WORD should be run through tilde expansion,
4477 parameter expansion, command substitution and arithmetic expansion.
4478 This leaves the result quoted, so quote_string_for_globbing () has
4479 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4480 it means that the entire expression was enclosed in double quotes.
4481 This means that quoting characters in the pattern do not make any
4482 special pattern characters quoted. For example, the `*' in the
4483 following retains its special meaning: "${foo#'*'}". */
4485 getpattern (value
, quoted
, expandpat
)
4487 int quoted
, expandpat
;
4494 /* There is a problem here: how to handle single or double quotes in the
4495 pattern string when the whole expression is between double quotes?
4496 POSIX.2 says that enclosing double quotes do not cause the pattern to
4497 be quoted, but does that leave us a problem with @ and array[@] and their
4498 expansions inside a pattern? */
4500 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4503 pat
= string_extract_double_quoted (tword
, &i
, 1);
4509 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4511 l
= *value
? expand_string_for_rhs (value
,
4512 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4513 (int *)NULL
, (int *)NULL
)
4515 pat
= string_list (l
);
4519 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4527 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4528 or ${name#[#]value}. */
4530 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4531 char *value
, *pattern
;
4532 int patspec
, quoted
;
4536 tword
= remove_pattern (value
, pattern
, patspec
);
4543 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4546 int patspec
, itype
, quoted
;
4552 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4554 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4555 w
= alloc_word_desc ();
4556 w
->word
= tword
? tword
: savestring ("");
4557 new = make_word_list (w
, new);
4560 l
= REVERSE_LIST (new, WORD_LIST
*);
4561 tword
= string_list_pos_params (itype
, l
, quoted
);
4568 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4571 int patspec
, quoted
;
4576 list
= list_rest_of_args ();
4578 return ((char *)NULL
);
4579 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4580 dispose_words (list
);
4584 #if defined (ARRAY_VARS)
4586 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4590 char *varname
; /* so we can figure out how it's indexed */
4600 /* compute itype from varname here */
4601 v
= array_variable_part (varname
, &ret
, 0);
4604 if (v
&& invisible_p (v
))
4605 return ((char *)NULL
);
4609 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4610 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4612 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4614 return ((char *)NULL
);
4615 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4616 dispose_words (list
);
4620 #endif /* ARRAY_VARS */
4623 parameter_brace_remove_pattern (varname
, value
, ind
, patstr
, rtype
, quoted
, flags
)
4624 char *varname
, *value
;
4627 int rtype
, quoted
, flags
;
4629 int vtype
, patspec
, starsub
;
4630 char *temp1
, *val
, *pattern
;
4634 return ((char *)NULL
);
4636 this_command_name
= varname
;
4638 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4640 return ((char *)NULL
);
4642 starsub
= vtype
& VT_STARSUB
;
4643 vtype
&= ~VT_STARSUB
;
4645 patspec
= getpatspec (rtype
, patstr
);
4646 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4649 /* Need to pass getpattern newly-allocated memory in case of expansion --
4650 the expansion code will free the passed string on an error. */
4651 temp1
= savestring (patstr
);
4652 pattern
= getpattern (temp1
, quoted
, 1);
4655 temp1
= (char *)NULL
; /* shut up gcc */
4659 case VT_ARRAYMEMBER
:
4660 temp1
= remove_pattern (val
, pattern
, patspec
);
4661 if (vtype
== VT_VARIABLE
)
4665 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4666 ? quote_string (temp1
)
4667 : quote_escapes (temp1
);
4672 #if defined (ARRAY_VARS)
4674 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4675 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4677 val
= quote_escapes (temp1
);
4684 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4685 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4687 val
= quote_escapes (temp1
);
4699 string_var_assignment (v
, s
)
4703 char flags
[MAX_ATTRIBUTES
], *ret
, *val
;
4706 val
= sh_quote_reusable (s
, 0);
4707 i
= var_attribute_string (v
, 0, flags
);
4708 ret
= (char *)xmalloc (i
+ strlen (val
) + strlen (v
->name
) + 16);
4710 sprintf (ret
, "declare -%s %s=%s", flags
, v
->name
, val
);
4712 sprintf (ret
, "%s=%s", v
->name
, val
);
4717 #if defined (ARRAY_VARS)
4719 array_var_assignment (v
, itype
, quoted
)
4723 char *ret
, *val
, flags
[MAX_ATTRIBUTES
];
4727 return (char *)NULL
;
4728 val
= array_p (v
) ? array_to_assign (array_cell (v
), 0)
4729 : assoc_to_assign (assoc_cell (v
), 0);
4732 val
= (char *)xmalloc (3);
4737 i
= var_attribute_string (v
, 0, flags
);
4738 ret
= (char *)xmalloc (i
+ strlen (val
) + strlen (v
->name
) + 16);
4739 sprintf (ret
, "declare -%s %s=%s", flags
, v
->name
, val
);
4746 pos_params_assignment (list
, itype
, quoted
)
4753 /* first, we transform the list to quote each word. */
4754 temp
= list_transform ('Q', (SHELL_VAR
*)0, list
, itype
, quoted
);
4755 ret
= (char *)xmalloc (strlen (temp
) + 8);
4756 strcpy (ret
, "set -- ");
4757 strcpy (ret
+ 7, temp
);
4763 string_transform (xc
, v
, s
)
4768 char *ret
, flags
[MAX_ATTRIBUTES
];
4771 if (((xc
== 'A' || xc
== 'a') && v
== 0) || (xc
!= 'a' && s
== 0))
4772 return (char *)NULL
;
4776 /* Transformations that interrogate the variable */
4778 i
= var_attribute_string (v
, 0, flags
);
4779 ret
= (i
> 0) ? savestring (flags
) : (char *)NULL
;
4782 ret
= string_var_assignment (v
, s
);
4784 /* Transformations that modify the variable's value */
4786 ret
= ansiexpand (s
, 0, strlen (s
), (int *)0);
4789 ret
= decode_prompt_string (s
);
4792 ret
= sh_quote_reusable (s
, 0);
4802 list_transform (xc
, v
, list
, itype
, quoted
)
4812 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4814 tword
= string_transform (xc
, v
, l
->word
->word
);
4815 w
= alloc_word_desc ();
4816 w
->word
= tword
? tword
: savestring (""); /* XXX */
4817 new = make_word_list (w
, new);
4820 l
= REVERSE_LIST (new, WORD_LIST
*);
4821 tword
= string_list_pos_params (itype
, l
, quoted
);
4828 parameter_list_transform (xc
, itype
, quoted
)
4836 list
= list_rest_of_args ();
4838 return ((char *)NULL
);
4840 return (pos_params_assignment (list
, itype
, quoted
));
4841 ret
= list_transform (xc
, (SHELL_VAR
*)0, list
, itype
, quoted
);
4842 dispose_words (list
);
4846 #if defined (ARRAY_VARS)
4848 array_transform (xc
, var
, varname
, quoted
)
4851 char *varname
; /* so we can figure out how it's indexed */
4861 /* compute itype from varname here */
4862 v
= array_variable_part (varname
, &ret
, 0);
4865 if (v
&& invisible_p (v
))
4866 return ((char *)NULL
);
4871 return (array_var_assignment (v
, itype
, quoted
));
4873 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4874 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4876 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4878 return ((char *)NULL
);
4879 ret
= list_transform (xc
, v
, list
, itype
, quoted
);
4880 dispose_words (list
);
4884 #endif /* ARRAY_VARS */
4887 parameter_brace_transform (varname
, value
, ind
, xform
, rtype
, quoted
, flags
)
4888 char *varname
, *value
;
4891 int rtype
, quoted
, flags
;
4898 if (value
== 0 && xc
!= 'A' && xc
!= 'a')
4899 return ((char *)NULL
);
4901 this_command_name
= varname
;
4903 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4905 return ((char *)NULL
);
4907 /* check for valid values of xc */
4910 case 'a': /* expand to a string with just attributes */
4911 case 'A': /* expand as an assignment statement with attributes */
4912 case 'E': /* expand like $'...' */
4913 case 'P': /* expand like prompt string */
4914 case 'Q': /* quote reusably */
4917 return &expand_param_error
;
4920 temp1
= (char *)NULL
; /* shut up gcc */
4921 switch (vtype
& ~VT_STARSUB
)
4924 case VT_ARRAYMEMBER
:
4925 temp1
= string_transform (xc
, v
, val
);
4926 if (vtype
== VT_VARIABLE
)
4930 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4931 ? quote_string (temp1
)
4932 : quote_escapes (temp1
);
4937 #if defined (ARRAY_VARS)
4939 temp1
= array_transform (xc
, v
, varname
, quoted
);
4940 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4942 val
= quote_escapes (temp1
);
4949 temp1
= parameter_list_transform (xc
, varname
[0], quoted
);
4950 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4952 val
= quote_escapes (temp1
);
4962 /*******************************************
4964 * Functions to expand WORD_DESCs *
4966 *******************************************/
4968 /* Expand WORD, performing word splitting on the result. This does
4969 parameter expansion, command substitution, arithmetic expansion,
4970 word splitting, and quote removal. */
4973 expand_word (word
, quoted
)
4977 WORD_LIST
*result
, *tresult
;
4979 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4980 result
= word_list_split (tresult
);
4981 dispose_words (tresult
);
4982 return (result
? dequote_list (result
) : result
);
4985 /* Expand WORD, but do not perform word splitting on the result. This
4986 does parameter expansion, command substitution, arithmetic expansion,
4987 and quote removal. */
4989 expand_word_unsplit (word
, quoted
)
4995 expand_no_split_dollar_star
= 1;
4996 #if defined (HANDLE_MULTIBYTE)
4997 if (ifs_firstc
[0] == 0)
4999 if (ifs_firstc
== 0)
5001 word
->flags
|= W_NOSPLIT
;
5002 word
->flags
|= W_NOSPLIT2
;
5003 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
5004 expand_no_split_dollar_star
= 0;
5006 return (result
? dequote_list (result
) : result
);
5009 /* Perform shell expansions on WORD, but do not perform word splitting or
5010 quote removal on the result. Virtually identical to expand_word_unsplit;
5011 could be combined if implementations don't diverge. */
5013 expand_word_leave_quoted (word
, quoted
)
5019 expand_no_split_dollar_star
= 1;
5020 #if defined (HANDLE_MULTIBYTE)
5021 if (ifs_firstc
[0] == 0)
5023 if (ifs_firstc
== 0)
5025 word
->flags
|= W_NOSPLIT
;
5026 word
->flags
|= W_NOSPLIT2
;
5027 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
5028 expand_no_split_dollar_star
= 0;
5033 #if defined (PROCESS_SUBSTITUTION)
5035 /*****************************************************************/
5037 /* Hacking Process Substitution */
5039 /*****************************************************************/
5041 #if !defined (HAVE_DEV_FD)
5042 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
5043 of FIFOs the shell has open. unlink_fifo_list will walk the list and
5044 unlink all of them. add_fifo_list adds the name of an open FIFO to the
5045 list. NFIFO is a count of the number of FIFOs in the list. */
5046 #define FIFO_INCR 20
5053 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
5055 static int fifo_list_size
;
5063 copy_fifo_list (sizep
)
5068 return (char *)NULL
;
5072 add_fifo_list (pathname
)
5075 if (nfifo
>= fifo_list_size
- 1)
5077 fifo_list_size
+= FIFO_INCR
;
5078 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
5079 fifo_list_size
* sizeof (struct temp_fifo
));
5082 fifo_list
[nfifo
].file
= savestring (pathname
);
5090 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
5092 unlink (fifo_list
[i
].file
);
5093 free (fifo_list
[i
].file
);
5094 fifo_list
[i
].file
= (char *)NULL
;
5095 fifo_list
[i
].proc
= -1;
5107 for (i
= saved
= 0; i
< nfifo
; i
++)
5109 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
5111 unlink (fifo_list
[i
].file
);
5112 free (fifo_list
[i
].file
);
5113 fifo_list
[i
].file
= (char *)NULL
;
5114 fifo_list
[i
].proc
= -1;
5120 /* If we didn't remove some of the FIFOs, compact the list. */
5123 for (i
= j
= 0; i
< nfifo
; i
++)
5124 if (fifo_list
[i
].file
)
5126 fifo_list
[j
].file
= fifo_list
[i
].file
;
5127 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
5136 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
5137 from some point in the past, and close all open FIFOs in fifo_list
5138 that are not marked as active in LIST. If LIST is NULL, close
5139 everything in fifo_list. LSIZE is the number of elements in LIST, in
5140 case it's larger than fifo_list_size (size of fifo_list). */
5142 close_new_fifos (list
, lsize
)
5150 unlink_fifo_list ();
5154 for (i
= 0; i
< lsize
; i
++)
5155 if (list
[i
] == 0 && i
< fifo_list_size
&& fifo_list
[i
].proc
!= -1)
5158 for (i
= lsize
; i
< fifo_list_size
; i
++)
5179 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
5180 if (mkfifo (tname
, 0600) < 0)
5183 return ((char *)NULL
);
5186 add_fifo_list (tname
);
5190 #else /* HAVE_DEV_FD */
5192 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
5193 has open to children. NFDS is a count of the number of bits currently
5194 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
5196 static char *dev_fd_list
= (char *)NULL
;
5198 static int totfds
; /* The highest possible number of open files. */
5219 for (i
= 0; nfds
&& i
< totfds
; i
++)
5226 copy_fifo_list (sizep
)
5231 if (nfds
== 0 || totfds
== 0)
5235 return (char *)NULL
;
5240 ret
= (char *)xmalloc (totfds
);
5241 return (memcpy (ret
, dev_fd_list
, totfds
));
5248 if (dev_fd_list
== 0 || fd
>= totfds
)
5253 totfds
= getdtablesize ();
5254 if (totfds
< 0 || totfds
> 256)
5259 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
5260 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
5263 dev_fd_list
[fd
] = 1;
5270 return 0; /* used for cleanup; not needed with /dev/fd */
5283 if (dev_fd_list
[fd
])
5286 dev_fd_list
[fd
] = 0;
5299 for (i
= 0; nfds
&& i
< totfds
; i
++)
5305 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
5306 the past, and close all open fds in dev_fd_list that are not marked
5307 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
5308 LSIZE is the number of elements in LIST, in case it's larger than
5309 totfds (size of dev_fd_list). */
5311 close_new_fifos (list
, lsize
)
5319 unlink_fifo_list ();
5323 for (i
= 0; i
< lsize
; i
++)
5324 if (list
[i
] == 0 && i
< totfds
&& dev_fd_list
[i
])
5327 for (i
= lsize
; i
< totfds
; i
++)
5331 #if defined (NOTDEF)
5332 print_dev_fd_list ()
5336 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
5339 for (i
= 0; i
< totfds
; i
++)
5342 fprintf (stderr
, " %d", i
);
5344 fprintf (stderr
, "\n");
5349 make_dev_fd_filename (fd
)
5352 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
5354 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
5356 strcpy (ret
, DEV_FD_PREFIX
);
5357 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
5358 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
5364 #endif /* HAVE_DEV_FD */
5366 /* Return a filename that will open a connection to the process defined by
5367 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
5368 a filename in /dev/fd corresponding to a descriptor that is one of the
5369 ends of the pipe. If not defined, we use named pipes on systems that have
5370 them. Systems without /dev/fd and named pipes are out of luck.
5372 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
5373 use the read end of the pipe and dup that file descriptor to fd 0 in
5374 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
5375 writing or use the write end of the pipe in the child, and dup that
5376 file descriptor to fd 1 in the child. The parent does the opposite. */
5379 process_substitute (string
, open_for_read_in_child
)
5381 int open_for_read_in_child
;
5386 #if defined (HAVE_DEV_FD)
5387 int parent_pipe_fd
, child_pipe_fd
;
5389 #endif /* HAVE_DEV_FD */
5390 #if defined (JOB_CONTROL)
5391 pid_t old_pipeline_pgrp
;
5394 if (!string
|| !*string
|| wordexp_only
)
5395 return ((char *)NULL
);
5397 #if !defined (HAVE_DEV_FD)
5398 pathname
= make_named_pipe ();
5399 #else /* HAVE_DEV_FD */
5400 if (pipe (fildes
) < 0)
5402 sys_error (_("cannot make pipe for process substitution"));
5403 return ((char *)NULL
);
5405 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
5406 the pipe in the parent, otherwise the read end. */
5407 parent_pipe_fd
= fildes
[open_for_read_in_child
];
5408 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
5409 /* Move the parent end of the pipe to some high file descriptor, to
5410 avoid clashes with FDs used by the script. */
5411 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
5413 pathname
= make_dev_fd_filename (parent_pipe_fd
);
5414 #endif /* HAVE_DEV_FD */
5418 sys_error (_("cannot make pipe for process substitution"));
5419 return ((char *)NULL
);
5422 old_pid
= last_made_pid
;
5424 #if defined (JOB_CONTROL)
5425 old_pipeline_pgrp
= pipeline_pgrp
;
5426 pipeline_pgrp
= shell_pgrp
;
5428 #endif /* JOB_CONTROL */
5430 pid
= make_child ((char *)NULL
, 1);
5433 reset_terminating_signals (); /* XXX */
5434 free_pushed_string_input ();
5435 /* Cancel traps, in trap.c. */
5436 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5437 setup_async_signals ();
5438 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
5441 #if defined (JOB_CONTROL)
5442 set_sigchld_handler ();
5443 stop_making_children ();
5444 /* XXX - should we only do this in the parent? (as in command subst) */
5445 pipeline_pgrp
= old_pipeline_pgrp
;
5446 #endif /* JOB_CONTROL */
5450 sys_error (_("cannot make child for process substitution"));
5452 #if defined (HAVE_DEV_FD)
5453 close (parent_pipe_fd
);
5454 close (child_pipe_fd
);
5455 #endif /* HAVE_DEV_FD */
5456 return ((char *)NULL
);
5461 #if defined (JOB_CONTROL)
5462 restore_pipeline (1);
5465 #if !defined (HAVE_DEV_FD)
5466 fifo_list
[nfifo
-1].proc
= pid
;
5469 last_made_pid
= old_pid
;
5471 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5473 #endif /* JOB_CONTROL && PGRP_PIPE */
5475 #if defined (HAVE_DEV_FD)
5476 close (child_pipe_fd
);
5477 #endif /* HAVE_DEV_FD */
5482 set_sigint_handler ();
5484 #if defined (JOB_CONTROL)
5485 set_job_control (0);
5486 #endif /* JOB_CONTROL */
5488 #if !defined (HAVE_DEV_FD)
5489 /* Open the named pipe in the child. */
5490 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
: O_WRONLY
);
5493 /* Two separate strings for ease of translation. */
5494 if (open_for_read_in_child
)
5495 sys_error (_("cannot open named pipe %s for reading"), pathname
);
5497 sys_error (_("cannot open named pipe %s for writing"), pathname
);
5501 if (open_for_read_in_child
)
5503 if (sh_unset_nodelay_mode (fd
) < 0)
5505 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
5509 #else /* HAVE_DEV_FD */
5511 #endif /* HAVE_DEV_FD */
5513 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
5515 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
5516 open_for_read_in_child
? 0 : 1);
5520 if (fd
!= (open_for_read_in_child
? 0 : 1))
5523 /* Need to close any files that this process has open to pipes inherited
5525 if (current_fds_to_close
)
5527 close_fd_bitmap (current_fds_to_close
);
5528 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
5531 #if defined (HAVE_DEV_FD)
5532 /* Make sure we close the parent's end of the pipe and clear the slot
5533 in the fd list so it is not closed later, if reallocated by, for
5534 instance, pipe(2). */
5535 close (parent_pipe_fd
);
5536 dev_fd_list
[parent_pipe_fd
] = 0;
5537 #endif /* HAVE_DEV_FD */
5539 /* subshells shouldn't have this flag, which controls using the temporary
5540 environment for variable lookups. */
5541 expanding_redir
= 0;
5543 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
5545 #if !defined (HAVE_DEV_FD)
5546 /* Make sure we close the named pipe in the child before we exit. */
5547 close (open_for_read_in_child
? 0 : 1);
5548 #endif /* !HAVE_DEV_FD */
5550 last_command_exit_value
= result
;
5551 result
= run_exit_trap ();
5555 #endif /* PROCESS_SUBSTITUTION */
5557 /***********************************/
5559 /* Command Substitution */
5561 /***********************************/
5564 read_comsub (fd
, quoted
, rflag
)
5568 char *istring
, buf
[128], *bufp
, *s
;
5569 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
5572 istring
= (char *)NULL
;
5573 istring_index
= istring_size
= bufn
= tflag
= 0;
5575 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
5576 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
5578 /* Read the output of the command through the pipe. This may need to be
5579 changed to understand multibyte characters in the future. */
5586 bufn
= zread (fd
, buf
, sizeof (buf
));
5596 internal_warning ("command substitution: ignored null byte in input");
5601 /* Add the character to ISTRING, possibly after resizing it. */
5602 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
5604 /* This is essentially quote_string inline */
5605 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
5606 istring
[istring_index
++] = CTLESC
;
5607 /* Escape CTLESC and CTLNUL in the output to protect those characters
5608 from the rest of the word expansions (word splitting and globbing.)
5609 This is essentially quote_escapes inline. */
5610 else if (skip_ctlesc
== 0 && c
== CTLESC
)
5612 tflag
|= W_HASCTLESC
;
5613 istring
[istring_index
++] = CTLESC
;
5615 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
5616 istring
[istring_index
++] = CTLESC
;
5618 istring
[istring_index
++] = c
;
5621 #if defined (__CYGWIN__)
5622 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
5625 istring
[istring_index
- 1] = '\n';
5632 istring
[istring_index
] = '\0';
5634 /* If we read no output, just return now and save ourselves some
5636 if (istring_index
== 0)
5641 return (char *)NULL
;
5644 /* Strip trailing newlines from the output of the command. */
5645 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5647 while (istring_index
> 0)
5649 if (istring
[istring_index
- 1] == '\n')
5653 /* If the newline was quoted, remove the quoting char. */
5654 if (istring
[istring_index
- 1] == CTLESC
)
5660 istring
[istring_index
] = '\0';
5663 strip_trailing (istring
, istring_index
- 1, 1);
5670 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5671 contained string possibly quoted. */
5673 command_substitute (string
, quoted
)
5677 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
5679 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
5682 istring
= (char *)NULL
;
5684 /* Don't fork () if there is no need to. In the case of no command to
5685 run, just return NULL. */
5687 for (s
= string
; s
&& *s
&& (shellblank (*s
) || *s
== '\n'); s
++)
5689 if (s
== 0 || *s
== 0)
5690 return ((WORD_DESC
*)NULL
);
5692 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5693 return ((WORD_DESC
*)NULL
);
5696 if (wordexp_only
&& read_but_dont_execute
)
5698 last_command_exit_value
= EX_WEXPCOMSUB
;
5699 jump_to_top_level (EXITPROG
);
5702 /* We're making the assumption here that the command substitution will
5703 eventually run a command from the file system. Since we'll run
5704 maybe_make_export_env in this subshell before executing that command,
5705 the parent shell and any other shells it starts will have to remake
5706 the environment. If we make it before we fork, other shells won't
5707 have to. Don't bother if we have any temporary variable assignments,
5708 though, because the export environment will be remade after this
5709 command completes anyway, but do it if all the words to be expanded
5710 are variable assignments. */
5711 if (subst_assign_varlist
== 0 || garglist
== 0)
5712 maybe_make_export_env (); /* XXX */
5714 /* Flags to pass to parse_and_execute() */
5715 pflags
= (interactive
&& sourcelevel
== 0) ? SEVAL_RESETLINE
: 0;
5717 /* Pipe the output of executing STRING into the current shell. */
5718 if (pipe (fildes
) < 0)
5720 sys_error (_("cannot make pipe for command substitution"));
5724 old_pid
= last_made_pid
;
5725 #if defined (JOB_CONTROL)
5726 old_pipeline_pgrp
= pipeline_pgrp
;
5727 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5728 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5729 pipeline_pgrp
= shell_pgrp
;
5730 cleanup_the_pipeline ();
5731 #endif /* JOB_CONTROL */
5733 old_async_pid
= last_asynchronous_pid
;
5734 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5735 last_asynchronous_pid
= old_async_pid
;
5739 /* Reset the signal handlers in the child, but don't free the
5740 trap strings. Set a flag noting that we have to free the
5741 trap strings if we run trap to change a signal disposition. */
5742 reset_signal_handlers ();
5743 subshell_environment
|= SUBSHELL_RESETTRAP
;
5746 #if defined (JOB_CONTROL)
5747 /* XXX DO THIS ONLY IN PARENT ? XXX */
5748 set_sigchld_handler ();
5749 stop_making_children ();
5751 pipeline_pgrp
= old_pipeline_pgrp
;
5753 stop_making_children ();
5754 #endif /* JOB_CONTROL */
5758 sys_error (_("cannot make child for command substitution"));
5761 last_made_pid
= old_pid
;
5766 return ((WORD_DESC
*)NULL
);
5771 set_sigint_handler (); /* XXX */
5773 free_pushed_string_input ();
5775 if (dup2 (fildes
[1], 1) < 0)
5777 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5778 exit (EXECUTION_FAILURE
);
5781 /* If standard output is closed in the parent shell
5782 (such as after `exec >&-'), file descriptor 1 will be
5783 the lowest available file descriptor, and end up in
5784 fildes[0]. This can happen for stdin and stderr as well,
5785 but stdout is more important -- it will cause no output
5786 to be generated from this command. */
5787 if ((fildes
[1] != fileno (stdin
)) &&
5788 (fildes
[1] != fileno (stdout
)) &&
5789 (fildes
[1] != fileno (stderr
)))
5792 if ((fildes
[0] != fileno (stdin
)) &&
5793 (fildes
[0] != fileno (stdout
)) &&
5794 (fildes
[0] != fileno (stderr
)))
5798 /* Let stdio know the fd may have changed from text to binary mode, and
5799 make sure to preserve stdout line buffering. */
5800 freopen (NULL
, "w", stdout
);
5801 sh_setlinebuf (stdout
);
5802 #endif /* __CYGWIN__ */
5804 /* The currently executing shell is not interactive. */
5807 /* This is a subshell environment. */
5808 subshell_environment
|= SUBSHELL_COMSUB
;
5810 /* Many shells do not appear to inherit the -v option for command
5812 change_flag ('v', FLAG_OFF
);
5814 /* When not in POSIX mode, command substitution does not inherit
5816 if (posixly_correct
== 0)
5818 builtin_ignoring_errexit
= 0;
5819 change_flag ('e', FLAG_OFF
);
5823 /* If we are expanding a redirection, we can dispose of any temporary
5824 environment we received, since redirections are not supposed to have
5825 access to the temporary environment. We will have to see whether this
5826 affects temporary environments supplied to `eval', but the temporary
5827 environment gets copied to builtin_env at some point. */
5828 if (expanding_redir
)
5830 flush_temporary_env ();
5831 expanding_redir
= 0;
5834 remove_quoted_escapes (string
);
5836 startup_state
= 2; /* see if we can avoid a fork */
5837 /* Give command substitution a place to jump back to on failure,
5838 so we don't go back up to main (). */
5839 result
= setjmp_nosigs (top_level
);
5841 /* If we're running a command substitution inside a shell function,
5842 trap `return' so we don't return from the function in the subshell
5843 and go off to never-never land. */
5844 if (result
== 0 && return_catch_flag
)
5845 function_value
= setjmp_nosigs (return_catch
);
5849 if (result
== ERREXIT
)
5850 rc
= last_command_exit_value
;
5851 else if (result
== EXITPROG
)
5852 rc
= last_command_exit_value
;
5854 rc
= EXECUTION_FAILURE
;
5855 else if (function_value
)
5856 rc
= return_catch_value
;
5860 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5864 last_command_exit_value
= rc
;
5865 rc
= run_exit_trap ();
5866 #if defined (PROCESS_SUBSTITUTION)
5867 unlink_fifo_list ();
5873 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5875 #endif /* JOB_CONTROL && PGRP_PIPE */
5880 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5884 current_command_subst_pid
= pid
;
5885 last_command_exit_value
= wait_for (pid
);
5886 last_command_subst_pid
= pid
;
5887 last_made_pid
= old_pid
;
5889 #if defined (JOB_CONTROL)
5890 /* If last_command_exit_value > 128, then the substituted command
5891 was terminated by a signal. If that signal was SIGINT, then send
5892 SIGINT to ourselves. This will break out of loops, for instance. */
5893 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5894 kill (getpid (), SIGINT
);
5896 /* wait_for gives the terminal back to shell_pgrp. If some other
5897 process group should have it, give it away to that group here.
5898 pipeline_pgrp is non-zero only while we are constructing a
5899 pipeline, so what we are concerned about is whether or not that
5900 pipeline was started in the background. A pipeline started in
5901 the background should never get the tty back here. */
5902 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5903 give_terminal_to (pipeline_pgrp
, 0);
5904 #endif /* JOB_CONTROL */
5906 ret
= alloc_word_desc ();
5907 ret
->word
= istring
;
5914 /********************************************************
5916 * Utility functions for parameter expansion *
5918 ********************************************************/
5920 #if defined (ARRAY_VARS)
5923 array_length_reference (s
)
5934 var
= array_variable_part (s
, &t
, &len
);
5936 /* If unbound variables should generate an error, report one and return
5938 if ((var
== 0 || invisible_p (var
) || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5942 last_command_exit_value
= EXECUTION_FAILURE
;
5947 else if (var
== 0 || invisible_p (var
))
5950 /* We support a couple of expansions for variables that are not arrays.
5951 We'll return the length of the value for v[0], and 1 for v[@] or
5952 v[*]. Return 0 for everything else. */
5954 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5955 h
= assoc_p (var
) ? assoc_cell (var
) : (HASH_TABLE
*)NULL
;
5957 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5960 return (h
? assoc_num_elements (h
) : 0);
5961 else if (array_p (var
))
5962 return (array
? array_num_elements (array
) : 0);
5964 return (var_isset (var
) ? 1 : 0);
5970 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5972 if (akey
== 0 || *akey
== 0)
5974 err_badarraysub (t
);
5978 t
= assoc_reference (assoc_cell (var
), akey
);
5983 ind
= array_expand_index (var
, t
, len
);
5984 /* negative subscripts to indexed arrays count back from end */
5985 if (var
&& array_p (var
) && ind
< 0)
5986 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
5989 err_badarraysub (t
);
5993 t
= array_reference (array
, ind
);
5995 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5998 len
= MB_STRLEN (t
);
6001 #endif /* ARRAY_VARS */
6004 valid_brace_expansion_word (name
, var_is_special
)
6008 if (DIGIT (*name
) && all_digits (name
))
6010 else if (var_is_special
)
6012 #if defined (ARRAY_VARS)
6013 else if (valid_array_reference (name
))
6015 #endif /* ARRAY_VARS */
6016 else if (legal_identifier (name
))
6023 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
6026 int *quoted_dollar_atp
, *contains_dollar_at
;
6032 if (quoted_dollar_atp
)
6033 *quoted_dollar_atp
= 0;
6034 if (contains_dollar_at
)
6035 *contains_dollar_at
= 0;
6039 /* check for $@ and $* */
6040 if (name
[0] == '@' && name
[1] == 0)
6042 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6043 *quoted_dollar_atp
= 1;
6044 if (contains_dollar_at
)
6045 *contains_dollar_at
= 1;
6048 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
6050 if (contains_dollar_at
)
6051 *contains_dollar_at
= 1;
6055 /* Now check for ${array[@]} and ${array[*]} */
6056 #if defined (ARRAY_VARS)
6057 else if (valid_array_reference (name
))
6059 temp1
= mbschr (name
, '[');
6060 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
6062 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6063 *quoted_dollar_atp
= 1;
6064 if (contains_dollar_at
)
6065 *contains_dollar_at
= 1;
6068 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
6069 which should result in separate words even when IFS is unset. */
6070 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
6072 if (contains_dollar_at
)
6073 *contains_dollar_at
= 1;
6081 /* Parameter expand NAME, and return a new string which is the expansion,
6082 or NULL if there was no expansion.
6083 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
6084 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
6085 NAME was found inside of a double-quoted expression. */
6087 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
, indp
)
6089 int var_is_special
, quoted
, pflags
;
6106 /* Handle multiple digit arguments, as in ${11}. */
6107 if (legal_number (name
, &arg_index
))
6109 tt
= get_dollar_var_value (arg_index
);
6111 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6113 : quote_escapes (tt
);
6115 temp
= (char *)NULL
;
6118 else if (var_is_special
) /* ${@} */
6121 tt
= (char *)xmalloc (2 + strlen (name
));
6122 tt
[sindex
= 0] = '$';
6123 strcpy (tt
+ 1, name
);
6125 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
6126 (int *)NULL
, (int *)NULL
, pflags
);
6129 #if defined (ARRAY_VARS)
6130 else if (valid_array_reference (name
))
6133 /* XXX - does this leak if name[@] or name[*]? */
6134 if (pflags
& PF_ASSIGNRHS
)
6136 var
= array_variable_part (name
, &tt
, (int *)0);
6137 if (ALL_ELEMENT_SUB (tt
[0]) && tt
[1] == ']')
6139 /* Only treat as double quoted if array variable */
6140 if (var
&& (array_p (var
) || assoc_p (var
)))
6141 temp
= array_value (name
, quoted
|Q_DOUBLE_QUOTES
, 0, &atype
, &ind
);
6143 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
6146 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
6149 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
6150 if (atype
== 0 && temp
)
6152 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6153 ? quote_string (temp
)
6154 : quote_escapes (temp
);
6155 rflags
|= W_ARRAYIND
;
6159 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6160 rflags
|= W_HASQUOTEDNULL
;
6163 else if (var
= find_variable (name
))
6165 if (var_isset (var
) && invisible_p (var
) == 0)
6167 #if defined (ARRAY_VARS)
6169 temp
= assoc_reference (assoc_cell (var
), "0");
6170 else if (array_p (var
))
6171 temp
= array_reference (array_cell (var
), 0);
6173 temp
= value_cell (var
);
6175 temp
= value_cell (var
);
6179 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6180 ? quote_string (temp
)
6181 : quote_escapes (temp
);
6184 temp
= (char *)NULL
;
6186 else if (var
= find_variable_last_nameref (name
))
6188 temp
= nameref_cell (var
);
6189 #if defined (ARRAY_VARS)
6190 /* Handle expanding nameref whose value is x[n] */
6191 if (temp
&& *temp
&& valid_array_reference (temp
))
6194 goto expand_arrayref
;
6198 /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */
6199 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
6201 last_command_exit_value
= EXECUTION_FAILURE
;
6202 report_error (_("%s: invalid variable name for name reference"), temp
);
6203 temp
= &expand_param_error
;
6206 temp
= (char *)NULL
;
6209 temp
= (char *)NULL
;
6213 ret
= alloc_word_desc ();
6215 ret
->flags
|= rflags
;
6221 parameter_brace_find_indir (name
, var_is_special
, quoted
, find_nameref
)
6223 int var_is_special
, quoted
, find_nameref
;
6229 if (find_nameref
&& var_is_special
== 0 && (v
= find_variable_last_nameref (name
)) &&
6230 nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
6231 return (savestring (t
));
6233 /* If var_is_special == 0, and name is not an array reference, this does
6234 more expansion than necessary. It should really look up the variable's
6235 value and not try to expand it. */
6236 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
, 0);
6238 /* Have to dequote here if necessary */
6241 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6242 ? dequote_string (t
)
6243 : dequote_escapes (t
);
6247 dispose_word_desc (w
);
6252 /* Expand an indirect reference to a variable: ${!NAME} expands to the
6253 value of the variable whose name is the value of NAME. */
6255 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
6257 int var_is_special
, quoted
;
6258 int *quoted_dollar_atp
, *contains_dollar_at
;
6264 /* See if it's a nameref first, behave in ksh93-compatible fashion.
6265 There is at least one incompatibility: given ${!foo[0]} where foo=bar,
6266 bash performs an indirect lookup on foo[0] and expands the result;
6267 ksh93 expands bar[0]. We could do that here -- there are enough usable
6268 primitives to do that -- but do not at this point. */
6269 if (var_is_special
== 0 && (v
= find_variable_last_nameref (name
)))
6271 if (nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
6273 w
= alloc_word_desc ();
6274 w
->word
= savestring (t
);
6280 t
= parameter_brace_find_indir (name
, var_is_special
, quoted
, 0);
6282 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6284 return (WORD_DESC
*)NULL
;
6286 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0, 0);
6292 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
6293 depending on the value of C, the separating character. C can be one of
6294 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
6295 between double quotes. */
6297 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
6299 int c
, quoted
, *qdollaratp
, *hasdollarat
;
6303 char *t
, *t1
, *temp
, *vname
;
6306 /* If the entire expression is between double quotes, we want to treat
6307 the value as a double-quoted string, with the exception that we strip
6308 embedded unescaped double quotes (for sh backwards compatibility). */
6309 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
6312 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
6317 w
= alloc_word_desc ();
6319 /* XXX was 0 not quoted */
6320 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
6323 *hasdollarat
= hasdol
|| (l
&& l
->next
);
6328 /* The expansion of TEMP returned something. We need to treat things
6329 slightly differently if HASDOL is non-zero. If we have "$@", the
6330 individual words have already been quoted. We need to turn them
6331 into a string with the words separated by the first character of
6332 $IFS without any additional quoting, so string_list_dollar_at won't
6333 do the right thing. We use string_list_dollar_star instead. */
6334 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
6336 /* If l->next is not null, we know that TEMP contained "$@", since that
6337 is the only expansion that creates more than one word. */
6338 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
6340 /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
6341 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
6342 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
6343 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
6344 (which is more paranoia than anything else), we need to return the
6345 quoted null string and set the flags to indicate it. */
6346 if (l
->next
== 0 && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
) && QUOTED_NULL (l
->word
->word
) && (l
->word
->flags
& W_HASQUOTEDNULL
))
6348 w
->flags
|= W_HASQUOTEDNULL
;
6352 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
6354 /* Posix interp 221 changed the rules on this. The idea is that
6355 something like "$xxx$@" should expand the same as "${foo-$xxx$@}"
6356 when foo and xxx are unset. The problem is that it's not in any
6357 way backwards compatible and few other shells do it. We're eventually
6358 going to try and split the difference (heh) a little bit here. */
6359 /* hasdol == 1 means we saw a quoted dollar at. */
6361 /* The brace expansion occurred between double quotes and there was
6362 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
6363 it does not expand to anything. In this case, we want to return
6364 a quoted empty string. */
6365 temp
= make_quoted_char ('\0');
6366 w
->flags
|= W_HASQUOTEDNULL
;
6369 temp
= (char *)NULL
;
6371 if (c
== '-' || c
== '+')
6378 t
= temp
? savestring (temp
) : savestring ("");
6379 t1
= dequote_string (t
);
6385 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1]) || VALID_INDIR_PARAM (name
[1])))
6387 vname
= parameter_brace_find_indir (name
+ 1, SPECIAL_VAR (name
, 1), quoted
, 1);
6388 if (vname
== 0 || *vname
== 0)
6390 report_error (_("%s: invalid indirect expansion"), name
);
6393 return &expand_wdesc_error
;
6395 if (legal_identifier (vname
) == 0)
6397 report_error (_("%s: invalid variable name"), vname
);
6400 return &expand_wdesc_error
;
6404 #if defined (ARRAY_VARS)
6405 if (valid_array_reference (vname
))
6406 assign_array_element (vname
, t1
, 0);
6408 #endif /* ARRAY_VARS */
6409 bind_variable (vname
, t1
, 0);
6411 stupidly_hack_special_variables (vname
);
6416 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
6423 /* Deal with the right hand side of a ${name:?value} expansion in the case
6424 that NAME is null or not set. If VALUE is non-null it is expanded and
6425 used as the error message to print, otherwise a standard message is
6428 parameter_brace_expand_error (name
, value
)
6434 last_command_exit_value
= EXECUTION_FAILURE
; /* ensure it's non-zero */
6435 if (value
&& *value
)
6437 l
= expand_string (value
, 0);
6438 temp
= string_list (l
);
6439 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
6444 report_error (_("%s: parameter null or not set"), name
);
6446 /* Free the data we have allocated during this expansion, since we
6447 are about to longjmp out. */
6452 /* Return 1 if NAME is something for which parameter_brace_expand_length is
6455 valid_length_expression (name
)
6458 return (name
[1] == '\0' || /* ${#} */
6459 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
6460 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
6461 #if defined (ARRAY_VARS)
6462 valid_array_reference (name
+ 1) || /* ${#a[7]} */
6464 legal_identifier (name
+ 1)); /* ${#PS1} */
6467 /* Handle the parameter brace expansion that requires us to return the
6468 length of a parameter. */
6470 parameter_brace_expand_length (name
)
6474 intmax_t number
, arg_index
;
6476 #if defined (ARRAY_VARS)
6480 if (name
[1] == '\0') /* ${#} */
6481 number
= number_of_args ();
6482 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
6483 number
= number_of_args ();
6484 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
6486 /* Take the lengths of some of the shell's special parameters. */
6490 t
= which_set_flags ();
6493 t
= itos (last_command_exit_value
);
6496 t
= itos (dollar_dollar_pid
);
6499 if (last_asynchronous_pid
== NO_PID
)
6500 t
= (char *)NULL
; /* XXX - error if set -u set? */
6502 t
= itos (last_asynchronous_pid
);
6505 t
= itos (number_of_args ());
6508 number
= STRLEN (t
);
6511 #if defined (ARRAY_VARS)
6512 else if (valid_array_reference (name
+ 1))
6513 number
= array_length_reference (name
+ 1);
6514 #endif /* ARRAY_VARS */
6519 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
6521 t
= get_dollar_var_value (arg_index
);
6522 if (t
== 0 && unbound_vars_is_error
)
6524 number
= MB_STRLEN (t
);
6527 #if defined (ARRAY_VARS)
6528 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
6531 t
= assoc_reference (assoc_cell (var
), "0");
6533 t
= array_reference (array_cell (var
), 0);
6534 if (t
== 0 && unbound_vars_is_error
)
6536 number
= MB_STRLEN (t
);
6541 newname
= savestring (name
);
6543 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
6544 t
= list
? string_list (list
) : (char *)NULL
;
6547 dispose_words (list
);
6549 number
= t
? MB_STRLEN (t
) : 0;
6557 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
6558 so we do some ad-hoc parsing of an arithmetic expression to find
6559 the first DELIM, instead of using strchr(3). Two rules:
6560 1. If the substring contains a `(', read until closing `)'.
6561 2. If the substring contains a `?', read past one `:' for each `?'.
6565 skiparith (substr
, delim
)
6570 int skipcol
, pcount
, i
;
6573 sublen
= strlen (substr
);
6574 i
= skipcol
= pcount
= 0;
6577 /* Balance parens */
6578 if (substr
[i
] == LPAREN
)
6584 if (substr
[i
] == RPAREN
&& pcount
)
6592 ADVANCE_CHAR (substr
, sublen
, i
);
6596 /* Skip one `:' for each `?' */
6597 if (substr
[i
] == ':' && skipcol
)
6603 if (substr
[i
] == delim
)
6605 if (substr
[i
] == '?')
6611 ADVANCE_CHAR (substr
, sublen
, i
);
6614 return (substr
+ i
);
6617 /* Verify and limit the start and end of the desired substring. If
6618 VTYPE == 0, a regular shell variable is being used; if it is 1,
6619 then the positional parameters are being used; if it is 2, then
6620 VALUE is really a pointer to an array variable that should be used.
6621 Return value is 1 if both values were OK, 0 if there was a problem
6622 with an invalid expression, or -1 if the values were out of range. */
6624 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
6626 char *value
, *substr
;
6628 intmax_t *e1p
, *e2p
;
6630 char *t
, *temp1
, *temp2
;
6633 #if defined (ARRAY_VARS)
6638 /* duplicate behavior of strchr(3) */
6639 t
= skiparith (substr
, ':');
6640 if (*t
&& *t
== ':')
6645 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
6646 *e1p
= evalexp (temp1
, &expok
);
6651 len
= -1; /* paranoia */
6655 case VT_ARRAYMEMBER
:
6656 len
= MB_STRLEN (value
);
6659 len
= number_of_args () + 1;
6661 len
++; /* add one arg if counting from $0 */
6663 #if defined (ARRAY_VARS)
6665 /* For arrays, the first value deals with array indices. Negative
6666 offsets count from one past the array's maximum index. Associative
6667 arrays treat the number of elements as the maximum index. */
6671 len
= assoc_num_elements (h
) + (*e1p
< 0);
6676 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
6682 if (len
== -1) /* paranoia */
6685 if (*e1p
< 0) /* negative offsets count from end */
6688 if (*e1p
> len
|| *e1p
< 0)
6691 #if defined (ARRAY_VARS)
6692 /* For arrays, the second offset deals with the number of elements. */
6693 if (vtype
== VT_ARRAYVAR
)
6694 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
6700 temp2
= savestring (t
);
6701 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6704 *e2p
= evalexp (temp1
, &expok
);
6709 if ((vtype
== VT_ARRAYVAR
|| vtype
== VT_POSPARMS
) && *e2p
< 0)
6711 /* bash-4.3: allow positional parameter length < 0 to count backwards
6712 from end of positional parameters */
6713 if (vtype
== VT_ARRAYVAR
&& *e2p
< 0)
6716 internal_error (_("%s: substring expression < 0"), t
);
6719 #if defined (ARRAY_VARS)
6720 /* In order to deal with sparse arrays, push the intelligence about how
6721 to deal with the number of elements desired down to the array-
6722 specific functions. */
6723 if (vtype
!= VT_ARRAYVAR
)
6729 if (*e2p
< 0 || *e2p
< *e1p
)
6731 internal_error (_("%s: substring expression < 0"), t
);
6736 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
6747 /* Return the type of variable specified by VARNAME (simple variable,
6748 positional param, or array variable). Also return the value specified
6749 by VARNAME (value of a variable or a reference to an array element).
6750 QUOTED is the standard description of quoting state, using Q_* defines.
6751 FLAGS is currently a set of flags to pass to array_value. If IND is
6752 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6753 passed to array_value so the array index is not computed again.
6754 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6755 characters in the value are quoted with CTLESC and takes appropriate
6756 steps. For convenience, *VALP is set to the dequoted VALUE. */
6758 get_var_and_type (varname
, value
, ind
, quoted
, flags
, varp
, valp
)
6759 char *varname
, *value
;
6765 int vtype
, want_indir
;
6771 want_indir
= *varname
== '!' &&
6772 (legal_variable_starter ((unsigned char)varname
[1]) || DIGIT (varname
[1])
6773 || VALID_INDIR_PARAM (varname
[1]));
6775 vname
= parameter_brace_find_indir (varname
+1, SPECIAL_VAR (varname
, 1), quoted
, 1);
6776 /* XXX - what if vname == 0 || *vname == 0 ? */
6780 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6781 vtype
= (vname
[0] == '@' || vname
[0] == '*') && vname
[1] == '\0';
6782 if (vtype
== VT_POSPARMS
&& vname
[0] == '*')
6783 vtype
|= VT_STARSUB
;
6784 *varp
= (SHELL_VAR
*)NULL
;
6786 #if defined (ARRAY_VARS)
6787 if (valid_array_reference (vname
))
6789 v
= array_variable_part (vname
, &temp
, (int *)0);
6790 /* If we want to signal array_value to use an already-computed index,
6791 set LIND to that index */
6792 lind
= (ind
!= INTMAX_MIN
&& (flags
& AV_USEIND
)) ? ind
: 0;
6793 if (v
&& invisible_p (v
))
6795 vtype
= VT_ARRAYMEMBER
;
6796 *varp
= (SHELL_VAR
*)NULL
;
6797 *valp
= (char *)NULL
;
6799 if (v
&& (array_p (v
) || assoc_p (v
)))
6801 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
6803 /* Callers have to differentiate between indexed and associative */
6804 vtype
= VT_ARRAYVAR
;
6806 vtype
|= VT_STARSUB
;
6807 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
6811 vtype
= VT_ARRAYMEMBER
;
6812 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6816 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
6818 vtype
= VT_VARIABLE
;
6820 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6821 *valp
= dequote_string (value
);
6823 *valp
= dequote_escapes (value
);
6827 vtype
= VT_ARRAYMEMBER
;
6829 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6832 else if ((v
= find_variable (vname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
6834 vtype
= VT_ARRAYMEMBER
;
6836 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
6841 if (value
&& vtype
== VT_VARIABLE
)
6843 *varp
= find_variable (vname
);
6844 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6845 *valp
= dequote_string (value
);
6847 *valp
= dequote_escapes (value
);
6859 /******************************************************/
6861 /* Functions to extract substrings of variable values */
6863 /******************************************************/
6865 #if defined (HANDLE_MULTIBYTE)
6866 /* Character-oriented rather than strictly byte-oriented substrings. S and
6867 E, rather being strict indices into STRING, indicate character (possibly
6868 multibyte character) positions that require calculation.
6869 Used by the ${param:offset[:length]} expansion. */
6871 mb_substring (string
, s
, e
)
6876 int start
, stop
, i
, slen
;
6880 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6881 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6884 while (string
[start
] && i
--)
6885 ADVANCE_CHAR (string
, slen
, start
);
6888 while (string
[stop
] && i
--)
6889 ADVANCE_CHAR (string
, slen
, stop
);
6890 tt
= substring (string
, start
, stop
);
6895 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6896 is `@', use the positional parameters; otherwise, use the value of
6897 VARNAME. If VARNAME is an array variable, use the array elements. */
6900 parameter_brace_substring (varname
, value
, ind
, substr
, quoted
, flags
)
6901 char *varname
, *value
;
6907 int vtype
, r
, starsub
;
6908 char *temp
, *val
, *tt
, *oname
;
6911 if (value
== 0 && ((varname
[0] != '@' && varname
[0] != '*') || varname
[1]))
6912 return ((char *)NULL
);
6914 oname
= this_command_name
;
6915 this_command_name
= varname
;
6917 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6920 this_command_name
= oname
;
6921 return ((char *)NULL
);
6924 starsub
= vtype
& VT_STARSUB
;
6925 vtype
&= ~VT_STARSUB
;
6927 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6928 this_command_name
= oname
;
6931 if (vtype
== VT_VARIABLE
)
6933 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6939 case VT_ARRAYMEMBER
:
6940 #if defined (HANDLE_MULTIBYTE)
6942 tt
= mb_substring (val
, e1
, e2
);
6945 tt
= substring (val
, e1
, e2
);
6947 if (vtype
== VT_VARIABLE
)
6949 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6950 temp
= quote_string (tt
);
6952 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6956 tt
= pos_params (varname
, e1
, e2
, quoted
);
6957 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6959 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6965 #if defined (ARRAY_VARS)
6968 /* we convert to list and take first e2 elements starting at e1th
6969 element -- officially undefined for now */
6970 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6972 /* We want E2 to be the number of elements desired (arrays can be sparse,
6973 so verify_substring_values just returns the numbers specified and we
6974 rely on array_subrange to understand how to deal with them). */
6975 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6976 /* array_subrange now calls array_quote_escapes as appropriate, so the
6977 caller no longer needs to. */
6981 temp
= (char *)NULL
;
6987 /****************************************************************/
6989 /* Functions to perform pattern substitution on variable values */
6991 /****************************************************************/
6994 shouldexp_replacement (s
)
6999 for (p
= s
; p
&& *p
; p
++)
7010 pat_subst (string
, pat
, rep
, mflags
)
7011 char *string
, *pat
, *rep
;
7014 char *ret
, *s
, *e
, *str
, *rstr
, *mstr
;
7015 int rsize
, rptr
, l
, replen
, mtype
, rxpand
, rslen
, mlen
;
7018 return (savestring (""));
7020 mtype
= mflags
& MATCH_TYPEMASK
;
7022 #if 0 /* bash-4.2 ? */
7023 rxpand
= (rep
&& *rep
) ? shouldexp_replacement (rep
) : 0;
7029 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
7030 * with REP and return the result.
7031 * 2. A null pattern with mtype == MATCH_END means to append REP to
7032 * STRING and return the result.
7033 * These don't understand or process `&' in the replacement string.
7035 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
7037 replen
= STRLEN (rep
);
7038 l
= STRLEN (string
);
7039 ret
= (char *)xmalloc (replen
+ l
+ 2);
7041 strcpy (ret
, string
);
7042 else if (mtype
== MATCH_BEG
)
7045 strcpy (ret
+ replen
, string
);
7049 strcpy (ret
, string
);
7050 strcpy (ret
+ l
, rep
);
7055 ret
= (char *)xmalloc (rsize
= 64);
7058 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
7060 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
7068 mstr
= xmalloc (mlen
+ 1);
7069 for (x
= 0; x
< mlen
; x
++)
7072 rstr
= strcreplace (rep
, '&', mstr
, 0);
7073 rslen
= strlen (rstr
);
7081 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ rslen
), rsize
, 64);
7083 /* OK, now copy the leading unmatched portion of the string (from
7084 str to s) to ret starting at rptr (the current offset). Then copy
7085 the replacement string at ret + rptr + (s - str). Increment
7086 rptr (if necessary) and str and go on. */
7089 strncpy (ret
+ rptr
, str
, l
);
7094 strncpy (ret
+ rptr
, rstr
, rslen
);
7097 str
= e
; /* e == end of match */
7102 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
7107 /* On a zero-length match, make sure we copy one character, since
7108 we increment one character to avoid infinite recursion. */
7109 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
7110 ret
[rptr
++] = *str
++;
7111 e
++; /* avoid infinite recursion on zero-length match */
7115 /* Now copy the unmatched portion of the input string */
7118 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
7119 strcpy (ret
+ rptr
, str
);
7127 /* Do pattern match and replacement on the positional parameters. */
7129 pos_params_pat_subst (string
, pat
, rep
, mflags
)
7130 char *string
, *pat
, *rep
;
7133 WORD_LIST
*save
, *params
;
7138 save
= params
= list_rest_of_args ();
7140 return ((char *)NULL
);
7142 for ( ; params
; params
= params
->next
)
7144 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
7145 w
= alloc_word_desc ();
7146 w
->word
= ret
? ret
: savestring ("");
7147 dispose_word (params
->word
);
7151 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
7152 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
7154 ret
= string_list_pos_params (pchar
, save
, qflags
);
7156 dispose_words (save
);
7161 /* Perform pattern substitution on VALUE, which is the expansion of
7162 VARNAME. PATSUB is an expression supplying the pattern to match
7163 and the string to substitute. QUOTED is a flags word containing
7164 the type of quoting currently in effect. */
7166 parameter_brace_patsub (varname
, value
, ind
, patsub
, quoted
, flags
)
7167 char *varname
, *value
;
7172 int vtype
, mflags
, starsub
, delim
;
7173 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
7177 return ((char *)NULL
);
7179 this_command_name
= varname
;
7181 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
7183 return ((char *)NULL
);
7185 starsub
= vtype
& VT_STARSUB
;
7186 vtype
&= ~VT_STARSUB
;
7189 /* PATSUB is never NULL when this is called. */
7192 mflags
|= MATCH_GLOBREP
;
7196 /* Malloc this because expand_string_if_necessary or one of the expansion
7197 functions in its call chain may free it on a substitution error. */
7198 lpatsub
= savestring (patsub
);
7200 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7201 mflags
|= MATCH_QUOTED
;
7204 mflags
|= MATCH_STARSUB
;
7206 /* If the pattern starts with a `/', make sure we skip over it when looking
7207 for the replacement delimiter. */
7208 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
7209 if (lpatsub
[delim
] == '/')
7212 rep
= lpatsub
+ delim
+ 1;
7217 if (rep
&& *rep
== '\0')
7220 /* Perform the same expansions on the pattern as performed by the
7221 pattern removal expansions. */
7222 pat
= getpattern (lpatsub
, quoted
, 1);
7226 /* We want to perform quote removal on the expanded replacement even if
7227 the entire expansion is double-quoted because the parser and string
7228 extraction functions treated quotes in the replacement string as
7229 special. THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */
7230 if (shell_compatibility_level
> 42)
7231 rep
= expand_string_if_necessary (rep
, quoted
& ~(Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
), expand_string_unsplit
);
7232 /* This is the bash-4.2 code. */
7233 else if ((mflags
& MATCH_QUOTED
) == 0)
7234 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
7236 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
7239 /* ksh93 doesn't allow the match specifier to be a part of the expanded
7240 pattern. This is an extension. Make sure we don't anchor the pattern
7241 at the beginning or end of the string if we're doing global replacement,
7244 if (mflags
& MATCH_GLOBREP
)
7245 mflags
|= MATCH_ANY
;
7246 else if (pat
&& pat
[0] == '#')
7248 mflags
|= MATCH_BEG
;
7251 else if (pat
&& pat
[0] == '%')
7253 mflags
|= MATCH_END
;
7257 mflags
|= MATCH_ANY
;
7259 /* OK, we now want to substitute REP for PAT in VAL. If
7260 flags & MATCH_GLOBREP is non-zero, the substitution is done
7261 everywhere, otherwise only the first occurrence of PAT is
7262 replaced. The pattern matching code doesn't understand
7263 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
7264 values passed in (VT_VARIABLE) so the pattern substitution
7265 code works right. We need to requote special chars after
7266 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
7267 other cases if QUOTED == 0, since the posparams and arrays
7268 indexed by * or @ do special things when QUOTED != 0. */
7273 case VT_ARRAYMEMBER
:
7274 temp
= pat_subst (val
, p
, rep
, mflags
);
7275 if (vtype
== VT_VARIABLE
)
7279 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
7285 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
7286 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
7288 tt
= quote_escapes (temp
);
7293 #if defined (ARRAY_VARS)
7295 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
7296 : array_patsub (array_cell (v
), p
, rep
, mflags
);
7297 /* Don't call quote_escapes anymore; array_patsub calls
7298 array_quote_escapes as appropriate before adding the
7299 space separators; ditto for assoc_patsub. */
7311 /****************************************************************/
7313 /* Functions to perform case modification on variable values */
7315 /****************************************************************/
7317 /* Do case modification on the positional parameters. */
7320 pos_params_modcase (string
, pat
, modop
, mflags
)
7325 WORD_LIST
*save
, *params
;
7330 save
= params
= list_rest_of_args ();
7332 return ((char *)NULL
);
7334 for ( ; params
; params
= params
->next
)
7336 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
7337 w
= alloc_word_desc ();
7338 w
->word
= ret
? ret
: savestring ("");
7339 dispose_word (params
->word
);
7343 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
7344 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
7346 ret
= string_list_pos_params (pchar
, save
, qflags
);
7347 dispose_words (save
);
7352 /* Perform case modification on VALUE, which is the expansion of
7353 VARNAME. MODSPEC is an expression supplying the type of modification
7354 to perform. QUOTED is a flags word containing the type of quoting
7355 currently in effect. */
7357 parameter_brace_casemod (varname
, value
, ind
, modspec
, patspec
, quoted
, flags
)
7358 char *varname
, *value
;
7363 int vtype
, starsub
, modop
, mflags
, x
;
7364 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
7368 return ((char *)NULL
);
7370 this_command_name
= varname
;
7372 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
7374 return ((char *)NULL
);
7376 starsub
= vtype
& VT_STARSUB
;
7377 vtype
&= ~VT_STARSUB
;
7381 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7382 mflags
|= MATCH_QUOTED
;
7384 mflags
|= MATCH_STARSUB
;
7389 x
= p
&& p
[0] == modspec
;
7390 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
7393 else if (modspec
== ',')
7395 x
= p
&& p
[0] == modspec
;
7396 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
7399 else if (modspec
== '~')
7401 x
= p
&& p
[0] == modspec
;
7402 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
7406 lpat
= p
? savestring (p
) : 0;
7407 /* Perform the same expansions on the pattern as performed by the
7408 pattern removal expansions. FOR LATER */
7409 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
7411 /* OK, now we do the case modification. */
7415 case VT_ARRAYMEMBER
:
7416 temp
= sh_modcase (val
, pat
, modop
);
7417 if (vtype
== VT_VARIABLE
)
7421 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
7428 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
7429 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
7431 tt
= quote_escapes (temp
);
7437 #if defined (ARRAY_VARS)
7439 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
7440 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
7441 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
7442 as appropriate before adding the space separators; ditto for
7454 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
7455 any occur, this must be a nested command substitution, so return 0.
7456 Otherwise, return 1. A valid arithmetic expression must always have a
7457 ( before a matching ), so any cases where there are more right parens
7458 means that this must not be an arithmetic expression, though the parser
7459 will not accept it without a balanced total number of parens. */
7461 chk_arithsub (s
, len
)
7473 else if (s
[i
] == RPAREN
)
7483 ADVANCE_CHAR (s
, len
, i
);
7489 ADVANCE_CHAR (s
, len
, i
);
7493 i
= skip_single_quoted (s
, len
, ++i
);
7497 i
= skip_double_quoted ((char *)s
, len
, ++i
);
7502 return (count
== 0);
7505 /****************************************************************/
7507 /* Functions to perform parameter expansion on a string */
7509 /****************************************************************/
7511 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
7513 parameter_brace_expand (string
, indexp
, quoted
, pflags
, quoted_dollar_atp
, contains_dollar_at
)
7515 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
, pflags
;
7517 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
7518 int want_substring
, want_indir
, want_patsub
, want_casemod
;
7519 char *name
, *value
, *temp
, *temp1
;
7520 WORD_DESC
*tdesc
, *ret
;
7521 int t_index
, sindex
, c
, tflag
, modspec
;
7525 temp
= temp1
= value
= (char *)NULL
;
7526 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
7527 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
7531 /* ${#var} doesn't have any of the other parameter expansions on it. */
7532 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
7533 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
7535 #if defined (CASEMOD_EXPANSIONS)
7536 /* To enable case-toggling expansions using the `~' operator character
7537 change the 1 to 0. */
7538 # if defined (CASEMOD_CAPCASE)
7539 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/@}", SX_VARNAME
);
7541 name
= string_extract (string
, &t_index
, "#%^,:-=?+/@}", SX_VARNAME
);
7542 # endif /* CASEMOD_CAPCASE */
7544 name
= string_extract (string
, &t_index
, "#%:-=?+/@}", SX_VARNAME
);
7545 #endif /* CASEMOD_EXPANSIONS */
7547 /* Handle ${@[stuff]} now that @ is a word expansion operator. Not exactly
7548 the cleanest code ever. */
7549 if (*name
== 0 && sindex
== t_index
&& string
[sindex
] == '@')
7551 name
= (char *)xrealloc (name
, 2);
7562 /* If the name really consists of a special variable, then make sure
7563 that we have the entire name. We don't allow indirect references
7564 to special variables except `#', `?', `@' and `*'. This clause is
7565 designed to handle ${#SPECIAL} and ${!SPECIAL}, not anything more
7567 if ((sindex
== t_index
&& VALID_SPECIAL_LENGTH_PARAM (string
[t_index
])) ||
7568 (sindex
== t_index
&& string
[sindex
] == '#' && VALID_SPECIAL_LENGTH_PARAM (string
[sindex
+ 1])) ||
7569 (sindex
== t_index
- 1 && string
[sindex
] == '!' && VALID_INDIR_PARAM (string
[t_index
])))
7572 temp1
= string_extract (string
, &t_index
, "#%:-=?+/@}", 0);
7573 name
= (char *)xrealloc (name
, 3 + (strlen (temp1
)));
7574 *name
= string
[sindex
];
7575 if (string
[sindex
] == '!')
7577 /* indirect reference of $#, $?, $@, or $* */
7578 name
[1] = string
[sindex
+ 1];
7579 strcpy (name
+ 2, temp1
);
7582 strcpy (name
+ 1, temp1
);
7587 /* Find out what character ended the variable name. Then
7588 do the appropriate thing. */
7589 if (c
= string
[sindex
])
7592 /* If c is followed by one of the valid parameter expansion
7593 characters, move past it as normal. If not, assume that
7594 a substring specification is being given, and do not move
7596 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
7599 if (c
= string
[sindex
])
7602 else if (c
== ':' && string
[sindex
] != RBRACE
)
7604 else if (c
== '/' /* && string[sindex] != RBRACE */) /* XXX */
7606 #if defined (CASEMOD_EXPANSIONS)
7607 else if (c
== '^' || c
== ',' || c
== '~')
7614 /* Catch the valid and invalid brace expressions that made it through the
7616 /* ${#-} is a valid expansion and means to take the length of $-.
7617 Similarly for ${#?} and ${##}... */
7618 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7619 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
7621 name
= (char *)xrealloc (name
, 3);
7624 c
= string
[sindex
++];
7627 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7628 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7629 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
7631 temp
= (char *)NULL
;
7632 goto bad_substitution
;
7635 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7636 either a variable name, one of the positional parameters or a special
7637 variable that expands to one of the positional parameters. */
7638 want_indir
= *name
== '!' &&
7639 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
7640 || VALID_INDIR_PARAM (name
[1]));
7642 /* Determine the value of this variable. */
7644 /* Check for special variables, directly referenced. */
7645 if (SPECIAL_VAR (name
, want_indir
))
7648 /* Check for special expansion things, like the length of a parameter */
7649 if (*name
== '#' && name
[1])
7651 /* If we are not pointing at the character just after the
7652 closing brace, then we haven't gotten all of the name.
7653 Since it begins with a special character, this is a bad
7654 substitution. Also check NAME for validity before trying
7656 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
7658 temp
= (char *)NULL
;
7659 goto bad_substitution
;
7662 number
= parameter_brace_expand_length (name
);
7663 if (number
== INTMAX_MIN
&& unbound_vars_is_error
)
7665 last_command_exit_value
= EXECUTION_FAILURE
;
7666 err_unboundvar (name
+1);
7668 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7674 return (&expand_wdesc_error
);
7677 ret
= alloc_word_desc ();
7678 ret
->word
= itos (number
);
7683 /* ${@} is identical to $@. */
7684 if (name
[0] == '@' && name
[1] == '\0')
7686 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7687 *quoted_dollar_atp
= 1;
7689 if (contains_dollar_at
)
7690 *contains_dollar_at
= 1;
7692 tflag
|= W_DOLLARAT
;
7695 /* Process ${!PREFIX*} expansion. */
7696 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7697 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
7698 legal_variable_starter ((unsigned char) name
[1]))
7703 temp1
= savestring (name
+ 1);
7704 number
= strlen (temp1
);
7705 temp1
[number
- 1] = '\0';
7706 x
= all_variables_matching_prefix (temp1
);
7707 xlist
= strvec_to_word_list (x
, 0, 0);
7708 if (string
[sindex
- 2] == '*')
7709 temp
= string_list_dollar_star (xlist
);
7712 temp
= string_list_dollar_at (xlist
, quoted
);
7713 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7714 *quoted_dollar_atp
= 1;
7715 if (contains_dollar_at
)
7716 *contains_dollar_at
= 1;
7718 tflag
|= W_DOLLARAT
;
7721 dispose_words (xlist
);
7727 ret
= alloc_word_desc ();
7729 ret
->flags
= tflag
; /* XXX */
7733 #if defined (ARRAY_VARS)
7734 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7735 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7736 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
7740 temp1
= savestring (name
+ 1);
7741 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
7743 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
7745 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
7748 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7749 *quoted_dollar_atp
= 1;
7750 if (contains_dollar_at
)
7751 *contains_dollar_at
= 1;
7753 tflag
|= W_DOLLARAT
;
7759 ret
= alloc_word_desc ();
7761 ret
->flags
= tflag
; /* XXX */
7767 #endif /* ARRAY_VARS */
7769 /* Make sure that NAME is valid before trying to go on. */
7770 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
7771 var_is_special
) == 0)
7773 temp
= (char *)NULL
;
7774 goto bad_substitution
;
7779 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7780 /* Turn off the W_ARRAYIND flag because there is no way for this function
7781 to return the index we're supposed to be using. */
7782 if (tdesc
&& tdesc
->flags
)
7783 tdesc
->flags
&= ~W_ARRAYIND
;
7786 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
|(pflags
&(PF_NOSPLIT2
|PF_ASSIGNRHS
)), &ind
);
7791 tflag
= tdesc
->flags
;
7792 dispose_word_desc (tdesc
);
7797 if (temp
== &expand_param_error
|| temp
== &expand_param_fatal
)
7801 return (temp
== &expand_param_error
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7804 #if defined (ARRAY_VARS)
7805 if (valid_array_reference (name
))
7806 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7809 var_is_set
= temp
!= (char *)0;
7810 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
7811 /* XXX - this may not need to be restricted to special variables */
7813 var_is_null
|= var_is_set
&& var_is_special
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
);
7815 /* Get the rest of the stuff inside the braces. */
7816 if (c
&& c
!= RBRACE
)
7818 /* Extract the contents of the ${ ... } expansion
7819 according to the Posix.2 rules. */
7820 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, (c
== '%' || c
== '#' || c
=='/' || c
== '^' || c
== ',' || c
==':') ? SX_POSIXEXP
|SX_WORD
: SX_WORD
);
7821 if (string
[sindex
] == RBRACE
)
7824 goto bad_substitution
;
7827 value
= (char *)NULL
;
7831 /* All the cases where an expansion can possibly generate an unbound
7833 if (want_substring
|| want_patsub
|| want_casemod
|| c
== '#' || c
== '%' || c
== RBRACE
)
7835 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
7837 last_command_exit_value
= EXECUTION_FAILURE
;
7838 err_unboundvar (name
);
7842 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7846 /* If this is a substring spec, process it and add the result. */
7849 temp1
= parameter_brace_substring (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7854 if (temp1
== &expand_param_error
)
7855 return (&expand_wdesc_error
);
7856 else if (temp1
== &expand_param_fatal
)
7857 return (&expand_wdesc_fatal
);
7859 ret
= alloc_word_desc ();
7861 /* We test quoted_dollar_atp because we want variants with double-quoted
7862 "$@" to take a different code path. In fact, we make sure at the end
7863 of expand_word_internal that we're only looking at these flags if
7864 quoted_dollar_at == 0. */
7866 (quoted_dollar_atp
== 0 || *quoted_dollar_atp
== 0) &&
7867 QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7868 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7871 else if (want_patsub
)
7873 temp1
= parameter_brace_patsub (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7878 if (temp1
== &expand_param_error
)
7879 return (&expand_wdesc_error
);
7880 else if (temp1
== &expand_param_fatal
)
7881 return (&expand_wdesc_fatal
);
7883 ret
= alloc_word_desc ();
7886 (quoted_dollar_atp
== 0 || *quoted_dollar_atp
== 0) &&
7887 QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7888 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7891 #if defined (CASEMOD_EXPANSIONS)
7892 else if (want_casemod
)
7894 temp1
= parameter_brace_casemod (name
, temp
, ind
, modspec
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7899 if (temp1
== &expand_param_error
)
7900 return (&expand_wdesc_error
);
7901 else if (temp1
== &expand_param_fatal
)
7902 return (&expand_wdesc_fatal
);
7904 ret
= alloc_word_desc ();
7907 (quoted_dollar_atp
== 0 || *quoted_dollar_atp
== 0) &&
7908 QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7909 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7914 /* Do the right thing based on which character ended the variable name. */
7920 last_command_exit_value
= EXECUTION_FAILURE
;
7921 report_error (_("%s: bad substitution"), string
? string
: "??");
7925 return &expand_wdesc_error
;
7931 temp1
= parameter_brace_transform (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7932 if (temp1
== &expand_param_error
|| temp1
== &expand_param_fatal
)
7933 goto bad_substitution
;
7939 ret
= alloc_word_desc ();
7941 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7942 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7945 case '#': /* ${param#[#]pattern} */
7946 case '%': /* ${param%[%]pattern} */
7947 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
7952 temp1
= parameter_brace_remove_pattern (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7957 ret
= alloc_word_desc ();
7959 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7960 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7967 if (var_is_set
&& var_is_null
== 0)
7969 /* If the operator is `+', we don't want the value of the named
7970 variable for anything, just the value of the right hand side. */
7973 /* XXX -- if we're double-quoted and the named variable is "$@",
7974 we want to turn off any special handling of "$@" --
7975 we're not using it, so whatever is on the rhs applies. */
7976 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7977 *quoted_dollar_atp
= 0;
7978 if (contains_dollar_at
)
7979 *contains_dollar_at
= 0;
7984 /* From Posix discussion on austin-group list. Issue 221
7985 requires that backslashes escaping `}' inside
7986 double-quoted ${...} be removed. */
7987 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7988 quoted
|= Q_DOLBRACE
;
7989 ret
= parameter_brace_expand_rhs (name
, value
, c
,
7992 contains_dollar_at
);
7993 /* XXX - fix up later, esp. noting presence of
7994 W_HASQUOTEDNULL in ret->flags */
7998 temp
= (char *)NULL
;
8004 /* Otherwise do nothing; just use the value in TEMP. */
8006 else /* VAR not set or VAR is NULL. */
8009 temp
= (char *)NULL
;
8010 if (c
== '=' && var_is_special
)
8012 last_command_exit_value
= EXECUTION_FAILURE
;
8013 report_error (_("$%s: cannot assign in this way"), name
);
8016 return &expand_wdesc_error
;
8020 parameter_brace_expand_error (name
, value
);
8021 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
8025 /* XXX -- if we're double-quoted and the named variable is "$@",
8026 we want to turn off any special handling of "$@" --
8027 we're not using it, so whatever is on the rhs applies. */
8028 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
8029 *quoted_dollar_atp
= 0;
8030 if (contains_dollar_at
)
8031 *contains_dollar_at
= 0;
8033 /* From Posix discussion on austin-group list. Issue 221 requires
8034 that backslashes escaping `}' inside double-quoted ${...} be
8036 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8037 quoted
|= Q_DOLBRACE
;
8038 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
8040 contains_dollar_at
);
8041 /* XXX - fix up later, esp. noting presence of
8042 W_HASQUOTEDNULL in tdesc->flags */
8053 ret
= alloc_word_desc ();
8060 /* Expand a single ${xxx} expansion. The braces are optional. When
8061 the braces are used, parameter_brace_expand() does the work,
8062 possibly calling param_expand recursively. */
8064 param_expand (string
, sindex
, quoted
, expanded_something
,
8065 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
8068 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
8069 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
8071 char *temp
, *temp1
, uerror
[3];
8072 int zindex
, t_index
, expok
;
8077 WORD_DESC
*tdesc
, *ret
;
8081 c
= string
[++zindex
];
8083 temp
= (char *)NULL
;
8084 ret
= tdesc
= (WORD_DESC
*)NULL
;
8087 /* Do simple cases first. Switch on what follows '$'. */
8101 temp1
= dollar_vars
[TODIGIT (c
)];
8102 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
8107 last_command_exit_value
= EXECUTION_FAILURE
;
8108 err_unboundvar (uerror
);
8109 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
8112 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
8113 ? quote_string (temp1
)
8114 : quote_escapes (temp1
);
8116 temp
= (char *)NULL
;
8120 /* $$ -- pid of the invoking shell. */
8122 temp
= itos (dollar_dollar_pid
);
8125 /* $# -- number of positional parameters. */
8127 temp
= itos (number_of_args ());
8130 /* $? -- return value of the last synchronous command. */
8132 temp
= itos (last_command_exit_value
);
8135 /* $- -- flags supplied to the shell on invocation or by `set'. */
8137 temp
= which_set_flags ();
8140 /* $! -- Pid of the last asynchronous command. */
8142 /* If no asynchronous pids have been created, expand to nothing.
8143 If `set -u' has been executed, and no async processes have
8144 been created, this is an expansion error. */
8145 if (last_asynchronous_pid
== NO_PID
)
8147 if (expanded_something
)
8148 *expanded_something
= 0;
8149 temp
= (char *)NULL
;
8150 if (unbound_vars_is_error
)
8155 last_command_exit_value
= EXECUTION_FAILURE
;
8156 err_unboundvar (uerror
);
8157 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
8161 temp
= itos (last_asynchronous_pid
);
8164 /* The only difference between this and $@ is when the arg is quoted. */
8165 case '*': /* `$*' */
8166 list
= list_rest_of_args ();
8169 /* According to austin-group posix proposal by Geoff Clare in
8170 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
8172 "The shell shall write a message to standard error and
8173 immediately exit when it tries to expand an unset parameter
8174 other than the '@' and '*' special parameters."
8177 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
8182 last_command_exit_value
= EXECUTION_FAILURE
;
8183 err_unboundvar (uerror
);
8184 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
8188 /* If there are no command-line arguments, this should just
8189 disappear if there are other characters in the expansion,
8190 even if it's quoted. */
8191 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
8192 temp
= (char *)NULL
;
8193 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
8195 /* If we have "$*" we want to make a string of the positional
8196 parameters, separated by the first character of $IFS, and
8197 quote the whole string, including the separators. If IFS
8198 is unset, the parameters are separated by ' '; if $IFS is
8199 null, the parameters are concatenated. */
8200 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
8203 temp1
= (quoted
& Q_DOUBLE_QUOTES
) ? quote_string (temp
) : temp
;
8205 tflag
|= W_HASQUOTEDNULL
;
8213 /* We check whether or not we're eventually going to split $* here,
8214 for example when IFS is empty and we are processing the rhs of
8215 an assignment statement. In that case, we don't separate the
8216 arguments at all. Otherwise, if the $* is not quoted it is
8218 # if defined (HANDLE_MULTIBYTE)
8219 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
8221 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
8223 temp
= string_list_dollar_star (list
);
8226 temp
= string_list_dollar_at (list
, quoted
);
8227 if (quoted
== 0 && (ifs_is_set
== 0 || ifs_is_null
))
8228 tflag
|= W_SPLITSPACE
;
8231 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
8232 *contains_dollar_at
= 1;
8235 dispose_words (list
);
8238 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
8239 means that we have to turn quoting off after we split into
8240 the individually quoted arguments so that the final split
8241 on the first character of $IFS is still done. */
8242 case '@': /* `$@' */
8243 list
= list_rest_of_args ();
8246 /* According to austin-group posix proposal by Geoff Clare in
8247 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
8249 "The shell shall write a message to standard error and
8250 immediately exit when it tries to expand an unset parameter
8251 other than the '@' and '*' special parameters."
8254 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
8259 last_command_exit_value
= EXECUTION_FAILURE
;
8260 err_unboundvar (uerror
);
8261 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
8265 /* We want to flag the fact that we saw this. We can't turn
8266 off quoting entirely, because other characters in the
8267 string might need it (consider "\"$@\""), but we need some
8268 way to signal that the final split on the first character
8269 of $IFS should be done, even though QUOTED is 1. */
8270 /* XXX - should this test include Q_PATQUOTE? */
8271 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
8272 *quoted_dollar_at_p
= 1;
8273 if (contains_dollar_at
)
8274 *contains_dollar_at
= 1;
8276 /* We want to separate the positional parameters with the first
8277 character of $IFS in case $IFS is something other than a space.
8278 We also want to make sure that splitting is done no matter what --
8279 according to POSIX.2, this expands to a list of the positional
8280 parameters no matter what IFS is set to. */
8281 /* XXX - what to do when in a context where word splitting is not
8282 performed? Even when IFS is not the default, posix seems to imply
8283 that we behave like unquoted $* ? Maybe we should use PF_NOSPLIT2
8285 temp
= string_list_dollar_at (list
, (pflags
& PF_ASSIGNRHS
) ? (quoted
|Q_DOUBLE_QUOTES
) : quoted
);
8287 tflag
|= W_DOLLARAT
;
8288 dispose_words (list
);
8292 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
, pflags
,
8294 contains_dollar_at
);
8296 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
8298 temp
= tdesc
? tdesc
->word
: (char *)0;
8301 /* Quoted nulls should be removed if there is anything else
8303 /* Note that we saw the quoted null so we can add one back at
8304 the end of this function if there are no other characters
8305 in the string, discard TEMP, and go on. The exception to
8306 this is when we have "${@}" and $1 is '', since $@ needs
8307 special handling. */
8308 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
8310 if (had_quoted_null_p
)
8311 *had_quoted_null_p
= 1;
8312 if (*quoted_dollar_at_p
== 0)
8315 tdesc
->word
= temp
= (char *)NULL
;
8323 /* Do command or arithmetic substitution. */
8325 /* We have to extract the contents of this paren substitution. */
8326 t_index
= zindex
+ 1;
8327 temp
= extract_command_subst (string
, &t_index
, 0);
8330 /* For Posix.2-style `$(( ))' arithmetic substitution,
8331 extract the expression and pass it to the evaluator. */
8332 if (temp
&& *temp
== LPAREN
)
8336 temp2
= savestring (temp1
);
8337 t_index
= strlen (temp2
) - 1;
8339 if (temp2
[t_index
] != RPAREN
)
8345 /* Cut off ending `)' */
8346 temp2
[t_index
] = '\0';
8348 if (chk_arithsub (temp2
, t_index
) == 0)
8352 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
8357 /* Expand variables found inside the expression. */
8358 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
|Q_ARITH
);
8362 /* No error messages. */
8363 this_command_name
= (char *)NULL
;
8364 number
= evalexp (temp1
, &expok
);
8369 if (interactive_shell
== 0 && posixly_correct
)
8371 last_command_exit_value
= EXECUTION_FAILURE
;
8372 return (&expand_wdesc_fatal
);
8375 return (&expand_wdesc_error
);
8377 temp
= itos (number
);
8382 if (pflags
& PF_NOCOMSUB
)
8383 /* we need zindex+1 because string[zindex] == RPAREN */
8384 temp1
= substring (string
, *sindex
, zindex
+1);
8387 tdesc
= command_substitute (temp
, quoted
);
8388 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
8390 dispose_word_desc (tdesc
);
8396 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
8397 away in a future bash release. */
8399 /* Extract the contents of this arithmetic substitution. */
8400 t_index
= zindex
+ 1;
8401 temp
= extract_arithmetic_subst (string
, &t_index
);
8405 temp
= savestring (string
);
8406 if (expanded_something
)
8407 *expanded_something
= 0;
8411 /* Do initial variable expansion. */
8412 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
|Q_ARITH
);
8417 /* Find the variable in VARIABLE_LIST. */
8418 temp
= (char *)NULL
;
8420 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
8422 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
8424 /* If this isn't a variable name, then just output the `$'. */
8425 if (temp1
== 0 || *temp1
== '\0')
8428 temp
= (char *)xmalloc (2);
8431 if (expanded_something
)
8432 *expanded_something
= 0;
8436 /* If the variable exists, return its value cell. */
8437 var
= find_variable (temp1
);
8439 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
8441 #if defined (ARRAY_VARS)
8442 if (assoc_p (var
) || array_p (var
))
8444 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
8445 : assoc_reference (assoc_cell (var
), "0");
8447 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
8448 ? quote_string (temp
)
8449 : quote_escapes (temp
);
8450 else if (unbound_vars_is_error
)
8451 goto unbound_variable
;
8456 temp
= value_cell (var
);
8458 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
8459 ? quote_string (temp
)
8460 : quote_escapes (temp
);
8467 else if (var
&& (invisible_p (var
) || var_isset (var
) == 0))
8468 temp
= (char *)NULL
;
8469 else if ((var
= find_variable_last_nameref (temp1
)) && var_isset (var
) && invisible_p (var
) == 0)
8471 temp
= nameref_cell (var
);
8472 #if defined (ARRAY_VARS)
8473 if (temp
&& *temp
&& valid_array_reference (temp
))
8475 tdesc
= parameter_brace_expand_word (temp
, SPECIAL_VAR (temp
, 0), quoted
, pflags
, (arrayind_t
*)NULL
);
8476 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
8483 /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */
8484 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
8486 last_command_exit_value
= EXECUTION_FAILURE
;
8487 report_error (_("%s: invalid variable name for name reference"), temp
);
8488 return (&expand_wdesc_error
); /* XXX */
8491 temp
= (char *)NULL
;
8494 temp
= (char *)NULL
;
8497 if (unbound_vars_is_error
)
8499 last_command_exit_value
= EXECUTION_FAILURE
;
8500 err_unboundvar (temp1
);
8509 last_command_exit_value
= EXECUTION_FAILURE
;
8510 return ((unbound_vars_is_error
&& interactive_shell
== 0)
8511 ? &expand_wdesc_fatal
8512 : &expand_wdesc_error
);
8523 ret
= alloc_word_desc ();
8524 ret
->flags
= tflag
; /* XXX */
8531 invalidate_cached_quoted_dollar_at ()
8533 dispose_words (cached_quoted_dollar_at
);
8534 cached_quoted_dollar_at
= 0;
8537 /* Make a word list which is the result of parameter and variable
8538 expansion, command substitution, arithmetic substitution, and
8539 quote removal of WORD. Return a pointer to a WORD_LIST which is
8540 the result of the expansion. If WORD contains a null word, the
8541 word list returned is also null.
8543 QUOTED contains flag values defined in shell.h.
8545 ISEXP is used to tell expand_word_internal that the word should be
8546 treated as the result of an expansion. This has implications for
8547 how IFS characters in the word are treated.
8549 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
8550 they point to an integer value which receives information about expansion.
8551 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
8552 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
8555 This only does word splitting in the case of $@ expansion. In that
8556 case, we split on ' '. */
8558 /* Values for the local variable quoted_state. */
8560 #define PARTIALLY_QUOTED 1
8561 #define WHOLLY_QUOTED 2
8564 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
8567 int *contains_dollar_at
;
8568 int *expanded_something
;
8573 /* The intermediate string that we build while expanding. */
8576 /* The current size of the above object. */
8579 /* Index into ISTRING. */
8582 /* Temporary string storage. */
8585 /* The text of WORD. */
8586 register char *string
;
8588 /* The size of STRING. */
8591 /* The index into STRING. */
8594 /* This gets 1 if we see a $@ while quoted. */
8595 int quoted_dollar_at
;
8597 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
8598 whether WORD contains no quoting characters, a partially quoted
8599 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
8603 int had_quoted_null
;
8604 int has_dollar_at
, temp_has_dollar_at
;
8605 int split_on_spaces
;
8607 int pflags
; /* flags passed to param_expand */
8609 int assignoff
; /* If assignment, offset of `=' */
8611 register unsigned char c
; /* Current character. */
8612 int t_index
; /* For calls to string_extract_xxx. */
8618 /* OK, let's see if we can optimize a common idiom: "$@" */
8619 if (STREQ (word
->word
, "\"$@\"") &&
8620 (word
->flags
== (W_HASDOLLAR
|W_QUOTED
)) &&
8621 dollar_vars
[1]) /* XXX - check IFS here as well? */
8623 if (contains_dollar_at
)
8624 *contains_dollar_at
= 1;
8625 if (expanded_something
)
8626 *expanded_something
= 1;
8627 if (cached_quoted_dollar_at
)
8628 return (copy_word_list (cached_quoted_dollar_at
));
8629 list
= list_rest_of_args ();
8630 list
= quote_list (list
);
8631 cached_quoted_dollar_at
= copy_word_list (list
);
8635 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
8636 istring
[istring_index
= 0] = '\0';
8637 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
8638 split_on_spaces
= 0;
8639 quoted_state
= UNQUOTED
;
8641 string
= word
->word
;
8643 goto finished_with_string
;
8644 /* Don't need the string length for the SADD... and COPY_ macros unless
8645 multibyte characters are possible. */
8646 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
8648 if (contains_dollar_at
)
8649 *contains_dollar_at
= 0;
8653 /* Begin the expansion. */
8659 /* Case on top-level character. */
8663 goto finished_with_string
;
8667 #if HANDLE_MULTIBYTE
8668 if (MB_CUR_MAX
> 1 && string
[sindex
])
8670 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8675 temp
= (char *)xmalloc (3);
8677 temp
[1] = c
= string
[sindex
];
8688 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
8694 #if defined (PROCESS_SUBSTITUTION)
8695 /* Process substitution. */
8699 /* bash-4.4/bash-5.0
8700 XXX - technically this should only be expanded at the start
8702 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
8704 sindex
--; /* add_character: label increments sindex */
8708 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
8710 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
, 0); /*))*/
8713 /* If the process substitution specification is `<()', we want to
8714 open the pipe for writing in the child and produce output; if
8715 it is `>()', we want to open the pipe for reading in the child
8716 and consume input. */
8717 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
8721 goto dollar_add_string
;
8723 #endif /* PROCESS_SUBSTITUTION */
8726 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8727 which are not assignment statements are not expanded. If the
8728 shell isn't in posix mode, though, we perform tilde expansion
8729 on `likely candidate' unquoted assignment statements (flags
8730 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8731 contains an unquoted :~ or =~. Something to think about: we
8732 now have a flag that says to perform tilde expansion on arguments
8733 to `assignment builtins' like declare and export that look like
8734 assignment statements. We now do tilde expansion on such words
8735 even in POSIX mode. */
8736 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
8738 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8739 goto add_ifs_character
;
8743 /* If we're not in posix mode or forcing assignment-statement tilde
8744 expansion, note where the `=' appears in the word and prepare to
8745 do tilde expansion following the first `='. */
8746 if ((word
->flags
& W_ASSIGNMENT
) &&
8747 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8748 assignoff
== -1 && sindex
> 0)
8750 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
8751 word
->flags
|= W_ITILDE
;
8753 else if ((word
->flags
& W_ASSIGNMENT
) &&
8754 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8755 string
[sindex
+1] == '~')
8756 word
->flags
|= W_ITILDE
;
8758 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8759 goto add_ifs_character
;
8764 if (word
->flags
& W_NOTILDE
)
8766 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8767 goto add_ifs_character
;
8772 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
8773 string
[sindex
+1] == '~')
8774 word
->flags
|= W_ITILDE
;
8776 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8777 goto add_ifs_character
;
8782 /* If the word isn't supposed to be tilde expanded, or we're not
8783 at the start of a word or after an unquoted : or = in an
8784 assignment statement, we don't do tilde expansion. If we don't want
8785 tilde expansion when expanding words to be passed to the arithmetic
8786 evaluator, remove the check for Q_ARITH. */
8787 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
8788 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
8789 ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) && ((quoted
& Q_ARITH
) == 0)))
8791 word
->flags
&= ~W_ITILDE
;
8792 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
8793 goto add_ifs_character
;
8798 if (word
->flags
& W_ASSIGNRHS
)
8800 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
8805 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
8807 word
->flags
&= ~W_ITILDE
;
8809 if (temp
&& *temp
&& t_index
> 0)
8811 temp1
= bash_tilde_expand (temp
, tflag
);
8812 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
8816 goto add_character
; /* tilde expansion failed */
8821 goto add_quoted_string
; /* XXX was add_string */
8830 if (expanded_something
)
8831 *expanded_something
= 1;
8833 temp_has_dollar_at
= 0;
8834 pflags
= (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0;
8835 if (word
->flags
& W_NOSPLIT2
)
8836 pflags
|= PF_NOSPLIT2
;
8837 if (word
->flags
& W_ASSIGNRHS
)
8838 pflags
|= PF_ASSIGNRHS
;
8839 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
8840 &temp_has_dollar_at
, "ed_dollar_at
,
8841 &had_quoted_null
, pflags
);
8842 has_dollar_at
+= temp_has_dollar_at
;
8843 split_on_spaces
+= (tword
->flags
& W_SPLITSPACE
);
8845 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
8849 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
8850 : &expand_word_fatal
);
8852 if (contains_dollar_at
&& has_dollar_at
)
8853 *contains_dollar_at
= 1;
8855 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
8856 had_quoted_null
= 1;
8858 temp
= tword
? tword
->word
: (char *)NULL
;
8859 dispose_word_desc (tword
);
8861 /* Kill quoted nulls; we will add them back at the end of
8862 expand_word_internal if nothing else in the string */
8863 if (had_quoted_null
&& temp
&& QUOTED_NULL (temp
))
8866 temp
= (char *)NULL
;
8872 case '`': /* Backquoted command substitution. */
8876 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
8877 /* The test of sindex against t_index is to allow bare instances of
8878 ` to pass through, for backwards compatibility. */
8879 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
8881 if (sindex
- 1 == t_index
)
8886 last_command_exit_value
= EXECUTION_FAILURE
;
8887 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
8890 return ((temp
== &extract_string_error
) ? &expand_word_error
8891 : &expand_word_fatal
);
8894 if (expanded_something
)
8895 *expanded_something
= 1;
8897 if (word
->flags
& W_NOCOMSUB
)
8898 /* sindex + 1 because string[sindex] == '`' */
8899 temp1
= substring (string
, t_index
, sindex
+ 1);
8902 de_backslash (temp
);
8903 tword
= command_substitute (temp
, quoted
);
8904 temp1
= tword
? tword
->word
: (char *)NULL
;
8906 dispose_word_desc (tword
);
8910 goto dollar_add_string
;
8914 if (string
[sindex
+ 1] == '\n')
8920 c
= string
[++sindex
];
8922 if (quoted
& Q_HERE_DOCUMENT
)
8924 else if (quoted
& Q_DOUBLE_QUOTES
)
8929 /* From Posix discussion on austin-group list: Backslash escaping
8930 a } in ${...} is removed. Issue 0000221 */
8931 if ((quoted
& Q_DOLBRACE
) && c
== RBRACE
)
8933 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8935 /* This is the fix for " $@\ " */
8936 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0) && isexp
== 0 && isifs (c
))
8938 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8939 DEFAULT_ARRAY_SIZE
);
8940 istring
[istring_index
++] = CTLESC
;
8941 istring
[istring_index
++] = '\\';
8942 istring
[istring_index
] = '\0';
8944 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8946 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
8948 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
8953 sindex
--; /* add_character: label increments sindex */
8958 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8963 /* BEFORE jumping here, we need to increment sindex if appropriate */
8964 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8965 DEFAULT_ARRAY_SIZE
);
8966 istring
[istring_index
++] = twochars
[0];
8967 istring
[istring_index
++] = twochars
[1];
8968 istring
[istring_index
] = '\0';
8973 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) && ((quoted
& Q_ARITH
) == 0))
8977 temp
= string_extract_double_quoted (string
, &sindex
, 0);
8979 /* If the quotes surrounded the entire string, then the
8980 whole word was quoted. */
8981 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8987 tword
= alloc_word_desc ();
8990 temp
= (char *)NULL
;
8992 temp_has_dollar_at
= 0; /* XXX */
8993 /* Need to get W_HASQUOTEDNULL flag through this function. */
8994 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &temp_has_dollar_at
, (int *)NULL
);
8995 has_dollar_at
+= temp_has_dollar_at
;
8997 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
9001 /* expand_word_internal has already freed temp_word->word
9002 for us because of the way it prints error messages. */
9003 tword
->word
= (char *)NULL
;
9004 dispose_word (tword
);
9008 dispose_word (tword
);
9010 /* "$@" (a double-quoted dollar-at) expands into nothing,
9011 not even a NULL word, when there are no positional
9013 if (list
== 0 && has_dollar_at
)
9019 /* If we get "$@", we know we have expanded something, so we
9020 need to remember it for the final split on $IFS. This is
9021 a special case; it's the only case where a quoted string
9022 can expand into more than one word. It's going to come back
9023 from the above call to expand_word_internal as a list with
9024 a single word, in which all characters are quoted and
9025 separated by blanks. What we want to do is to turn it back
9026 into a list for the next piece of code. */
9028 dequote_list (list
);
9030 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
9031 had_quoted_null
= 1; /* XXX */
9036 if (contains_dollar_at
)
9037 *contains_dollar_at
= 1;
9038 if (expanded_something
)
9039 *expanded_something
= 1;
9044 /* What we have is "". This is a minor optimization. */
9046 list
= (WORD_LIST
*)NULL
;
9049 /* The code above *might* return a list (consider the case of "$@",
9050 where it returns "$1", "$2", etc.). We can't throw away the
9051 rest of the list, and we have to make sure each word gets added
9052 as quoted. We test on tresult->next: if it is non-NULL, we
9053 quote the whole list, save it to a string with string_list, and
9054 add that string. We don't need to quote the results of this
9055 (and it would be wrong, since that would quote the separators
9056 as well), so we go directly to add_string. */
9061 /* Testing quoted_dollar_at makes sure that "$@" is
9062 split correctly when $IFS does not contain a space. */
9063 temp
= quoted_dollar_at
9064 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
9065 : string_list (quote_list (list
));
9066 dispose_words (list
);
9071 temp
= savestring (list
->word
->word
);
9072 tflag
= list
->word
->flags
;
9073 dispose_words (list
);
9075 /* If the string is not a quoted null string, we want
9076 to remove any embedded unquoted CTLNUL characters.
9077 We do not want to turn quoted null strings back into
9078 the empty string, though. We do this because we
9079 want to remove any quoted nulls from expansions that
9080 contain other characters. For example, if we have
9081 x"$*"y or "x$*y" and there are no positional parameters,
9082 the $* should expand into nothing. */
9083 /* We use the W_HASQUOTEDNULL flag to differentiate the
9084 cases: a quoted null character as above and when
9085 CTLNUL is contained in the (non-null) expansion
9086 of some variable. We use the had_quoted_null flag to
9087 pass the value through this function to its caller. */
9088 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
9089 remove_quoted_nulls (temp
); /* XXX */
9093 temp
= (char *)NULL
;
9095 /* We do not want to add quoted nulls to strings that are only
9096 partially quoted; we can throw them away. The exception to
9097 this is when we are going to be performing word splitting,
9098 since we have to preserve a null argument if the next character
9099 will cause word splitting. */
9100 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
&& (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)))
9108 temp
= quote_string (temp
);
9116 sindex
--; /* add_character: label increments sindex */
9123 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
9127 temp
= string_extract_single_quoted (string
, &sindex
);
9129 /* If the entire STRING was surrounded by single quotes,
9130 then the string is wholly quoted. */
9131 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
9135 /* If all we had was '', it is a null expansion. */
9139 temp
= (char *)NULL
;
9142 remove_quoted_escapes (temp
); /* ??? */
9144 /* We do not want to add quoted nulls to strings that are only
9145 partially quoted; such nulls are discarded. */
9146 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
9149 /* If we have a quoted null expansion, add a quoted NULL to istring. */
9153 sindex
--; /* add_character: label increments sindex */
9157 goto add_quoted_string
;
9162 /* This is the fix for " $@ " */
9164 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
9166 if (string
[sindex
]) /* from old goto dollar_add_string */
9175 #if HANDLE_MULTIBYTE
9181 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
9186 twochars
[0] = CTLESC
;
9193 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
9196 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
9197 DEFAULT_ARRAY_SIZE
);
9198 istring
[istring_index
++] = c
;
9199 istring
[istring_index
] = '\0';
9201 /* Next character. */
9206 finished_with_string
:
9207 /* OK, we're ready to return. If we have a quoted string, and
9208 quoted_dollar_at is not set, we do no splitting at all; otherwise
9209 we split on ' '. The routines that call this will handle what to
9210 do if nothing has been expanded. */
9212 /* Partially and wholly quoted strings which expand to the empty
9213 string are retained as an empty arguments. Unquoted strings
9214 which expand to the empty string are discarded. The single
9215 exception is the case of expanding "$@" when there are no
9216 positional parameters. In that case, we discard the expansion. */
9218 /* Because of how the code that handles "" and '' in partially
9219 quoted strings works, we need to make ISTRING into a QUOTED_NULL
9220 if we saw quoting characters, but the expansion was empty.
9221 "" and '' are tossed away before we get to this point when
9222 processing partially quoted strings. This makes "" and $xxx""
9223 equivalent when xxx is unset. We also look to see whether we
9224 saw a quoted null from a ${} expansion and add one back if we
9227 /* If we expand to nothing and there were no single or double quotes
9228 in the word, we throw it away. Otherwise, we return a NULL word.
9229 The single exception is for $@ surrounded by double quotes when
9230 there are no positional parameters. In that case, we also throw
9233 if (*istring
== '\0')
9235 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
9237 istring
[0] = CTLNUL
;
9239 tword
= make_bare_word (istring
);
9240 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
9241 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
9242 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
9243 tword
->flags
|= W_QUOTED
;
9245 /* According to sh, ksh, and Posix.2, if a word expands into nothing
9246 and a double-quoted "$@" appears anywhere in it, then the entire
9248 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
9249 list
= (WORD_LIST
*)NULL
;
9253 tword
= make_bare_word (istring
);
9254 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
9255 tword
->flags
|= W_QUOTED
;
9256 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
9260 list
= (WORD_LIST
*)NULL
;
9263 else if (word
->flags
& W_NOSPLIT
)
9265 tword
= make_bare_word (istring
);
9266 if (word
->flags
& W_ASSIGNMENT
)
9267 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
9268 if (word
->flags
& W_COMPASSIGN
)
9269 tword
->flags
|= W_COMPASSIGN
; /* XXX */
9270 if (word
->flags
& W_NOGLOB
)
9271 tword
->flags
|= W_NOGLOB
; /* XXX */
9272 if (word
->flags
& W_NOBRACE
)
9273 tword
->flags
|= W_NOBRACE
; /* XXX */
9274 if (word
->flags
& W_NOEXPAND
)
9275 tword
->flags
|= W_NOEXPAND
; /* XXX */
9276 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
9277 tword
->flags
|= W_QUOTED
;
9278 if (had_quoted_null
&& QUOTED_NULL (istring
))
9279 tword
->flags
|= W_HASQUOTEDNULL
;
9280 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
9287 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
9289 /* If we have $@, we need to split the results no matter what. If
9290 IFS is unset or NULL, string_list_dollar_at has separated the
9291 positional parameters with a space, so we split on space (we have
9292 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
9293 string_list_dollar_at has separated the positional parameters
9294 with the first character of $IFS, so we split on $IFS. If
9295 SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
9296 unset or null, and we want to make sure that we split on spaces
9297 regardless of what else has happened to IFS since the expansion. */
9298 if (split_on_spaces
)
9299 list
= list_string (istring
, " ", 1); /* XXX quoted == 1? */
9300 /* If we have $@ (has_dollar_at != 0) and we are in a context where we
9301 don't want to split the result (W_NOSPLIT2), and we are not quoted,
9302 we have already separated the arguments with the first character of
9303 $IFS. In this case, we want to return a list with a single word
9304 with the separator possibly replaced with a space (it's what other
9306 quoted_dollar_at is internal to this function and is set if we are
9307 passed an argument that is unquoted (quoted == 0) but we encounter a
9308 double-quoted $@ while expanding it. */
9309 else if (has_dollar_at
&& quoted_dollar_at
== 0 && ifs_chars
&& quoted
== 0 && (word
->flags
& W_NOSPLIT2
))
9311 /* Only split and rejoin if we have to */
9312 if (*ifs_chars
&& *ifs_chars
!= ' ')
9314 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
9315 tstring
= string_list (list
);
9319 tword
= make_bare_word (tstring
);
9320 if (tstring
!= istring
)
9322 goto set_word_flags
;
9324 else if (has_dollar_at
&& ifs_chars
)
9325 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
9328 tword
= make_bare_word (istring
);
9330 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
9331 tword
->flags
|= W_QUOTED
;
9332 if (word
->flags
& W_ASSIGNMENT
)
9333 tword
->flags
|= W_ASSIGNMENT
;
9334 if (word
->flags
& W_COMPASSIGN
)
9335 tword
->flags
|= W_COMPASSIGN
;
9336 if (word
->flags
& W_NOGLOB
)
9337 tword
->flags
|= W_NOGLOB
;
9338 if (word
->flags
& W_NOBRACE
)
9339 tword
->flags
|= W_NOBRACE
;
9340 if (word
->flags
& W_NOEXPAND
)
9341 tword
->flags
|= W_NOEXPAND
;
9342 if (had_quoted_null
&& QUOTED_NULL (istring
))
9343 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
9344 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
9352 /* **************************************************************** */
9354 /* Functions for Quote Removal */
9356 /* **************************************************************** */
9358 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
9359 backslash quoting rules for within double quotes or a here document. */
9361 string_quote_removal (string
, quoted
)
9366 char *r
, *result_string
, *temp
, *send
;
9367 int sindex
, tindex
, dquote
;
9371 /* The result can be no longer than the original string. */
9372 slen
= strlen (string
);
9373 send
= string
+ slen
;
9375 r
= result_string
= (char *)xmalloc (slen
+ 1);
9377 for (dquote
= sindex
= 0; c
= string
[sindex
];)
9382 c
= string
[++sindex
];
9388 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
9393 SCOPY_CHAR_M (r
, string
, send
, sindex
);
9397 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
9403 tindex
= sindex
+ 1;
9404 temp
= string_extract_single_quoted (string
, &tindex
);
9415 dquote
= 1 - dquote
;
9421 return (result_string
);
9426 /* Perform quote removal on word WORD. This allocates and returns a new
9429 word_quote_removal (word
, quoted
)
9436 t
= string_quote_removal (word
->word
, quoted
);
9437 w
= alloc_word_desc ();
9438 w
->word
= t
? t
: savestring ("");
9442 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
9443 the members of the list are treated as if they are surrounded by
9444 double quotes. Return a new list, or NULL if LIST is NULL. */
9446 word_list_quote_removal (list
, quoted
)
9450 WORD_LIST
*result
, *t
, *tresult
, *e
;
9452 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
9454 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
9456 result
= (WORD_LIST
*) list_append (result
, tresult
);
9459 result
= e
= tresult
;
9472 /*******************************************
9474 * Functions to perform word splitting *
9476 *******************************************/
9486 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
9488 ifs_is_set
= ifs_var
!= 0;
9489 ifs_is_null
= ifs_is_set
&& (*ifs_value
== 0);
9491 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
9492 handle multibyte chars in IFS */
9493 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
9494 for (t
= ifs_value
; t
&& *t
; t
++)
9500 #if defined (HANDLE_MULTIBYTE)
9503 ifs_firstc
[0] = '\0';
9509 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
9510 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
9511 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
9513 ifs_firstc
[0] = ifs_value
[0];
9514 ifs_firstc
[1] = '\0';
9518 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
9521 ifs_firstc
= ifs_value
? *ifs_value
: 0;
9531 /* This splits a single word into a WORD LIST on $IFS, but only if the word
9532 is not quoted. list_string () performs quote removal for us, even if we
9533 don't do any splitting. */
9535 word_split (w
, ifs_chars
)
9545 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
9546 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
9549 result
= (WORD_LIST
*)NULL
;
9554 /* Perform word splitting on LIST and return the RESULT. It is possible
9555 to return (WORD_LIST *)NULL. */
9557 word_list_split (list
)
9560 WORD_LIST
*result
, *t
, *tresult
, *e
;
9562 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
9564 tresult
= word_split (t
->word
, ifs_value
);
9566 result
= e
= tresult
;
9577 /**************************************************
9579 * Functions to expand an entire WORD_LIST *
9581 **************************************************/
9583 /* Do any word-expansion-specific cleanup and jump to top_level */
9585 exp_jump_to_top_level (v
)
9588 set_pipestatus_from_exit (last_command_exit_value
);
9590 /* Cleanup code goes here. */
9591 expand_no_split_dollar_star
= 0; /* XXX */
9592 expanding_redir
= 0;
9593 assigning_in_environment
= 0;
9595 if (parse_and_execute_level
== 0)
9596 top_level_cleanup (); /* from sig.c */
9598 jump_to_top_level (v
);
9601 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
9602 ELIST, and set ELIST to the new list. */
9603 #define PREPEND_LIST(nlist, elist) \
9604 do { nlist->next = elist; elist = nlist; } while (0)
9606 /* Separate out any initial variable assignments from TLIST. If set -k has
9607 been executed, remove all assignment statements from TLIST. Initial
9608 variable assignments and other environment assignments are placed
9609 on SUBST_ASSIGN_VARLIST. */
9611 separate_out_assignments (tlist
)
9614 register WORD_LIST
*vp
, *lp
;
9617 return ((WORD_LIST
*)NULL
);
9619 if (subst_assign_varlist
)
9620 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
9622 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9625 /* Separate out variable assignments at the start of the command.
9626 Loop invariant: vp->next == lp
9628 lp = list of words left after assignment statements skipped
9629 tlist = original list of words
9631 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
9637 /* If lp != tlist, we have some initial assignment statements.
9638 We make SUBST_ASSIGN_VARLIST point to the list of assignment
9639 words and TLIST point to the remaining words. */
9642 subst_assign_varlist
= tlist
;
9643 /* ASSERT(vp->next == lp); */
9644 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
9645 tlist
= lp
; /* remainder of word list */
9648 /* vp == end of variable list */
9649 /* tlist == remainder of original word list without variable assignments */
9651 /* All the words in tlist were assignment statements */
9652 return ((WORD_LIST
*)NULL
);
9654 /* ASSERT(tlist != NULL); */
9655 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
9657 /* If the -k option is in effect, we need to go through the remaining
9658 words, separate out the assignment words, and place them on
9659 SUBST_ASSIGN_VARLIST. */
9660 if (place_keywords_in_env
)
9662 WORD_LIST
*tp
; /* tp == running pointer into tlist */
9667 /* Loop Invariant: tp->next == lp */
9668 /* Loop postcondition: tlist == word list without assignment statements */
9671 if (lp
->word
->flags
& W_ASSIGNMENT
)
9673 /* Found an assignment statement, add this word to end of
9674 subst_assign_varlist (vp). */
9675 if (!subst_assign_varlist
)
9676 subst_assign_varlist
= vp
= lp
;
9683 /* Remove the word pointed to by LP from TLIST. */
9684 tp
->next
= lp
->next
;
9685 /* ASSERT(vp == lp); */
9686 lp
->next
= (WORD_LIST
*)NULL
;
9699 #define WEXP_VARASSIGN 0x001
9700 #define WEXP_BRACEEXP 0x002
9701 #define WEXP_TILDEEXP 0x004
9702 #define WEXP_PARAMEXP 0x008
9703 #define WEXP_PATHEXP 0x010
9705 /* All of the expansions, including variable assignments at the start of
9707 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9709 /* All of the expansions except variable assignments at the start of
9711 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9713 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
9714 expansion, command substitution, arithmetic expansion, word splitting, and
9716 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
9718 /* Take the list of words in LIST and do the various substitutions. Return
9719 a new list of words which is the expanded list, and without things like
9720 variable assignments. */
9726 return (expand_word_list_internal (list
, WEXP_ALL
));
9729 /* Same as expand_words (), but doesn't hack variable or environment
9732 expand_words_no_vars (list
)
9735 return (expand_word_list_internal (list
, WEXP_NOVARS
));
9739 expand_words_shellexp (list
)
9742 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
9746 glob_expand_word_list (tlist
, eflags
)
9750 char **glob_array
, *temp_string
;
9751 register int glob_index
;
9752 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
9755 output_list
= disposables
= (WORD_LIST
*)NULL
;
9756 glob_array
= (char **)NULL
;
9759 /* For each word, either globbing is attempted or the word is
9760 added to orig_list. If globbing succeeds, the results are
9761 added to orig_list and the word (tlist) is added to the list
9762 of disposable words. If globbing fails and failed glob
9763 expansions are left unchanged (the shell default), the
9764 original word is added to orig_list. If globbing fails and
9765 failed glob expansions are removed, the original word is
9766 added to the list of disposable words. orig_list ends up
9767 in reverse order and requires a call to REVERSE_LIST to
9768 be set right. After all words are examined, the disposable
9772 /* If the word isn't an assignment and contains an unquoted
9773 pattern matching character, then glob it. */
9774 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
9775 unquoted_glob_pattern_p (tlist
->word
->word
))
9777 glob_array
= shell_glob_filename (tlist
->word
->word
);
9779 /* Handle error cases.
9780 I don't think we should report errors like "No such file
9781 or directory". However, I would like to report errors
9782 like "Read failed". */
9784 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
9786 glob_array
= (char **)xmalloc (sizeof (char *));
9787 glob_array
[0] = (char *)NULL
;
9790 /* Dequote the current word in case we have to use it. */
9791 if (glob_array
[0] == NULL
)
9793 temp_string
= dequote_string (tlist
->word
->word
);
9794 free (tlist
->word
->word
);
9795 tlist
->word
->word
= temp_string
;
9798 /* Make the array into a word list. */
9799 glob_list
= (WORD_LIST
*)NULL
;
9800 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
9802 tword
= make_bare_word (glob_array
[glob_index
]);
9803 glob_list
= make_word_list (tword
, glob_list
);
9808 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
9809 PREPEND_LIST (tlist
, disposables
);
9811 else if (fail_glob_expansion
!= 0)
9813 last_command_exit_value
= EXECUTION_FAILURE
;
9814 report_error (_("no match: %s"), tlist
->word
->word
);
9815 exp_jump_to_top_level (DISCARD
);
9817 else if (allow_null_glob_expansion
== 0)
9819 /* Failed glob expressions are left unchanged. */
9820 PREPEND_LIST (tlist
, output_list
);
9824 /* Failed glob expressions are removed. */
9825 PREPEND_LIST (tlist
, disposables
);
9830 /* Dequote the string. */
9831 temp_string
= dequote_string (tlist
->word
->word
);
9832 free (tlist
->word
->word
);
9833 tlist
->word
->word
= temp_string
;
9834 PREPEND_LIST (tlist
, output_list
);
9837 strvec_dispose (glob_array
);
9838 glob_array
= (char **)NULL
;
9844 dispose_words (disposables
);
9847 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9849 return (output_list
);
9852 #if defined (BRACE_EXPANSION)
9854 brace_expand_word_list (tlist
, eflags
)
9858 register char **expansions
;
9860 WORD_LIST
*disposables
, *output_list
, *next
;
9864 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
9868 if (tlist
->word
->flags
& W_NOBRACE
)
9870 /*itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);*/
9871 PREPEND_LIST (tlist
, output_list
);
9875 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9877 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9878 PREPEND_LIST (tlist
, output_list
);
9882 /* Only do brace expansion if the word has a brace character. If
9883 not, just add the word list element to BRACES and continue. In
9884 the common case, at least when running shell scripts, this will
9885 degenerate to a bunch of calls to `mbschr', and then what is
9886 basically a reversal of TLIST into BRACES, which is corrected
9887 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9889 if (mbschr (tlist
->word
->word
, LBRACE
))
9891 expansions
= brace_expand (tlist
->word
->word
);
9893 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
9895 w
= alloc_word_desc ();
9896 w
->word
= temp_string
;
9898 /* If brace expansion didn't change the word, preserve
9899 the flags. We may want to preserve the flags
9900 unconditionally someday -- XXX */
9901 if (STREQ (temp_string
, tlist
->word
->word
))
9902 w
->flags
= tlist
->word
->flags
;
9904 w
= make_word_flags (w
, temp_string
);
9906 output_list
= make_word_list (w
, output_list
);
9910 /* Add TLIST to the list of words to be freed after brace
9911 expansion has been performed. */
9912 PREPEND_LIST (tlist
, disposables
);
9915 PREPEND_LIST (tlist
, output_list
);
9919 dispose_words (disposables
);
9922 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9924 return (output_list
);
9928 #if defined (ARRAY_VARS)
9929 /* Take WORD, a compound associative array assignment, and internally run
9930 'declare -A w', where W is the variable name portion of WORD. */
9932 make_internal_declare (word
, option
)
9940 w
= make_word (word
);
9942 t
= assignment (w
->word
, 0);
9945 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
9946 wl
= make_word_list (make_word (option
), wl
);
9948 return (declare_builtin (wl
));
9953 shell_expand_word_list (tlist
, eflags
)
9957 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
9958 int expanded_something
, has_dollar_at
;
9961 /* We do tilde expansion all the time. This is what 1003.2 says. */
9962 new_list
= (WORD_LIST
*)NULL
;
9963 for (orig_list
= tlist
; tlist
; tlist
= next
)
9965 temp_string
= tlist
->word
->word
;
9969 #if defined (ARRAY_VARS)
9970 /* If this is a compound array assignment to a builtin that accepts
9971 such assignments (e.g., `declare'), take the assignment and perform
9972 it separately, handling the semantics of declarations inside shell
9973 functions. This avoids the double-evaluation of such arguments,
9974 because `declare' does some evaluation of compound assignments on
9976 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9979 char opts
[16], opti
;
9982 if (tlist
->word
->flags
& (W_ASSIGNASSOC
|W_ASSNGLOBAL
|W_ASSIGNARRAY
))
9985 if ((tlist
->word
->flags
& (W_ASSIGNASSOC
|W_ASSNGLOBAL
)) == (W_ASSIGNASSOC
|W_ASSNGLOBAL
))
9990 else if (tlist
->word
->flags
& W_ASSIGNASSOC
)
9992 else if ((tlist
->word
->flags
& (W_ASSIGNARRAY
|W_ASSNGLOBAL
)) == (W_ASSIGNARRAY
|W_ASSNGLOBAL
))
9997 else if (tlist
->word
->flags
& W_ASSIGNARRAY
)
9999 else if (tlist
->word
->flags
& W_ASSNGLOBAL
)
10000 opts
[opti
++] = 'g';
10002 /* If we have special handling note the integer attribute and others
10003 that transform the value upon assignment. What we do is take all
10004 of the option arguments and scan through them looking for options
10005 that cause such transformations, and add them to the `opts' array. */
10006 /* if (opti > 0) */
10012 memset (omap
, '\0', sizeof (omap
));
10013 for (l
= orig_list
->next
; l
!= tlist
; l
= l
->next
)
10015 if (l
->word
->word
[0] != '-')
10016 break; /* non-option argument */
10017 if (l
->word
->word
[0] == '-' && l
->word
->word
[1] == '-' && l
->word
->word
[2] == 0)
10018 break; /* -- signals end of options */
10019 for (oind
= 1; l
->word
->word
[oind
]; oind
++)
10020 switch (l
->word
->word
[oind
])
10026 omap
[l
->word
->word
[oind
]] = 1;
10028 opts
[opti
++] = '-';
10035 for (oind
= 0; oind
< sizeof (omap
); oind
++)
10037 opts
[opti
++] = oind
;
10042 make_internal_declare (tlist
->word
->word
, opts
);
10044 t
= do_word_assignment (tlist
->word
, 0);
10047 last_command_exit_value
= EXECUTION_FAILURE
;
10048 exp_jump_to_top_level (DISCARD
);
10051 /* Now transform the word as ksh93 appears to do and go on */
10052 t
= assignment (tlist
->word
->word
, 0);
10053 tlist
->word
->word
[t
] = '\0';
10054 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
|W_ASSIGNARRAY
);
10058 expanded_something
= 0;
10059 expanded
= expand_word_internal
10060 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
10062 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
10064 /* By convention, each time this error is returned,
10065 tlist->word->word has already been freed. */
10066 tlist
->word
->word
= (char *)NULL
;
10068 /* Dispose our copy of the original list. */
10069 dispose_words (orig_list
);
10070 /* Dispose the new list we're building. */
10071 dispose_words (new_list
);
10073 last_command_exit_value
= EXECUTION_FAILURE
;
10074 if (expanded
== &expand_word_error
)
10075 exp_jump_to_top_level (DISCARD
);
10077 exp_jump_to_top_level (FORCE_EOF
);
10080 /* Don't split words marked W_NOSPLIT. */
10081 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
10083 temp_list
= word_list_split (expanded
);
10084 dispose_words (expanded
);
10088 /* If no parameter expansion, command substitution, process
10089 substitution, or arithmetic substitution took place, then
10090 do not do word splitting. We still have to remove quoted
10091 null characters from the result. */
10092 word_list_remove_quoted_nulls (expanded
);
10093 temp_list
= expanded
;
10096 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
10097 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
10101 dispose_words (orig_list
);
10104 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
10109 /* The workhorse for expand_words () and expand_words_no_vars ().
10110 First arg is LIST, a WORD_LIST of words.
10111 Second arg EFLAGS is a flags word controlling which expansions are
10114 This does all of the substitutions: brace expansion, tilde expansion,
10115 parameter expansion, command substitution, arithmetic expansion,
10116 process substitution, word splitting, and pathname expansion, according
10117 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
10118 set, or for which no expansion is done, do not undergo word splitting.
10119 Words with the W_NOGLOB bit set do not undergo pathname expansion; words
10120 with W_NOBRACE set do not undergo brace expansion (see
10121 brace_expand_word_list above). */
10123 expand_word_list_internal (list
, eflags
)
10127 WORD_LIST
*new_list
, *temp_list
;
10130 tempenv_assign_error
= 0;
10132 return ((WORD_LIST
*)NULL
);
10134 garglist
= new_list
= copy_word_list (list
);
10135 if (eflags
& WEXP_VARASSIGN
)
10137 garglist
= new_list
= separate_out_assignments (new_list
);
10140 if (subst_assign_varlist
)
10142 /* All the words were variable assignments, so they are placed
10143 into the shell's environment. */
10144 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
10146 this_command_name
= (char *)NULL
; /* no arithmetic errors */
10147 tint
= do_word_assignment (temp_list
->word
, 0);
10148 /* Variable assignment errors in non-interactive shells
10149 running in Posix.2 mode cause the shell to exit. */
10152 last_command_exit_value
= EXECUTION_FAILURE
;
10153 if (interactive_shell
== 0 && posixly_correct
)
10154 exp_jump_to_top_level (FORCE_EOF
);
10156 exp_jump_to_top_level (DISCARD
);
10159 dispose_words (subst_assign_varlist
);
10160 subst_assign_varlist
= (WORD_LIST
*)NULL
;
10162 return ((WORD_LIST
*)NULL
);
10166 /* Begin expanding the words that remain. The expansions take place on
10167 things that aren't really variable assignments. */
10169 #if defined (BRACE_EXPANSION)
10170 /* Do brace expansion on this word if there are any brace characters
10172 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
10173 new_list
= brace_expand_word_list (new_list
, eflags
);
10174 #endif /* BRACE_EXPANSION */
10176 /* Perform the `normal' shell expansions: tilde expansion, parameter and
10177 variable substitution, command substitution, arithmetic expansion,
10178 and word splitting. */
10179 new_list
= shell_expand_word_list (new_list
, eflags
);
10181 /* Okay, we're almost done. Now let's just do some filename
10185 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
10186 /* Glob expand the word list unless globbing has been disabled. */
10187 new_list
= glob_expand_word_list (new_list
, eflags
);
10189 /* Dequote the words, because we're not performing globbing. */
10190 new_list
= dequote_list (new_list
);
10193 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
10195 sh_wassign_func_t
*assign_func
;
10196 int is_special_builtin
, is_builtin_or_func
;
10198 /* If the remainder of the words expand to nothing, Posix.2 requires
10199 that the variable and environment assignments affect the shell's
10201 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
10202 tempenv_assign_error
= 0;
10204 is_builtin_or_func
= (new_list
&& new_list
->word
&& (find_shell_builtin (new_list
->word
->word
) || find_function (new_list
->word
->word
)));
10205 /* Posix says that special builtins exit if a variable assignment error
10206 occurs in an assignment preceding it. */
10207 is_special_builtin
= (posixly_correct
&& new_list
&& new_list
->word
&& find_special_builtin (new_list
->word
->word
));
10209 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
10211 this_command_name
= (char *)NULL
;
10212 assigning_in_environment
= (assign_func
== assign_in_env
);
10213 tint
= (*assign_func
) (temp_list
->word
, is_builtin_or_func
);
10214 assigning_in_environment
= 0;
10215 /* Variable assignment errors in non-interactive shells running
10216 in Posix.2 mode cause the shell to exit. */
10219 if (assign_func
== do_word_assignment
)
10221 last_command_exit_value
= EXECUTION_FAILURE
;
10222 if (interactive_shell
== 0 && posixly_correct
&& is_special_builtin
)
10223 exp_jump_to_top_level (FORCE_EOF
);
10225 exp_jump_to_top_level (DISCARD
);
10228 tempenv_assign_error
++;
10232 dispose_words (subst_assign_varlist
);
10233 subst_assign_varlist
= (WORD_LIST
*)NULL
;