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-2010 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"
57 #include "builtins/getopt.h"
58 #include "builtins/common.h"
60 #include "builtins/builtext.h"
62 #include <tilde/tilde.h>
63 #include <glob/strmatch.h>
69 /* The size that strings change by. */
70 #define DEFAULT_INITIAL_ARRAY_SIZE 112
71 #define DEFAULT_ARRAY_SIZE 128
77 #define VT_ARRAYMEMBER 3
80 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
82 /* Flags for quoted_strchr */
83 #define ST_BACKSL 0x01
84 #define ST_CTLESC 0x02
85 #define ST_SQUOTE 0x04 /* unused yet */
86 #define ST_DQUOTE 0x08 /* unused yet */
88 /* Flags for the `pflags' argument to param_expand() */
89 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
91 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
93 /* These defs make it easier to use the editor. */
99 #if defined (HANDLE_MULTIBYTE)
104 /* Evaluates to 1 if C is one of the shell's special parameters whose length
105 can be taken, but is also one of the special expansion characters. */
106 #define VALID_SPECIAL_LENGTH_PARAM(c) \
107 ((c) == '-' || (c) == '?' || (c) == '#')
109 /* Evaluates to 1 if C is one of the shell's special parameters for which an
110 indirect variable reference may be made. */
111 #define VALID_INDIR_PARAM(c) \
112 ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
114 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
115 in ${parameter[:]OPword}. */
116 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
118 /* Evaluates to 1 if this is one of the shell's special variables. */
119 #define SPECIAL_VAR(name, wi) \
120 ((DIGIT (*name) && all_digits (name)) || \
121 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
122 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
124 /* An expansion function that takes a string and a quoted flag and returns
125 a WORD_LIST *. Used as the type of the third argument to
126 expand_string_if_necessary(). */
127 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
129 /* Process ID of the last command executed within command substitution. */
130 pid_t last_command_subst_pid
= NO_PID
;
131 pid_t current_command_subst_pid
= NO_PID
;
133 /* Variables used to keep track of the characters in IFS. */
136 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
138 #if defined (HANDLE_MULTIBYTE)
139 unsigned char ifs_firstc
[MB_LEN_MAX
];
140 size_t ifs_firstc_len
;
142 unsigned char ifs_firstc
;
145 /* Sentinel to tell when we are performing variable assignments preceding a
146 command name and putting them into the environment. Used to make sure
147 we use the temporary environment when looking up variable values. */
148 int assigning_in_environment
;
150 /* Used to hold a list of variable assignments preceding a command. Global
151 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
152 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
153 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
155 /* Extern functions and variables from different files. */
156 extern int last_command_exit_value
, last_command_exit_signal
;
157 extern int subshell_environment
, line_number
;
158 extern int subshell_level
, parse_and_execute_level
, sourcelevel
;
159 extern int eof_encountered
;
160 extern int return_catch_flag
, return_catch_value
;
161 extern pid_t dollar_dollar_pid
;
162 extern int posixly_correct
;
163 extern char *this_command_name
;
164 extern struct fd_bitmap
*current_fds_to_close
;
165 extern int wordexp_only
;
166 extern int expanding_redir
;
167 extern int tempenv_assign_error
;
169 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
170 extern wchar_t *wcsdup
__P((const wchar_t *));
173 /* Non-zero means to allow unmatched globbed filenames to expand to
175 int allow_null_glob_expansion
;
177 /* Non-zero means to throw an error when globbing fails to match anything. */
178 int fail_glob_expansion
;
181 /* Variables to keep track of which words in an expanded word list (the
182 output of expand_word_list_internal) are the result of globbing
183 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
184 (CURRENTLY UNUSED). */
185 char *glob_argv_flags
;
186 static int glob_argv_flags_size
;
189 static WORD_LIST expand_word_error
, expand_word_fatal
;
190 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
191 static char expand_param_error
, expand_param_fatal
;
192 static char extract_string_error
, extract_string_fatal
;
194 /* Tell the expansion functions to not longjmp back to top_level on fatal
195 errors. Enabled when doing completion and prompt string expansion. */
196 static int no_longjmp_on_fatal_error
= 0;
198 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
199 $* on $IFS, primarily when doing assignment statements. */
200 static int expand_no_split_dollar_star
= 0;
202 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
203 without any leading variable assignments. */
204 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
206 static char *quoted_substring
__P((char *, int, int));
207 static int quoted_strlen
__P((char *));
208 static char *quoted_strchr
__P((char *, int, int));
210 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
211 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
212 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
213 static WORD_LIST
*expand_string_internal
__P((char *, int));
214 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
215 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
217 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
218 static char *make_quoted_char
__P((int));
219 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
221 static int unquoted_substring
__P((char *, char *));
222 static int unquoted_member
__P((int, char *));
224 #if defined (ARRAY_VARS)
225 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
227 static int do_assignment_internal
__P((const WORD_DESC
*, int));
229 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
230 static char *string_extract
__P((char *, int *, char *, int));
231 static char *string_extract_double_quoted
__P((char *, int *, int));
232 static inline char *string_extract_single_quoted
__P((char *, int *));
233 static inline int skip_single_quoted
__P((const char *, size_t, int));
234 static int skip_double_quoted
__P((char *, size_t, int));
235 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
236 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
237 static int skip_matched_pair
__P((const char *, int, int, int, int));
239 static char *pos_params
__P((char *, int, int, int));
241 static unsigned char *mb_getcharlens
__P((char *, int));
243 static char *remove_upattern
__P((char *, char *, int));
244 #if defined (HANDLE_MULTIBYTE)
245 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
247 static char *remove_pattern
__P((char *, char *, int));
249 static int match_upattern
__P((char *, char *, int, char **, char **));
250 #if defined (HANDLE_MULTIBYTE)
251 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
253 static int match_pattern
__P((char *, char *, int, char **, char **));
254 static int getpatspec
__P((int, char *));
255 static char *getpattern
__P((char *, int, int));
256 static char *variable_remove_pattern
__P((char *, char *, int, int));
257 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
258 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
260 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
262 static char *parameter_brace_remove_pattern
__P((char *, char *, int, char *, int, int, int));
264 static char *process_substitute
__P((char *, int));
266 static char *read_comsub
__P((int, int, int *));
269 static arrayind_t array_length_reference
__P((char *));
272 static int valid_brace_expansion_word
__P((char *, int));
273 static int chk_atstar
__P((char *, int, int *, int *));
274 static int chk_arithsub
__P((const char *, int));
276 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int, arrayind_t
*));
277 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
278 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
279 static void parameter_brace_expand_error
__P((char *, char *));
281 static int valid_length_expression
__P((char *));
282 static intmax_t parameter_brace_expand_length
__P((char *));
284 static char *skiparith
__P((char *, int));
285 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
286 static int get_var_and_type
__P((char *, char *, arrayind_t
, int, int, SHELL_VAR
**, char **));
287 static char *mb_substring
__P((char *, int, int));
288 static char *parameter_brace_substring
__P((char *, char *, int, char *, int, int));
290 static int shouldexp_replacement
__P((char *));
292 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
294 static char *parameter_brace_patsub
__P((char *, char *, int, char *, int, int));
296 static char *pos_params_casemod
__P((char *, char *, int, int));
297 static char *parameter_brace_casemod
__P((char *, char *, int, int, char *, int, int));
299 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int, int *, int *));
300 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
302 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
304 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
306 static void exp_jump_to_top_level
__P((int));
308 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
309 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
310 #ifdef BRACE_EXPANSION
311 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
313 #if defined (ARRAY_VARS)
314 static int make_internal_declare
__P((char *, char *));
316 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
317 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
319 /* **************************************************************** */
321 /* Utility Functions */
323 /* **************************************************************** */
327 dump_word_flags (flags
)
333 fprintf (stderr
, "%d -> ", f
);
334 if (f
& W_ASSIGNASSOC
)
337 fprintf (stderr
, "W_ASSIGNASSOC%s", f
? "|" : "");
342 fprintf (stderr
, "W_HASCTLESC%s", f
? "|" : "");
347 fprintf (stderr
, "W_NOPROCSUB%s", f
? "|" : "");
352 fprintf (stderr
, "W_DQUOTE%s", f
? "|" : "");
354 if (f
& W_HASQUOTEDNULL
)
356 f
&= ~W_HASQUOTEDNULL
;
357 fprintf (stderr
, "W_HASQUOTEDNULL%s", f
? "|" : "");
362 fprintf (stderr
, "W_ASSIGNARG%s", f
? "|" : "");
367 fprintf (stderr
, "W_ASSNBLTIN%s", f
? "|" : "");
369 if (f
& W_COMPASSIGN
)
372 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
377 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
382 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
387 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
392 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
397 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
399 if (f
& W_DOLLARSTAR
)
402 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
407 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
412 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
417 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
422 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
427 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
432 fprintf (stderr
, "W_GLOBEXP%s", f
? "|" : "");
434 if (f
& W_ASSIGNMENT
)
437 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
442 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
447 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
449 fprintf (stderr
, "\n");
454 #ifdef INCLUDE_UNUSED
456 quoted_substring (string
, start
, end
)
461 register char *result
, *s
, *r
;
465 /* Move to string[start], skipping quoted characters. */
466 for (s
= string
, l
= 0; *s
&& l
< start
; )
478 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
480 /* Copy LEN characters, including quote characters. */
482 for (l
= 0; l
< len
; s
++)
496 #ifdef INCLUDE_UNUSED
497 /* Return the length of S, skipping over quoted characters */
521 /* Find the first occurrence of character C in string S, obeying shell
522 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
523 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
524 escaped with CTLESC are skipped. */
526 quoted_strchr (s
, c
, flags
)
534 if (((flags
& ST_BACKSL
) && *p
== '\\')
535 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
539 return ((char *)NULL
);
545 return ((char *)NULL
);
548 /* Return 1 if CHARACTER appears in an unquoted portion of
549 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
551 unquoted_member (character
, string
)
559 slen
= strlen (string
);
561 while (c
= string
[sindex
])
569 ADVANCE_CHAR (string
, slen
, sindex
);
575 ADVANCE_CHAR (string
, slen
, sindex
);
579 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
583 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
590 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
592 unquoted_substring (substr
, string
)
593 char *substr
, *string
;
596 int sindex
, c
, sublen
;
599 if (substr
== 0 || *substr
== '\0')
602 slen
= strlen (string
);
603 sublen
= strlen (substr
);
604 for (sindex
= 0; c
= string
[sindex
]; )
606 if (STREQN (string
+ sindex
, substr
, sublen
))
614 ADVANCE_CHAR (string
, slen
, sindex
);
618 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
622 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
626 ADVANCE_CHAR (string
, slen
, sindex
);
633 /* Most of the substitutions must be done in parallel. In order
634 to avoid using tons of unclear goto's, I have some functions
635 for manipulating malloc'ed strings. They all take INDX, a
636 pointer to an integer which is the offset into the string
637 where manipulation is taking place. They also take SIZE, a
638 pointer to an integer which is the current length of the
639 character array for this string. */
641 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
642 of space allocated to TARGET. SOURCE can be NULL, in which
643 case nothing happens. Gets rid of SOURCE by freeing it.
644 Returns TARGET in case the location has changed. */
646 sub_append_string (source
, target
, indx
, size
)
647 char *source
, *target
;
654 srclen
= STRLEN (source
);
655 if (srclen
>= (int)(*size
- *indx
))
658 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
659 target
= (char *)xrealloc (target
, (*size
= n
));
662 FASTCOPY (source
, target
+ *indx
, srclen
);
664 target
[*indx
] = '\0';
673 /* Append the textual representation of NUMBER to TARGET.
674 INDX and SIZE are as in SUB_APPEND_STRING. */
676 sub_append_number (number
, target
, indx
, size
)
683 temp
= itos (number
);
684 return (sub_append_string (temp
, target
, indx
, size
));
688 /* Extract a substring from STRING, starting at SINDEX and ending with
689 one of the characters in CHARLIST. Don't make the ending character
690 part of the string. Leave SINDEX pointing at the ending character.
691 Understand about backslashes in the string. If (flags & SX_VARNAME)
692 is non-zero, and array variables have been compiled into the shell,
693 everything between a `[' and a corresponding `]' is skipped over.
694 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
695 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
696 contain a closing character from CHARLIST. */
698 string_extract (string
, sindex
, charlist
, flags
)
710 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
713 while (c
= string
[i
])
722 #if defined (ARRAY_VARS)
723 else if ((flags
& SX_VARNAME
) && c
== '[')
726 /* If this is an array subscript, skip over it and continue. */
727 ni
= skipsubscript (string
, i
, 0);
728 if (string
[ni
] == ']')
732 else if (MEMBER (c
, charlist
))
738 ADVANCE_CHAR (string
, slen
, i
);
741 /* If we had to have a matching delimiter and didn't find one, return an
742 error and let the caller deal with it. */
743 if ((flags
& SX_REQMATCH
) && found
== 0)
746 return (&extract_string_error
);
749 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
755 /* Extract the contents of STRING as if it is enclosed in double quotes.
756 SINDEX, when passed in, is the offset of the character immediately
757 following the opening double quote; on exit, SINDEX is left pointing after
758 the closing double quote. If STRIPDQ is non-zero, unquoted double
759 quotes are stripped and the string is terminated by a null byte.
760 Backslashes between the embedded double quotes are processed. If STRIPDQ
761 is zero, an unquoted `"' terminates the string. */
763 string_extract_double_quoted (string
, sindex
, stripdq
)
765 int *sindex
, stripdq
;
771 char *temp
, *ret
; /* The new string we return. */
772 int pass_next
, backquote
, si
; /* State variables for the machine. */
776 slen
= strlen (string
+ *sindex
) + *sindex
;
777 send
= string
+ slen
;
779 pass_next
= backquote
= dquote
= 0;
780 temp
= (char *)xmalloc (1 + slen
- *sindex
);
784 while (c
= string
[i
])
786 /* Process a character that was quoted by a backslash. */
789 /* XXX - take another look at this in light of Interp 221 */
792 ``The backslash shall retain its special meaning as an escape
793 character only when followed by one of the characters:
796 If STRIPDQ is zero, we handle the double quotes here and let
797 expand_word_internal handle the rest. If STRIPDQ is non-zero,
798 we have already been through one round of backslash stripping,
799 and want to strip these backslashes only if DQUOTE is non-zero,
800 indicating that we are inside an embedded double-quoted string. */
802 /* If we are in an embedded quoted string, then don't strip
803 backslashes before characters for which the backslash
804 retains its special meaning, but remove backslashes in
805 front of other characters. If we are not in an
806 embedded quoted string, don't strip backslashes at all.
807 This mess is necessary because the string was already
808 surrounded by double quotes (and sh has some really weird
810 The returned string will be run through expansion as if
811 it were double-quoted. */
812 if ((stripdq
== 0 && c
!= '"') ||
813 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
818 COPY_CHAR_I (temp
, j
, string
, send
, i
);
822 /* A backslash protects the next character. The code just above
823 handles preserving the backslash in front of any character but
832 /* Inside backquotes, ``the portion of the quoted string from the
833 initial backquote and the characters up to the next backquote
834 that is not preceded by a backslash, having escape characters
835 removed, defines that command''. */
853 /* Pass everything between `$(' and the matching `)' or a quoted
854 ${ ... } pair through according to the Posix.2 specification. */
855 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
860 if (string
[i
+ 1] == LPAREN
)
861 ret
= extract_command_subst (string
, &si
, 0);
863 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, 0);
866 temp
[j
++] = string
[i
+ 1];
868 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
870 if (ret
== 0 && no_longjmp_on_fatal_error
)
873 ret
= string
+ i
+ 2;
876 for (t
= 0; ret
[t
]; t
++, j
++)
878 temp
[j
] = string
[si
];
893 /* Add any character but a double quote to the quoted string we're
896 goto add_one_character
;
910 /* Point to after the closing quote. */
918 /* This should really be another option to string_extract_double_quoted. */
920 skip_double_quoted (string
, slen
, sind
)
927 int pass_next
, backquote
, si
;
930 pass_next
= backquote
= 0;
932 while (c
= string
[i
])
937 ADVANCE_CHAR (string
, slen
, i
);
950 ADVANCE_CHAR (string
, slen
, i
);
959 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
962 if (string
[i
+ 1] == LPAREN
)
963 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
965 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, SX_NOALLOC
);
972 ADVANCE_CHAR (string
, slen
, i
);
985 /* Extract the contents of STRING as if it is enclosed in single quotes.
986 SINDEX, when passed in, is the offset of the character immediately
987 following the opening single quote; on exit, SINDEX is left pointing after
988 the closing single quote. */
990 string_extract_single_quoted (string
, sindex
)
999 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1000 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
1002 while (string
[i
] && string
[i
] != '\'')
1003 ADVANCE_CHAR (string
, slen
, i
);
1005 t
= substring (string
, *sindex
, i
);
1015 skip_single_quoted (string
, slen
, sind
)
1024 while (string
[c
] && string
[c
] != '\'')
1025 ADVANCE_CHAR (string
, slen
, c
);
1032 /* Just like string_extract, but doesn't hack backslashes or any of
1033 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1035 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1043 #if defined (HANDLE_MULTIBYTE)
1051 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1053 temp
= string_extract_single_quoted (string
, sindex
);
1054 --*sindex
; /* leave *sindex at separator character */
1060 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1061 this only if MB_CUR_MAX > 1. */
1062 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1064 #if defined (HANDLE_MULTIBYTE)
1065 clen
= strlen (charlist
);
1068 while (c
= string
[i
])
1070 #if defined (HANDLE_MULTIBYTE)
1073 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1078 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1079 through, to protect the CTLNULs from later calls to
1080 remove_quoted_nulls. */
1081 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1087 #if defined (HANDLE_MULTIBYTE)
1088 mblength
= MBLEN (string
+ i
, slen
- i
);
1092 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1093 if (MB_INVALIDCH (mblength
))
1095 if (MEMBER (c
, charlist
))
1103 len
= mbstowcs (wcharlist
, charlist
, 0);
1106 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1107 mbstowcs (wcharlist
, charlist
, len
+ 1);
1110 if (wcschr (wcharlist
, wc
))
1116 if (MEMBER (c
, charlist
))
1119 ADVANCE_CHAR (string
, slen
, i
);
1122 #if defined (HANDLE_MULTIBYTE)
1126 temp
= substring (string
, *sindex
, i
);
1132 /* Extract the $( construct in STRING, and return a new string.
1133 Start extracting at (SINDEX) as if we had just seen "$(".
1134 Make (SINDEX) get the position of the matching ")". )
1135 XFLAGS is additional flags to pass to other extraction functions. */
1137 extract_command_subst (string
, sindex
, xflags
)
1142 if (string
[*sindex
] == LPAREN
)
1143 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1146 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1147 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1151 /* Extract the $[ construct in STRING, and return a new string. (])
1152 Start extracting at (SINDEX) as if we had just seen "$[".
1153 Make (SINDEX) get the position of the matching "]". */
1155 extract_arithmetic_subst (string
, sindex
)
1159 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1162 #if defined (PROCESS_SUBSTITUTION)
1163 /* Extract the <( or >( construct in STRING, and return a new string.
1164 Start extracting at (SINDEX) as if we had just seen "<(".
1165 Make (SINDEX) get the position of the matching ")". */ /*))*/
1167 extract_process_subst (string
, starter
, sindex
)
1172 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", 0));
1174 #endif /* PROCESS_SUBSTITUTION */
1176 #if defined (ARRAY_VARS)
1177 /* This can be fooled by unquoted right parens in the passed string. If
1178 each caller verifies that the last character in STRING is a right paren,
1179 we don't even need to call extract_delimited_string. */
1181 extract_array_assignment_list (string
, sindex
)
1188 slen
= strlen (string
); /* ( */
1189 if (string
[slen
- 1] == ')')
1191 ret
= substring (string
, *sindex
, slen
- 1);
1199 /* Extract and create a new string from the contents of STRING, a
1200 character string delimited with OPENER and CLOSER. SINDEX is
1201 the address of an int describing the current offset in STRING;
1202 it should point to just after the first OPENER found. On exit,
1203 SINDEX gets the position of the last character of the matching CLOSER.
1204 If OPENER is more than a single character, ALT_OPENER, if non-null,
1205 contains a character string that can also match CLOSER and thus
1206 needs to be skipped. */
1208 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1211 char *opener
, *alt_opener
, *closer
;
1217 int pass_character
, nesting_level
, in_comment
;
1218 int len_closer
, len_opener
, len_alt_opener
;
1221 slen
= strlen (string
+ *sindex
) + *sindex
;
1222 len_opener
= STRLEN (opener
);
1223 len_alt_opener
= STRLEN (alt_opener
);
1224 len_closer
= STRLEN (closer
);
1226 pass_character
= in_comment
= 0;
1231 while (nesting_level
)
1242 ADVANCE_CHAR (string
, slen
, i
);
1246 if (pass_character
) /* previous char was backslash */
1249 ADVANCE_CHAR (string
, slen
, i
);
1253 /* Not exactly right yet; should handle shell metacharacters and
1254 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1255 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1258 ADVANCE_CHAR (string
, slen
, i
);
1262 if (c
== CTLESC
|| c
== '\\')
1269 /* Process a nested command substitution, but only if we're parsing an
1270 arithmetic substitution. */
1271 if ((flags
& SX_COMMAND
) && string
[i
] == '$' && string
[i
+1] == LPAREN
)
1274 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1279 /* Process a nested OPENER. */
1280 if (STREQN (string
+ i
, opener
, len_opener
))
1282 si
= i
+ len_opener
;
1283 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1288 /* Process a nested ALT_OPENER */
1289 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1291 si
= i
+ len_alt_opener
;
1292 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1297 /* If the current substring terminates the delimited string, decrement
1298 the nesting level. */
1299 if (STREQN (string
+ i
, closer
, len_closer
))
1301 i
+= len_closer
- 1; /* move to last byte of the closer */
1303 if (nesting_level
== 0)
1307 /* Pass old-style command substitution through verbatim. */
1311 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1316 /* Pass single-quoted and double-quoted strings through verbatim. */
1317 if (c
== '\'' || c
== '"')
1320 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1321 : skip_double_quoted (string
, slen
, si
);
1325 /* move past this character, which was not special. */
1326 ADVANCE_CHAR (string
, slen
, i
);
1329 if (c
== 0 && nesting_level
)
1331 if (no_longjmp_on_fatal_error
== 0)
1333 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1334 last_command_exit_value
= EXECUTION_FAILURE
;
1335 exp_jump_to_top_level (DISCARD
);
1340 return (char *)NULL
;
1344 si
= i
- *sindex
- len_closer
+ 1;
1345 if (flags
& SX_NOALLOC
)
1346 result
= (char *)NULL
;
1349 result
= (char *)xmalloc (1 + si
);
1350 strncpy (result
, string
+ *sindex
, si
);
1358 /* Extract a parameter expansion expression within ${ and } from STRING.
1359 Obey the Posix.2 rules for finding the ending `}': count braces while
1360 skipping over enclosed quoted strings and command substitutions.
1361 SINDEX is the address of an int describing the current offset in STRING;
1362 it should point to just after the first `{' found. On exit, SINDEX
1363 gets the position of the matching `}'. QUOTED is non-zero if this
1364 occurs inside double quotes. */
1365 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1367 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1369 int *sindex
, quoted
, flags
;
1373 int pass_character
, nesting_level
, si
, dolbrace_state
;
1379 slen
= strlen (string
+ *sindex
) + *sindex
;
1381 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1382 parse_matched_pair() */
1384 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
1385 dolbrace_state
= (flags
& SX_POSIXEXP
) ? DOLBRACE_QUOTE
: DOLBRACE_PARAM
;
1388 while (c
= string
[i
])
1393 ADVANCE_CHAR (string
, slen
, i
);
1397 /* CTLESCs and backslashes quote the next character. */
1398 if (c
== CTLESC
|| c
== '\\')
1405 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1415 if (nesting_level
== 0)
1421 /* Pass the contents of old-style command substitutions through
1426 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1431 /* Pass the contents of new-style command substitutions and
1432 arithmetic substitutions through verbatim. */
1433 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1436 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1442 /* Pass the contents of single-quoted and double-quoted strings
1443 through verbatim. */
1444 if (c
== '\'' || c
== '"')
1447 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1448 : skip_double_quoted (string
, slen
, si
);
1449 /* skip_XXX_quoted leaves index one past close quote */
1452 #else /* XXX - bash-4.2 */
1453 /* Pass the contents of double-quoted strings through verbatim. */
1457 i
= skip_double_quoted (string
, slen
, si
);
1458 /* skip_XXX_quoted leaves index one past close quote */
1464 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1465 if (posixly_correct
&& shell_compatibility_level
> 41 && dolbrace_state
!= DOLBRACE_QUOTE
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1466 ADVANCE_CHAR (string
, slen
, i
);
1470 i
= skip_single_quoted (string
, slen
, si
);
1477 /* move past this character, which was not special. */
1478 ADVANCE_CHAR (string
, slen
, i
);
1480 /* This logic must agree with parse.y:parse_matched_pair, since they
1481 share the same defines. */
1482 if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '%' && (i
- *sindex
) > 1)
1483 dolbrace_state
= DOLBRACE_QUOTE
;
1484 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '#' && (i
- *sindex
) > 1)
1485 dolbrace_state
= DOLBRACE_QUOTE
;
1486 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '/' && (i
- *sindex
) > 1)
1487 dolbrace_state
= DOLBRACE_QUOTE
;
1488 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '^' && (i
- *sindex
) > 1)
1489 dolbrace_state
= DOLBRACE_QUOTE
;
1490 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== ',' && (i
- *sindex
) > 1)
1491 dolbrace_state
= DOLBRACE_QUOTE
;
1492 else if (dolbrace_state
== DOLBRACE_PARAM
&& strchr ("#%^,~:-=?+/", c
) != 0)
1493 dolbrace_state
= DOLBRACE_OP
;
1494 else if (dolbrace_state
== DOLBRACE_OP
&& strchr ("#%^,~:-=?+/", c
) == 0)
1495 dolbrace_state
= DOLBRACE_WORD
;
1498 if (c
== 0 && nesting_level
)
1500 if (no_longjmp_on_fatal_error
== 0)
1502 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1503 last_command_exit_value
= EXECUTION_FAILURE
;
1504 exp_jump_to_top_level (DISCARD
);
1509 return ((char *)NULL
);
1513 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1519 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1520 STRING, and returns a pointer to it. */
1522 de_backslash (string
)
1525 register size_t slen
;
1526 register int i
, j
, prev_i
;
1529 slen
= strlen (string
);
1532 /* Loop copying string[i] to string[j], i >= j. */
1535 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1536 string
[i
+ 1] == '$'))
1539 ADVANCE_CHAR (string
, slen
, i
);
1541 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1552 /* Replace instances of \! in a string with !. */
1554 unquote_bang (string
)
1558 register char *temp
;
1560 temp
= (char *)xmalloc (1 + strlen (string
));
1562 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1564 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1570 strcpy (string
, temp
);
1575 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1577 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1578 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1579 matched pairs of quotes or backquotes, or skip word expansions; it is
1580 intended to be used after expansion has been performed and during final
1581 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1583 skip_matched_pair (string
, start
, open
, close
, flags
)
1585 int start
, open
, close
, flags
;
1587 int i
, pass_next
, backq
, si
, c
, count
;
1592 slen
= strlen (string
+ start
) + start
;
1593 no_longjmp_on_fatal_error
= 1;
1595 i
= start
+ 1; /* skip over leading bracket */
1597 pass_next
= backq
= 0;
1598 ss
= (char *)string
;
1599 while (c
= string
[i
])
1606 ADVANCE_CHAR (string
, slen
, i
);
1619 ADVANCE_CHAR (string
, slen
, i
);
1622 else if ((flags
& 1) == 0 && c
== '`')
1628 else if ((flags
& 1) == 0 && c
== open
)
1634 else if (c
== close
)
1642 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1644 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1645 : skip_double_quoted (ss
, slen
, ++i
);
1646 /* no increment, the skip functions increment past the closing quote. */
1648 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1651 if (string
[si
] == '\0')
1654 if (string
[i
+1] == LPAREN
)
1655 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1657 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1659 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1665 ADVANCE_CHAR (string
, slen
, i
);
1671 #if defined (ARRAY_VARS)
1673 skipsubscript (string
, start
, flags
)
1677 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1681 /* Skip characters in STRING until we find a character in DELIMS, and return
1682 the index of that character. START is the index into string at which we
1683 begin. This is similar in spirit to strpbrk, but it returns an index into
1684 STRING and takes a starting index. This little piece of code knows quite
1685 a lot of shell syntax. It's very similar to skip_double_quoted and other
1686 functions of that ilk. */
1688 skip_to_delim (string
, start
, delims
, flags
)
1694 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
, skipcmd
;
1696 char *temp
, open
[3];
1699 slen
= strlen (string
+ start
) + start
;
1700 if (flags
& SD_NOJMP
)
1701 no_longjmp_on_fatal_error
= 1;
1702 invert
= (flags
& SD_INVERT
);
1703 skipcmd
= (flags
& SD_NOSKIPCMD
) == 0;
1706 pass_next
= backq
= 0;
1707 while (c
= string
[i
])
1709 /* If this is non-zero, we should not let quote characters be delimiters
1710 and the current character is a single or double quote. We should not
1711 test whether or not it's a delimiter until after we skip single- or
1712 double-quoted strings. */
1713 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1719 ADVANCE_CHAR (string
, slen
, i
);
1732 ADVANCE_CHAR (string
, slen
, i
);
1741 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1743 else if (c
== '\'' || c
== '"')
1745 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1746 : skip_double_quoted (string
, slen
, ++i
);
1747 /* no increment, the skip functions increment past the closing quote. */
1749 else if (c
== '$' && ((skipcmd
&& string
[i
+1] == LPAREN
) || string
[i
+1] == LBRACE
))
1752 if (string
[si
] == '\0')
1755 if (string
[i
+1] == LPAREN
)
1756 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1758 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1760 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1765 #if defined (PROCESS_SUBSTITUTION)
1766 else if (skipcmd
&& (c
== '<' || c
== '>') && string
[i
+1] == LPAREN
)
1769 if (string
[si
] == '\0')
1771 temp
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &si
);
1773 if (string
[i
] == '\0')
1778 #endif /* PROCESS_SUBSTITUTION */
1779 #if defined (EXTENDED_GLOB)
1780 else if ((flags
& SD_EXTGLOB
) && extended_glob
&& string
[i
+1] == LPAREN
&& member (c
, "?*+!@"))
1783 if (string
[si
] == '\0')
1789 temp
= extract_delimited_string (string
, &si
, open
, "(", ")", SX_NOALLOC
); /* ) */
1792 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1798 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1801 ADVANCE_CHAR (string
, slen
, i
);
1807 #if defined (READLINE)
1808 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1809 an unclosed quoted string), or if the character at EINDEX is quoted
1810 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1811 single and double-quoted string parsing functions should not return an
1812 error if there are unclosed quotes or braces. The characters that this
1813 recognizes need to be the same as the contents of
1814 rl_completer_quote_characters. */
1817 char_is_quoted (string
, eindex
)
1821 int i
, pass_next
, c
;
1825 slen
= strlen (string
);
1826 no_longjmp_on_fatal_error
= 1;
1835 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1837 ADVANCE_CHAR (string
, slen
, i
);
1846 else if (c
== '\'' || c
== '"')
1848 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1849 : skip_double_quoted (string
, slen
, ++i
);
1852 /* no increment, the skip_xxx functions go one past end */
1855 ADVANCE_CHAR (string
, slen
, i
);
1862 unclosed_pair (string
, eindex
, openstr
)
1867 int i
, pass_next
, openc
, olen
;
1871 slen
= strlen (string
);
1872 olen
= strlen (openstr
);
1873 i
= pass_next
= openc
= 0;
1879 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1881 ADVANCE_CHAR (string
, slen
, i
);
1884 else if (string
[i
] == '\\')
1890 else if (STREQN (string
+ i
, openstr
, olen
))
1895 else if (string
[i
] == '\'' || string
[i
] == '"')
1897 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1898 : skip_double_quoted (string
, slen
, i
);
1903 ADVANCE_CHAR (string
, slen
, i
);
1908 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1909 individual words. If DELIMS is NULL, the current value of $IFS is used
1910 to split the string, and the function follows the shell field splitting
1911 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1912 gets the number of words in the returned list. CWP, if non-NULL, gets
1913 the index of the word containing SENTINEL. Non-whitespace chars in
1914 DELIMS delimit separate fields. */
1916 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1920 int sentinel
, flags
;
1923 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1924 char *token
, *d
, *d2
;
1925 WORD_LIST
*ret
, *tl
;
1927 if (string
== 0 || *string
== '\0')
1933 return ((WORD_LIST
*)NULL
);
1936 d
= (delims
== 0) ? ifs_value
: delims
;
1937 ifs_split
= delims
== 0;
1939 /* Make d2 the non-whitespace characters in delims */
1944 #if defined (HANDLE_MULTIBYTE)
1945 size_t mblength
= 1;
1949 slength
= strlen (delims
);
1950 d2
= (char *)xmalloc (slength
+ 1);
1954 #if defined (HANDLE_MULTIBYTE)
1955 mbstate_t state_bak
;
1957 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1958 if (MB_INVALIDCH (mblength
))
1960 else if (mblength
> 1)
1962 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1965 slength
-= mblength
;
1969 if (whitespace (delims
[i
]) == 0)
1970 d2
[ts
++] = delims
[i
];
1978 ret
= (WORD_LIST
*)NULL
;
1980 /* Remove sequences of whitespace characters at the start of the string, as
1981 long as those characters are delimiters. */
1982 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1984 if (string
[i
] == '\0')
1990 dflags
= flags
|SD_NOJMP
;
1993 te
= skip_to_delim (string
, ts
, d
, dflags
);
1995 /* If we have a non-whitespace delimiter character, use it to make a
1996 separate field. This is just about what $IFS splitting does and
1997 is closer to the behavior of the shell parser. */
1998 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
2001 /* If we're using IFS splitting, the non-whitespace delimiter char
2002 and any additional IFS whitespace delimits a field. */
2004 while (member (string
[te
], d
) && spctabnl (string
[te
]))
2007 while (member (string
[te
], d2
))
2011 token
= substring (string
, ts
, te
);
2013 ret
= add_string_to_list (token
, ret
);
2017 if (sentinel
>= ts
&& sentinel
<= te
)
2020 /* If the cursor is at whitespace just before word start, set the
2021 sentinel word to the current word. */
2022 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
2025 /* If the cursor is at whitespace between two words, make a new, empty
2026 word, add it before (well, after, since the list is in reverse order)
2027 the word we just added, and set the current word to that one. */
2028 if (cwp
&& cw
== -1 && sentinel
< ts
)
2030 tl
= make_word_list (make_word (""), ret
->next
);
2036 if (string
[te
] == 0)
2040 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
2049 /* Special case for SENTINEL at the end of STRING. If we haven't found
2050 the word containing SENTINEL yet, and the index we're looking for is at
2051 the end of STRING (or past the end of the previously-found token,
2052 possible if the end of the line is composed solely of IFS whitespace)
2053 add an additional null argument and set the current word pointer to that. */
2054 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
2056 if (whitespace (string
[sentinel
- 1]))
2059 ret
= add_string_to_list (token
, ret
);
2070 return (REVERSE_LIST (ret
, WORD_LIST
*));
2072 #endif /* READLINE */
2076 /* Extract the name of the variable to bind to from the assignment string. */
2078 assignment_name (string
)
2084 offset
= assignment (string
, 0);
2086 return (char *)NULL
;
2087 temp
= substring (string
, 0, offset
);
2092 /* **************************************************************** */
2094 /* Functions to convert strings to WORD_LISTs and vice versa */
2096 /* **************************************************************** */
2098 /* Return a single string of all the words in LIST. SEP is the separator
2099 to put between individual elements of LIST in the output string. */
2101 string_list_internal (list
, sep
)
2105 register WORD_LIST
*t
;
2107 int word_len
, sep_len
, result_size
;
2110 return ((char *)NULL
);
2112 /* Short-circuit quickly if we don't need to separate anything. */
2113 if (list
->next
== 0)
2114 return (savestring (list
->word
->word
));
2116 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2117 sep_len
= STRLEN (sep
);
2120 for (t
= list
; t
; t
= t
->next
)
2123 result_size
+= sep_len
;
2124 result_size
+= strlen (t
->word
->word
);
2127 r
= result
= (char *)xmalloc (result_size
+ 1);
2129 for (t
= list
; t
; t
= t
->next
)
2131 if (t
!= list
&& sep_len
)
2135 FASTCOPY (sep
, r
, sep_len
);
2142 word_len
= strlen (t
->word
->word
);
2143 FASTCOPY (t
->word
->word
, r
, word_len
);
2151 /* Return a single string of all the words present in LIST, separating
2152 each word with a space. */
2157 return (string_list_internal (list
, " "));
2160 /* An external interface that can be used by the rest of the shell to
2161 obtain a string containing the first character in $IFS. Handles all
2162 the multibyte complications. If LENP is non-null, it is set to the
2163 length of the returned string. */
2165 ifs_firstchar (lenp
)
2171 ret
= xmalloc (MB_LEN_MAX
+ 1);
2172 #if defined (HANDLE_MULTIBYTE)
2173 if (ifs_firstc_len
== 1)
2175 ret
[0] = ifs_firstc
[0];
2177 len
= ret
[0] ? 1 : 0;
2181 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2182 ret
[len
= ifs_firstc_len
] = '\0';
2185 ret
[0] = ifs_firstc
;
2187 len
= ret
[0] ? 0 : 1;
2196 /* Return a single string of all the words present in LIST, obeying the
2197 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2198 expansion [of $*] appears within a double quoted string, it expands
2199 to a single field with the value of each parameter separated by the
2200 first character of the IFS variable, or by a <space> if IFS is unset." */
2202 string_list_dollar_star (list
)
2206 #if defined (HANDLE_MULTIBYTE)
2207 # if defined (__GNUC__)
2208 char sep
[MB_CUR_MAX
+ 1];
2216 #if defined (HANDLE_MULTIBYTE)
2217 # if !defined (__GNUC__)
2218 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2219 # endif /* !__GNUC__ */
2220 if (ifs_firstc_len
== 1)
2222 sep
[0] = ifs_firstc
[0];
2227 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2228 sep
[ifs_firstc_len
] = '\0';
2231 sep
[0] = ifs_firstc
;
2235 ret
= string_list_internal (list
, sep
);
2236 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2242 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2243 is non-zero, the $@ appears within double quotes, and we should quote
2244 the list before converting it into a string. If IFS is unset, and the
2245 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2246 in the words in the list, because the default value of $IFS is
2247 <space><tab><newline>, IFS characters in the words in the list should
2248 also be split. If IFS is null, and the word is not quoted, we need
2249 to quote the words in the list to preserve the positional parameters
2252 string_list_dollar_at (list
, quoted
)
2257 #if defined (HANDLE_MULTIBYTE)
2258 # if defined (__GNUC__)
2259 char sep
[MB_CUR_MAX
+ 1];
2262 # endif /* !__GNUC__ */
2268 /* XXX this could just be ifs = ifs_value; */
2269 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2271 #if defined (HANDLE_MULTIBYTE)
2272 # if !defined (__GNUC__)
2273 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2274 # endif /* !__GNUC__ */
2277 if (ifs_firstc_len
== 1)
2279 sep
[0] = ifs_firstc
[0];
2284 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2285 sep
[ifs_firstc_len
] = '\0';
2294 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2298 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2299 it now that quote_escapes quotes spaces */
2300 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2302 : list_quote_escapes (list
);
2304 ret
= string_list_internal (tlist
, sep
);
2305 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2311 /* Turn the positional paramters into a string, understanding quoting and
2312 the various subtleties of using the first character of $IFS as the
2313 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2314 string_list as appropriate. */
2316 string_list_pos_params (pchar
, list
, quoted
)
2324 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2326 tlist
= quote_list (list
);
2327 word_list_remove_quoted_nulls (tlist
);
2328 ret
= string_list_dollar_star (tlist
);
2330 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2332 tlist
= quote_list (list
);
2333 word_list_remove_quoted_nulls (tlist
);
2334 ret
= string_list (tlist
);
2336 else if (pchar
== '*')
2338 /* Even when unquoted, string_list_dollar_star does the right thing
2339 making sure that the first character of $IFS is used as the
2341 ret
= string_list_dollar_star (list
);
2343 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2344 /* We use string_list_dollar_at, but only if the string is quoted, since
2345 that quotes the escapes if it's not, which we don't want. We could
2346 use string_list (the old code did), but that doesn't do the right
2347 thing if the first character of $IFS is not a space. We use
2348 string_list_dollar_star if the string is unquoted so we make sure that
2349 the elements of $@ are separated by the first character of $IFS for
2351 ret
= string_list_dollar_at (list
, quoted
);
2352 else if (pchar
== '@')
2353 ret
= string_list_dollar_star (list
);
2355 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2360 /* Return the list of words present in STRING. Separate the string into
2361 words at any of the characters found in SEPARATORS. If QUOTED is
2362 non-zero then word in the list will have its quoted flag set, otherwise
2363 the quoted flag is left as make_word () deemed fit.
2365 This obeys the P1003.2 word splitting semantics. If `separators' is
2366 exactly <space><tab><newline>, then the splitting algorithm is that of
2367 the Bourne shell, which treats any sequence of characters from `separators'
2368 as a delimiter. If IFS is unset, which results in `separators' being set
2369 to "", no splitting occurs. If separators has some other value, the
2370 following rules are applied (`IFS white space' means zero or more
2371 occurrences of <space>, <tab>, or <newline>, as long as those characters
2372 are in `separators'):
2374 1) IFS white space is ignored at the start and the end of the
2376 2) Each occurrence of a character in `separators' that is not
2377 IFS white space, along with any adjacent occurrences of
2378 IFS white space delimits a field.
2379 3) Any nonzero-length sequence of IFS white space delimits a field.
2382 /* BEWARE! list_string strips null arguments. Don't call it twice and
2383 expect to have "" preserved! */
2385 /* This performs word splitting and quoted null character removal on
2388 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2389 : (c) == (separators)[0]) \
2393 list_string (string
, separators
, quoted
)
2394 register char *string
, *separators
;
2399 char *current_word
, *s
;
2400 int sindex
, sh_style_split
, whitesep
, xflags
;
2403 if (!string
|| !*string
)
2404 return ((WORD_LIST
*)NULL
);
2406 sh_style_split
= separators
&& separators
[0] == ' ' &&
2407 separators
[1] == '\t' &&
2408 separators
[2] == '\n' &&
2409 separators
[3] == '\0';
2410 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2412 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2413 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2417 /* Remove sequences of whitespace at the beginning of STRING, as
2418 long as those characters appear in IFS. Do not do this if
2419 STRING is quoted or if there are no separator characters. */
2420 if (!quoted
|| !separators
|| !*separators
)
2422 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2425 return ((WORD_LIST
*)NULL
);
2430 /* OK, now STRING points to a word that does not begin with white space.
2431 The splitting algorithm is:
2432 extract a word, stopping at a separator
2433 skip sequences of spc, tab, or nl as long as they are separators
2434 This obeys the field splitting rules in Posix.2. */
2435 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2436 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2438 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2439 unless multibyte chars are possible. */
2440 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2441 if (current_word
== 0)
2444 /* If we have a quoted empty string, add a quoted null argument. We
2445 want to preserve the quoted null character iff this is a quoted
2446 empty string; otherwise the quoted null characters are removed
2448 if (QUOTED_NULL (current_word
))
2450 t
= alloc_word_desc ();
2451 t
->word
= make_quoted_char ('\0');
2452 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2453 result
= make_word_list (t
, result
);
2455 else if (current_word
[0] != '\0')
2457 /* If we have something, then add it regardless. However,
2458 perform quoted null character removal on the current word. */
2459 remove_quoted_nulls (current_word
);
2460 result
= add_string_to_list (current_word
, result
);
2461 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2462 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2463 result
->word
->flags
|= W_QUOTED
;
2466 /* If we're not doing sequences of separators in the traditional
2467 Bourne shell style, then add a quoted null argument. */
2468 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2470 t
= alloc_word_desc ();
2471 t
->word
= make_quoted_char ('\0');
2472 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2473 result
= make_word_list (t
, result
);
2476 free (current_word
);
2478 /* Note whether or not the separator is IFS whitespace, used later. */
2479 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2481 /* Move past the current separator character. */
2485 ADVANCE_CHAR (string
, slen
, sindex
);
2488 /* Now skip sequences of space, tab, or newline characters if they are
2489 in the list of separators. */
2490 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2493 /* If the first separator was IFS whitespace and the current character
2494 is a non-whitespace IFS character, it should be part of the current
2495 field delimiter, not a separate delimiter that would result in an
2496 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2497 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2500 /* An IFS character that is not IFS white space, along with any
2501 adjacent IFS white space, shall delimit a field. (SUSv3) */
2502 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2506 return (REVERSE_LIST (result
, WORD_LIST
*));
2509 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2510 ENDPTR is set to the first character after the word. This is used by
2511 the `read' builtin. This is never called with SEPARATORS != $IFS;
2512 it should be simplified.
2514 XXX - this function is very similar to list_string; they should be
2517 get_word_from_string (stringp
, separators
, endptr
)
2518 char **stringp
, *separators
, **endptr
;
2522 int sindex
, sh_style_split
, whitesep
, xflags
;
2525 if (!stringp
|| !*stringp
|| !**stringp
)
2526 return ((char *)NULL
);
2528 sh_style_split
= separators
&& separators
[0] == ' ' &&
2529 separators
[1] == '\t' &&
2530 separators
[2] == '\n' &&
2531 separators
[3] == '\0';
2532 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2534 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2535 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2541 /* Remove sequences of whitespace at the beginning of STRING, as
2542 long as those characters appear in IFS. */
2543 if (sh_style_split
|| !separators
|| !*separators
)
2545 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2547 /* If the string is nothing but whitespace, update it and return. */
2553 return ((char *)NULL
);
2557 /* OK, S points to a word that does not begin with white space.
2558 Now extract a word, stopping at a separator, save a pointer to
2559 the first character after the word, then skip sequences of spc,
2560 tab, or nl as long as they are separators.
2562 This obeys the field splitting rules in Posix.2. */
2564 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2565 unless multibyte chars are possible. */
2566 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2567 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2569 /* Set ENDPTR to the first character after the end of the word. */
2571 *endptr
= s
+ sindex
;
2573 /* Note whether or not the separator is IFS whitespace, used later. */
2574 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2576 /* Move past the current separator character. */
2580 ADVANCE_CHAR (s
, slen
, sindex
);
2583 /* Now skip sequences of space, tab, or newline characters if they are
2584 in the list of separators. */
2585 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2588 /* If the first separator was IFS whitespace and the current character is
2589 a non-whitespace IFS character, it should be part of the current field
2590 delimiter, not a separate delimiter that would result in an empty field.
2591 Look at POSIX.2, 3.6.5, (3)(b). */
2592 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2595 /* An IFS character that is not IFS white space, along with any adjacent
2596 IFS white space, shall delimit a field. */
2597 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2601 /* Update STRING to point to the next field. */
2602 *stringp
= s
+ sindex
;
2603 return (current_word
);
2606 /* Remove IFS white space at the end of STRING. Start at the end
2607 of the string and walk backwards until the beginning of the string
2608 or we find a character that's not IFS white space and not CTLESC.
2609 Only let CTLESC escape a white space character if SAW_ESCAPE is
2612 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2613 char *string
, *separators
;
2618 s
= string
+ STRLEN (string
) - 1;
2619 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2620 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2628 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2629 backslashes, single and double quotes. */
2631 list_string_with_quotes (string
)
2637 int c
, i
, tokstart
, len
;
2639 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2641 if (s
== 0 || *s
== 0)
2642 return ((WORD_LIST
*)NULL
);
2646 list
= (WORD_LIST
*)NULL
;
2657 i
= skip_single_quoted (s
, s_len
, ++i
);
2659 i
= skip_double_quoted (s
, s_len
, ++i
);
2660 else if (c
== 0 || spctabnl (c
))
2662 /* We have found the end of a token. Make a word out of it and
2663 add it to the word list. */
2664 token
= substring (s
, tokstart
, i
);
2665 list
= add_string_to_list (token
, list
);
2667 while (spctabnl (s
[i
]))
2675 i
++; /* normal character */
2677 return (REVERSE_LIST (list
, WORD_LIST
*));
2681 /********************************************************/
2683 /* Functions to perform assignment statements */
2685 /********************************************************/
2687 #if defined (ARRAY_VARS)
2689 do_compound_assignment (name
, value
, flags
)
2694 int mklocal
, mkassoc
;
2697 mklocal
= flags
& ASS_MKLOCAL
;
2698 mkassoc
= flags
& ASS_MKASSOC
;
2700 if (mklocal
&& variable_context
)
2702 v
= find_variable (name
);
2703 list
= expand_compound_array_assignment (v
, value
, flags
);
2705 v
= make_local_assoc_variable (name
);
2706 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2707 v
= make_local_array_variable (name
);
2708 assign_compound_array_list (v
, list
, flags
);
2711 v
= assign_array_from_string (name
, value
, flags
);
2717 /* Given STRING, an assignment string, get the value of the right side
2718 of the `=', and bind it to the left side. If EXPAND is true, then
2719 perform parameter expansion, command substitution, and arithmetic
2720 expansion on the right-hand side. Perform tilde expansion in any
2721 case. Do not perform word splitting on the result of expansion. */
2723 do_assignment_internal (word
, expand
)
2724 const WORD_DESC
*word
;
2727 int offset
, appendop
, assign_list
, aflags
, retval
;
2728 char *name
, *value
, *temp
;
2730 #if defined (ARRAY_VARS)
2736 if (word
== 0 || word
->word
== 0)
2739 appendop
= assign_list
= aflags
= 0;
2740 string
= word
->word
;
2741 offset
= assignment (string
, 0);
2742 name
= savestring (string
);
2743 value
= (char *)NULL
;
2745 if (name
[offset
] == '=')
2747 if (name
[offset
- 1] == '+')
2750 name
[offset
- 1] = '\0';
2753 name
[offset
] = 0; /* might need this set later */
2754 temp
= name
+ offset
+ 1;
2756 #if defined (ARRAY_VARS)
2757 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2759 assign_list
= ni
= 1;
2760 value
= extract_array_assignment_list (temp
, &ni
);
2764 if (expand
&& temp
[0])
2765 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2767 value
= savestring (temp
);
2772 value
= (char *)xmalloc (1);
2776 if (echo_command_at_execute
)
2779 name
[offset
- 1] = '+';
2780 xtrace_print_assignment (name
, value
, assign_list
, 1);
2782 name
[offset
- 1] = '\0';
2785 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2788 aflags
|= ASS_APPEND
;
2790 #if defined (ARRAY_VARS)
2791 if (t
= mbschr (name
, '[')) /*]*/
2795 report_error (_("%s: cannot assign list to array member"), name
);
2798 entry
= assign_array_element (name
, value
, aflags
);
2802 else if (assign_list
)
2804 if (word
->flags
& W_ASSIGNARG
)
2805 aflags
|= ASS_MKLOCAL
;
2806 if (word
->flags
& W_ASSIGNASSOC
)
2807 aflags
|= ASS_MKASSOC
;
2808 entry
= do_compound_assignment (name
, value
, aflags
);
2811 #endif /* ARRAY_VARS */
2812 entry
= bind_variable (name
, value
, aflags
);
2814 stupidly_hack_special_variables (name
);
2817 /* Return 1 if the assignment seems to have been performed correctly. */
2818 if (entry
== 0 || readonly_p (entry
))
2819 retval
= 0; /* assignment failure */
2820 else if (noassign_p (entry
))
2822 last_command_exit_value
= EXECUTION_FAILURE
;
2823 retval
= 1; /* error status, but not assignment failure */
2828 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2829 VUNSETATTR (entry
, att_invisible
);
2831 ASSIGN_RETURN (retval
);
2834 VUNSETATTR (entry
, att_invisible
);
2836 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2840 /* Perform the assignment statement in STRING, and expand the
2841 right side by doing tilde, command and parameter expansion. */
2843 do_assignment (string
)
2848 td
.flags
= W_ASSIGNMENT
;
2851 return do_assignment_internal (&td
, 1);
2855 do_word_assignment (word
, flags
)
2859 return do_assignment_internal (word
, 1);
2862 /* Given STRING, an assignment string, get the value of the right side
2863 of the `=', and bind it to the left side. Do not perform any word
2864 expansions on the right hand side. */
2866 do_assignment_no_expand (string
)
2871 td
.flags
= W_ASSIGNMENT
;
2874 return (do_assignment_internal (&td
, 0));
2877 /***************************************************
2879 * Functions to manage the positional parameters *
2881 ***************************************************/
2883 /* Return the word list that corresponds to `$*'. */
2885 list_rest_of_args ()
2887 register WORD_LIST
*list
, *args
;
2890 /* Break out of the loop as soon as one of the dollar variables is null. */
2891 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2892 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2894 for (args
= rest_of_args
; args
; args
= args
->next
)
2895 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2897 return (REVERSE_LIST (list
, WORD_LIST
*));
2903 register WORD_LIST
*list
;
2906 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2908 for (list
= rest_of_args
; list
; list
= list
->next
)
2913 /* Return the value of a positional parameter. This handles values > 10. */
2915 get_dollar_var_value (ind
)
2922 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2923 else /* We want something like ${11} */
2926 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2928 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2933 /* Make a single large string out of the dollar digit variables,
2934 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2935 case of "$*" with respect to IFS. */
2937 string_rest_of_args (dollar_star
)
2940 register WORD_LIST
*list
;
2943 list
= list_rest_of_args ();
2944 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2945 dispose_words (list
);
2949 /* Return a string containing the positional parameters from START to
2950 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2951 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2952 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2953 no quoting chars are added. */
2955 pos_params (string
, start
, end
, quoted
)
2957 int start
, end
, quoted
;
2959 WORD_LIST
*save
, *params
, *h
, *t
;
2963 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2965 return ((char *)NULL
);
2967 save
= params
= list_rest_of_args ();
2969 return ((char *)NULL
);
2971 if (start
== 0) /* handle ${@:0[:x]} specially */
2973 t
= make_word_list (make_word (dollar_vars
[0]), params
);
2977 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
2978 params
= params
->next
;
2980 return ((char *)NULL
);
2981 for (h
= t
= params
; params
&& i
< end
; i
++)
2984 params
= params
->next
;
2987 t
->next
= (WORD_LIST
*)NULL
;
2989 ret
= string_list_pos_params (string
[0], h
, quoted
);
2994 dispose_words (save
);
2998 /******************************************************************/
3000 /* Functions to expand strings to strings or WORD_LISTs */
3002 /******************************************************************/
3004 #if defined (PROCESS_SUBSTITUTION)
3005 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3007 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3010 /* If there are any characters in STRING that require full expansion,
3011 then call FUNC to expand STRING; otherwise just perform quote
3012 removal if necessary. This returns a new string. */
3014 expand_string_if_necessary (string
, quoted
, func
)
3025 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3026 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3030 if (EXP_CHAR (string
[i
]))
3032 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3034 ADVANCE_CHAR (string
, slen
, i
);
3039 list
= (*func
) (string
, quoted
);
3042 ret
= string_list (list
);
3043 dispose_words (list
);
3048 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3049 ret
= string_quote_removal (string
, quoted
);
3051 ret
= savestring (string
);
3056 static inline char *
3057 expand_string_to_string_internal (string
, quoted
, func
)
3065 if (string
== 0 || *string
== '\0')
3066 return ((char *)NULL
);
3068 list
= (*func
) (string
, quoted
);
3071 ret
= string_list (list
);
3072 dispose_words (list
);
3081 expand_string_to_string (string
, quoted
)
3085 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
3089 expand_string_unsplit_to_string (string
, quoted
)
3093 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3097 expand_assignment_string_to_string (string
, quoted
)
3101 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3105 expand_arith_string (string
, quoted
)
3109 return (expand_string_if_necessary (string
, quoted
, expand_string
));
3112 #if defined (COND_COMMAND)
3113 /* Just remove backslashes in STRING. Returns a new string. */
3115 remove_backslashes (string
)
3120 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3121 for (s
= string
; s
&& *s
; )
3133 /* This needs better error handling. */
3134 /* Expand W for use as an argument to a unary or binary operator in a
3135 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3136 to the != or == operator, and should be treated as a pattern. In
3137 this case, we quote the string specially for the globbing code. If
3138 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3139 be quoted appropriately for regcomp/regexec. The caller is responsible
3140 for removing the backslashes if the unquoted word is needed later. */
3142 cond_expand_word (w
, special
)
3150 if (w
->word
== 0 || w
->word
[0] == '\0')
3151 return ((char *)NULL
);
3153 w
->flags
|= W_NOSPLIT2
;
3154 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3160 r
= string_list (l
);
3164 qflags
= QGLOB_CVTNULL
;
3166 qflags
|= QGLOB_REGEXP
;
3167 p
= string_list (l
);
3168 r
= quote_string_for_globbing (p
, qflags
);
3180 /* Call expand_word_internal to expand W and handle error returns.
3181 A convenience function for functions that don't want to handle
3182 any errors or free any memory before aborting. */
3184 call_expand_word_internal (w
, q
, i
, c
, e
)
3190 result
= expand_word_internal (w
, q
, i
, c
, e
);
3191 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3193 /* By convention, each time this error is returned, w->word has
3194 already been freed (it sometimes may not be in the fatal case,
3195 but that doesn't result in a memory leak because we're going
3196 to exit in most cases). */
3197 w
->word
= (char *)NULL
;
3198 last_command_exit_value
= EXECUTION_FAILURE
;
3199 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3206 /* Perform parameter expansion, command substitution, and arithmetic
3207 expansion on STRING, as if it were a word. Leave the result quoted. */
3209 expand_string_internal (string
, quoted
)
3216 if (string
== 0 || *string
== 0)
3217 return ((WORD_LIST
*)NULL
);
3220 td
.word
= savestring (string
);
3222 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3228 /* Expand STRING by performing parameter expansion, command substitution,
3229 and arithmetic expansion. Dequote the resulting WORD_LIST before
3230 returning it, but do not perform word splitting. The call to
3231 remove_quoted_nulls () is in here because word splitting normally
3232 takes care of quote removal. */
3234 expand_string_unsplit (string
, quoted
)
3240 if (string
== 0 || *string
== '\0')
3241 return ((WORD_LIST
*)NULL
);
3243 expand_no_split_dollar_star
= 1;
3244 value
= expand_string_internal (string
, quoted
);
3245 expand_no_split_dollar_star
= 0;
3251 remove_quoted_nulls (value
->word
->word
);
3252 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3254 dequote_list (value
);
3259 /* Expand the rhs of an assignment statement */
3261 expand_string_assignment (string
, quoted
)
3268 if (string
== 0 || *string
== '\0')
3269 return ((WORD_LIST
*)NULL
);
3271 expand_no_split_dollar_star
= 1;
3273 td
.flags
= W_ASSIGNRHS
;
3274 td
.word
= savestring (string
);
3275 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3278 expand_no_split_dollar_star
= 0;
3284 remove_quoted_nulls (value
->word
->word
);
3285 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3287 dequote_list (value
);
3293 /* Expand one of the PS? prompt strings. This is a sort of combination of
3294 expand_string_unsplit and expand_string_internal, but returns the
3295 passed string when an error occurs. Might want to trap other calls
3296 to jump_to_top_level here so we don't endlessly loop. */
3298 expand_prompt_string (string
, quoted
, wflags
)
3306 if (string
== 0 || *string
== 0)
3307 return ((WORD_LIST
*)NULL
);
3310 td
.word
= savestring (string
);
3312 no_longjmp_on_fatal_error
= 1;
3313 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3314 no_longjmp_on_fatal_error
= 0;
3316 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3318 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3326 remove_quoted_nulls (value
->word
->word
);
3327 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3329 dequote_list (value
);
3334 /* Expand STRING just as if you were expanding a word, but do not dequote
3335 the resultant WORD_LIST. This is called only from within this file,
3336 and is used to correctly preserve quoted characters when expanding
3337 things like ${1+"$@"}. This does parameter expansion, command
3338 substitution, arithmetic expansion, and word splitting. */
3340 expand_string_leave_quoted (string
, quoted
)
3347 if (string
== 0 || *string
== '\0')
3348 return ((WORD_LIST
*)NULL
);
3350 tlist
= expand_string_internal (string
, quoted
);
3354 tresult
= word_list_split (tlist
);
3355 dispose_words (tlist
);
3358 return ((WORD_LIST
*)NULL
);
3361 /* This does not perform word splitting or dequote the WORD_LIST
3364 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3366 int quoted
, *dollar_at_p
, *has_dollar_at
;
3371 if (string
== 0 || *string
== '\0')
3372 return (WORD_LIST
*)NULL
;
3376 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3380 /* Expand STRING just as if you were expanding a word. This also returns
3381 a list of words. Note that filename globbing is *NOT* done for word
3382 or string expansion, just when the shell is expanding a command. This
3383 does parameter expansion, command substitution, arithmetic expansion,
3384 and word splitting. Dequote the resultant WORD_LIST before returning. */
3386 expand_string (string
, quoted
)
3392 if (string
== 0 || *string
== '\0')
3393 return ((WORD_LIST
*)NULL
);
3395 result
= expand_string_leave_quoted (string
, quoted
);
3396 return (result
? dequote_list (result
) : result
);
3399 /***************************************************
3401 * Functions to handle quoting chars *
3403 ***************************************************/
3407 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3408 The parser passes CTLNUL as CTLESC CTLNUL. */
3410 /* Quote escape characters in string s, but no other characters. This is
3411 used to protect CTLESC and CTLNUL in variable values from the rest of
3412 the word expansion process after the variable is expanded (word splitting
3413 and filename generation). If IFS is null, we quote spaces as well, just
3414 in case we split on spaces later (in the case of unquoted $@, we will
3415 eventually attempt to split the entire word on spaces). Corresponding
3416 code exists in dequote_escapes. Even if we don't end up splitting on
3417 spaces, quoting spaces is not a problem. This should never be called on
3418 a string that is quoted with single or double quotes or part of a here
3419 document (effectively double-quoted). */
3421 quote_escapes (string
)
3424 register char *s
, *t
;
3426 char *result
, *send
;
3427 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3430 slen
= strlen (string
);
3431 send
= string
+ slen
;
3433 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3435 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3436 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3438 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3443 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3445 COPY_CHAR_P (t
, s
, send
);
3452 list_quote_escapes (list
)
3455 register WORD_LIST
*w
;
3458 for (w
= list
; w
; w
= w
->next
)
3461 w
->word
->word
= quote_escapes (t
);
3467 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3469 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3470 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3471 data stream pass through properly.
3473 We need to remove doubled CTLESC characters inside quoted strings before
3474 quoting the entire string, so we do not double the number of CTLESC
3477 Also used by parts of the pattern substitution code. */
3479 dequote_escapes (string
)
3482 register char *s
, *t
, *s1
;
3484 char *result
, *send
;
3491 slen
= strlen (string
);
3492 send
= string
+ slen
;
3494 t
= result
= (char *)xmalloc (slen
+ 1);
3496 if (strchr (string
, CTLESC
) == 0)
3497 return (strcpy (result
, string
));
3499 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3504 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3510 COPY_CHAR_P (t
, s
, send
);
3516 /* Return a new string with the quoted representation of character C.
3517 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3518 set in any resultant WORD_DESC where this value is the word. */
3520 make_quoted_char (c
)
3525 temp
= (char *)xmalloc (3);
3540 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3541 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3542 this value is the word. */
3544 quote_string (string
)
3549 char *result
, *send
;
3553 result
= (char *)xmalloc (2);
3561 slen
= strlen (string
);
3562 send
= string
+ slen
;
3564 result
= (char *)xmalloc ((slen
* 2) + 1);
3566 for (t
= result
; string
< send
; )
3569 COPY_CHAR_P (t
, string
, send
);
3576 /* De-quote quoted characters in STRING. */
3578 dequote_string (string
)
3581 register char *s
, *t
;
3583 char *result
, *send
;
3586 slen
= strlen (string
);
3588 t
= result
= (char *)xmalloc (slen
+ 1);
3590 if (QUOTED_NULL (string
))
3596 /* If no character in the string can be quoted, don't bother examining
3597 each character. Just return a copy of the string passed to us. */
3598 if (strchr (string
, CTLESC
) == NULL
)
3599 return (strcpy (result
, string
));
3601 send
= string
+ slen
;
3611 COPY_CHAR_P (t
, s
, send
);
3618 /* Quote the entire WORD_LIST list. */
3623 register WORD_LIST
*w
;
3626 for (w
= list
; w
; w
= w
->next
)
3629 w
->word
->word
= quote_string (t
);
3631 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3632 w
->word
->flags
|= W_QUOTED
;
3638 /* De-quote quoted characters in each word in LIST. */
3644 register WORD_LIST
*tlist
;
3646 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3648 s
= dequote_string (tlist
->word
->word
);
3649 if (QUOTED_NULL (tlist
->word
->word
))
3650 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3651 free (tlist
->word
->word
);
3652 tlist
->word
->word
= s
;
3657 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3660 remove_quoted_escapes (string
)
3667 t
= dequote_escapes (string
);
3675 /* Perform quoted null character removal on STRING. We don't allow any
3676 quoted null characters in the middle or at the ends of strings because
3677 of how expand_word_internal works. remove_quoted_nulls () turns
3678 STRING into an empty string iff it only consists of a quoted null,
3679 and removes all unquoted CTLNUL characters. */
3681 remove_quoted_nulls (string
)
3684 register size_t slen
;
3685 register int i
, j
, prev_i
;
3688 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3689 return string
; /* XXX */
3691 slen
= strlen (string
);
3696 if (string
[i
] == CTLESC
)
3698 /* Old code had j++, but we cannot assume that i == j at this
3699 point -- what if a CTLNUL has already been removed from the
3700 string? We don't want to drop the CTLESC or recopy characters
3701 that we've already copied down. */
3702 i
++; string
[j
++] = CTLESC
;
3706 else if (string
[i
] == CTLNUL
)
3710 ADVANCE_CHAR (string
, slen
, i
);
3713 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3723 /* Perform quoted null character removal on each element of LIST.
3724 This modifies LIST. */
3726 word_list_remove_quoted_nulls (list
)
3729 register WORD_LIST
*t
;
3731 for (t
= list
; t
; t
= t
->next
)
3733 remove_quoted_nulls (t
->word
->word
);
3734 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3738 /* **************************************************************** */
3740 /* Functions for Matching and Removing Patterns */
3742 /* **************************************************************** */
3744 #if defined (HANDLE_MULTIBYTE)
3745 #if 0 /* Currently unused */
3746 static unsigned char *
3747 mb_getcharlens (string
, len
)
3751 int i
, offset
, last
;
3758 ret
= (unsigned char *)xmalloc (len
);
3759 memset (ret
, 0, len
);
3760 while (string
[last
])
3762 ADVANCE_CHAR (string
, len
, offset
);
3763 ret
[last
] = offset
- last
;
3771 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3772 can have one of 4 values:
3773 RP_LONG_LEFT remove longest matching portion at start of PARAM
3774 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3775 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3776 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3779 #define RP_LONG_LEFT 1
3780 #define RP_SHORT_LEFT 2
3781 #define RP_LONG_RIGHT 3
3782 #define RP_SHORT_RIGHT 4
3784 /* Returns its first argument if nothing matched; new memory otherwise */
3786 remove_upattern (param
, pattern
, op
)
3787 char *param
, *pattern
;
3792 register char *p
, *ret
, c
;
3794 len
= STRLEN (param
);
3799 case RP_LONG_LEFT
: /* remove longest match at start */
3800 for (p
= end
; p
>= param
; p
--)
3803 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3806 return (savestring (p
));
3813 case RP_SHORT_LEFT
: /* remove shortest match at start */
3814 for (p
= param
; p
<= end
; p
++)
3817 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3820 return (savestring (p
));
3826 case RP_LONG_RIGHT
: /* remove longest match at end */
3827 for (p
= param
; p
<= end
; p
++)
3829 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3832 ret
= savestring (param
);
3839 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3840 for (p
= end
; p
>= param
; p
--)
3842 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3845 ret
= savestring (param
);
3853 return (param
); /* no match, return original string */
3856 #if defined (HANDLE_MULTIBYTE)
3857 /* Returns its first argument if nothing matched; new memory otherwise */
3859 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3870 case RP_LONG_LEFT
: /* remove longest match at start */
3871 for (n
= wstrlen
; n
>= 0; n
--)
3873 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3874 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3877 return (wcsdup (wparam
+ n
));
3883 case RP_SHORT_LEFT
: /* remove shortest match at start */
3884 for (n
= 0; n
<= wstrlen
; n
++)
3886 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3887 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3890 return (wcsdup (wparam
+ n
));
3896 case RP_LONG_RIGHT
: /* remove longest match at end */
3897 for (n
= 0; n
<= wstrlen
; n
++)
3899 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3901 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3902 ret
= wcsdup (wparam
);
3909 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3910 for (n
= wstrlen
; n
>= 0; n
--)
3912 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3914 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3915 ret
= wcsdup (wparam
);
3923 return (wparam
); /* no match, return original string */
3925 #endif /* HANDLE_MULTIBYTE */
3928 remove_pattern (param
, pattern
, op
)
3929 char *param
, *pattern
;
3936 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3937 return (savestring (param
));
3939 #if defined (HANDLE_MULTIBYTE)
3942 wchar_t *ret
, *oret
;
3944 wchar_t *wparam
, *wpattern
;
3947 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3948 if (n
== (size_t)-1)
3950 xret
= remove_upattern (param
, pattern
, op
);
3951 return ((xret
== param
) ? savestring (param
) : xret
);
3953 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3954 if (n
== (size_t)-1)
3957 xret
= remove_upattern (param
, pattern
, op
);
3958 return ((xret
== param
) ? savestring (param
) : xret
);
3960 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3961 /* Don't bother to convert wparam back to multibyte string if nothing
3962 matched; just return copy of original string */
3967 return (savestring (param
));
3974 xret
= (char *)xmalloc (n
+ 1);
3975 memset (&ps
, '\0', sizeof (mbstate_t));
3976 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3977 xret
[n
] = '\0'; /* just to make sure */
3984 xret
= remove_upattern (param
, pattern
, op
);
3985 return ((xret
== param
) ? savestring (param
) : xret
);
3989 /* Match PAT anywhere in STRING and return the match boundaries.
3990 This returns 1 in case of a successful match, 0 otherwise. SP
3991 and EP are pointers into the string where the match begins and
3992 ends, respectively. MTYPE controls what kind of match is attempted.
3993 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3994 of the string, respectively. The longest match is returned. */
3996 match_upattern (string
, pat
, mtype
, sp
, ep
)
4002 register char *p
, *p1
, *npat
;
4006 /* If the pattern doesn't match anywhere in the string, go ahead and
4007 short-circuit right away. A minor optimization, saves a bunch of
4008 unnecessary calls to strmatch (up to N calls for a string of N
4009 characters) if the match is unsuccessful. To preserve the semantics
4010 of the substring matches below, we make sure that the pattern has
4011 `*' as first and last character, making a new pattern if necessary. */
4012 /* XXX - check this later if I ever implement `**' with special meaning,
4013 since this will potentially result in `**' at the beginning or end */
4015 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == LPAREN
&& extended_glob
) || pat
[len
- 1] != '*')
4017 p
= npat
= (char *)xmalloc (len
+ 3);
4019 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == LPAREN
&& extended_glob
))
4023 if (p1
[-1] != '*' || p
[-2] == '\\')
4029 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
4032 if (c
== FNM_NOMATCH
)
4035 len
= STRLEN (string
);
4038 mlen
= umatchlen (pat
, len
);
4043 for (p
= string
; p
<= end
; p
++)
4045 if (match_pattern_char (pat
, p
))
4048 for (p1
= end
; p1
>= p
; p1
--)
4050 p1
= (mlen
== -1) ? end
: p
+ mlen
;
4051 /* p1 - p = length of portion of string to be considered
4052 p = current position in string
4053 mlen = number of characters consumed by match (-1 for entire string)
4055 we want to break immediately if the potential match len
4056 is greater than the number of characters remaining in the
4061 for ( ; p1
>= p
; p1
--)
4064 c
= *p1
; *p1
= '\0';
4065 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4074 /* If MLEN != -1, we have a fixed length pattern. */
4085 if (match_pattern_char (pat
, string
) == 0)
4089 for (p
= end
; p
>= string
; p
--)
4091 for (p
= (mlen
== -1) ? end
: string
+ mlen
; p
>= string
; p
--)
4095 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
4104 /* If MLEN != -1, we have a fixed length pattern. */
4114 for (p
= string
; p
<= end
; p
++)
4116 for (p
= end
- ((mlen
== -1) ? len
: mlen
); p
<= end
; p
++)
4119 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4126 /* If MLEN != -1, we have a fixed length pattern. */
4138 #if defined (HANDLE_MULTIBYTE)
4139 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4140 This returns 1 in case of a successful match, 0 otherwise. Wide
4141 character version. */
4143 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4151 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4154 int n
, n1
, n2
, simple
;
4156 simple
= (wpat
[0] != L
'\\' && wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'[');
4157 #if defined (EXTENDED_GLOB)
4159 simple
|= (wpat
[1] != L
'(' || (wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'+' && wpat
[0] != L
'!' && wpat
[0] != L
'@')); /*)*/
4162 /* If the pattern doesn't match anywhere in the string, go ahead and
4163 short-circuit right away. A minor optimization, saves a bunch of
4164 unnecessary calls to strmatch (up to N calls for a string of N
4165 characters) if the match is unsuccessful. To preserve the semantics
4166 of the substring matches below, we make sure that the pattern has
4167 `*' as first and last character, making a new pattern if necessary. */
4168 len
= wcslen (wpat
);
4169 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == WLPAREN
&& extended_glob
) || wpat
[len
- 1] != L
'*')
4171 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4173 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == WLPAREN
&& extended_glob
))
4175 while (*wp1
!= L
'\0')
4177 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4183 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
4186 if (len
== FNM_NOMATCH
)
4189 mlen
= wmatchlen (wpat
, wstrlen
);
4191 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4195 for (n
= 0; n
<= wstrlen
; n
++)
4198 n2
= simple
? (*wpat
== wstring
[n
]) : match_pattern_wchar (wpat
, wstring
+ n
);
4200 n2
= match_pattern_wchar (wpat
, wstring
+ n
);
4205 for (n1
= wstrlen
; n1
>= n
; n1
--)
4207 n1
= (mlen
== -1) ? wstrlen
: n
+ mlen
;
4211 for ( ; n1
>= n
; n1
--)
4214 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4215 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4224 /* If MLEN != -1, we have a fixed length pattern. */
4235 if (match_pattern_wchar (wpat
, wstring
) == 0)
4239 for (n
= wstrlen
; n
>= 0; n
--)
4241 for (n
= (mlen
== -1) ? wstrlen
: mlen
; n
>= 0; n
--)
4244 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4245 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
4254 /* If MLEN != -1, we have a fixed length pattern. */
4264 for (n
= 0; n
<= wstrlen
; n
++)
4266 for (n
= wstrlen
- ((mlen
== -1) ? wstrlen
: mlen
); n
<= wstrlen
; n
++)
4269 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4272 *ep
= indices
[wstrlen
];
4276 /* If MLEN != -1, we have a fixed length pattern. */
4287 #endif /* HANDLE_MULTIBYTE */
4290 match_pattern (string
, pat
, mtype
, sp
, ep
)
4295 #if defined (HANDLE_MULTIBYTE)
4298 wchar_t *wstring
, *wpat
;
4300 size_t slen
, plen
, mslen
, mplen
;
4303 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4306 #if defined (HANDLE_MULTIBYTE)
4310 slen
= STRLEN (string
);
4311 mslen
= MBSLEN (string
);
4312 plen
= STRLEN (pat
);
4313 mplen
= MBSLEN (pat
);
4314 if (slen
== mslen
&& plen
== mplen
)
4316 if (mbsmbchar (string
) == 0 && mbsmbchar (pat
) == 0)
4318 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4320 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4321 if (n
== (size_t)-1)
4322 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4323 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4324 if (n
== (size_t)-1)
4327 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4329 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4339 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4343 getpatspec (c
, value
)
4348 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4350 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4353 /* Posix.2 says that the WORD should be run through tilde expansion,
4354 parameter expansion, command substitution and arithmetic expansion.
4355 This leaves the result quoted, so quote_string_for_globbing () has
4356 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4357 it means that the entire expression was enclosed in double quotes.
4358 This means that quoting characters in the pattern do not make any
4359 special pattern characters quoted. For example, the `*' in the
4360 following retains its special meaning: "${foo#'*'}". */
4362 getpattern (value
, quoted
, expandpat
)
4364 int quoted
, expandpat
;
4371 /* There is a problem here: how to handle single or double quotes in the
4372 pattern string when the whole expression is between double quotes?
4373 POSIX.2 says that enclosing double quotes do not cause the pattern to
4374 be quoted, but does that leave us a problem with @ and array[@] and their
4375 expansions inside a pattern? */
4377 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4380 pat
= string_extract_double_quoted (tword
, &i
, 1);
4386 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4388 l
= *value
? expand_string_for_rhs (value
,
4389 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4390 (int *)NULL
, (int *)NULL
)
4392 pat
= string_list (l
);
4396 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4404 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4405 or ${name#[#]value}. */
4407 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4408 char *value
, *pattern
;
4409 int patspec
, quoted
;
4413 tword
= remove_pattern (value
, pattern
, patspec
);
4420 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4423 int patspec
, itype
, quoted
;
4429 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4431 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4432 w
= alloc_word_desc ();
4433 w
->word
= tword
? tword
: savestring ("");
4434 new = make_word_list (w
, new);
4437 l
= REVERSE_LIST (new, WORD_LIST
*);
4438 tword
= string_list_pos_params (itype
, l
, quoted
);
4445 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4448 int patspec
, quoted
;
4453 list
= list_rest_of_args ();
4455 return ((char *)NULL
);
4456 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4457 dispose_words (list
);
4461 #if defined (ARRAY_VARS)
4463 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4467 char *varname
; /* so we can figure out how it's indexed */
4477 /* compute itype from varname here */
4478 v
= array_variable_part (varname
, &ret
, 0);
4481 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4482 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4484 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4486 return ((char *)NULL
);
4487 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4488 dispose_words (list
);
4492 #endif /* ARRAY_VARS */
4495 parameter_brace_remove_pattern (varname
, value
, ind
, patstr
, rtype
, quoted
, flags
)
4496 char *varname
, *value
;
4499 int rtype
, quoted
, flags
;
4501 int vtype
, patspec
, starsub
;
4502 char *temp1
, *val
, *pattern
;
4506 return ((char *)NULL
);
4508 this_command_name
= varname
;
4510 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4512 return ((char *)NULL
);
4514 starsub
= vtype
& VT_STARSUB
;
4515 vtype
&= ~VT_STARSUB
;
4517 patspec
= getpatspec (rtype
, patstr
);
4518 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4521 /* Need to pass getpattern newly-allocated memory in case of expansion --
4522 the expansion code will free the passed string on an error. */
4523 temp1
= savestring (patstr
);
4524 pattern
= getpattern (temp1
, quoted
, 1);
4527 temp1
= (char *)NULL
; /* shut up gcc */
4531 case VT_ARRAYMEMBER
:
4532 temp1
= remove_pattern (val
, pattern
, patspec
);
4533 if (vtype
== VT_VARIABLE
)
4537 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4538 ? quote_string (temp1
)
4539 : quote_escapes (temp1
);
4544 #if defined (ARRAY_VARS)
4546 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4547 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4549 val
= quote_escapes (temp1
);
4556 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4557 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4559 val
= quote_escapes (temp1
);
4570 /*******************************************
4572 * Functions to expand WORD_DESCs *
4574 *******************************************/
4576 /* Expand WORD, performing word splitting on the result. This does
4577 parameter expansion, command substitution, arithmetic expansion,
4578 word splitting, and quote removal. */
4581 expand_word (word
, quoted
)
4585 WORD_LIST
*result
, *tresult
;
4587 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4588 result
= word_list_split (tresult
);
4589 dispose_words (tresult
);
4590 return (result
? dequote_list (result
) : result
);
4593 /* Expand WORD, but do not perform word splitting on the result. This
4594 does parameter expansion, command substitution, arithmetic expansion,
4595 and quote removal. */
4597 expand_word_unsplit (word
, quoted
)
4603 expand_no_split_dollar_star
= 1;
4604 #if defined (HANDLE_MULTIBYTE)
4605 if (ifs_firstc
[0] == 0)
4607 if (ifs_firstc
== 0)
4609 word
->flags
|= W_NOSPLIT
;
4610 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4611 expand_no_split_dollar_star
= 0;
4613 return (result
? dequote_list (result
) : result
);
4616 /* Perform shell expansions on WORD, but do not perform word splitting or
4617 quote removal on the result. Virtually identical to expand_word_unsplit;
4618 could be combined if implementations don't diverge. */
4620 expand_word_leave_quoted (word
, quoted
)
4626 expand_no_split_dollar_star
= 1;
4627 #if defined (HANDLE_MULTIBYTE)
4628 if (ifs_firstc
[0] == 0)
4630 if (ifs_firstc
== 0)
4632 word
->flags
|= W_NOSPLIT
;
4633 word
->flags
|= W_NOSPLIT2
;
4634 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4635 expand_no_split_dollar_star
= 0;
4640 #if defined (PROCESS_SUBSTITUTION)
4642 /*****************************************************************/
4644 /* Hacking Process Substitution */
4646 /*****************************************************************/
4648 #if !defined (HAVE_DEV_FD)
4649 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4650 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4651 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4652 list. NFIFO is a count of the number of FIFOs in the list. */
4653 #define FIFO_INCR 20
4660 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4662 static int fifo_list_size
;
4665 copy_fifo_list (sizep
)
4670 return (char *)NULL
;
4674 add_fifo_list (pathname
)
4677 if (nfifo
>= fifo_list_size
- 1)
4679 fifo_list_size
+= FIFO_INCR
;
4680 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4681 fifo_list_size
* sizeof (struct temp_fifo
));
4684 fifo_list
[nfifo
].file
= savestring (pathname
);
4692 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4694 unlink (fifo_list
[i
].file
);
4695 free (fifo_list
[i
].file
);
4696 fifo_list
[i
].file
= (char *)NULL
;
4697 fifo_list
[i
].proc
= -1;
4709 for (i
= saved
= 0; i
< nfifo
; i
++)
4711 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4713 unlink (fifo_list
[i
].file
);
4714 free (fifo_list
[i
].file
);
4715 fifo_list
[i
].file
= (char *)NULL
;
4716 fifo_list
[i
].proc
= -1;
4722 /* If we didn't remove some of the FIFOs, compact the list. */
4725 for (i
= j
= 0; i
< nfifo
; i
++)
4726 if (fifo_list
[i
].file
)
4728 fifo_list
[j
].file
= fifo_list
[i
].file
;
4729 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4738 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4739 from some point in the past, and close all open FIFOs in fifo_list
4740 that are not marked as active in LIST. If LIST is NULL, close
4741 everything in fifo_list. LSIZE is the number of elements in LIST, in
4742 case it's larger than fifo_list_size (size of fifo_list). */
4744 close_new_fifos (list
, lsize
)
4752 unlink_fifo_list ();
4756 for (i
= 0; i
< lsize
; i
++)
4757 if (list
[i
] == 0 && i
< fifo_list_size
&& fifo_list
[i
].proc
!= -1)
4760 for (i
= lsize
; i
< fifo_list_size
; i
++)
4781 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4782 if (mkfifo (tname
, 0600) < 0)
4785 return ((char *)NULL
);
4788 add_fifo_list (tname
);
4792 #else /* HAVE_DEV_FD */
4794 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4795 has open to children. NFDS is a count of the number of bits currently
4796 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4798 static char *dev_fd_list
= (char *)NULL
;
4800 static int totfds
; /* The highest possible number of open files. */
4803 copy_fifo_list (sizep
)
4808 if (nfds
== 0 || totfds
== 0)
4812 return (char *)NULL
;
4817 ret
= (char *)xmalloc (totfds
);
4818 return (memcpy (ret
, dev_fd_list
, totfds
));
4825 if (dev_fd_list
== 0 || fd
>= totfds
)
4830 totfds
= getdtablesize ();
4831 if (totfds
< 0 || totfds
> 256)
4836 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4837 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4840 dev_fd_list
[fd
] = 1;
4847 return 0; /* used for cleanup; not needed with /dev/fd */
4860 if (dev_fd_list
[fd
])
4863 dev_fd_list
[fd
] = 0;
4876 for (i
= 0; nfds
&& i
< totfds
; i
++)
4882 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4883 the past, and close all open fds in dev_fd_list that are not marked
4884 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4885 LSIZE is the number of elements in LIST, in case it's larger than
4886 totfds (size of dev_fd_list). */
4888 close_new_fifos (list
, lsize
)
4896 unlink_fifo_list ();
4900 for (i
= 0; i
< lsize
; i
++)
4901 if (list
[i
] == 0 && i
< totfds
&& dev_fd_list
[i
])
4904 for (i
= lsize
; i
< totfds
; i
++)
4908 #if defined (NOTDEF)
4909 print_dev_fd_list ()
4913 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4916 for (i
= 0; i
< totfds
; i
++)
4919 fprintf (stderr
, " %d", i
);
4921 fprintf (stderr
, "\n");
4926 make_dev_fd_filename (fd
)
4929 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4931 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4933 strcpy (ret
, DEV_FD_PREFIX
);
4934 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4935 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4941 #endif /* HAVE_DEV_FD */
4943 /* Return a filename that will open a connection to the process defined by
4944 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4945 a filename in /dev/fd corresponding to a descriptor that is one of the
4946 ends of the pipe. If not defined, we use named pipes on systems that have
4947 them. Systems without /dev/fd and named pipes are out of luck.
4949 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4950 use the read end of the pipe and dup that file descriptor to fd 0 in
4951 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4952 writing or use the write end of the pipe in the child, and dup that
4953 file descriptor to fd 1 in the child. The parent does the opposite. */
4956 process_substitute (string
, open_for_read_in_child
)
4958 int open_for_read_in_child
;
4963 #if defined (HAVE_DEV_FD)
4964 int parent_pipe_fd
, child_pipe_fd
;
4966 #endif /* HAVE_DEV_FD */
4967 #if defined (JOB_CONTROL)
4968 pid_t old_pipeline_pgrp
;
4971 if (!string
|| !*string
|| wordexp_only
)
4972 return ((char *)NULL
);
4974 #if !defined (HAVE_DEV_FD)
4975 pathname
= make_named_pipe ();
4976 #else /* HAVE_DEV_FD */
4977 if (pipe (fildes
) < 0)
4979 sys_error (_("cannot make pipe for process substitution"));
4980 return ((char *)NULL
);
4982 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4983 the pipe in the parent, otherwise the read end. */
4984 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4985 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4986 /* Move the parent end of the pipe to some high file descriptor, to
4987 avoid clashes with FDs used by the script. */
4988 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4990 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4991 #endif /* HAVE_DEV_FD */
4995 sys_error (_("cannot make pipe for process substitution"));
4996 return ((char *)NULL
);
4999 old_pid
= last_made_pid
;
5001 #if defined (JOB_CONTROL)
5002 old_pipeline_pgrp
= pipeline_pgrp
;
5003 pipeline_pgrp
= shell_pgrp
;
5005 #endif /* JOB_CONTROL */
5007 pid
= make_child ((char *)NULL
, 1);
5010 reset_terminating_signals (); /* XXX */
5011 free_pushed_string_input ();
5012 /* Cancel traps, in trap.c. */
5013 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5014 setup_async_signals ();
5015 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
5018 #if defined (JOB_CONTROL)
5019 set_sigchld_handler ();
5020 stop_making_children ();
5021 /* XXX - should we only do this in the parent? (as in command subst) */
5022 pipeline_pgrp
= old_pipeline_pgrp
;
5023 #endif /* JOB_CONTROL */
5027 sys_error (_("cannot make child for process substitution"));
5029 #if defined (HAVE_DEV_FD)
5030 close (parent_pipe_fd
);
5031 close (child_pipe_fd
);
5032 #endif /* HAVE_DEV_FD */
5033 return ((char *)NULL
);
5038 #if defined (JOB_CONTROL)
5039 restore_pipeline (1);
5042 #if !defined (HAVE_DEV_FD)
5043 fifo_list
[nfifo
-1].proc
= pid
;
5046 last_made_pid
= old_pid
;
5048 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5050 #endif /* JOB_CONTROL && PGRP_PIPE */
5052 #if defined (HAVE_DEV_FD)
5053 close (child_pipe_fd
);
5054 #endif /* HAVE_DEV_FD */
5059 set_sigint_handler ();
5061 #if defined (JOB_CONTROL)
5062 set_job_control (0);
5063 #endif /* JOB_CONTROL */
5065 #if !defined (HAVE_DEV_FD)
5066 /* Open the named pipe in the child. */
5067 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
5070 /* Two separate strings for ease of translation. */
5071 if (open_for_read_in_child
)
5072 sys_error (_("cannot open named pipe %s for reading"), pathname
);
5074 sys_error (_("cannot open named pipe %s for writing"), pathname
);
5078 if (open_for_read_in_child
)
5080 if (sh_unset_nodelay_mode (fd
) < 0)
5082 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
5086 #else /* HAVE_DEV_FD */
5088 #endif /* HAVE_DEV_FD */
5090 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
5092 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
5093 open_for_read_in_child
? 0 : 1);
5097 if (fd
!= (open_for_read_in_child
? 0 : 1))
5100 /* Need to close any files that this process has open to pipes inherited
5102 if (current_fds_to_close
)
5104 close_fd_bitmap (current_fds_to_close
);
5105 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
5108 #if defined (HAVE_DEV_FD)
5109 /* Make sure we close the parent's end of the pipe and clear the slot
5110 in the fd list so it is not closed later, if reallocated by, for
5111 instance, pipe(2). */
5112 close (parent_pipe_fd
);
5113 dev_fd_list
[parent_pipe_fd
] = 0;
5114 #endif /* HAVE_DEV_FD */
5116 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
5118 #if !defined (HAVE_DEV_FD)
5119 /* Make sure we close the named pipe in the child before we exit. */
5120 close (open_for_read_in_child
? 0 : 1);
5121 #endif /* !HAVE_DEV_FD */
5126 #endif /* PROCESS_SUBSTITUTION */
5128 /***********************************/
5130 /* Command Substitution */
5132 /***********************************/
5135 read_comsub (fd
, quoted
, rflag
)
5139 char *istring
, buf
[128], *bufp
, *s
;
5140 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
5143 istring
= (char *)NULL
;
5144 istring_index
= istring_size
= bufn
= tflag
= 0;
5146 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
5147 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
5149 /* Read the output of the command through the pipe. This may need to be
5150 changed to understand multibyte characters in the future. */
5157 bufn
= zread (fd
, buf
, sizeof (buf
));
5167 internal_warning ("read_comsub: ignored null byte in input");
5172 /* Add the character to ISTRING, possibly after resizing it. */
5173 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
5175 /* This is essentially quote_string inline */
5176 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
5177 istring
[istring_index
++] = CTLESC
;
5178 /* Escape CTLESC and CTLNUL in the output to protect those characters
5179 from the rest of the word expansions (word splitting and globbing.)
5180 This is essentially quote_escapes inline. */
5181 else if (skip_ctlesc
== 0 && c
== CTLESC
)
5183 tflag
|= W_HASCTLESC
;
5184 istring
[istring_index
++] = CTLESC
;
5186 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
5187 istring
[istring_index
++] = CTLESC
;
5189 istring
[istring_index
++] = c
;
5192 #if defined (__CYGWIN__)
5193 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
5196 istring
[istring_index
- 1] = '\n';
5203 istring
[istring_index
] = '\0';
5205 /* If we read no output, just return now and save ourselves some
5207 if (istring_index
== 0)
5212 return (char *)NULL
;
5215 /* Strip trailing newlines from the output of the command. */
5216 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5218 while (istring_index
> 0)
5220 if (istring
[istring_index
- 1] == '\n')
5224 /* If the newline was quoted, remove the quoting char. */
5225 if (istring
[istring_index
- 1] == CTLESC
)
5231 istring
[istring_index
] = '\0';
5234 strip_trailing (istring
, istring_index
- 1, 1);
5241 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5242 contained string possibly quoted. */
5244 command_substitute (string
, quoted
)
5248 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
5250 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
5253 istring
= (char *)NULL
;
5255 /* Don't fork () if there is no need to. In the case of no command to
5256 run, just return NULL. */
5257 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5258 return ((WORD_DESC
*)NULL
);
5260 if (wordexp_only
&& read_but_dont_execute
)
5262 last_command_exit_value
= EX_WEXPCOMSUB
;
5263 jump_to_top_level (EXITPROG
);
5266 /* We're making the assumption here that the command substitution will
5267 eventually run a command from the file system. Since we'll run
5268 maybe_make_export_env in this subshell before executing that command,
5269 the parent shell and any other shells it starts will have to remake
5270 the environment. If we make it before we fork, other shells won't
5271 have to. Don't bother if we have any temporary variable assignments,
5272 though, because the export environment will be remade after this
5273 command completes anyway, but do it if all the words to be expanded
5274 are variable assignments. */
5275 if (subst_assign_varlist
== 0 || garglist
== 0)
5276 maybe_make_export_env (); /* XXX */
5278 /* Flags to pass to parse_and_execute() */
5279 pflags
= (interactive
&& sourcelevel
== 0) ? SEVAL_RESETLINE
: 0;
5281 /* Pipe the output of executing STRING into the current shell. */
5282 if (pipe (fildes
) < 0)
5284 sys_error (_("cannot make pipe for command substitution"));
5288 old_pid
= last_made_pid
;
5289 #if defined (JOB_CONTROL)
5290 old_pipeline_pgrp
= pipeline_pgrp
;
5291 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5292 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5293 pipeline_pgrp
= shell_pgrp
;
5294 cleanup_the_pipeline ();
5295 #endif /* JOB_CONTROL */
5297 old_async_pid
= last_asynchronous_pid
;
5298 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5299 last_asynchronous_pid
= old_async_pid
;
5303 /* Reset the signal handlers in the child, but don't free the
5304 trap strings. Set a flag noting that we have to free the
5305 trap strings if we run trap to change a signal disposition. */
5306 reset_signal_handlers ();
5307 subshell_environment
|= SUBSHELL_RESETTRAP
;
5310 #if defined (JOB_CONTROL)
5311 /* XXX DO THIS ONLY IN PARENT ? XXX */
5312 set_sigchld_handler ();
5313 stop_making_children ();
5315 pipeline_pgrp
= old_pipeline_pgrp
;
5317 stop_making_children ();
5318 #endif /* JOB_CONTROL */
5322 sys_error (_("cannot make child for command substitution"));
5328 return ((WORD_DESC
*)NULL
);
5333 set_sigint_handler (); /* XXX */
5335 free_pushed_string_input ();
5337 if (dup2 (fildes
[1], 1) < 0)
5339 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5340 exit (EXECUTION_FAILURE
);
5343 /* If standard output is closed in the parent shell
5344 (such as after `exec >&-'), file descriptor 1 will be
5345 the lowest available file descriptor, and end up in
5346 fildes[0]. This can happen for stdin and stderr as well,
5347 but stdout is more important -- it will cause no output
5348 to be generated from this command. */
5349 if ((fildes
[1] != fileno (stdin
)) &&
5350 (fildes
[1] != fileno (stdout
)) &&
5351 (fildes
[1] != fileno (stderr
)))
5354 if ((fildes
[0] != fileno (stdin
)) &&
5355 (fildes
[0] != fileno (stdout
)) &&
5356 (fildes
[0] != fileno (stderr
)))
5360 /* Let stdio know the fd may have changed from text to binary mode, and
5361 make sure to preserve stdout line buffering. */
5362 freopen (NULL
, "w", stdout
);
5363 sh_setlinebuf (stdout
);
5364 #endif /* __CYGWIN__ */
5366 /* The currently executing shell is not interactive. */
5369 /* This is a subshell environment. */
5370 subshell_environment
|= SUBSHELL_COMSUB
;
5372 /* When not in POSIX mode, command substitution does not inherit
5374 if (posixly_correct
== 0)
5375 exit_immediately_on_error
= 0;
5377 remove_quoted_escapes (string
);
5379 startup_state
= 2; /* see if we can avoid a fork */
5380 /* Give command substitution a place to jump back to on failure,
5381 so we don't go back up to main (). */
5382 result
= setjmp (top_level
);
5384 /* If we're running a command substitution inside a shell function,
5385 trap `return' so we don't return from the function in the subshell
5386 and go off to never-never land. */
5387 if (result
== 0 && return_catch_flag
)
5388 function_value
= setjmp (return_catch
);
5392 if (result
== ERREXIT
)
5393 rc
= last_command_exit_value
;
5394 else if (result
== EXITPROG
)
5395 rc
= last_command_exit_value
;
5397 rc
= EXECUTION_FAILURE
;
5398 else if (function_value
)
5399 rc
= return_catch_value
;
5403 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5407 last_command_exit_value
= rc
;
5408 rc
= run_exit_trap ();
5409 #if defined (PROCESS_SUBSTITUTION)
5410 unlink_fifo_list ();
5416 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5418 #endif /* JOB_CONTROL && PGRP_PIPE */
5423 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5427 current_command_subst_pid
= pid
;
5428 last_command_exit_value
= wait_for (pid
);
5429 last_command_subst_pid
= pid
;
5430 last_made_pid
= old_pid
;
5432 #if defined (JOB_CONTROL)
5433 /* If last_command_exit_value > 128, then the substituted command
5434 was terminated by a signal. If that signal was SIGINT, then send
5435 SIGINT to ourselves. This will break out of loops, for instance. */
5436 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5437 kill (getpid (), SIGINT
);
5439 /* wait_for gives the terminal back to shell_pgrp. If some other
5440 process group should have it, give it away to that group here.
5441 pipeline_pgrp is non-zero only while we are constructing a
5442 pipline, so what we are concerned about is whether or not that
5443 pipeline was started in the background. A pipeline started in
5444 the background should never get the tty back here. */
5445 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5446 give_terminal_to (pipeline_pgrp
, 0);
5447 #endif /* JOB_CONTROL */
5449 ret
= alloc_word_desc ();
5450 ret
->word
= istring
;
5457 /********************************************************
5459 * Utility functions for parameter expansion *
5461 ********************************************************/
5463 #if defined (ARRAY_VARS)
5466 array_length_reference (s
)
5477 var
= array_variable_part (s
, &t
, &len
);
5479 /* If unbound variables should generate an error, report one and return
5481 if ((var
== 0 || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5485 last_command_exit_value
= EXECUTION_FAILURE
;
5493 /* We support a couple of expansions for variables that are not arrays.
5494 We'll return the length of the value for v[0], and 1 for v[@] or
5495 v[*]. Return 0 for everything else. */
5497 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5498 h
= assoc_p (var
) ? assoc_cell (var
) : (HASH_TABLE
*)NULL
;
5500 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5503 return (h
? assoc_num_elements (h
) : 0);
5504 else if (array_p (var
))
5505 return (array
? array_num_elements (array
) : 0);
5507 return (var_isset (var
) ? 1 : 0);
5513 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5515 if (akey
== 0 || *akey
== 0)
5517 err_badarraysub (t
);
5520 t
= assoc_reference (assoc_cell (var
), akey
);
5524 ind
= array_expand_index (t
, len
);
5527 err_badarraysub (t
);
5531 t
= array_reference (array
, ind
);
5533 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5536 len
= MB_STRLEN (t
);
5539 #endif /* ARRAY_VARS */
5542 valid_brace_expansion_word (name
, var_is_special
)
5546 if (DIGIT (*name
) && all_digits (name
))
5548 else if (var_is_special
)
5550 #if defined (ARRAY_VARS)
5551 else if (valid_array_reference (name
))
5553 #endif /* ARRAY_VARS */
5554 else if (legal_identifier (name
))
5561 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5564 int *quoted_dollar_atp
, *contains_dollar_at
;
5570 if (quoted_dollar_atp
)
5571 *quoted_dollar_atp
= 0;
5572 if (contains_dollar_at
)
5573 *contains_dollar_at
= 0;
5577 /* check for $@ and $* */
5578 if (name
[0] == '@' && name
[1] == 0)
5580 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5581 *quoted_dollar_atp
= 1;
5582 if (contains_dollar_at
)
5583 *contains_dollar_at
= 1;
5586 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5588 if (contains_dollar_at
)
5589 *contains_dollar_at
= 1;
5593 /* Now check for ${array[@]} and ${array[*]} */
5594 #if defined (ARRAY_VARS)
5595 else if (valid_array_reference (name
))
5597 temp1
= mbschr (name
, '[');
5598 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5600 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5601 *quoted_dollar_atp
= 1;
5602 if (contains_dollar_at
)
5603 *contains_dollar_at
= 1;
5606 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5607 which should result in separate words even when IFS is unset. */
5608 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5610 if (contains_dollar_at
)
5611 *contains_dollar_at
= 1;
5619 /* Parameter expand NAME, and return a new string which is the expansion,
5620 or NULL if there was no expansion.
5621 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5622 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5623 NAME was found inside of a double-quoted expression. */
5625 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
, indp
)
5627 int var_is_special
, quoted
, pflags
;
5644 /* Handle multiple digit arguments, as in ${11}. */
5645 if (legal_number (name
, &arg_index
))
5647 tt
= get_dollar_var_value (arg_index
);
5649 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5651 : quote_escapes (tt
);
5653 temp
= (char *)NULL
;
5656 else if (var_is_special
) /* ${@} */
5659 tt
= (char *)xmalloc (2 + strlen (name
));
5660 tt
[sindex
= 0] = '$';
5661 strcpy (tt
+ 1, name
);
5663 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5664 (int *)NULL
, (int *)NULL
, pflags
);
5667 #if defined (ARRAY_VARS)
5668 else if (valid_array_reference (name
))
5670 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5671 if (atype
== 0 && temp
)
5673 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5674 ? quote_string (temp
)
5675 : quote_escapes (temp
);
5676 rflags
|= W_ARRAYIND
;
5680 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5681 rflags
|= W_HASQUOTEDNULL
;
5684 else if (var
= find_variable (name
))
5686 if (var_isset (var
) && invisible_p (var
) == 0)
5688 #if defined (ARRAY_VARS)
5690 temp
= assoc_reference (assoc_cell (var
), "0");
5691 else if (array_p (var
))
5692 temp
= array_reference (array_cell (var
), 0);
5694 temp
= value_cell (var
);
5696 temp
= value_cell (var
);
5700 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5701 ? quote_string (temp
)
5702 : quote_escapes (temp
);
5705 temp
= (char *)NULL
;
5708 temp
= (char *)NULL
;
5712 ret
= alloc_word_desc ();
5714 ret
->flags
|= rflags
;
5719 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5720 value of the variable whose name is the value of NAME. */
5722 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5724 int var_is_special
, quoted
;
5725 int *quoted_dollar_atp
, *contains_dollar_at
;
5730 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
, 0);
5732 /* Have to dequote here if necessary */
5735 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5736 ? dequote_string (t
)
5737 : dequote_escapes (t
);
5741 dispose_word_desc (w
);
5743 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5745 return (WORD_DESC
*)NULL
;
5747 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0, 0);
5753 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5754 depending on the value of C, the separating character. C can be one of
5755 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5756 between double quotes. */
5758 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5760 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5764 char *t
, *t1
, *temp
;
5767 /* If the entire expression is between double quotes, we want to treat
5768 the value as a double-quoted string, with the exception that we strip
5769 embedded unescaped double quotes (for sh backwards compatibility). */
5770 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5773 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5778 w
= alloc_word_desc ();
5780 /* XXX was 0 not quoted */
5781 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5784 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5789 /* The expansion of TEMP returned something. We need to treat things
5790 slightly differently if HASDOL is non-zero. If we have "$@", the
5791 individual words have already been quoted. We need to turn them
5792 into a string with the words separated by the first character of
5793 $IFS without any additional quoting, so string_list_dollar_at won't
5794 do the right thing. We use string_list_dollar_star instead. */
5795 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5797 /* If l->next is not null, we know that TEMP contained "$@", since that
5798 is the only expansion that creates more than one word. */
5799 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5803 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5805 /* The brace expansion occurred between double quotes and there was
5806 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5807 it does not expand to anything. In this case, we want to return
5808 a quoted empty string. */
5809 temp
= make_quoted_char ('\0');
5810 w
->flags
|= W_HASQUOTEDNULL
;
5813 temp
= (char *)NULL
;
5815 if (c
== '-' || c
== '+')
5822 t
= temp
? savestring (temp
) : savestring ("");
5823 t1
= dequote_string (t
);
5825 #if defined (ARRAY_VARS)
5826 if (valid_array_reference (name
))
5827 assign_array_element (name
, t1
, 0);
5829 #endif /* ARRAY_VARS */
5830 bind_variable (name
, t1
, 0);
5832 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5839 /* Deal with the right hand side of a ${name:?value} expansion in the case
5840 that NAME is null or not set. If VALUE is non-null it is expanded and
5841 used as the error message to print, otherwise a standard message is
5844 parameter_brace_expand_error (name
, value
)
5850 if (value
&& *value
)
5852 l
= expand_string (value
, 0);
5853 temp
= string_list (l
);
5854 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5859 report_error (_("%s: parameter null or not set"), name
);
5861 /* Free the data we have allocated during this expansion, since we
5862 are about to longjmp out. */
5867 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5870 valid_length_expression (name
)
5873 return (name
[1] == '\0' || /* ${#} */
5874 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5875 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5876 #if defined (ARRAY_VARS)
5877 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5879 legal_identifier (name
+ 1)); /* ${#PS1} */
5882 /* Handle the parameter brace expansion that requires us to return the
5883 length of a parameter. */
5885 parameter_brace_expand_length (name
)
5889 intmax_t number
, arg_index
;
5891 #if defined (ARRAY_VARS)
5895 if (name
[1] == '\0') /* ${#} */
5896 number
= number_of_args ();
5897 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5898 number
= number_of_args ();
5899 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5901 /* Take the lengths of some of the shell's special parameters. */
5905 t
= which_set_flags ();
5908 t
= itos (last_command_exit_value
);
5911 t
= itos (dollar_dollar_pid
);
5914 if (last_asynchronous_pid
== NO_PID
)
5915 t
= (char *)NULL
; /* XXX - error if set -u set? */
5917 t
= itos (last_asynchronous_pid
);
5920 t
= itos (number_of_args ());
5923 number
= STRLEN (t
);
5926 #if defined (ARRAY_VARS)
5927 else if (valid_array_reference (name
+ 1))
5928 number
= array_length_reference (name
+ 1);
5929 #endif /* ARRAY_VARS */
5934 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5936 t
= get_dollar_var_value (arg_index
);
5937 if (t
== 0 && unbound_vars_is_error
)
5939 number
= MB_STRLEN (t
);
5942 #if defined (ARRAY_VARS)
5943 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
5946 t
= assoc_reference (assoc_cell (var
), "0");
5948 t
= array_reference (array_cell (var
), 0);
5949 if (t
== 0 && unbound_vars_is_error
)
5951 number
= MB_STRLEN (t
);
5956 newname
= savestring (name
);
5958 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5959 t
= list
? string_list (list
) : (char *)NULL
;
5962 dispose_words (list
);
5964 number
= t
? MB_STRLEN (t
) : 0;
5972 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5973 so we do some ad-hoc parsing of an arithmetic expression to find
5974 the first DELIM, instead of using strchr(3). Two rules:
5975 1. If the substring contains a `(', read until closing `)'.
5976 2. If the substring contains a `?', read past one `:' for each `?'.
5980 skiparith (substr
, delim
)
5985 int skipcol
, pcount
, i
;
5988 sublen
= strlen (substr
);
5989 i
= skipcol
= pcount
= 0;
5992 /* Balance parens */
5993 if (substr
[i
] == LPAREN
)
5999 if (substr
[i
] == RPAREN
&& pcount
)
6007 ADVANCE_CHAR (substr
, sublen
, i
);
6011 /* Skip one `:' for each `?' */
6012 if (substr
[i
] == ':' && skipcol
)
6018 if (substr
[i
] == delim
)
6020 if (substr
[i
] == '?')
6026 ADVANCE_CHAR (substr
, sublen
, i
);
6029 return (substr
+ i
);
6032 /* Verify and limit the start and end of the desired substring. If
6033 VTYPE == 0, a regular shell variable is being used; if it is 1,
6034 then the positional parameters are being used; if it is 2, then
6035 VALUE is really a pointer to an array variable that should be used.
6036 Return value is 1 if both values were OK, 0 if there was a problem
6037 with an invalid expression, or -1 if the values were out of range. */
6039 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
6041 char *value
, *substr
;
6043 intmax_t *e1p
, *e2p
;
6045 char *t
, *temp1
, *temp2
;
6048 #if defined (ARRAY_VARS)
6053 /* duplicate behavior of strchr(3) */
6054 t
= skiparith (substr
, ':');
6055 if (*t
&& *t
== ':')
6060 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
6061 *e1p
= evalexp (temp1
, &expok
);
6066 len
= -1; /* paranoia */
6070 case VT_ARRAYMEMBER
:
6071 len
= MB_STRLEN (value
);
6074 len
= number_of_args () + 1;
6076 len
++; /* add one arg if counting from $0 */
6078 #if defined (ARRAY_VARS)
6080 /* For arrays, the first value deals with array indices. Negative
6081 offsets count from one past the array's maximum index. Associative
6082 arrays treat the number of elements as the maximum index. */
6086 len
= assoc_num_elements (h
) + (*e1p
< 0);
6091 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
6097 if (len
== -1) /* paranoia */
6100 if (*e1p
< 0) /* negative offsets count from end */
6103 if (*e1p
> len
|| *e1p
< 0)
6106 #if defined (ARRAY_VARS)
6107 /* For arrays, the second offset deals with the number of elements. */
6108 if (vtype
== VT_ARRAYVAR
)
6109 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
6115 temp2
= savestring (t
);
6116 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6119 *e2p
= evalexp (temp1
, &expok
);
6123 if ((vtype
== VT_ARRAYVAR
|| vtype
== VT_POSPARMS
) && *e2p
< 0)
6125 internal_error (_("%s: substring expression < 0"), t
);
6128 #if defined (ARRAY_VARS)
6129 /* In order to deal with sparse arrays, push the intelligence about how
6130 to deal with the number of elements desired down to the array-
6131 specific functions. */
6132 if (vtype
!= VT_ARRAYVAR
)
6138 if (*e2p
< 0 || *e2p
< *e1p
)
6140 internal_error (_("%s: substring expression < 0"), t
);
6145 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
6156 /* Return the type of variable specified by VARNAME (simple variable,
6157 positional param, or array variable). Also return the value specified
6158 by VARNAME (value of a variable or a reference to an array element).
6159 QUOTED is the standard description of quoting state, using Q_* defines.
6160 FLAGS is currently a set of flags to pass to array_value. If IND is
6161 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6162 passed to array_value so the array index is not computed again.
6163 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6164 characters in the value are quoted with CTLESC and takes appropriate
6165 steps. For convenience, *VALP is set to the dequoted VALUE. */
6167 get_var_and_type (varname
, value
, ind
, quoted
, flags
, varp
, valp
)
6168 char *varname
, *value
;
6176 #if defined (ARRAY_VARS)
6181 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6182 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
6183 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
6184 vtype
|= VT_STARSUB
;
6185 *varp
= (SHELL_VAR
*)NULL
;
6187 #if defined (ARRAY_VARS)
6188 if (valid_array_reference (varname
))
6190 v
= array_variable_part (varname
, &temp
, (int *)0);
6191 /* If we want to signal array_value to use an already-computed index,
6192 set LIND to that index */
6193 lind
= (ind
!= INTMAX_MIN
&& (flags
& AV_USEIND
)) ? ind
: 0;
6194 if (v
&& (array_p (v
) || assoc_p (v
)))
6196 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
6198 /* Callers have to differentiate betwen indexed and associative */
6199 vtype
= VT_ARRAYVAR
;
6201 vtype
|= VT_STARSUB
;
6202 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
6206 vtype
= VT_ARRAYMEMBER
;
6207 *valp
= array_value (varname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6211 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
6213 vtype
= VT_VARIABLE
;
6215 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6216 *valp
= dequote_string (value
);
6218 *valp
= dequote_escapes (value
);
6222 vtype
= VT_ARRAYMEMBER
;
6224 *valp
= array_value (varname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6227 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
6229 vtype
= VT_ARRAYMEMBER
;
6231 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
6236 if (value
&& vtype
== VT_VARIABLE
)
6238 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6239 *valp
= dequote_string (value
);
6241 *valp
= dequote_escapes (value
);
6250 /******************************************************/
6252 /* Functions to extract substrings of variable values */
6254 /******************************************************/
6256 #if defined (HANDLE_MULTIBYTE)
6257 /* Character-oriented rather than strictly byte-oriented substrings. S and
6258 E, rather being strict indices into STRING, indicate character (possibly
6259 multibyte character) positions that require calculation.
6260 Used by the ${param:offset[:length]} expansion. */
6262 mb_substring (string
, s
, e
)
6267 int start
, stop
, i
, slen
;
6271 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6272 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6275 while (string
[start
] && i
--)
6276 ADVANCE_CHAR (string
, slen
, start
);
6279 while (string
[stop
] && i
--)
6280 ADVANCE_CHAR (string
, slen
, stop
);
6281 tt
= substring (string
, start
, stop
);
6286 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6287 is `@', use the positional parameters; otherwise, use the value of
6288 VARNAME. If VARNAME is an array variable, use the array elements. */
6291 parameter_brace_substring (varname
, value
, ind
, substr
, quoted
, flags
)
6292 char *varname
, *value
;
6298 int vtype
, r
, starsub
;
6299 char *temp
, *val
, *tt
, *oname
;
6303 return ((char *)NULL
);
6305 oname
= this_command_name
;
6306 this_command_name
= varname
;
6308 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6311 this_command_name
= oname
;
6312 return ((char *)NULL
);
6315 starsub
= vtype
& VT_STARSUB
;
6316 vtype
&= ~VT_STARSUB
;
6318 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6319 this_command_name
= oname
;
6321 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6326 case VT_ARRAYMEMBER
:
6327 #if defined (HANDLE_MULTIBYTE)
6329 tt
= mb_substring (val
, e1
, e2
);
6332 tt
= substring (val
, e1
, e2
);
6334 if (vtype
== VT_VARIABLE
)
6336 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6337 temp
= quote_string (tt
);
6339 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6343 tt
= pos_params (varname
, e1
, e2
, quoted
);
6344 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6346 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6352 #if defined (ARRAY_VARS)
6355 /* we convert to list and take first e2 elements starting at e1th
6356 element -- officially undefined for now */
6357 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6359 /* We want E2 to be the number of elements desired (arrays can be sparse,
6360 so verify_substring_values just returns the numbers specified and we
6361 rely on array_subrange to understand how to deal with them). */
6362 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6363 /* array_subrange now calls array_quote_escapes as appropriate, so the
6364 caller no longer needs to. */
6368 temp
= (char *)NULL
;
6374 /****************************************************************/
6376 /* Functions to perform pattern substitution on variable values */
6378 /****************************************************************/
6381 shouldexp_replacement (s
)
6386 for (p
= s
; p
&& *p
; p
++)
6397 pat_subst (string
, pat
, rep
, mflags
)
6398 char *string
, *pat
, *rep
;
6401 char *ret
, *s
, *e
, *str
, *rstr
, *mstr
;
6402 int rsize
, rptr
, l
, replen
, mtype
, rxpand
, rslen
, mlen
;
6405 return (savestring (""));
6407 mtype
= mflags
& MATCH_TYPEMASK
;
6409 #if 0 /* bash-4.2 ? */
6410 rxpand
= (rep
&& *rep
) ? shouldexp_replacement (rep
) : 0;
6416 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6417 * with REP and return the result.
6418 * 2. A null pattern with mtype == MATCH_END means to append REP to
6419 * STRING and return the result.
6420 * These don't understand or process `&' in the replacement string.
6422 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
6424 replen
= STRLEN (rep
);
6425 l
= STRLEN (string
);
6426 ret
= (char *)xmalloc (replen
+ l
+ 2);
6428 strcpy (ret
, string
);
6429 else if (mtype
== MATCH_BEG
)
6432 strcpy (ret
+ replen
, string
);
6436 strcpy (ret
, string
);
6437 strcpy (ret
+ l
, rep
);
6442 ret
= (char *)xmalloc (rsize
= 64);
6445 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6447 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6455 mstr
= xmalloc (mlen
+ 1);
6456 for (x
= 0; x
< mlen
; x
++)
6459 rstr
= strcreplace (rep
, '&', mstr
, 0);
6460 rslen
= strlen (rstr
);
6468 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ rslen
), rsize
, 64);
6470 /* OK, now copy the leading unmatched portion of the string (from
6471 str to s) to ret starting at rptr (the current offset). Then copy
6472 the replacement string at ret + rptr + (s - str). Increment
6473 rptr (if necessary) and str and go on. */
6476 strncpy (ret
+ rptr
, str
, l
);
6481 strncpy (ret
+ rptr
, rstr
, rslen
);
6484 str
= e
; /* e == end of match */
6489 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6494 /* On a zero-length match, make sure we copy one character, since
6495 we increment one character to avoid infinite recursion. */
6496 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6497 ret
[rptr
++] = *str
++;
6498 e
++; /* avoid infinite recursion on zero-length match */
6502 /* Now copy the unmatched portion of the input string */
6505 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6506 strcpy (ret
+ rptr
, str
);
6514 /* Do pattern match and replacement on the positional parameters. */
6516 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6517 char *string
, *pat
, *rep
;
6520 WORD_LIST
*save
, *params
;
6525 save
= params
= list_rest_of_args ();
6527 return ((char *)NULL
);
6529 for ( ; params
; params
= params
->next
)
6531 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6532 w
= alloc_word_desc ();
6533 w
->word
= ret
? ret
: savestring ("");
6534 dispose_word (params
->word
);
6538 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6539 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6542 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
6543 ret
= string_list_dollar_star (quote_list (save
));
6544 else if ((mflags
& MATCH_STARSUB
) == MATCH_STARSUB
)
6545 ret
= string_list_dollar_star (save
);
6546 else if ((mflags
& MATCH_QUOTED
) == MATCH_QUOTED
)
6547 ret
= string_list_dollar_at (save
, qflags
);
6549 ret
= string_list_dollar_star (save
);
6551 ret
= string_list_pos_params (pchar
, save
, qflags
);
6554 dispose_words (save
);
6559 /* Perform pattern substitution on VALUE, which is the expansion of
6560 VARNAME. PATSUB is an expression supplying the pattern to match
6561 and the string to substitute. QUOTED is a flags word containing
6562 the type of quoting currently in effect. */
6564 parameter_brace_patsub (varname
, value
, ind
, patsub
, quoted
, flags
)
6565 char *varname
, *value
;
6570 int vtype
, mflags
, starsub
, delim
;
6571 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6575 return ((char *)NULL
);
6577 this_command_name
= varname
;
6579 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6581 return ((char *)NULL
);
6583 starsub
= vtype
& VT_STARSUB
;
6584 vtype
&= ~VT_STARSUB
;
6587 if (patsub
&& *patsub
== '/')
6589 mflags
|= MATCH_GLOBREP
;
6593 /* Malloc this because expand_string_if_necessary or one of the expansion
6594 functions in its call chain may free it on a substitution error. */
6595 lpatsub
= savestring (patsub
);
6597 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6598 mflags
|= MATCH_QUOTED
;
6601 mflags
|= MATCH_STARSUB
;
6603 /* If the pattern starts with a `/', make sure we skip over it when looking
6604 for the replacement delimiter. */
6606 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
6611 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6612 if (lpatsub
[delim
] == '/')
6615 rep
= lpatsub
+ delim
+ 1;
6621 if (rep
&& *rep
== '\0')
6624 /* Perform the same expansions on the pattern as performed by the
6625 pattern removal expansions. */
6626 pat
= getpattern (lpatsub
, quoted
, 1);
6630 if ((mflags
& MATCH_QUOTED
) == 0)
6631 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6633 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6636 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6637 pattern. This is an extension. Make sure we don't anchor the pattern
6638 at the beginning or end of the string if we're doing global replacement,
6641 if (mflags
& MATCH_GLOBREP
)
6642 mflags
|= MATCH_ANY
;
6643 else if (pat
&& pat
[0] == '#')
6645 mflags
|= MATCH_BEG
;
6648 else if (pat
&& pat
[0] == '%')
6650 mflags
|= MATCH_END
;
6654 mflags
|= MATCH_ANY
;
6656 /* OK, we now want to substitute REP for PAT in VAL. If
6657 flags & MATCH_GLOBREP is non-zero, the substitution is done
6658 everywhere, otherwise only the first occurrence of PAT is
6659 replaced. The pattern matching code doesn't understand
6660 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6661 values passed in (VT_VARIABLE) so the pattern substitution
6662 code works right. We need to requote special chars after
6663 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6664 other cases if QUOTED == 0, since the posparams and arrays
6665 indexed by * or @ do special things when QUOTED != 0. */
6670 case VT_ARRAYMEMBER
:
6671 temp
= pat_subst (val
, p
, rep
, mflags
);
6672 if (vtype
== VT_VARIABLE
)
6676 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6682 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6683 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6685 tt
= quote_escapes (temp
);
6690 #if defined (ARRAY_VARS)
6692 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6693 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6694 /* Don't call quote_escapes anymore; array_patsub calls
6695 array_quote_escapes as appropriate before adding the
6696 space separators; ditto for assoc_patsub. */
6708 /****************************************************************/
6710 /* Functions to perform case modification on variable values */
6712 /****************************************************************/
6714 /* Do case modification on the positional parameters. */
6717 pos_params_modcase (string
, pat
, modop
, mflags
)
6722 WORD_LIST
*save
, *params
;
6727 save
= params
= list_rest_of_args ();
6729 return ((char *)NULL
);
6731 for ( ; params
; params
= params
->next
)
6733 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6734 w
= alloc_word_desc ();
6735 w
->word
= ret
? ret
: savestring ("");
6736 dispose_word (params
->word
);
6740 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6741 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6743 ret
= string_list_pos_params (pchar
, save
, qflags
);
6744 dispose_words (save
);
6749 /* Perform case modification on VALUE, which is the expansion of
6750 VARNAME. MODSPEC is an expression supplying the type of modification
6751 to perform. QUOTED is a flags word containing the type of quoting
6752 currently in effect. */
6754 parameter_brace_casemod (varname
, value
, ind
, modspec
, patspec
, quoted
, flags
)
6755 char *varname
, *value
;
6760 int vtype
, starsub
, modop
, mflags
, x
;
6761 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6765 return ((char *)NULL
);
6767 this_command_name
= varname
;
6769 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6771 return ((char *)NULL
);
6773 starsub
= vtype
& VT_STARSUB
;
6774 vtype
&= ~VT_STARSUB
;
6778 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6779 mflags
|= MATCH_QUOTED
;
6781 mflags
|= MATCH_STARSUB
;
6786 x
= p
&& p
[0] == modspec
;
6787 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6790 else if (modspec
== ',')
6792 x
= p
&& p
[0] == modspec
;
6793 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6796 else if (modspec
== '~')
6798 x
= p
&& p
[0] == modspec
;
6799 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6803 lpat
= p
? savestring (p
) : 0;
6804 /* Perform the same expansions on the pattern as performed by the
6805 pattern removal expansions. FOR LATER */
6806 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6808 /* OK, now we do the case modification. */
6812 case VT_ARRAYMEMBER
:
6813 temp
= sh_modcase (val
, pat
, modop
);
6814 if (vtype
== VT_VARIABLE
)
6818 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6825 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6826 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6828 tt
= quote_escapes (temp
);
6834 #if defined (ARRAY_VARS)
6836 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
6837 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
6838 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6839 as appropriate before adding the space separators; ditto for
6851 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6852 any occur, this must be a nested command substitution, so return 0.
6853 Otherwise, return 1. A valid arithmetic expression must always have a
6854 ( before a matching ), so any cases where there are more right parens
6855 means that this must not be an arithmetic expression, though the parser
6856 will not accept it without a balanced total number of parens. */
6858 chk_arithsub (s
, len
)
6870 else if (s
[i
] == RPAREN
)
6880 ADVANCE_CHAR (s
, len
, i
);
6886 ADVANCE_CHAR (s
, len
, i
);
6890 i
= skip_single_quoted (s
, len
, ++i
);
6894 i
= skip_double_quoted ((char *)s
, len
, ++i
);
6899 return (count
== 0);
6902 /****************************************************************/
6904 /* Functions to perform parameter expansion on a string */
6906 /****************************************************************/
6908 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6910 parameter_brace_expand (string
, indexp
, quoted
, pflags
, quoted_dollar_atp
, contains_dollar_at
)
6912 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
, pflags
;
6914 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
6915 int want_substring
, want_indir
, want_patsub
, want_casemod
;
6916 char *name
, *value
, *temp
, *temp1
;
6917 WORD_DESC
*tdesc
, *ret
;
6918 int t_index
, sindex
, c
, tflag
, modspec
;
6922 temp
= temp1
= value
= (char *)NULL
;
6923 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
6924 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
6928 /* ${#var} doesn't have any of the other parameter expansions on it. */
6929 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
6930 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
6932 #if defined (CASEMOD_EXPANSIONS)
6933 /* To enable case-toggling expansions using the `~' operator character
6934 change the 1 to 0. */
6935 # if defined (CASEMOD_CAPCASE)
6936 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
6938 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
6939 # endif /* CASEMOD_CAPCASE */
6941 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
6942 #endif /* CASEMOD_EXPANSIONS */
6949 /* If the name really consists of a special variable, then make sure
6950 that we have the entire name. We don't allow indirect references
6951 to special variables except `#', `?', `@' and `*'. */
6952 if ((sindex
== t_index
&& VALID_SPECIAL_LENGTH_PARAM (string
[t_index
])) ||
6953 (sindex
== t_index
- 1 && string
[sindex
] == '!' && VALID_INDIR_PARAM (string
[t_index
])))
6957 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
6958 name
= (char *)xmalloc (3 + (strlen (temp1
)));
6959 *name
= string
[sindex
];
6960 if (string
[sindex
] == '!')
6962 /* indirect reference of $#, $?, $@, or $* */
6963 name
[1] = string
[sindex
+ 1];
6964 strcpy (name
+ 2, temp1
);
6967 strcpy (name
+ 1, temp1
);
6972 /* Find out what character ended the variable name. Then
6973 do the appropriate thing. */
6974 if (c
= string
[sindex
])
6977 /* If c is followed by one of the valid parameter expansion
6978 characters, move past it as normal. If not, assume that
6979 a substring specification is being given, and do not move
6981 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
6984 if (c
= string
[sindex
])
6987 else if (c
== ':' && string
[sindex
] != RBRACE
)
6989 else if (c
== '/' && string
[sindex
] != RBRACE
)
6991 #if defined (CASEMOD_EXPANSIONS)
6992 else if (c
== '^' || c
== ',' || c
== '~')
6999 /* Catch the valid and invalid brace expressions that made it through the
7001 /* ${#-} is a valid expansion and means to take the length of $-.
7002 Similarly for ${#?} and ${##}... */
7003 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7004 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
7006 name
= (char *)xrealloc (name
, 3);
7009 c
= string
[sindex
++];
7012 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7013 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7014 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
7016 temp
= (char *)NULL
;
7017 goto bad_substitution
;
7020 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7021 either a variable name, one of the positional parameters or a special
7022 variable that expands to one of the positional parameters. */
7023 want_indir
= *name
== '!' &&
7024 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
7025 || VALID_INDIR_PARAM (name
[1]));
7027 /* Determine the value of this variable. */
7029 /* Check for special variables, directly referenced. */
7030 if (SPECIAL_VAR (name
, want_indir
))
7033 /* Check for special expansion things, like the length of a parameter */
7034 if (*name
== '#' && name
[1])
7036 /* If we are not pointing at the character just after the
7037 closing brace, then we haven't gotten all of the name.
7038 Since it begins with a special character, this is a bad
7039 substitution. Also check NAME for validity before trying
7041 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
7043 temp
= (char *)NULL
;
7044 goto bad_substitution
;
7047 number
= parameter_brace_expand_length (name
);
7048 if (number
== INTMAX_MIN
&& unbound_vars_is_error
)
7050 last_command_exit_value
= EXECUTION_FAILURE
;
7051 err_unboundvar (name
+1);
7053 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7059 return (&expand_wdesc_error
);
7062 ret
= alloc_word_desc ();
7063 ret
->word
= itos (number
);
7068 /* ${@} is identical to $@. */
7069 if (name
[0] == '@' && name
[1] == '\0')
7071 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7072 *quoted_dollar_atp
= 1;
7074 if (contains_dollar_at
)
7075 *contains_dollar_at
= 1;
7078 /* Process ${!PREFIX*} expansion. */
7079 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7080 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
7081 legal_variable_starter ((unsigned char) name
[1]))
7086 temp1
= savestring (name
+ 1);
7087 number
= strlen (temp1
);
7088 temp1
[number
- 1] = '\0';
7089 x
= all_variables_matching_prefix (temp1
);
7090 xlist
= strvec_to_word_list (x
, 0, 0);
7091 if (string
[sindex
- 2] == '*')
7092 temp
= string_list_dollar_star (xlist
);
7095 temp
= string_list_dollar_at (xlist
, quoted
);
7096 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7097 *quoted_dollar_atp
= 1;
7098 if (contains_dollar_at
)
7099 *contains_dollar_at
= 1;
7102 dispose_words (xlist
);
7106 ret
= alloc_word_desc ();
7111 #if defined (ARRAY_VARS)
7112 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7113 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7114 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
7118 temp1
= savestring (name
+ 1);
7119 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
7121 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
7123 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
7126 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7127 *quoted_dollar_atp
= 1;
7128 if (contains_dollar_at
)
7129 *contains_dollar_at
= 1;
7135 ret
= alloc_word_desc ();
7142 #endif /* ARRAY_VARS */
7144 /* Make sure that NAME is valid before trying to go on. */
7145 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
7146 var_is_special
) == 0)
7148 temp
= (char *)NULL
;
7149 goto bad_substitution
;
7153 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7155 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
|(pflags
&PF_NOSPLIT2
), &ind
);
7160 tflag
= tdesc
->flags
;
7161 dispose_word_desc (tdesc
);
7166 #if defined (ARRAY_VARS)
7167 if (valid_array_reference (name
))
7168 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7171 var_is_set
= temp
!= (char *)0;
7172 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
7174 /* Get the rest of the stuff inside the braces. */
7175 if (c
&& c
!= RBRACE
)
7177 /* Extract the contents of the ${ ... } expansion
7178 according to the Posix.2 rules. */
7179 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, (c
== '%' || c
== '#') ? SX_POSIXEXP
: 0);
7180 if (string
[sindex
] == RBRACE
)
7183 goto bad_substitution
;
7186 value
= (char *)NULL
;
7190 /* All the cases where an expansion can possibly generate an unbound
7192 if (want_substring
|| want_patsub
|| want_casemod
|| c
== '#' || c
== '%' || c
== RBRACE
)
7194 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
7196 last_command_exit_value
= EXECUTION_FAILURE
;
7197 err_unboundvar (name
);
7201 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7205 /* If this is a substring spec, process it and add the result. */
7208 temp1
= parameter_brace_substring (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7213 if (temp1
== &expand_param_error
)
7214 return (&expand_wdesc_error
);
7215 else if (temp1
== &expand_param_fatal
)
7216 return (&expand_wdesc_fatal
);
7218 ret
= alloc_word_desc ();
7220 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7221 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7224 else if (want_patsub
)
7226 temp1
= parameter_brace_patsub (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7231 if (temp1
== &expand_param_error
)
7232 return (&expand_wdesc_error
);
7233 else if (temp1
== &expand_param_fatal
)
7234 return (&expand_wdesc_fatal
);
7236 ret
= alloc_word_desc ();
7238 ret
= alloc_word_desc ();
7240 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7241 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7244 #if defined (CASEMOD_EXPANSIONS)
7245 else if (want_casemod
)
7247 temp1
= parameter_brace_casemod (name
, temp
, ind
, modspec
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7252 if (temp1
== &expand_param_error
)
7253 return (&expand_wdesc_error
);
7254 else if (temp1
== &expand_param_fatal
)
7255 return (&expand_wdesc_fatal
);
7257 ret
= alloc_word_desc ();
7259 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7260 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7265 /* Do the right thing based on which character ended the variable name. */
7271 report_error (_("%s: bad substitution"), string
? string
: "??");
7275 return &expand_wdesc_error
;
7280 case '#': /* ${param#[#]pattern} */
7281 case '%': /* ${param%[%]pattern} */
7282 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
7287 temp1
= parameter_brace_remove_pattern (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7292 ret
= alloc_word_desc ();
7294 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7295 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7302 if (var_is_set
&& var_is_null
== 0)
7304 /* If the operator is `+', we don't want the value of the named
7305 variable for anything, just the value of the right hand side. */
7308 /* XXX -- if we're double-quoted and the named variable is "$@",
7309 we want to turn off any special handling of "$@" --
7310 we're not using it, so whatever is on the rhs applies. */
7311 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7312 *quoted_dollar_atp
= 0;
7313 if (contains_dollar_at
)
7314 *contains_dollar_at
= 0;
7319 /* From Posix discussion on austin-group list. Issue 221
7320 requires that backslashes escaping `}' inside
7321 double-quoted ${...} be removed. */
7322 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7323 quoted
|= Q_DOLBRACE
;
7324 ret
= parameter_brace_expand_rhs (name
, value
, c
,
7327 contains_dollar_at
);
7328 /* XXX - fix up later, esp. noting presence of
7329 W_HASQUOTEDNULL in ret->flags */
7333 temp
= (char *)NULL
;
7339 /* Otherwise do nothing; just use the value in TEMP. */
7341 else /* VAR not set or VAR is NULL. */
7344 temp
= (char *)NULL
;
7345 if (c
== '=' && var_is_special
)
7347 report_error (_("$%s: cannot assign in this way"), name
);
7350 return &expand_wdesc_error
;
7354 parameter_brace_expand_error (name
, value
);
7355 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7359 /* XXX -- if we're double-quoted and the named variable is "$@",
7360 we want to turn off any special handling of "$@" --
7361 we're not using it, so whatever is on the rhs applies. */
7362 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7363 *quoted_dollar_atp
= 0;
7364 if (contains_dollar_at
)
7365 *contains_dollar_at
= 0;
7367 /* From Posix discussion on austin-group list. Issue 221 requires
7368 that backslashes escaping `}' inside double-quoted ${...} be
7370 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7371 quoted
|= Q_DOLBRACE
;
7372 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
7374 contains_dollar_at
);
7375 /* XXX - fix up later, esp. noting presence of
7376 W_HASQUOTEDNULL in tdesc->flags */
7387 ret
= alloc_word_desc ();
7394 /* Expand a single ${xxx} expansion. The braces are optional. When
7395 the braces are used, parameter_brace_expand() does the work,
7396 possibly calling param_expand recursively. */
7398 param_expand (string
, sindex
, quoted
, expanded_something
,
7399 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
7402 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
7403 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
7405 char *temp
, *temp1
, uerror
[3];
7406 int zindex
, t_index
, expok
;
7411 WORD_DESC
*tdesc
, *ret
;
7415 c
= string
[++zindex
];
7417 temp
= (char *)NULL
;
7418 ret
= tdesc
= (WORD_DESC
*)NULL
;
7421 /* Do simple cases first. Switch on what follows '$'. */
7435 temp1
= dollar_vars
[TODIGIT (c
)];
7436 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
7441 last_command_exit_value
= EXECUTION_FAILURE
;
7442 err_unboundvar (uerror
);
7443 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7446 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7447 ? quote_string (temp1
)
7448 : quote_escapes (temp1
);
7450 temp
= (char *)NULL
;
7454 /* $$ -- pid of the invoking shell. */
7456 temp
= itos (dollar_dollar_pid
);
7459 /* $# -- number of positional parameters. */
7461 temp
= itos (number_of_args ());
7464 /* $? -- return value of the last synchronous command. */
7466 temp
= itos (last_command_exit_value
);
7469 /* $- -- flags supplied to the shell on invocation or by `set'. */
7471 temp
= which_set_flags ();
7474 /* $! -- Pid of the last asynchronous command. */
7476 /* If no asynchronous pids have been created, expand to nothing.
7477 If `set -u' has been executed, and no async processes have
7478 been created, this is an expansion error. */
7479 if (last_asynchronous_pid
== NO_PID
)
7481 if (expanded_something
)
7482 *expanded_something
= 0;
7483 temp
= (char *)NULL
;
7484 if (unbound_vars_is_error
)
7489 last_command_exit_value
= EXECUTION_FAILURE
;
7490 err_unboundvar (uerror
);
7491 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7495 temp
= itos (last_asynchronous_pid
);
7498 /* The only difference between this and $@ is when the arg is quoted. */
7499 case '*': /* `$*' */
7500 list
= list_rest_of_args ();
7503 /* According to austin-group posix proposal by Geoff Clare in
7504 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7506 "The shell shall write a message to standard error and
7507 immediately exit when it tries to expand an unset parameter
7508 other than the '@' and '*' special parameters."
7511 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7516 last_command_exit_value
= EXECUTION_FAILURE
;
7517 err_unboundvar (uerror
);
7518 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7522 /* If there are no command-line arguments, this should just
7523 disappear if there are other characters in the expansion,
7524 even if it's quoted. */
7525 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7526 temp
= (char *)NULL
;
7527 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7529 /* If we have "$*" we want to make a string of the positional
7530 parameters, separated by the first character of $IFS, and
7531 quote the whole string, including the separators. If IFS
7532 is unset, the parameters are separated by ' '; if $IFS is
7533 null, the parameters are concatenated. */
7534 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7537 temp1
= quote_string (temp
);
7539 tflag
|= W_HASQUOTEDNULL
;
7546 /* We check whether or not we're eventually going to split $* here,
7547 for example when IFS is empty and we are processing the rhs of
7548 an assignment statement. In that case, we don't separate the
7549 arguments at all. Otherwise, if the $* is not quoted it is
7552 # if defined (HANDLE_MULTIBYTE)
7553 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7555 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7557 temp
= string_list_dollar_star (list
);
7559 temp
= string_list_dollar_at (list
, quoted
);
7561 temp
= string_list_dollar_at (list
, quoted
);
7563 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7564 *contains_dollar_at
= 1;
7567 dispose_words (list
);
7570 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7571 means that we have to turn quoting off after we split into
7572 the individually quoted arguments so that the final split
7573 on the first character of $IFS is still done. */
7574 case '@': /* `$@' */
7575 list
= list_rest_of_args ();
7578 /* According to austin-group posix proposal by Geoff Clare in
7579 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7581 "The shell shall write a message to standard error and
7582 immediately exit when it tries to expand an unset parameter
7583 other than the '@' and '*' special parameters."
7586 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7591 last_command_exit_value
= EXECUTION_FAILURE
;
7592 err_unboundvar (uerror
);
7593 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7597 /* We want to flag the fact that we saw this. We can't turn
7598 off quoting entirely, because other characters in the
7599 string might need it (consider "\"$@\""), but we need some
7600 way to signal that the final split on the first character
7601 of $IFS should be done, even though QUOTED is 1. */
7602 /* XXX - should this test include Q_PATQUOTE? */
7603 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7604 *quoted_dollar_at_p
= 1;
7605 if (contains_dollar_at
)
7606 *contains_dollar_at
= 1;
7609 if (pflags
& PF_NOSPLIT2
)
7610 temp
= string_list_internal (quoted
? quote_list (list
) : list
, " ");
7613 /* We want to separate the positional parameters with the first
7614 character of $IFS in case $IFS is something other than a space.
7615 We also want to make sure that splitting is done no matter what --
7616 according to POSIX.2, this expands to a list of the positional
7617 parameters no matter what IFS is set to. */
7618 temp
= string_list_dollar_at (list
, quoted
);
7620 dispose_words (list
);
7624 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
, pflags
,
7626 contains_dollar_at
);
7628 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7630 temp
= tdesc
? tdesc
->word
: (char *)0;
7633 /* Quoted nulls should be removed if there is anything else
7635 /* Note that we saw the quoted null so we can add one back at
7636 the end of this function if there are no other characters
7637 in the string, discard TEMP, and go on. The exception to
7638 this is when we have "${@}" and $1 is '', since $@ needs
7639 special handling. */
7640 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7642 if (had_quoted_null_p
)
7643 *had_quoted_null_p
= 1;
7644 if (*quoted_dollar_at_p
== 0)
7647 tdesc
->word
= temp
= (char *)NULL
;
7655 /* Do command or arithmetic substitution. */
7657 /* We have to extract the contents of this paren substitution. */
7658 t_index
= zindex
+ 1;
7659 temp
= extract_command_subst (string
, &t_index
, 0);
7662 /* For Posix.2-style `$(( ))' arithmetic substitution,
7663 extract the expression and pass it to the evaluator. */
7664 if (temp
&& *temp
== LPAREN
)
7668 temp2
= savestring (temp1
);
7669 t_index
= strlen (temp2
) - 1;
7671 if (temp2
[t_index
] != RPAREN
)
7677 /* Cut off ending `)' */
7678 temp2
[t_index
] = '\0';
7680 if (chk_arithsub (temp2
, t_index
) == 0)
7684 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7689 /* Expand variables found inside the expression. */
7690 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7694 /* No error messages. */
7695 this_command_name
= (char *)NULL
;
7696 number
= evalexp (temp1
, &expok
);
7701 if (interactive_shell
== 0 && posixly_correct
)
7703 last_command_exit_value
= EXECUTION_FAILURE
;
7704 return (&expand_wdesc_fatal
);
7707 return (&expand_wdesc_error
);
7709 temp
= itos (number
);
7714 if (pflags
& PF_NOCOMSUB
)
7715 /* we need zindex+1 because string[zindex] == RPAREN */
7716 temp1
= substring (string
, *sindex
, zindex
+1);
7719 tdesc
= command_substitute (temp
, quoted
);
7720 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7722 dispose_word_desc (tdesc
);
7728 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7729 away in a future bash release. */
7731 /* Extract the contents of this arithmetic substitution. */
7732 t_index
= zindex
+ 1;
7733 temp
= extract_arithmetic_subst (string
, &t_index
);
7737 temp
= savestring (string
);
7738 if (expanded_something
)
7739 *expanded_something
= 0;
7743 /* Do initial variable expansion. */
7744 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7749 /* Find the variable in VARIABLE_LIST. */
7750 temp
= (char *)NULL
;
7752 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7754 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7756 /* If this isn't a variable name, then just output the `$'. */
7757 if (temp1
== 0 || *temp1
== '\0')
7760 temp
= (char *)xmalloc (2);
7763 if (expanded_something
)
7764 *expanded_something
= 0;
7768 /* If the variable exists, return its value cell. */
7769 var
= find_variable (temp1
);
7771 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7773 #if defined (ARRAY_VARS)
7774 if (assoc_p (var
) || array_p (var
))
7776 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7777 : assoc_reference (assoc_cell (var
), "0");
7779 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7780 ? quote_string (temp
)
7781 : quote_escapes (temp
);
7782 else if (unbound_vars_is_error
)
7783 goto unbound_variable
;
7788 temp
= value_cell (var
);
7790 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7791 ? quote_string (temp
)
7792 : quote_escapes (temp
);
7800 temp
= (char *)NULL
;
7803 if (unbound_vars_is_error
)
7805 last_command_exit_value
= EXECUTION_FAILURE
;
7806 err_unboundvar (temp1
);
7815 last_command_exit_value
= EXECUTION_FAILURE
;
7816 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7817 ? &expand_wdesc_fatal
7818 : &expand_wdesc_error
);
7829 ret
= alloc_word_desc ();
7830 ret
->flags
= tflag
; /* XXX */
7836 /* Make a word list which is the result of parameter and variable
7837 expansion, command substitution, arithmetic substitution, and
7838 quote removal of WORD. Return a pointer to a WORD_LIST which is
7839 the result of the expansion. If WORD contains a null word, the
7840 word list returned is also null.
7842 QUOTED contains flag values defined in shell.h.
7844 ISEXP is used to tell expand_word_internal that the word should be
7845 treated as the result of an expansion. This has implications for
7846 how IFS characters in the word are treated.
7848 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7849 they point to an integer value which receives information about expansion.
7850 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7851 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7854 This only does word splitting in the case of $@ expansion. In that
7855 case, we split on ' '. */
7857 /* Values for the local variable quoted_state. */
7859 #define PARTIALLY_QUOTED 1
7860 #define WHOLLY_QUOTED 2
7863 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7866 int *contains_dollar_at
;
7867 int *expanded_something
;
7872 /* The intermediate string that we build while expanding. */
7875 /* The current size of the above object. */
7878 /* Index into ISTRING. */
7881 /* Temporary string storage. */
7884 /* The text of WORD. */
7885 register char *string
;
7887 /* The size of STRING. */
7890 /* The index into STRING. */
7893 /* This gets 1 if we see a $@ while quoted. */
7894 int quoted_dollar_at
;
7896 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7897 whether WORD contains no quoting characters, a partially quoted
7898 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7902 int had_quoted_null
;
7905 int pflags
; /* flags passed to param_expand */
7907 int assignoff
; /* If assignment, offset of `=' */
7909 register unsigned char c
; /* Current character. */
7910 int t_index
; /* For calls to string_extract_xxx. */
7916 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
7917 istring
[istring_index
= 0] = '\0';
7918 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
7919 quoted_state
= UNQUOTED
;
7921 string
= word
->word
;
7923 goto finished_with_string
;
7924 /* Don't need the string length for the SADD... and COPY_ macros unless
7925 multibyte characters are possible. */
7926 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
7928 if (contains_dollar_at
)
7929 *contains_dollar_at
= 0;
7933 /* Begin the expansion. */
7939 /* Case on toplevel character. */
7943 goto finished_with_string
;
7947 #if HANDLE_MULTIBYTE
7948 if (MB_CUR_MAX
> 1 && string
[sindex
])
7950 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7955 temp
= (char *)xmalloc (3);
7957 temp
[1] = c
= string
[sindex
];
7968 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
7974 #if defined (PROCESS_SUBSTITUTION)
7975 /* Process substitution. */
7979 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
7981 sindex
--; /* add_character: label increments sindex */
7985 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
7987 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
7990 /* If the process substitution specification is `<()', we want to
7991 open the pipe for writing in the child and produce output; if
7992 it is `>()', we want to open the pipe for reading in the child
7993 and consume input. */
7994 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
7998 goto dollar_add_string
;
8000 #endif /* PROCESS_SUBSTITUTION */
8003 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8004 which are not assignment statements are not expanded. If the
8005 shell isn't in posix mode, though, we perform tilde expansion
8006 on `likely candidate' unquoted assignment statements (flags
8007 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8008 contains an unquoted :~ or =~. Something to think about: we
8009 now have a flag that says to perform tilde expansion on arguments
8010 to `assignment builtins' like declare and export that look like
8011 assignment statements. We now do tilde expansion on such words
8012 even in POSIX mode. */
8013 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
8015 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8016 goto add_ifs_character
;
8020 /* If we're not in posix mode or forcing assignment-statement tilde
8021 expansion, note where the `=' appears in the word and prepare to
8022 do tilde expansion following the first `='. */
8023 if ((word
->flags
& W_ASSIGNMENT
) &&
8024 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8025 assignoff
== -1 && sindex
> 0)
8027 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
8028 word
->flags
|= W_ITILDE
;
8030 else if ((word
->flags
& W_ASSIGNMENT
) &&
8031 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8032 string
[sindex
+1] == '~')
8033 word
->flags
|= W_ITILDE
;
8035 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8036 goto add_ifs_character
;
8041 if (word
->flags
& W_NOTILDE
)
8043 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8044 goto add_ifs_character
;
8049 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
8050 string
[sindex
+1] == '~')
8051 word
->flags
|= W_ITILDE
;
8053 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8054 goto add_ifs_character
;
8059 /* If the word isn't supposed to be tilde expanded, or we're not
8060 at the start of a word or after an unquoted : or = in an
8061 assignment statement, we don't do tilde expansion. */
8062 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
8063 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
8064 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8066 word
->flags
&= ~W_ITILDE
;
8067 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
8068 goto add_ifs_character
;
8073 if (word
->flags
& W_ASSIGNRHS
)
8075 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
8080 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
8082 word
->flags
&= ~W_ITILDE
;
8084 if (temp
&& *temp
&& t_index
> 0)
8086 temp1
= bash_tilde_expand (temp
, tflag
);
8087 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
8091 goto add_character
; /* tilde expansion failed */
8096 goto add_quoted_string
; /* XXX was add_string */
8105 if (expanded_something
)
8106 *expanded_something
= 1;
8109 pflags
= (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0;
8110 if (word
->flags
& W_NOSPLIT2
)
8111 pflags
|= PF_NOSPLIT2
;
8112 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
8113 &has_dollar_at
, "ed_dollar_at
,
8114 &had_quoted_null
, pflags
);
8116 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
8120 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
8121 : &expand_word_fatal
);
8123 if (contains_dollar_at
&& has_dollar_at
)
8124 *contains_dollar_at
= 1;
8126 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
8127 had_quoted_null
= 1;
8130 dispose_word_desc (tword
);
8135 case '`': /* Backquoted command substitution. */
8139 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
8140 /* The test of sindex against t_index is to allow bare instances of
8141 ` to pass through, for backwards compatibility. */
8142 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
8144 if (sindex
- 1 == t_index
)
8149 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
8152 return ((temp
== &extract_string_error
) ? &expand_word_error
8153 : &expand_word_fatal
);
8156 if (expanded_something
)
8157 *expanded_something
= 1;
8159 if (word
->flags
& W_NOCOMSUB
)
8160 /* sindex + 1 because string[sindex] == '`' */
8161 temp1
= substring (string
, t_index
, sindex
+ 1);
8164 de_backslash (temp
);
8165 tword
= command_substitute (temp
, quoted
);
8166 temp1
= tword
? tword
->word
: (char *)NULL
;
8168 dispose_word_desc (tword
);
8172 goto dollar_add_string
;
8176 if (string
[sindex
+ 1] == '\n')
8182 c
= string
[++sindex
];
8184 if (quoted
& Q_HERE_DOCUMENT
)
8186 else if (quoted
& Q_DOUBLE_QUOTES
)
8191 /* From Posix discussion on austin-group list: Backslash escaping
8192 a } in ${...} is removed. Issue 0000221 */
8193 if ((quoted
& Q_DOLBRACE
) && c
== RBRACE
)
8195 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8197 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
8199 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
8204 sindex
--; /* add_character: label increments sindex */
8209 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8214 /* BEFORE jumping here, we need to increment sindex if appropriate */
8215 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8216 DEFAULT_ARRAY_SIZE
);
8217 istring
[istring_index
++] = twochars
[0];
8218 istring
[istring_index
++] = twochars
[1];
8219 istring
[istring_index
] = '\0';
8225 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
8227 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8232 temp
= string_extract_double_quoted (string
, &sindex
, 0);
8234 /* If the quotes surrounded the entire string, then the
8235 whole word was quoted. */
8236 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8242 tword
= alloc_word_desc ();
8245 temp
= (char *)NULL
;
8248 /* Need to get W_HASQUOTEDNULL flag through this function. */
8249 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
8251 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
8255 /* expand_word_internal has already freed temp_word->word
8256 for us because of the way it prints error messages. */
8257 tword
->word
= (char *)NULL
;
8258 dispose_word (tword
);
8262 dispose_word (tword
);
8264 /* "$@" (a double-quoted dollar-at) expands into nothing,
8265 not even a NULL word, when there are no positional
8267 if (list
== 0 && has_dollar_at
)
8273 /* If we get "$@", we know we have expanded something, so we
8274 need to remember it for the final split on $IFS. This is
8275 a special case; it's the only case where a quoted string
8276 can expand into more than one word. It's going to come back
8277 from the above call to expand_word_internal as a list with
8278 a single word, in which all characters are quoted and
8279 separated by blanks. What we want to do is to turn it back
8280 into a list for the next piece of code. */
8282 dequote_list (list
);
8284 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
8285 had_quoted_null
= 1;
8290 if (contains_dollar_at
)
8291 *contains_dollar_at
= 1;
8292 if (expanded_something
)
8293 *expanded_something
= 1;
8298 /* What we have is "". This is a minor optimization. */
8300 list
= (WORD_LIST
*)NULL
;
8303 /* The code above *might* return a list (consider the case of "$@",
8304 where it returns "$1", "$2", etc.). We can't throw away the
8305 rest of the list, and we have to make sure each word gets added
8306 as quoted. We test on tresult->next: if it is non-NULL, we
8307 quote the whole list, save it to a string with string_list, and
8308 add that string. We don't need to quote the results of this
8309 (and it would be wrong, since that would quote the separators
8310 as well), so we go directly to add_string. */
8316 if (quoted_dollar_at
&& (word
->flags
& W_NOSPLIT2
))
8317 temp
= string_list_internal (quote_list (list
), " ");
8320 /* Testing quoted_dollar_at makes sure that "$@" is
8321 split correctly when $IFS does not contain a space. */
8322 temp
= quoted_dollar_at
8323 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
8324 : string_list (quote_list (list
));
8325 dispose_words (list
);
8330 temp
= savestring (list
->word
->word
);
8331 tflag
= list
->word
->flags
;
8332 dispose_words (list
);
8334 /* If the string is not a quoted null string, we want
8335 to remove any embedded unquoted CTLNUL characters.
8336 We do not want to turn quoted null strings back into
8337 the empty string, though. We do this because we
8338 want to remove any quoted nulls from expansions that
8339 contain other characters. For example, if we have
8340 x"$*"y or "x$*y" and there are no positional parameters,
8341 the $* should expand into nothing. */
8342 /* We use the W_HASQUOTEDNULL flag to differentiate the
8343 cases: a quoted null character as above and when
8344 CTLNUL is contained in the (non-null) expansion
8345 of some variable. We use the had_quoted_null flag to
8346 pass the value through this function to its caller. */
8347 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
8348 remove_quoted_nulls (temp
); /* XXX */
8352 temp
= (char *)NULL
;
8354 /* We do not want to add quoted nulls to strings that are only
8355 partially quoted; we can throw them away. */
8356 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
&& (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)))
8364 temp
= quote_string (temp
);
8372 sindex
--; /* add_character: label increments sindex */
8380 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
8382 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8387 temp
= string_extract_single_quoted (string
, &sindex
);
8389 /* If the entire STRING was surrounded by single quotes,
8390 then the string is wholly quoted. */
8391 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8395 /* If all we had was '', it is a null expansion. */
8399 temp
= (char *)NULL
;
8402 remove_quoted_escapes (temp
); /* ??? */
8404 /* We do not want to add quoted nulls to strings that are only
8405 partially quoted; such nulls are discarded. */
8406 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
8409 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8413 sindex
--; /* add_character: label increments sindex */
8417 goto add_quoted_string
;
8422 /* This is the fix for " $@ " */
8424 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
8426 if (string
[sindex
]) /* from old goto dollar_add_string */
8435 #if HANDLE_MULTIBYTE
8441 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8446 twochars
[0] = CTLESC
;
8453 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
8456 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
8457 DEFAULT_ARRAY_SIZE
);
8458 istring
[istring_index
++] = c
;
8459 istring
[istring_index
] = '\0';
8461 /* Next character. */
8466 finished_with_string
:
8467 /* OK, we're ready to return. If we have a quoted string, and
8468 quoted_dollar_at is not set, we do no splitting at all; otherwise
8469 we split on ' '. The routines that call this will handle what to
8470 do if nothing has been expanded. */
8472 /* Partially and wholly quoted strings which expand to the empty
8473 string are retained as an empty arguments. Unquoted strings
8474 which expand to the empty string are discarded. The single
8475 exception is the case of expanding "$@" when there are no
8476 positional parameters. In that case, we discard the expansion. */
8478 /* Because of how the code that handles "" and '' in partially
8479 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8480 if we saw quoting characters, but the expansion was empty.
8481 "" and '' are tossed away before we get to this point when
8482 processing partially quoted strings. This makes "" and $xxx""
8483 equivalent when xxx is unset. We also look to see whether we
8484 saw a quoted null from a ${} expansion and add one back if we
8487 /* If we expand to nothing and there were no single or double quotes
8488 in the word, we throw it away. Otherwise, we return a NULL word.
8489 The single exception is for $@ surrounded by double quotes when
8490 there are no positional parameters. In that case, we also throw
8493 if (*istring
== '\0')
8495 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
8497 istring
[0] = CTLNUL
;
8499 tword
= make_bare_word (istring
);
8500 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8501 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8502 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8503 tword
->flags
|= W_QUOTED
;
8505 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8506 and a double-quoted "$@" appears anywhere in it, then the entire
8508 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8509 list
= (WORD_LIST
*)NULL
;
8513 tword
= make_bare_word (istring
);
8514 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8515 tword
->flags
|= W_QUOTED
;
8516 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8520 list
= (WORD_LIST
*)NULL
;
8523 else if (word
->flags
& W_NOSPLIT
)
8525 tword
= make_bare_word (istring
);
8526 if (word
->flags
& W_ASSIGNMENT
)
8527 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8528 if (word
->flags
& W_COMPASSIGN
)
8529 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8530 if (word
->flags
& W_NOGLOB
)
8531 tword
->flags
|= W_NOGLOB
; /* XXX */
8532 if (word
->flags
& W_NOEXPAND
)
8533 tword
->flags
|= W_NOEXPAND
; /* XXX */
8534 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8535 tword
->flags
|= W_QUOTED
;
8536 if (had_quoted_null
)
8537 tword
->flags
|= W_HASQUOTEDNULL
;
8538 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8544 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8546 /* If we have $@, we need to split the results no matter what. If
8547 IFS is unset or NULL, string_list_dollar_at has separated the
8548 positional parameters with a space, so we split on space (we have
8549 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8550 string_list_dollar_at has separated the positional parameters
8551 with the first character of $IFS, so we split on $IFS. */
8552 if (has_dollar_at
&& ifs_chars
)
8553 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8556 tword
= make_bare_word (istring
);
8557 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8558 tword
->flags
|= W_QUOTED
;
8559 if (word
->flags
& W_ASSIGNMENT
)
8560 tword
->flags
|= W_ASSIGNMENT
;
8561 if (word
->flags
& W_COMPASSIGN
)
8562 tword
->flags
|= W_COMPASSIGN
;
8563 if (word
->flags
& W_NOGLOB
)
8564 tword
->flags
|= W_NOGLOB
;
8565 if (word
->flags
& W_NOEXPAND
)
8566 tword
->flags
|= W_NOEXPAND
;
8567 if (had_quoted_null
)
8568 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8569 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8577 /* **************************************************************** */
8579 /* Functions for Quote Removal */
8581 /* **************************************************************** */
8583 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8584 backslash quoting rules for within double quotes or a here document. */
8586 string_quote_removal (string
, quoted
)
8591 char *r
, *result_string
, *temp
, *send
;
8592 int sindex
, tindex
, dquote
;
8596 /* The result can be no longer than the original string. */
8597 slen
= strlen (string
);
8598 send
= string
+ slen
;
8600 r
= result_string
= (char *)xmalloc (slen
+ 1);
8602 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8607 c
= string
[++sindex
];
8613 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8618 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8622 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8628 tindex
= sindex
+ 1;
8629 temp
= string_extract_single_quoted (string
, &tindex
);
8640 dquote
= 1 - dquote
;
8646 return (result_string
);
8651 /* Perform quote removal on word WORD. This allocates and returns a new
8654 word_quote_removal (word
, quoted
)
8661 t
= string_quote_removal (word
->word
, quoted
);
8662 w
= alloc_word_desc ();
8663 w
->word
= t
? t
: savestring ("");
8667 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8668 the members of the list are treated as if they are surrounded by
8669 double quotes. Return a new list, or NULL if LIST is NULL. */
8671 word_list_quote_removal (list
, quoted
)
8675 WORD_LIST
*result
, *t
, *tresult
, *e
;
8677 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8679 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8681 result
= (WORD_LIST
*) list_append (result
, tresult
);
8684 result
= e
= tresult
;
8697 /*******************************************
8699 * Functions to perform word splitting *
8701 *******************************************/
8711 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8713 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8714 handle multibyte chars in IFS */
8715 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8716 for (t
= ifs_value
; t
&& *t
; t
++)
8722 #if defined (HANDLE_MULTIBYTE)
8725 ifs_firstc
[0] = '\0';
8731 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8732 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8733 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8735 ifs_firstc
[0] = ifs_value
[0];
8736 ifs_firstc
[1] = '\0';
8740 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8743 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8753 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8754 is not quoted. list_string () performs quote removal for us, even if we
8755 don't do any splitting. */
8757 word_split (w
, ifs_chars
)
8767 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8768 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8771 result
= (WORD_LIST
*)NULL
;
8776 /* Perform word splitting on LIST and return the RESULT. It is possible
8777 to return (WORD_LIST *)NULL. */
8779 word_list_split (list
)
8782 WORD_LIST
*result
, *t
, *tresult
, *e
;
8784 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8786 tresult
= word_split (t
->word
, ifs_value
);
8788 result
= e
= tresult
;
8799 /**************************************************
8801 * Functions to expand an entire WORD_LIST *
8803 **************************************************/
8805 /* Do any word-expansion-specific cleanup and jump to top_level */
8807 exp_jump_to_top_level (v
)
8810 set_pipestatus_from_exit (last_command_exit_value
);
8812 /* Cleanup code goes here. */
8813 expand_no_split_dollar_star
= 0; /* XXX */
8814 expanding_redir
= 0;
8815 assigning_in_environment
= 0;
8817 if (parse_and_execute_level
== 0)
8818 top_level_cleanup (); /* from sig.c */
8820 jump_to_top_level (v
);
8823 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8824 ELIST, and set ELIST to the new list. */
8825 #define PREPEND_LIST(nlist, elist) \
8826 do { nlist->next = elist; elist = nlist; } while (0)
8828 /* Separate out any initial variable assignments from TLIST. If set -k has
8829 been executed, remove all assignment statements from TLIST. Initial
8830 variable assignments and other environment assignments are placed
8831 on SUBST_ASSIGN_VARLIST. */
8833 separate_out_assignments (tlist
)
8836 register WORD_LIST
*vp
, *lp
;
8839 return ((WORD_LIST
*)NULL
);
8841 if (subst_assign_varlist
)
8842 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8844 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8847 /* Separate out variable assignments at the start of the command.
8848 Loop invariant: vp->next == lp
8850 lp = list of words left after assignment statements skipped
8851 tlist = original list of words
8853 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8859 /* If lp != tlist, we have some initial assignment statements.
8860 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8861 words and TLIST point to the remaining words. */
8864 subst_assign_varlist
= tlist
;
8865 /* ASSERT(vp->next == lp); */
8866 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8867 tlist
= lp
; /* remainder of word list */
8870 /* vp == end of variable list */
8871 /* tlist == remainder of original word list without variable assignments */
8873 /* All the words in tlist were assignment statements */
8874 return ((WORD_LIST
*)NULL
);
8876 /* ASSERT(tlist != NULL); */
8877 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8879 /* If the -k option is in effect, we need to go through the remaining
8880 words, separate out the assignment words, and place them on
8881 SUBST_ASSIGN_VARLIST. */
8882 if (place_keywords_in_env
)
8884 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8889 /* Loop Invariant: tp->next == lp */
8890 /* Loop postcondition: tlist == word list without assignment statements */
8893 if (lp
->word
->flags
& W_ASSIGNMENT
)
8895 /* Found an assignment statement, add this word to end of
8896 subst_assign_varlist (vp). */
8897 if (!subst_assign_varlist
)
8898 subst_assign_varlist
= vp
= lp
;
8905 /* Remove the word pointed to by LP from TLIST. */
8906 tp
->next
= lp
->next
;
8907 /* ASSERT(vp == lp); */
8908 lp
->next
= (WORD_LIST
*)NULL
;
8921 #define WEXP_VARASSIGN 0x001
8922 #define WEXP_BRACEEXP 0x002
8923 #define WEXP_TILDEEXP 0x004
8924 #define WEXP_PARAMEXP 0x008
8925 #define WEXP_PATHEXP 0x010
8927 /* All of the expansions, including variable assignments at the start of
8929 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8931 /* All of the expansions except variable assignments at the start of
8933 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8935 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8936 expansion, command substitution, arithmetic expansion, word splitting, and
8938 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8940 /* Take the list of words in LIST and do the various substitutions. Return
8941 a new list of words which is the expanded list, and without things like
8942 variable assignments. */
8948 return (expand_word_list_internal (list
, WEXP_ALL
));
8951 /* Same as expand_words (), but doesn't hack variable or environment
8954 expand_words_no_vars (list
)
8957 return (expand_word_list_internal (list
, WEXP_NOVARS
));
8961 expand_words_shellexp (list
)
8964 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
8968 glob_expand_word_list (tlist
, eflags
)
8972 char **glob_array
, *temp_string
;
8973 register int glob_index
;
8974 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
8977 output_list
= disposables
= (WORD_LIST
*)NULL
;
8978 glob_array
= (char **)NULL
;
8981 /* For each word, either globbing is attempted or the word is
8982 added to orig_list. If globbing succeeds, the results are
8983 added to orig_list and the word (tlist) is added to the list
8984 of disposable words. If globbing fails and failed glob
8985 expansions are left unchanged (the shell default), the
8986 original word is added to orig_list. If globbing fails and
8987 failed glob expansions are removed, the original word is
8988 added to the list of disposable words. orig_list ends up
8989 in reverse order and requires a call to REVERSE_LIST to
8990 be set right. After all words are examined, the disposable
8994 /* If the word isn't an assignment and contains an unquoted
8995 pattern matching character, then glob it. */
8996 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
8997 unquoted_glob_pattern_p (tlist
->word
->word
))
8999 glob_array
= shell_glob_filename (tlist
->word
->word
);
9001 /* Handle error cases.
9002 I don't think we should report errors like "No such file
9003 or directory". However, I would like to report errors
9004 like "Read failed". */
9006 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
9008 glob_array
= (char **)xmalloc (sizeof (char *));
9009 glob_array
[0] = (char *)NULL
;
9012 /* Dequote the current word in case we have to use it. */
9013 if (glob_array
[0] == NULL
)
9015 temp_string
= dequote_string (tlist
->word
->word
);
9016 free (tlist
->word
->word
);
9017 tlist
->word
->word
= temp_string
;
9020 /* Make the array into a word list. */
9021 glob_list
= (WORD_LIST
*)NULL
;
9022 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
9024 tword
= make_bare_word (glob_array
[glob_index
]);
9025 tword
->flags
|= W_GLOBEXP
; /* XXX */
9026 glob_list
= make_word_list (tword
, glob_list
);
9031 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
9032 PREPEND_LIST (tlist
, disposables
);
9034 else if (fail_glob_expansion
!= 0)
9036 report_error (_("no match: %s"), tlist
->word
->word
);
9037 exp_jump_to_top_level (DISCARD
);
9039 else if (allow_null_glob_expansion
== 0)
9041 /* Failed glob expressions are left unchanged. */
9042 PREPEND_LIST (tlist
, output_list
);
9046 /* Failed glob expressions are removed. */
9047 PREPEND_LIST (tlist
, disposables
);
9052 /* Dequote the string. */
9053 temp_string
= dequote_string (tlist
->word
->word
);
9054 free (tlist
->word
->word
);
9055 tlist
->word
->word
= temp_string
;
9056 PREPEND_LIST (tlist
, output_list
);
9059 strvec_dispose (glob_array
);
9060 glob_array
= (char **)NULL
;
9066 dispose_words (disposables
);
9069 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9071 return (output_list
);
9074 #if defined (BRACE_EXPANSION)
9076 brace_expand_word_list (tlist
, eflags
)
9080 register char **expansions
;
9082 WORD_LIST
*disposables
, *output_list
, *next
;
9086 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
9090 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9092 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9093 PREPEND_LIST (tlist
, output_list
);
9097 /* Only do brace expansion if the word has a brace character. If
9098 not, just add the word list element to BRACES and continue. In
9099 the common case, at least when running shell scripts, this will
9100 degenerate to a bunch of calls to `mbschr', and then what is
9101 basically a reversal of TLIST into BRACES, which is corrected
9102 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9104 if (mbschr (tlist
->word
->word
, LBRACE
))
9106 expansions
= brace_expand (tlist
->word
->word
);
9108 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
9110 w
= make_word (temp_string
);
9111 /* If brace expansion didn't change the word, preserve
9112 the flags. We may want to preserve the flags
9113 unconditionally someday -- XXX */
9114 if (STREQ (temp_string
, tlist
->word
->word
))
9115 w
->flags
= tlist
->word
->flags
;
9116 output_list
= make_word_list (w
, output_list
);
9117 free (expansions
[eindex
]);
9121 /* Add TLIST to the list of words to be freed after brace
9122 expansion has been performed. */
9123 PREPEND_LIST (tlist
, disposables
);
9126 PREPEND_LIST (tlist
, output_list
);
9130 dispose_words (disposables
);
9133 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9135 return (output_list
);
9139 #if defined (ARRAY_VARS)
9140 /* Take WORD, a compound associative array assignment, and internally run
9141 'declare -A w', where W is the variable name portion of WORD. */
9143 make_internal_declare (word
, option
)
9151 w
= make_word (word
);
9153 t
= assignment (w
->word
, 0);
9156 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
9157 wl
= make_word_list (make_word (option
), wl
);
9159 return (declare_builtin (wl
));
9164 shell_expand_word_list (tlist
, eflags
)
9168 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
9169 int expanded_something
, has_dollar_at
;
9172 /* We do tilde expansion all the time. This is what 1003.2 says. */
9173 new_list
= (WORD_LIST
*)NULL
;
9174 for (orig_list
= tlist
; tlist
; tlist
= next
)
9176 temp_string
= tlist
->word
->word
;
9180 #if defined (ARRAY_VARS)
9181 /* If this is a compound array assignment to a builtin that accepts
9182 such assignments (e.g., `declare'), take the assignment and perform
9183 it separately, handling the semantics of declarations inside shell
9184 functions. This avoids the double-evaluation of such arguments,
9185 because `declare' does some evaluation of compound assignments on
9187 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9191 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
9192 make_internal_declare (tlist
->word
->word
, "-A");
9194 t
= do_word_assignment (tlist
->word
, 0);
9197 last_command_exit_value
= EXECUTION_FAILURE
;
9198 exp_jump_to_top_level (DISCARD
);
9201 /* Now transform the word as ksh93 appears to do and go on */
9202 t
= assignment (tlist
->word
->word
, 0);
9203 tlist
->word
->word
[t
] = '\0';
9204 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
9208 expanded_something
= 0;
9209 expanded
= expand_word_internal
9210 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
9212 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
9214 /* By convention, each time this error is returned,
9215 tlist->word->word has already been freed. */
9216 tlist
->word
->word
= (char *)NULL
;
9218 /* Dispose our copy of the original list. */
9219 dispose_words (orig_list
);
9220 /* Dispose the new list we're building. */
9221 dispose_words (new_list
);
9223 last_command_exit_value
= EXECUTION_FAILURE
;
9224 if (expanded
== &expand_word_error
)
9225 exp_jump_to_top_level (DISCARD
);
9227 exp_jump_to_top_level (FORCE_EOF
);
9230 /* Don't split words marked W_NOSPLIT. */
9231 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
9233 temp_list
= word_list_split (expanded
);
9234 dispose_words (expanded
);
9238 /* If no parameter expansion, command substitution, process
9239 substitution, or arithmetic substitution took place, then
9240 do not do word splitting. We still have to remove quoted
9241 null characters from the result. */
9242 word_list_remove_quoted_nulls (expanded
);
9243 temp_list
= expanded
;
9246 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
9247 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
9251 dispose_words (orig_list
);
9254 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
9259 /* The workhorse for expand_words () and expand_words_no_vars ().
9260 First arg is LIST, a WORD_LIST of words.
9261 Second arg EFLAGS is a flags word controlling which expansions are
9264 This does all of the substitutions: brace expansion, tilde expansion,
9265 parameter expansion, command substitution, arithmetic expansion,
9266 process substitution, word splitting, and pathname expansion, according
9267 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9268 set, or for which no expansion is done, do not undergo word splitting.
9269 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
9271 expand_word_list_internal (list
, eflags
)
9275 WORD_LIST
*new_list
, *temp_list
;
9279 return ((WORD_LIST
*)NULL
);
9281 garglist
= new_list
= copy_word_list (list
);
9282 if (eflags
& WEXP_VARASSIGN
)
9284 garglist
= new_list
= separate_out_assignments (new_list
);
9287 if (subst_assign_varlist
)
9289 /* All the words were variable assignments, so they are placed
9290 into the shell's environment. */
9291 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9293 this_command_name
= (char *)NULL
; /* no arithmetic errors */
9294 tint
= do_word_assignment (temp_list
->word
, 0);
9295 /* Variable assignment errors in non-interactive shells
9296 running in Posix.2 mode cause the shell to exit. */
9299 last_command_exit_value
= EXECUTION_FAILURE
;
9300 if (interactive_shell
== 0 && posixly_correct
)
9301 exp_jump_to_top_level (FORCE_EOF
);
9303 exp_jump_to_top_level (DISCARD
);
9306 dispose_words (subst_assign_varlist
);
9307 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9309 return ((WORD_LIST
*)NULL
);
9313 /* Begin expanding the words that remain. The expansions take place on
9314 things that aren't really variable assignments. */
9316 #if defined (BRACE_EXPANSION)
9317 /* Do brace expansion on this word if there are any brace characters
9319 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
9320 new_list
= brace_expand_word_list (new_list
, eflags
);
9321 #endif /* BRACE_EXPANSION */
9323 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9324 variable substitution, command substitution, arithmetic expansion,
9325 and word splitting. */
9326 new_list
= shell_expand_word_list (new_list
, eflags
);
9328 /* Okay, we're almost done. Now let's just do some filename
9332 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
9333 /* Glob expand the word list unless globbing has been disabled. */
9334 new_list
= glob_expand_word_list (new_list
, eflags
);
9336 /* Dequote the words, because we're not performing globbing. */
9337 new_list
= dequote_list (new_list
);
9340 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
9342 sh_wassign_func_t
*assign_func
;
9343 int is_special_builtin
, is_builtin_or_func
;
9345 /* If the remainder of the words expand to nothing, Posix.2 requires
9346 that the variable and environment assignments affect the shell's
9348 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
9349 tempenv_assign_error
= 0;
9351 is_builtin_or_func
= (new_list
&& new_list
->word
&& (find_shell_builtin (new_list
->word
->word
) || find_function (new_list
->word
->word
)));
9352 /* Posix says that special builtins exit if a variable assignment error
9353 occurs in an assignment preceding it. */
9354 is_special_builtin
= (posixly_correct
&& new_list
&& new_list
->word
&& find_special_builtin (new_list
->word
->word
));
9356 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9358 this_command_name
= (char *)NULL
;
9359 assigning_in_environment
= (assign_func
== assign_in_env
);
9360 tint
= (*assign_func
) (temp_list
->word
, is_builtin_or_func
);
9361 assigning_in_environment
= 0;
9362 /* Variable assignment errors in non-interactive shells running
9363 in Posix.2 mode cause the shell to exit. */
9366 if (assign_func
== do_word_assignment
)
9368 last_command_exit_value
= EXECUTION_FAILURE
;
9369 if (interactive_shell
== 0 && posixly_correct
&& is_special_builtin
)
9370 exp_jump_to_top_level (FORCE_EOF
);
9372 exp_jump_to_top_level (DISCARD
);
9375 tempenv_assign_error
++;
9379 dispose_words (subst_assign_varlist
);
9380 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9384 tint
= list_length (new_list
) + 1;
9385 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
9386 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
9387 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
9388 glob_argv_flags
[tint
] = '\0';