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-2006 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License along
22 with Bash; see the file COPYING. If not, write to the Free Software
23 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
27 #include "bashtypes.h"
29 #include "chartypes.h"
34 #if defined (HAVE_UNISTD_H)
39 #include "posixstat.h"
45 #include "execute_cmd.h"
49 #include "mailcheck.h"
53 #include "builtins/getopt.h"
54 #include "builtins/common.h"
56 #include <tilde/tilde.h>
57 #include <glob/strmatch.h>
63 /* The size that strings change by. */
64 #define DEFAULT_INITIAL_ARRAY_SIZE 112
65 #define DEFAULT_ARRAY_SIZE 128
71 #define VT_ARRAYMEMBER 3
73 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
75 /* Flags for quoted_strchr */
76 #define ST_BACKSL 0x01
77 #define ST_CTLESC 0x02
78 #define ST_SQUOTE 0x04 /* unused yet */
79 #define ST_DQUOTE 0x08 /* unused yet */
81 /* Flags for the string extraction functions. */
82 #define EX_NOALLOC 0x01 /* just skip; don't return substring */
83 #define EX_VARNAME 0x02 /* variable name; for string_extract () */
84 #define EX_REQMATCH 0x04 /* closing/matching delimiter required */
85 #define EX_COMMAND 0x08 /* extracting a shell script/command */
87 /* Flags for the `pflags' argument to param_expand() */
88 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 /* These defs make it easier to use the editor. */
96 /* Evaluates to 1 if C is one of the shell's special parameters whose length
97 can be taken, but is also one of the special expansion characters. */
98 #define VALID_SPECIAL_LENGTH_PARAM(c) \
99 ((c) == '-' || (c) == '?' || (c) == '#')
101 /* Evaluates to 1 if C is one of the shell's special parameters for which an
102 indirect variable reference may be made. */
103 #define VALID_INDIR_PARAM(c) \
104 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
106 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
107 in ${parameter[:]OPword}. */
108 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
110 /* Evaluates to 1 if this is one of the shell's special variables. */
111 #define SPECIAL_VAR(name, wi) \
112 ((DIGIT (*name) && all_digits (name)) || \
113 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
114 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
116 /* An expansion function that takes a string and a quoted flag and returns
117 a WORD_LIST *. Used as the type of the third argument to
118 expand_string_if_necessary(). */
119 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
121 /* Process ID of the last command executed within command substitution. */
122 pid_t last_command_subst_pid
= NO_PID
;
123 pid_t current_command_subst_pid
= NO_PID
;
125 /* Variables used to keep track of the characters in IFS. */
128 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
130 #if defined (HANDLE_MULTIBYTE)
131 unsigned char ifs_firstc
[MB_LEN_MAX
];
132 size_t ifs_firstc_len
;
134 unsigned char ifs_firstc
;
137 /* Extern functions and variables from different files. */
138 extern int last_command_exit_value
, last_command_exit_signal
;
139 extern int subshell_environment
;
140 extern int subshell_level
;
141 extern int eof_encountered
;
142 extern int return_catch_flag
, return_catch_value
;
143 extern pid_t dollar_dollar_pid
;
144 extern int posixly_correct
;
145 extern char *this_command_name
;
146 extern struct fd_bitmap
*current_fds_to_close
;
147 extern int wordexp_only
;
148 extern int expanding_redir
;
149 extern int tempenv_assign_error
;
151 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
152 extern wchar_t *wcsdup
__P((const wchar_t *));
155 /* Non-zero means to allow unmatched globbed filenames to expand to
157 int allow_null_glob_expansion
;
159 /* Non-zero means to throw an error when globbing fails to match anything. */
160 int fail_glob_expansion
;
163 /* Variables to keep track of which words in an expanded word list (the
164 output of expand_word_list_internal) are the result of globbing
165 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
166 (CURRENTLY UNUSED). */
167 char *glob_argv_flags
;
168 static int glob_argv_flags_size
;
171 static WORD_LIST expand_word_error
, expand_word_fatal
;
172 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
173 static char expand_param_error
, expand_param_fatal
;
174 static char extract_string_error
, extract_string_fatal
;
176 /* Tell the expansion functions to not longjmp back to top_level on fatal
177 errors. Enabled when doing completion and prompt string expansion. */
178 static int no_longjmp_on_fatal_error
= 0;
180 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
181 $* on $IFS, primarily when doing assignment statements. */
182 static int expand_no_split_dollar_star
= 0;
184 /* Used to hold a list of variable assignments preceding a command. Global
185 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
187 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
189 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
190 without any leading variable assignments. */
191 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
193 static char *quoted_substring
__P((char *, int, int));
194 static int quoted_strlen
__P((char *));
195 static char *quoted_strchr
__P((char *, int, int));
197 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
198 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
199 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
200 static WORD_LIST
*expand_string_internal
__P((char *, int));
201 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
202 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
204 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
205 static char *dequote_escapes
__P((char *));
206 static char *make_quoted_char
__P((int));
207 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
208 static char *remove_quoted_escapes
__P((char *));
209 static char *remove_quoted_nulls
__P((char *));
211 static int unquoted_substring
__P((char *, char *));
212 static int unquoted_member
__P((int, char *));
214 #if defined (ARRAY_VARS)
215 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
217 static int do_assignment_internal
__P((const WORD_DESC
*, int));
219 static char *string_extract_verbatim
__P((char *, size_t, int *, char *));
220 static char *string_extract
__P((char *, int *, char *, int));
221 static char *string_extract_double_quoted
__P((char *, int *, int));
222 static inline char *string_extract_single_quoted
__P((char *, int *));
223 static inline int skip_single_quoted
__P((const char *, size_t, int));
224 static int skip_double_quoted
__P((char *, size_t, int));
225 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
226 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
228 static char *pos_params
__P((char *, int, int, int));
230 static unsigned char *mb_getcharlens
__P((char *, int));
232 static char *remove_upattern
__P((char *, char *, int));
233 #if defined (HANDLE_MULTIBYTE)
234 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
236 static char *remove_pattern
__P((char *, char *, int));
238 static int match_pattern_char
__P((char *, char *));
239 static int match_upattern
__P((char *, char *, int, char **, char **));
240 #if defined (HANDLE_MULTIBYTE)
241 static int match_pattern_wchar
__P((wchar_t *, wchar_t *));
242 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
244 static int match_pattern
__P((char *, char *, int, char **, char **));
245 static int getpatspec
__P((int, char *));
246 static char *getpattern
__P((char *, int, int));
247 static char *variable_remove_pattern
__P((char *, char *, int, int));
248 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
249 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
251 static char *array_remove_pattern
__P((ARRAY
*, char *, int, char *, int));
253 static char *parameter_brace_remove_pattern
__P((char *, char *, char *, int, int));
255 static char *process_substitute
__P((char *, int));
257 static char *read_comsub
__P((int, int));
260 static arrayind_t array_length_reference
__P((char *));
263 static int valid_brace_expansion_word
__P((char *, int));
264 static int chk_atstar
__P((char *, int, int *, int *));
265 static int chk_arithsub
__P((const char *, int));
267 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int));
268 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
269 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
270 static void parameter_brace_expand_error
__P((char *, char *));
272 static int valid_length_expression
__P((char *));
273 static intmax_t parameter_brace_expand_length
__P((char *));
275 static char *skiparith
__P((char *, int));
276 static int verify_substring_values
__P((char *, char *, int, intmax_t *, intmax_t *));
277 static int get_var_and_type
__P((char *, char *, int, SHELL_VAR
**, char **));
278 static char *mb_substring
__P((char *, int, int));
279 static char *parameter_brace_substring
__P((char *, char *, char *, int));
281 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
283 static char *parameter_brace_patsub
__P((char *, char *, char *, int));
285 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int *, int *));
286 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
288 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
290 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
292 static void exp_jump_to_top_level
__P((int));
294 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
295 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
296 #ifdef BRACE_EXPANSION
297 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
299 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
300 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
302 /* **************************************************************** */
304 /* Utility Functions */
306 /* **************************************************************** */
308 #ifdef INCLUDE_UNUSED
310 quoted_substring (string
, start
, end
)
315 register char *result
, *s
, *r
;
319 /* Move to string[start], skipping quoted characters. */
320 for (s
= string
, l
= 0; *s
&& l
< start
; )
332 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
334 /* Copy LEN characters, including quote characters. */
336 for (l
= 0; l
< len
; s
++)
350 #ifdef INCLUDE_UNUSED
351 /* Return the length of S, skipping over quoted characters */
375 /* Find the first occurrence of character C in string S, obeying shell
376 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
377 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
378 escaped with CTLESC are skipped. */
380 quoted_strchr (s
, c
, flags
)
388 if (((flags
& ST_BACKSL
) && *p
== '\\')
389 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
393 return ((char *)NULL
);
399 return ((char *)NULL
);
402 /* Return 1 if CHARACTER appears in an unquoted portion of
403 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
405 unquoted_member (character
, string
)
413 slen
= strlen (string
);
415 while (c
= string
[sindex
])
423 ADVANCE_CHAR (string
, slen
, sindex
);
429 ADVANCE_CHAR (string
, slen
, sindex
);
433 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
437 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
444 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
446 unquoted_substring (substr
, string
)
447 char *substr
, *string
;
450 int sindex
, c
, sublen
;
453 if (substr
== 0 || *substr
== '\0')
456 slen
= strlen (string
);
457 sublen
= strlen (substr
);
458 for (sindex
= 0; c
= string
[sindex
]; )
460 if (STREQN (string
+ sindex
, substr
, sublen
))
469 ADVANCE_CHAR (string
, slen
, sindex
);
473 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
477 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
481 ADVANCE_CHAR (string
, slen
, sindex
);
488 /* Most of the substitutions must be done in parallel. In order
489 to avoid using tons of unclear goto's, I have some functions
490 for manipulating malloc'ed strings. They all take INDX, a
491 pointer to an integer which is the offset into the string
492 where manipulation is taking place. They also take SIZE, a
493 pointer to an integer which is the current length of the
494 character array for this string. */
496 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
497 of space allocated to TARGET. SOURCE can be NULL, in which
498 case nothing happens. Gets rid of SOURCE by freeing it.
499 Returns TARGET in case the location has changed. */
501 sub_append_string (source
, target
, indx
, size
)
502 char *source
, *target
;
509 srclen
= STRLEN (source
);
510 if (srclen
>= (int)(*size
- *indx
))
513 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
514 target
= (char *)xrealloc (target
, (*size
= n
));
517 FASTCOPY (source
, target
+ *indx
, srclen
);
519 target
[*indx
] = '\0';
528 /* Append the textual representation of NUMBER to TARGET.
529 INDX and SIZE are as in SUB_APPEND_STRING. */
531 sub_append_number (number
, target
, indx
, size
)
538 temp
= itos (number
);
539 return (sub_append_string (temp
, target
, indx
, size
));
543 /* Extract a substring from STRING, starting at SINDEX and ending with
544 one of the characters in CHARLIST. Don't make the ending character
545 part of the string. Leave SINDEX pointing at the ending character.
546 Understand about backslashes in the string. If (flags & EX_VARNAME)
547 is non-zero, and array variables have been compiled into the shell,
548 everything between a `[' and a corresponding `]' is skipped over.
549 If (flags & EX_NOALLOC) is non-zero, don't return the substring, just
550 update SINDEX. If (flags & EX_REQMATCH) is non-zero, the string must
551 contain a closing character from CHARLIST. */
553 string_extract (string
, sindex
, charlist
, flags
)
565 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
568 while (c
= string
[i
])
577 #if defined (ARRAY_VARS)
578 else if ((flags
& EX_VARNAME
) && c
== '[')
581 /* If this is an array subscript, skip over it and continue. */
582 ni
= skipsubscript (string
, i
);
583 if (string
[ni
] == ']')
587 else if (MEMBER (c
, charlist
))
593 ADVANCE_CHAR (string
, slen
, i
);
596 /* If we had to have a matching delimiter and didn't find one, return an
597 error and let the caller deal with it. */
598 if ((flags
& EX_REQMATCH
) && found
== 0)
601 return (&extract_string_error
);
604 temp
= (flags
& EX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
610 /* Extract the contents of STRING as if it is enclosed in double quotes.
611 SINDEX, when passed in, is the offset of the character immediately
612 following the opening double quote; on exit, SINDEX is left pointing after
613 the closing double quote. If STRIPDQ is non-zero, unquoted double
614 quotes are stripped and the string is terminated by a null byte.
615 Backslashes between the embedded double quotes are processed. If STRIPDQ
616 is zero, an unquoted `"' terminates the string. */
618 string_extract_double_quoted (string
, sindex
, stripdq
)
620 int *sindex
, stripdq
;
626 char *temp
, *ret
; /* The new string we return. */
627 int pass_next
, backquote
, si
; /* State variables for the machine. */
631 slen
= strlen (string
+ *sindex
) + *sindex
;
632 send
= string
+ slen
;
634 pass_next
= backquote
= dquote
= 0;
635 temp
= (char *)xmalloc (1 + slen
- *sindex
);
639 while (c
= string
[i
])
641 /* Process a character that was quoted by a backslash. */
646 ``The backslash shall retain its special meaning as an escape
647 character only when followed by one of the characters:
650 If STRIPDQ is zero, we handle the double quotes here and let
651 expand_word_internal handle the rest. If STRIPDQ is non-zero,
652 we have already been through one round of backslash stripping,
653 and want to strip these backslashes only if DQUOTE is non-zero,
654 indicating that we are inside an embedded double-quoted string. */
656 /* If we are in an embedded quoted string, then don't strip
657 backslashes before characters for which the backslash
658 retains its special meaning, but remove backslashes in
659 front of other characters. If we are not in an
660 embedded quoted string, don't strip backslashes at all.
661 This mess is necessary because the string was already
662 surrounded by double quotes (and sh has some really weird
664 The returned string will be run through expansion as if
665 it were double-quoted. */
666 if ((stripdq
== 0 && c
!= '"') ||
667 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
672 COPY_CHAR_I (temp
, j
, string
, send
, i
);
676 /* A backslash protects the next character. The code just above
677 handles preserving the backslash in front of any character but
686 /* Inside backquotes, ``the portion of the quoted string from the
687 initial backquote and the characters up to the next backquote
688 that is not preceded by a backslash, having escape characters
689 removed, defines that command''. */
707 /* Pass everything between `$(' and the matching `)' or a quoted
708 ${ ... } pair through according to the Posix.2 specification. */
709 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
714 if (string
[i
+ 1] == LPAREN
)
715 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_COMMAND
); /*)*/
717 ret
= extract_dollar_brace_string (string
, &si
, 1, 0);
720 temp
[j
++] = string
[i
+ 1];
722 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
724 if (ret
== 0 && no_longjmp_on_fatal_error
)
727 ret
= string
+ i
+ 2;
730 for (t
= 0; ret
[t
]; t
++, j
++)
732 temp
[j
] = string
[si
];
747 /* Add any character but a double quote to the quoted string we're
750 goto add_one_character
;
764 /* Point to after the closing quote. */
772 /* This should really be another option to string_extract_double_quoted. */
774 skip_double_quoted (string
, slen
, sind
)
781 int pass_next
, backquote
, si
;
784 pass_next
= backquote
= 0;
786 while (c
= string
[i
])
791 ADVANCE_CHAR (string
, slen
, i
);
804 ADVANCE_CHAR (string
, slen
, i
);
813 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
816 if (string
[i
+ 1] == LPAREN
)
817 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_NOALLOC
|EX_COMMAND
); /* ) */
819 ret
= extract_dollar_brace_string (string
, &si
, 0, EX_NOALLOC
);
826 ADVANCE_CHAR (string
, slen
, i
);
839 /* Extract the contents of STRING as if it is enclosed in single quotes.
840 SINDEX, when passed in, is the offset of the character immediately
841 following the opening single quote; on exit, SINDEX is left pointing after
842 the closing single quote. */
844 string_extract_single_quoted (string
, sindex
)
853 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
854 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
856 while (string
[i
] && string
[i
] != '\'')
857 ADVANCE_CHAR (string
, slen
, i
);
859 t
= substring (string
, *sindex
, i
);
869 skip_single_quoted (string
, slen
, sind
)
878 while (string
[c
] && string
[c
] != '\'')
879 ADVANCE_CHAR (string
, slen
, c
);
886 /* Just like string_extract, but doesn't hack backslashes or any of
887 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
889 string_extract_verbatim (string
, slen
, sindex
, charlist
)
895 register int i
= *sindex
;
896 #if defined (HANDLE_MULTIBYTE)
904 if (charlist
[0] == '\'' && charlist
[1] == '\0')
906 temp
= string_extract_single_quoted (string
, sindex
);
907 --*sindex
; /* leave *sindex at separator character */
913 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
914 this only if MB_CUR_MAX > 1. */
915 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
917 #if defined (HANDLE_MULTIBYTE)
918 clen
= strlen (charlist
);
921 while (c
= string
[i
])
923 #if defined (HANDLE_MULTIBYTE)
932 #if defined (HANDLE_MULTIBYTE)
933 mblength
= MBLEN (string
+ i
, slen
- i
);
937 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
938 if (MB_INVALIDCH (mblength
))
940 if (MEMBER (c
, charlist
))
948 len
= mbstowcs (wcharlist
, charlist
, 0);
951 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
952 mbstowcs (wcharlist
, charlist
, len
+ 1);
955 if (wcschr (wcharlist
, wc
))
961 if (MEMBER (c
, charlist
))
964 ADVANCE_CHAR (string
, slen
, i
);
967 #if defined (HANDLE_MULTIBYTE)
971 temp
= substring (string
, *sindex
, i
);
977 /* Extract the $( construct in STRING, and return a new string.
978 Start extracting at (SINDEX) as if we had just seen "$(".
979 Make (SINDEX) get the position of the matching ")". ) */
981 extract_command_subst (string
, sindex
)
985 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", EX_COMMAND
)); /*)*/
988 /* Extract the $[ construct in STRING, and return a new string. (])
989 Start extracting at (SINDEX) as if we had just seen "$[".
990 Make (SINDEX) get the position of the matching "]". */
992 extract_arithmetic_subst (string
, sindex
)
996 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
999 #if defined (PROCESS_SUBSTITUTION)
1000 /* Extract the <( or >( construct in STRING, and return a new string.
1001 Start extracting at (SINDEX) as if we had just seen "<(".
1002 Make (SINDEX) get the position of the matching ")". */ /*))*/
1004 extract_process_subst (string
, starter
, sindex
)
1009 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", 0));
1011 #endif /* PROCESS_SUBSTITUTION */
1013 #if defined (ARRAY_VARS)
1014 /* This can be fooled by unquoted right parens in the passed string. If
1015 each caller verifies that the last character in STRING is a right paren,
1016 we don't even need to call extract_delimited_string. */
1018 extract_array_assignment_list (string
, sindex
)
1025 slen
= strlen (string
); /* ( */
1026 if (string
[slen
- 1] == ')')
1028 ret
= substring (string
, *sindex
, slen
- 1);
1036 /* Extract and create a new string from the contents of STRING, a
1037 character string delimited with OPENER and CLOSER. SINDEX is
1038 the address of an int describing the current offset in STRING;
1039 it should point to just after the first OPENER found. On exit,
1040 SINDEX gets the position of the last character of the matching CLOSER.
1041 If OPENER is more than a single character, ALT_OPENER, if non-null,
1042 contains a character string that can also match CLOSER and thus
1043 needs to be skipped. */
1045 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1048 char *opener
, *alt_opener
, *closer
;
1054 int pass_character
, nesting_level
, in_comment
;
1055 int len_closer
, len_opener
, len_alt_opener
;
1058 slen
= strlen (string
+ *sindex
) + *sindex
;
1059 len_opener
= STRLEN (opener
);
1060 len_alt_opener
= STRLEN (alt_opener
);
1061 len_closer
= STRLEN (closer
);
1063 pass_character
= in_comment
= 0;
1068 while (nesting_level
)
1079 ADVANCE_CHAR (string
, slen
, i
);
1083 if (pass_character
) /* previous char was backslash */
1086 ADVANCE_CHAR (string
, slen
, i
);
1090 /* Not exactly right yet; should handle shell metacharacters and
1091 multibyte characters, too. */
1092 if ((flags
& EX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || whitespace (string
[i
- 1])))
1095 ADVANCE_CHAR (string
, slen
, i
);
1099 if (c
== CTLESC
|| c
== '\\')
1106 /* Process a nested OPENER. */
1107 if (STREQN (string
+ i
, opener
, len_opener
))
1109 si
= i
+ len_opener
;
1110 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|EX_NOALLOC
);
1115 /* Process a nested ALT_OPENER */
1116 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1118 si
= i
+ len_alt_opener
;
1119 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|EX_NOALLOC
);
1124 /* If the current substring terminates the delimited string, decrement
1125 the nesting level. */
1126 if (STREQN (string
+ i
, closer
, len_closer
))
1128 i
+= len_closer
- 1; /* move to last byte of the closer */
1130 if (nesting_level
== 0)
1134 /* Pass old-style command substitution through verbatim. */
1138 t
= string_extract (string
, &si
, "`", flags
|EX_NOALLOC
);
1143 /* Pass single-quoted and double-quoted strings through verbatim. */
1144 if (c
== '\'' || c
== '"')
1147 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1148 : skip_double_quoted (string
, slen
, si
);
1152 /* move past this character, which was not special. */
1153 ADVANCE_CHAR (string
, slen
, i
);
1156 if (c
== 0 && nesting_level
)
1158 if (no_longjmp_on_fatal_error
== 0)
1160 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1161 last_command_exit_value
= EXECUTION_FAILURE
;
1162 exp_jump_to_top_level (DISCARD
);
1167 return (char *)NULL
;
1171 si
= i
- *sindex
- len_closer
+ 1;
1172 if (flags
& EX_NOALLOC
)
1173 result
= (char *)NULL
;
1176 result
= (char *)xmalloc (1 + si
);
1177 strncpy (result
, string
+ *sindex
, si
);
1185 /* Extract a parameter expansion expression within ${ and } from STRING.
1186 Obey the Posix.2 rules for finding the ending `}': count braces while
1187 skipping over enclosed quoted strings and command substitutions.
1188 SINDEX is the address of an int describing the current offset in STRING;
1189 it should point to just after the first `{' found. On exit, SINDEX
1190 gets the position of the matching `}'. QUOTED is non-zero if this
1191 occurs inside double quotes. */
1192 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1194 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1196 int *sindex
, quoted
, flags
;
1200 int pass_character
, nesting_level
, si
;
1206 slen
= strlen (string
+ *sindex
) + *sindex
;
1209 while (c
= string
[i
])
1214 ADVANCE_CHAR (string
, slen
, i
);
1218 /* CTLESCs and backslashes quote the next character. */
1219 if (c
== CTLESC
|| c
== '\\')
1226 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1236 if (nesting_level
== 0)
1242 /* Pass the contents of old-style command substitutions through
1247 t
= string_extract (string
, &si
, "`", flags
|EX_NOALLOC
);
1252 /* Pass the contents of new-style command substitutions and
1253 arithmetic substitutions through verbatim. */
1254 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1257 t
= extract_delimited_string (string
, &si
, "$(", "(", ")", flags
|EX_NOALLOC
|EX_COMMAND
); /*)*/
1262 /* Pass the contents of single-quoted and double-quoted strings
1263 through verbatim. */
1264 if (c
== '\'' || c
== '"')
1267 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1268 : skip_double_quoted (string
, slen
, si
);
1269 /* skip_XXX_quoted leaves index one past close quote */
1273 /* move past this character, which was not special. */
1274 ADVANCE_CHAR (string
, slen
, i
);
1277 if (c
== 0 && nesting_level
)
1279 if (no_longjmp_on_fatal_error
== 0)
1281 report_error ("bad substitution: no closing `%s' in %s", "}", string
);
1282 last_command_exit_value
= EXECUTION_FAILURE
;
1283 exp_jump_to_top_level (DISCARD
);
1288 return ((char *)NULL
);
1292 result
= (flags
& EX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1298 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1299 STRING, and returns a pointer to it. */
1301 de_backslash (string
)
1304 register size_t slen
;
1305 register int i
, j
, prev_i
;
1308 slen
= strlen (string
);
1311 /* Loop copying string[i] to string[j], i >= j. */
1314 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1315 string
[i
+ 1] == '$'))
1318 ADVANCE_CHAR (string
, slen
, i
);
1320 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1331 /* Replace instances of \! in a string with !. */
1333 unquote_bang (string
)
1337 register char *temp
;
1339 temp
= (char *)xmalloc (1 + strlen (string
));
1341 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1343 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1349 strcpy (string
, temp
);
1354 #if defined (READLINE)
1355 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1356 an unclosed quoted string), or if the character at EINDEX is quoted
1357 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1358 single and double-quoted string parsing functions should not return an
1359 error if there are unclosed quotes or braces. The characters that this
1360 recognizes need to be the same as the contents of
1361 rl_completer_quote_characters. */
1363 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1366 char_is_quoted (string
, eindex
)
1370 int i
, pass_next
, c
;
1374 slen
= strlen (string
);
1375 no_longjmp_on_fatal_error
= 1;
1384 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1386 ADVANCE_CHAR (string
, slen
, i
);
1395 else if (c
== '\'' || c
== '"')
1397 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1398 : skip_double_quoted (string
, slen
, ++i
);
1401 /* no increment, the skip_xxx functions go one past end */
1404 ADVANCE_CHAR (string
, slen
, i
);
1411 unclosed_pair (string
, eindex
, openstr
)
1416 int i
, pass_next
, openc
, olen
;
1420 slen
= strlen (string
);
1421 olen
= strlen (openstr
);
1422 i
= pass_next
= openc
= 0;
1428 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1430 ADVANCE_CHAR (string
, slen
, i
);
1433 else if (string
[i
] == '\\')
1439 else if (STREQN (string
+ i
, openstr
, olen
))
1444 else if (string
[i
] == '\'' || string
[i
] == '"')
1446 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1447 : skip_double_quoted (string
, slen
, i
);
1452 ADVANCE_CHAR (string
, slen
, i
);
1457 /* Skip characters in STRING until we find a character in DELIMS, and return
1458 the index of that character. START is the index into string at which we
1459 begin. This is similar in spirit to strpbrk, but it returns an index into
1460 STRING and takes a starting index. This little piece of code knows quite
1461 a lot of shell syntax. It's very similar to skip_double_quoted and other
1462 functions of that ilk. */
1464 skip_to_delim (string
, start
, delims
)
1469 int i
, pass_next
, backq
, si
, c
;
1474 slen
= strlen (string
+ start
) + start
;
1475 no_longjmp_on_fatal_error
= 1;
1477 pass_next
= backq
= 0;
1478 while (c
= string
[i
])
1485 ADVANCE_CHAR (string
, slen
, i
);
1498 ADVANCE_CHAR (string
, slen
, i
);
1507 else if (c
== '\'' || c
== '"')
1509 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1510 : skip_double_quoted (string
, slen
, ++i
);
1511 /* no increment, the skip functions increment past the closing quote. */
1513 else if (c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1516 if (string
[si
] == '\0')
1519 if (string
[i
+1] == LPAREN
)
1520 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_NOALLOC
|EX_COMMAND
); /* ) */
1522 temp
= extract_dollar_brace_string (string
, &si
, 0, EX_NOALLOC
);
1524 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1529 else if (member (c
, delims
))
1532 ADVANCE_CHAR (string
, slen
, i
);
1538 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1539 individual words. If DELIMS is NULL, the current value of $IFS is used
1540 to split the string, and the function follows the shell field splitting
1541 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1542 gets the number of words in the returned list. CWP, if non-NULL, gets
1543 the index of the word containing SENTINEL. Non-whitespace chars in
1544 DELIMS delimit separate fields. */
1546 split_at_delims (string
, slen
, delims
, sentinel
, nwp
, cwp
)
1553 int ts
, te
, i
, nw
, cw
, ifs_split
;
1554 char *token
, *d
, *d2
;
1555 WORD_LIST
*ret
, *tl
;
1557 if (string
== 0 || *string
== '\0')
1563 return ((WORD_LIST
*)NULL
);
1566 d
= (delims
== 0) ? ifs_value
: delims
;
1567 ifs_split
= delims
== 0;
1569 /* Make d2 the non-whitespace characters in delims */
1574 #if defined (HANDLE_MULTIBYTE)
1575 size_t mblength
= 1;
1579 slength
= strlen (delims
);
1580 d2
= (char *)xmalloc (slength
+ 1);
1584 #if defined (HANDLE_MULTIBYTE)
1585 mbstate_t state_bak
;
1587 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1588 if (MB_INVALIDCH (mblength
))
1590 else if (mblength
> 1)
1592 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1595 slength
-= mblength
;
1599 if (whitespace (delims
[i
]) == 0)
1600 d2
[ts
++] = delims
[i
];
1608 ret
= (WORD_LIST
*)NULL
;
1610 /* Remove sequences of whitspace characters at the start of the string, as
1611 long as those characters are delimiters. */
1612 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1614 if (string
[i
] == '\0')
1622 te
= skip_to_delim (string
, ts
, d
);
1624 /* If we have a non-whitespace delimiter character, use it to make a
1625 separate field. This is just about what $IFS splitting does and
1626 is closer to the behavior of the shell parser. */
1627 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
1630 /* If we're using IFS splitting, the non-whitespace delimiter char
1631 and any additional IFS whitespace delimits a field. */
1633 while (member (string
[te
], d
) && spctabnl (string
[te
]))
1636 while (member (string
[te
], d2
))
1640 token
= substring (string
, ts
, te
);
1642 ret
= add_string_to_list (token
, ret
);
1646 if (sentinel
>= ts
&& sentinel
<= te
)
1649 /* If the cursor is at whitespace just before word start, set the
1650 sentinel word to the current word. */
1651 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
1654 /* If the cursor is at whitespace between two words, make a new, empty
1655 word, add it before (well, after, since the list is in reverse order)
1656 the word we just added, and set the current word to that one. */
1657 if (cwp
&& cw
== -1 && sentinel
< ts
)
1659 tl
= make_word_list (make_word (""), ret
->next
);
1665 if (string
[te
] == 0)
1669 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
1678 /* Special case for SENTINEL at the end of STRING. If we haven't found
1679 the word containing SENTINEL yet, and the index we're looking for is at
1680 the end of STRING, add an additional null argument and set the current
1681 word pointer to that. */
1682 if (cwp
&& cw
== -1 && sentinel
>= slen
)
1684 if (whitespace (string
[sentinel
- 1]))
1687 ret
= add_string_to_list (token
, ret
);
1698 return (REVERSE_LIST (ret
, WORD_LIST
*));
1700 #endif /* READLINE */
1704 /* Extract the name of the variable to bind to from the assignment string. */
1706 assignment_name (string
)
1712 offset
= assignment (string
, 0);
1714 return (char *)NULL
;
1715 temp
= substring (string
, 0, offset
);
1720 /* **************************************************************** */
1722 /* Functions to convert strings to WORD_LISTs and vice versa */
1724 /* **************************************************************** */
1726 /* Return a single string of all the words in LIST. SEP is the separator
1727 to put between individual elements of LIST in the output string. */
1729 string_list_internal (list
, sep
)
1733 register WORD_LIST
*t
;
1735 int word_len
, sep_len
, result_size
;
1738 return ((char *)NULL
);
1740 /* Short-circuit quickly if we don't need to separate anything. */
1741 if (list
->next
== 0)
1742 return (savestring (list
->word
->word
));
1744 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1745 sep_len
= STRLEN (sep
);
1748 for (t
= list
; t
; t
= t
->next
)
1751 result_size
+= sep_len
;
1752 result_size
+= strlen (t
->word
->word
);
1755 r
= result
= (char *)xmalloc (result_size
+ 1);
1757 for (t
= list
; t
; t
= t
->next
)
1759 if (t
!= list
&& sep_len
)
1763 FASTCOPY (sep
, r
, sep_len
);
1770 word_len
= strlen (t
->word
->word
);
1771 FASTCOPY (t
->word
->word
, r
, word_len
);
1779 /* Return a single string of all the words present in LIST, separating
1780 each word with a space. */
1785 return (string_list_internal (list
, " "));
1788 /* Return a single string of all the words present in LIST, obeying the
1789 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1790 expansion [of $*] appears within a double quoted string, it expands
1791 to a single field with the value of each parameter separated by the
1792 first character of the IFS variable, or by a <space> if IFS is unset." */
1794 string_list_dollar_star (list
)
1798 #if defined (HANDLE_MULTIBYTE)
1799 # if defined (__GNUC__)
1800 char sep
[MB_CUR_MAX
+ 1];
1808 #if defined (HANDLE_MULTIBYTE)
1809 # if !defined (__GNUC__)
1810 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
1811 # endif /* !__GNUC__ */
1812 if (ifs_firstc_len
== 1)
1814 sep
[0] = ifs_firstc
[0];
1819 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
1820 sep
[ifs_firstc_len
] = '\0';
1823 sep
[0] = ifs_firstc
;
1827 ret
= string_list_internal (list
, sep
);
1828 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1834 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1835 is non-zero, the $@ appears within double quotes, and we should quote
1836 the list before converting it into a string. If IFS is unset, and the
1837 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1838 in the words in the list, because the default value of $IFS is
1839 <space><tab><newline>, IFS characters in the words in the list should
1840 also be split. If IFS is null, and the word is not quoted, we need
1841 to quote the words in the list to preserve the positional parameters
1844 string_list_dollar_at (list
, quoted
)
1849 #if defined (HANDLE_MULTIBYTE)
1850 # if defined (__GNUC__)
1851 char sep
[MB_CUR_MAX
+ 1];
1854 # endif /* !__GNUC__ */
1860 /* XXX this could just be ifs = ifs_value; */
1861 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
1863 #if defined (HANDLE_MULTIBYTE)
1864 # if !defined (__GNUC__)
1865 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
1866 # endif /* !__GNUC__ */
1869 if (ifs_firstc_len
== 1)
1871 sep
[0] = ifs_firstc
[0];
1876 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
1877 sep
[ifs_firstc_len
] = '\0';
1886 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
1890 tlist
= ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (ifs
&& *ifs
== 0))
1892 : list_quote_escapes (list
);
1894 ret
= string_list_internal (tlist
, sep
);
1895 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1901 /* Return the list of words present in STRING. Separate the string into
1902 words at any of the characters found in SEPARATORS. If QUOTED is
1903 non-zero then word in the list will have its quoted flag set, otherwise
1904 the quoted flag is left as make_word () deemed fit.
1906 This obeys the P1003.2 word splitting semantics. If `separators' is
1907 exactly <space><tab><newline>, then the splitting algorithm is that of
1908 the Bourne shell, which treats any sequence of characters from `separators'
1909 as a delimiter. If IFS is unset, which results in `separators' being set
1910 to "", no splitting occurs. If separators has some other value, the
1911 following rules are applied (`IFS white space' means zero or more
1912 occurrences of <space>, <tab>, or <newline>, as long as those characters
1913 are in `separators'):
1915 1) IFS white space is ignored at the start and the end of the
1917 2) Each occurrence of a character in `separators' that is not
1918 IFS white space, along with any adjacent occurrences of
1919 IFS white space delimits a field.
1920 3) Any nonzero-length sequence of IFS white space delimits a field.
1923 /* BEWARE! list_string strips null arguments. Don't call it twice and
1924 expect to have "" preserved! */
1926 /* This performs word splitting and quoted null character removal on
1929 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1930 : (c) == (separators)[0]) \
1934 list_string (string
, separators
, quoted
)
1935 register char *string
, *separators
;
1940 char *current_word
, *s
;
1941 int sindex
, sh_style_split
, whitesep
;
1944 if (!string
|| !*string
)
1945 return ((WORD_LIST
*)NULL
);
1947 sh_style_split
= separators
&& separators
[0] == ' ' &&
1948 separators
[1] == '\t' &&
1949 separators
[2] == '\n' &&
1950 separators
[3] == '\0';
1953 /* Remove sequences of whitespace at the beginning of STRING, as
1954 long as those characters appear in IFS. Do not do this if
1955 STRING is quoted or if there are no separator characters. */
1956 if (!quoted
|| !separators
|| !*separators
)
1958 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
1961 return ((WORD_LIST
*)NULL
);
1966 /* OK, now STRING points to a word that does not begin with white space.
1967 The splitting algorithm is:
1968 extract a word, stopping at a separator
1969 skip sequences of spc, tab, or nl as long as they are separators
1970 This obeys the field splitting rules in Posix.2. */
1971 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
1972 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
1974 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
1975 unless multibyte chars are possible. */
1976 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
);
1977 if (current_word
== 0)
1980 /* If we have a quoted empty string, add a quoted null argument. We
1981 want to preserve the quoted null character iff this is a quoted
1982 empty string; otherwise the quoted null characters are removed
1984 if (QUOTED_NULL (current_word
))
1986 t
= alloc_word_desc ();
1987 t
->word
= make_quoted_char ('\0');
1988 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
1989 result
= make_word_list (t
, result
);
1991 else if (current_word
[0] != '\0')
1993 /* If we have something, then add it regardless. However,
1994 perform quoted null character removal on the current word. */
1995 remove_quoted_nulls (current_word
);
1996 result
= add_string_to_list (current_word
, result
);
1997 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
1998 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
1999 result
->word
->flags
|= W_QUOTED
;
2002 /* If we're not doing sequences of separators in the traditional
2003 Bourne shell style, then add a quoted null argument. */
2004 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2006 t
= alloc_word_desc ();
2007 t
->word
= make_quoted_char ('\0');
2008 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2009 result
= make_word_list (t
, result
);
2012 free (current_word
);
2014 /* Note whether or not the separator is IFS whitespace, used later. */
2015 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2017 /* Move past the current separator character. */
2021 ADVANCE_CHAR (string
, slen
, sindex
);
2024 /* Now skip sequences of space, tab, or newline characters if they are
2025 in the list of separators. */
2026 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2029 /* If the first separator was IFS whitespace and the current character
2030 is a non-whitespace IFS character, it should be part of the current
2031 field delimiter, not a separate delimiter that would result in an
2032 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2033 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2036 /* An IFS character that is not IFS white space, along with any
2037 adjacent IFS white space, shall delimit a field. (SUSv3) */
2038 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2042 return (REVERSE_LIST (result
, WORD_LIST
*));
2045 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2046 ENDPTR is set to the first character after the word. This is used by
2047 the `read' builtin. This is never called with SEPARATORS != $IFS;
2048 it should be simplified.
2050 XXX - this function is very similar to list_string; they should be
2053 get_word_from_string (stringp
, separators
, endptr
)
2054 char **stringp
, *separators
, **endptr
;
2058 int sindex
, sh_style_split
, whitesep
;
2061 if (!stringp
|| !*stringp
|| !**stringp
)
2062 return ((char *)NULL
);
2066 sh_style_split
= separators
&& separators
[0] == ' ' &&
2067 separators
[1] == '\t' &&
2068 separators
[2] == '\n' &&
2069 separators
[3] == '\0';
2073 /* Remove sequences of whitespace at the beginning of STRING, as
2074 long as those characters appear in IFS. */
2075 if (sh_style_split
|| !separators
|| !*separators
)
2077 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2079 /* If the string is nothing but whitespace, update it and return. */
2085 return ((char *)NULL
);
2089 /* OK, S points to a word that does not begin with white space.
2090 Now extract a word, stopping at a separator, save a pointer to
2091 the first character after the word, then skip sequences of spc,
2092 tab, or nl as long as they are separators.
2094 This obeys the field splitting rules in Posix.2. */
2096 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2097 unless multibyte chars are possible. */
2098 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2099 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
);
2101 /* Set ENDPTR to the first character after the end of the word. */
2103 *endptr
= s
+ sindex
;
2105 /* Note whether or not the separator is IFS whitespace, used later. */
2106 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2108 /* Move past the current separator character. */
2112 ADVANCE_CHAR (s
, slen
, sindex
);
2115 /* Now skip sequences of space, tab, or newline characters if they are
2116 in the list of separators. */
2117 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2120 /* If the first separator was IFS whitespace and the current character is
2121 a non-whitespace IFS character, it should be part of the current field
2122 delimiter, not a separate delimiter that would result in an empty field.
2123 Look at POSIX.2, 3.6.5, (3)(b). */
2124 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2127 /* An IFS character that is not IFS white space, along with any adjacent
2128 IFS white space, shall delimit a field. */
2129 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2133 /* Update STRING to point to the next field. */
2134 *stringp
= s
+ sindex
;
2135 return (current_word
);
2138 /* Remove IFS white space at the end of STRING. Start at the end
2139 of the string and walk backwards until the beginning of the string
2140 or we find a character that's not IFS white space and not CTLESC.
2141 Only let CTLESC escape a white space character if SAW_ESCAPE is
2144 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2145 char *string
, *separators
;
2150 s
= string
+ STRLEN (string
) - 1;
2151 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2152 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2160 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2161 backslashes, single and double quotes. */
2163 list_string_with_quotes (string
)
2169 int c
, i
, tokstart
, len
;
2171 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2173 if (s
== 0 || *s
== 0)
2174 return ((WORD_LIST
*)NULL
);
2178 list
= (WORD_LIST
*)NULL
;
2189 i
= skip_single_quoted (s
, s_len
, ++i
);
2191 i
= skip_double_quoted (s
, s_len
, ++i
);
2192 else if (c
== 0 || spctabnl (c
))
2194 /* We have found the end of a token. Make a word out of it and
2195 add it to the word list. */
2196 token
= substring (s
, tokstart
, i
);
2197 list
= add_string_to_list (token
, list
);
2199 while (spctabnl (s
[i
]))
2207 i
++; /* normal character */
2209 return (REVERSE_LIST (list
, WORD_LIST
*));
2213 /********************************************************/
2215 /* Functions to perform assignment statements */
2217 /********************************************************/
2219 #if defined (ARRAY_VARS)
2221 do_compound_assignment (name
, value
, flags
)
2229 mklocal
= flags
& ASS_MKLOCAL
;
2231 if (mklocal
&& variable_context
)
2233 list
= expand_compound_array_assignment (value
, flags
);
2234 v
= find_variable (name
);
2235 if (v
== 0 || array_p (v
) == 0 || v
->context
!= variable_context
)
2236 v
= make_local_array_variable (name
);
2237 assign_compound_array_list (v
, list
, flags
);
2240 v
= assign_array_from_string (name
, value
, flags
);
2246 /* Given STRING, an assignment string, get the value of the right side
2247 of the `=', and bind it to the left side. If EXPAND is true, then
2248 perform parameter expansion, command substitution, and arithmetic
2249 expansion on the right-hand side. Perform tilde expansion in any
2250 case. Do not perform word splitting on the result of expansion. */
2252 do_assignment_internal (word
, expand
)
2253 const WORD_DESC
*word
;
2256 int offset
, tlen
, appendop
, assign_list
, aflags
;
2259 #if defined (ARRAY_VARS)
2265 if (word
== 0 || word
->word
== 0)
2268 appendop
= assign_list
= aflags
= 0;
2269 string
= word
->word
;
2270 offset
= assignment (string
, 0);
2271 name
= savestring (string
);
2272 value
= (char *)NULL
;
2274 if (name
[offset
] == '=')
2278 if (name
[offset
- 1] == '+')
2281 name
[offset
- 1] = '\0';
2284 name
[offset
] = 0; /* might need this set later */
2285 temp
= name
+ offset
+ 1;
2286 tlen
= STRLEN (temp
);
2288 #if defined (ARRAY_VARS)
2289 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2291 assign_list
= ni
= 1;
2292 value
= extract_array_assignment_list (temp
, &ni
);
2297 if (expand
&& temp
[0])
2298 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2300 value
= savestring (temp
);
2305 value
= (char *)xmalloc (1);
2309 if (echo_command_at_execute
)
2312 name
[offset
- 1] = '+';
2313 xtrace_print_assignment (name
, value
, assign_list
, 1);
2315 name
[offset
- 1] = '\0';
2318 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2321 aflags
|= ASS_APPEND
;
2323 #if defined (ARRAY_VARS)
2324 if (t
= xstrchr (name
, '[')) /*]*/
2328 report_error (_("%s: cannot assign list to array member"), name
);
2331 entry
= assign_array_element (name
, value
, aflags
);
2335 else if (assign_list
)
2337 if (word
->flags
& W_ASSIGNARG
)
2338 aflags
|= ASS_MKLOCAL
;
2339 entry
= do_compound_assignment (name
, value
, aflags
);
2342 #endif /* ARRAY_VARS */
2343 entry
= bind_variable (name
, value
, aflags
);
2345 stupidly_hack_special_variables (name
);
2348 VUNSETATTR (entry
, att_invisible
);
2350 /* Return 1 if the assignment seems to have been performed correctly. */
2351 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2354 /* Perform the assignment statement in STRING, and expand the
2355 right side by doing tilde, command and parameter expansion. */
2357 do_assignment (string
)
2362 td
.flags
= W_ASSIGNMENT
;
2365 return do_assignment_internal (&td
, 1);
2369 do_word_assignment (word
)
2372 return do_assignment_internal (word
, 1);
2375 /* Given STRING, an assignment string, get the value of the right side
2376 of the `=', and bind it to the left side. Do not perform any word
2377 expansions on the right hand side. */
2379 do_assignment_no_expand (string
)
2384 td
.flags
= W_ASSIGNMENT
;
2387 return (do_assignment_internal (&td
, 0));
2390 /***************************************************
2392 * Functions to manage the positional parameters *
2394 ***************************************************/
2396 /* Return the word list that corresponds to `$*'. */
2398 list_rest_of_args ()
2400 register WORD_LIST
*list
, *args
;
2403 /* Break out of the loop as soon as one of the dollar variables is null. */
2404 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2405 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2407 for (args
= rest_of_args
; args
; args
= args
->next
)
2408 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2410 return (REVERSE_LIST (list
, WORD_LIST
*));
2416 register WORD_LIST
*list
;
2419 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2421 for (list
= rest_of_args
; list
; list
= list
->next
)
2426 /* Return the value of a positional parameter. This handles values > 10. */
2428 get_dollar_var_value (ind
)
2435 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2436 else /* We want something like ${11} */
2439 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2441 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2446 /* Make a single large string out of the dollar digit variables,
2447 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2448 case of "$*" with respect to IFS. */
2450 string_rest_of_args (dollar_star
)
2453 register WORD_LIST
*list
;
2456 list
= list_rest_of_args ();
2457 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2458 dispose_words (list
);
2462 /* Return a string containing the positional parameters from START to
2463 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2464 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2465 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2466 no quoting chars are added. */
2468 pos_params (string
, start
, end
, quoted
)
2470 int start
, end
, quoted
;
2472 WORD_LIST
*save
, *params
, *h
, *t
;
2476 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2478 return ((char *)NULL
);
2480 save
= params
= list_rest_of_args ();
2482 return ((char *)NULL
);
2484 for (i
= 1; params
&& i
< start
; i
++)
2485 params
= params
->next
;
2487 return ((char *)NULL
);
2488 for (h
= t
= params
; params
&& i
< end
; i
++)
2491 params
= params
->next
;
2494 t
->next
= (WORD_LIST
*)NULL
;
2495 if (string
[0] == '*')
2497 if (quoted
& Q_DOUBLE_QUOTES
)
2498 ret
= string_list_dollar_star (quote_list (h
));
2499 else if (quoted
& Q_HERE_DOCUMENT
)
2500 ret
= string_list (quote_list (h
));
2502 ret
= string_list (h
);
2505 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (h
) : h
);
2509 dispose_words (save
);
2513 /******************************************************************/
2515 /* Functions to expand strings to strings or WORD_LISTs */
2517 /******************************************************************/
2519 #if defined (PROCESS_SUBSTITUTION)
2520 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2522 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2525 /* If there are any characters in STRING that require full expansion,
2526 then call FUNC to expand STRING; otherwise just perform quote
2527 removal if necessary. This returns a new string. */
2529 expand_string_if_necessary (string
, quoted
, func
)
2540 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2541 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
2545 if (EXP_CHAR (string
[i
]))
2547 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
2549 ADVANCE_CHAR (string
, slen
, i
);
2554 list
= (*func
) (string
, quoted
);
2557 ret
= string_list (list
);
2558 dispose_words (list
);
2563 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
2564 ret
= string_quote_removal (string
, quoted
);
2566 ret
= savestring (string
);
2571 static inline char *
2572 expand_string_to_string_internal (string
, quoted
, func
)
2580 if (string
== 0 || *string
== '\0')
2581 return ((char *)NULL
);
2583 list
= (*func
) (string
, quoted
);
2586 ret
= string_list (list
);
2587 dispose_words (list
);
2596 expand_string_to_string (string
, quoted
)
2600 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
2604 expand_string_unsplit_to_string (string
, quoted
)
2608 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
2612 expand_assignment_string_to_string (string
, quoted
)
2616 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
2620 expand_arith_string (string
, quoted
)
2623 return (expand_string_if_necessary (string
, quoted
, expand_string
));
2626 #if defined (COND_COMMAND)
2627 /* Just remove backslashes in STRING. Returns a new string. */
2629 remove_backslashes (string
)
2634 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
2635 for (s
= string
; s
&& *s
; )
2647 /* This needs better error handling. */
2648 /* Expand W for use as an argument to a unary or binary operator in a
2649 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
2650 to the != or == operator, and should be treated as a pattern. In
2651 this case, we quote the string specially for the globbing code. The
2652 caller is responsible for removing the backslashes if the unquoted
2653 words is needed later. */
2655 cond_expand_word (w
, special
)
2662 if (w
->word
== 0 || w
->word
[0] == '\0')
2663 return ((char *)NULL
);
2665 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
2671 r
= string_list (l
);
2675 p
= string_list (l
);
2676 r
= quote_string_for_globbing (p
, QGLOB_CVTNULL
);
2688 /* Call expand_word_internal to expand W and handle error returns.
2689 A convenience function for functions that don't want to handle
2690 any errors or free any memory before aborting. */
2692 call_expand_word_internal (w
, q
, i
, c
, e
)
2698 result
= expand_word_internal (w
, q
, i
, c
, e
);
2699 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
2701 /* By convention, each time this error is returned, w->word has
2702 already been freed (it sometimes may not be in the fatal case,
2703 but that doesn't result in a memory leak because we're going
2704 to exit in most cases). */
2705 w
->word
= (char *)NULL
;
2706 last_command_exit_value
= EXECUTION_FAILURE
;
2707 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
2714 /* Perform parameter expansion, command substitution, and arithmetic
2715 expansion on STRING, as if it were a word. Leave the result quoted. */
2717 expand_string_internal (string
, quoted
)
2724 if (string
== 0 || *string
== 0)
2725 return ((WORD_LIST
*)NULL
);
2728 td
.word
= savestring (string
);
2730 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2736 /* Expand STRING by performing parameter expansion, command substitution,
2737 and arithmetic expansion. Dequote the resulting WORD_LIST before
2738 returning it, but do not perform word splitting. The call to
2739 remove_quoted_nulls () is in here because word splitting normally
2740 takes care of quote removal. */
2742 expand_string_unsplit (string
, quoted
)
2748 if (string
== 0 || *string
== '\0')
2749 return ((WORD_LIST
*)NULL
);
2751 expand_no_split_dollar_star
= 1;
2752 value
= expand_string_internal (string
, quoted
);
2753 expand_no_split_dollar_star
= 0;
2759 remove_quoted_nulls (value
->word
->word
);
2760 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2762 dequote_list (value
);
2767 /* Expand the rhs of an assignment statement */
2769 expand_string_assignment (string
, quoted
)
2776 if (string
== 0 || *string
== '\0')
2777 return ((WORD_LIST
*)NULL
);
2779 expand_no_split_dollar_star
= 1;
2781 td
.flags
= W_ASSIGNRHS
;
2782 td
.word
= savestring (string
);
2783 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2786 expand_no_split_dollar_star
= 0;
2792 remove_quoted_nulls (value
->word
->word
);
2793 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2795 dequote_list (value
);
2801 /* Expand one of the PS? prompt strings. This is a sort of combination of
2802 expand_string_unsplit and expand_string_internal, but returns the
2803 passed string when an error occurs. Might want to trap other calls
2804 to jump_to_top_level here so we don't endlessly loop. */
2806 expand_prompt_string (string
, quoted
)
2813 if (string
== 0 || *string
== 0)
2814 return ((WORD_LIST
*)NULL
);
2817 td
.word
= savestring (string
);
2819 no_longjmp_on_fatal_error
= 1;
2820 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2821 no_longjmp_on_fatal_error
= 0;
2823 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
2825 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
2833 remove_quoted_nulls (value
->word
->word
);
2834 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2836 dequote_list (value
);
2841 /* Expand STRING just as if you were expanding a word, but do not dequote
2842 the resultant WORD_LIST. This is called only from within this file,
2843 and is used to correctly preserve quoted characters when expanding
2844 things like ${1+"$@"}. This does parameter expansion, command
2845 substitution, arithmetic expansion, and word splitting. */
2847 expand_string_leave_quoted (string
, quoted
)
2854 if (string
== 0 || *string
== '\0')
2855 return ((WORD_LIST
*)NULL
);
2857 tlist
= expand_string_internal (string
, quoted
);
2861 tresult
= word_list_split (tlist
);
2862 dispose_words (tlist
);
2865 return ((WORD_LIST
*)NULL
);
2868 /* This does not perform word splitting or dequote the WORD_LIST
2871 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
2873 int quoted
, *dollar_at_p
, *has_dollar_at
;
2878 if (string
== 0 || *string
== '\0')
2879 return (WORD_LIST
*)NULL
;
2883 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
2887 /* Expand STRING just as if you were expanding a word. This also returns
2888 a list of words. Note that filename globbing is *NOT* done for word
2889 or string expansion, just when the shell is expanding a command. This
2890 does parameter expansion, command substitution, arithmetic expansion,
2891 and word splitting. Dequote the resultant WORD_LIST before returning. */
2893 expand_string (string
, quoted
)
2899 if (string
== 0 || *string
== '\0')
2900 return ((WORD_LIST
*)NULL
);
2902 result
= expand_string_leave_quoted (string
, quoted
);
2903 return (result
? dequote_list (result
) : result
);
2906 /***************************************************
2908 * Functions to handle quoting chars *
2910 ***************************************************/
2914 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2915 The parser passes CTLNUL as CTLESC CTLNUL. */
2917 /* Quote escape characters in string s, but no other characters. This is
2918 used to protect CTLESC and CTLNUL in variable values from the rest of
2919 the word expansion process after the variable is expanded. */
2921 quote_escapes (string
)
2924 register char *s
, *t
;
2926 char *result
, *send
;
2929 slen
= strlen (string
);
2930 send
= string
+ slen
;
2932 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
2937 if (*s
== CTLESC
|| *s
== CTLNUL
)
2939 COPY_CHAR_P (t
, s
, send
);
2946 list_quote_escapes (list
)
2949 register WORD_LIST
*w
;
2952 for (w
= list
; w
; w
= w
->next
)
2955 w
->word
->word
= quote_escapes (t
);
2961 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2963 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2964 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2965 data stream pass through properly.
2967 We need to remove doubled CTLESC characters inside quoted strings before
2968 quoting the entire string, so we do not double the number of CTLESC
2971 Also used by parts of the pattern substitution code. */
2973 dequote_escapes (string
)
2976 register char *s
, *t
;
2978 char *result
, *send
;
2984 slen
= strlen (string
);
2985 send
= string
+ slen
;
2987 t
= result
= (char *)xmalloc (slen
+ 1);
2990 if (strchr (string
, CTLESC
) == 0)
2991 return (strcpy (result
, s
));
2995 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
))
3001 COPY_CHAR_P (t
, s
, send
);
3007 /* Return a new string with the quoted representation of character C.
3008 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3009 set in any resultant WORD_DESC where this value is the word. */
3011 make_quoted_char (c
)
3016 temp
= (char *)xmalloc (3);
3031 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3032 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3033 this value is the word. */
3035 quote_string (string
)
3040 char *result
, *send
;
3044 result
= (char *)xmalloc (2);
3052 slen
= strlen (string
);
3053 send
= string
+ slen
;
3055 result
= (char *)xmalloc ((slen
* 2) + 1);
3057 for (t
= result
; string
< send
; )
3060 COPY_CHAR_P (t
, string
, send
);
3067 /* De-quote quoted characters in STRING. */
3069 dequote_string (string
)
3072 register char *s
, *t
;
3074 char *result
, *send
;
3077 slen
= strlen (string
);
3079 t
= result
= (char *)xmalloc (slen
+ 1);
3081 if (QUOTED_NULL (string
))
3087 /* If no character in the string can be quoted, don't bother examining
3088 each character. Just return a copy of the string passed to us. */
3089 if (strchr (string
, CTLESC
) == NULL
)
3090 return (strcpy (result
, string
));
3092 send
= string
+ slen
;
3102 COPY_CHAR_P (t
, s
, send
);
3109 /* Quote the entire WORD_LIST list. */
3114 register WORD_LIST
*w
;
3117 for (w
= list
; w
; w
= w
->next
)
3120 w
->word
->word
= quote_string (t
);
3122 w
->word
->flags
|= W_QUOTED
;
3123 /* XXX - turn on W_HAVEQUOTEDNULL here? */
3128 /* De-quote quoted characters in each word in LIST. */
3134 register WORD_LIST
*tlist
;
3136 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3138 s
= dequote_string (tlist
->word
->word
);
3139 free (tlist
->word
->word
);
3140 tlist
->word
->word
= s
;
3141 /* XXX - turn off W_HAVEQUOTEDNULL here? */
3146 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3149 remove_quoted_escapes (string
)
3156 t
= dequote_escapes (string
);
3164 /* Perform quoted null character removal on STRING. We don't allow any
3165 quoted null characters in the middle or at the ends of strings because
3166 of how expand_word_internal works. remove_quoted_nulls () turns
3167 STRING into an empty string iff it only consists of a quoted null,
3168 and removes all unquoted CTLNUL characters. */
3170 remove_quoted_nulls (string
)
3173 register size_t slen
;
3174 register int i
, j
, prev_i
;
3177 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3178 return string
; /* XXX */
3180 slen
= strlen (string
);
3185 if (string
[i
] == CTLESC
)
3187 /* Old code had j++, but we cannot assume that i == j at this
3188 point -- what if a CTLNUL has already been removed from the
3189 string? We don't want to drop the CTLESC or recopy characters
3190 that we've already copied down. */
3191 i
++; string
[j
++] = CTLESC
;
3195 else if (string
[i
] == CTLNUL
)
3199 ADVANCE_CHAR (string
, slen
, i
);
3202 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3212 /* Perform quoted null character removal on each element of LIST.
3213 This modifies LIST. */
3215 word_list_remove_quoted_nulls (list
)
3218 register WORD_LIST
*t
;
3220 for (t
= list
; t
; t
= t
->next
)
3222 remove_quoted_nulls (t
->word
->word
);
3223 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3227 /* **************************************************************** */
3229 /* Functions for Matching and Removing Patterns */
3231 /* **************************************************************** */
3233 #if defined (HANDLE_MULTIBYTE)
3234 #if 0 /* Currently unused */
3235 static unsigned char *
3236 mb_getcharlens (string
, len
)
3240 int i
, offset
, last
;
3247 ret
= (unsigned char *)xmalloc (len
);
3248 memset (ret
, 0, len
);
3249 while (string
[last
])
3251 ADVANCE_CHAR (string
, len
, offset
);
3252 ret
[last
] = offset
- last
;
3260 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3261 can have one of 4 values:
3262 RP_LONG_LEFT remove longest matching portion at start of PARAM
3263 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3264 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3265 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3268 #define RP_LONG_LEFT 1
3269 #define RP_SHORT_LEFT 2
3270 #define RP_LONG_RIGHT 3
3271 #define RP_SHORT_RIGHT 4
3274 remove_upattern (param
, pattern
, op
)
3275 char *param
, *pattern
;
3280 register char *p
, *ret
, c
;
3282 len
= STRLEN (param
);
3287 case RP_LONG_LEFT
: /* remove longest match at start */
3288 for (p
= end
; p
>= param
; p
--)
3291 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3294 return (savestring (p
));
3301 case RP_SHORT_LEFT
: /* remove shortest match at start */
3302 for (p
= param
; p
<= end
; p
++)
3305 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3308 return (savestring (p
));
3314 case RP_LONG_RIGHT
: /* remove longest match at end */
3315 for (p
= param
; p
<= end
; p
++)
3317 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3320 ret
= savestring (param
);
3327 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3328 for (p
= end
; p
>= param
; p
--)
3330 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3333 ret
= savestring (param
);
3341 return (savestring (param
)); /* no match, return original string */
3344 #if defined (HANDLE_MULTIBYTE)
3346 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3357 case RP_LONG_LEFT
: /* remove longest match at start */
3358 for (n
= wstrlen
; n
>= 0; n
--)
3360 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3361 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3364 return (wcsdup (wparam
+ n
));
3370 case RP_SHORT_LEFT
: /* remove shortest match at start */
3371 for (n
= 0; n
<= wstrlen
; n
++)
3373 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3374 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3377 return (wcsdup (wparam
+ n
));
3383 case RP_LONG_RIGHT
: /* remove longest match at end */
3384 for (n
= 0; n
<= wstrlen
; n
++)
3386 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3388 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3389 ret
= wcsdup (wparam
);
3396 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3397 for (n
= wstrlen
; n
>= 0; n
--)
3399 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3401 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3402 ret
= wcsdup (wparam
);
3410 return (wcsdup (wparam
)); /* no match, return original string */
3412 #endif /* HANDLE_MULTIBYTE */
3415 remove_pattern (param
, pattern
, op
)
3416 char *param
, *pattern
;
3421 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3422 return (savestring (param
));
3424 #if defined (HANDLE_MULTIBYTE)
3427 wchar_t *ret
, *oret
;
3429 wchar_t *wparam
, *wpattern
;
3433 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3434 if (n
== (size_t)-1)
3435 return (remove_upattern (param
, pattern
, op
));
3436 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3437 if (n
== (size_t)-1)
3440 return (remove_upattern (param
, pattern
, op
));
3442 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3448 xret
= (char *)xmalloc (n
+ 1);
3449 memset (&ps
, '\0', sizeof (mbstate_t));
3450 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3451 xret
[n
] = '\0'; /* just to make sure */
3457 return (remove_upattern (param
, pattern
, op
));
3460 /* Return 1 of the first character of STRING could match the first
3461 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3463 match_pattern_char (pat
, string
)
3474 return (*string
== c
);
3476 return (*string
== *pat
);
3478 return (*pat
== LPAREN
? 1 : (*string
!= '\0'));
3484 return (*pat
== LPAREN
? 1 : (*string
== c
));
3486 return (*string
!= '\0');
3490 /* Match PAT anywhere in STRING and return the match boundaries.
3491 This returns 1 in case of a successful match, 0 otherwise. SP
3492 and EP are pointers into the string where the match begins and
3493 ends, respectively. MTYPE controls what kind of match is attempted.
3494 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3495 of the string, respectively. The longest match is returned. */
3497 match_upattern (string
, pat
, mtype
, sp
, ep
)
3503 register char *p
, *p1
, *npat
;
3506 /* If the pattern doesn't match anywhere in the string, go ahead and
3507 short-circuit right away. A minor optimization, saves a bunch of
3508 unnecessary calls to strmatch (up to N calls for a string of N
3509 characters) if the match is unsuccessful. To preserve the semantics
3510 of the substring matches below, we make sure that the pattern has
3511 `*' as first and last character, making a new pattern if necessary. */
3512 /* XXX - check this later if I ever implement `**' with special meaning,
3513 since this will potentially result in `**' at the beginning or end */
3515 if (pat
[0] != '*' || pat
[len
- 1] != '*')
3517 p
= npat
= (char *)xmalloc (len
+ 3);
3523 if (p1
[-1] != '*' || p
[-2] == '\\')
3529 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
3532 if (c
== FNM_NOMATCH
)
3535 len
= STRLEN (string
);
3541 for (p
= string
; p
<= end
; p
++)
3543 if (match_pattern_char (pat
, p
))
3545 for (p1
= end
; p1
>= p
; p1
--)
3547 c
= *p1
; *p1
= '\0';
3548 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3563 if (match_pattern_char (pat
, string
) == 0)
3566 for (p
= end
; p
>= string
; p
--)
3569 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
3582 for (p
= string
; p
<= end
; p
++)
3584 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3599 #if defined (HANDLE_MULTIBYTE)
3600 /* Return 1 of the first character of WSTRING could match the first
3601 character of pattern WPAT. Wide character version. */
3603 match_pattern_wchar (wpat
, wstring
)
3604 wchar_t *wpat
, *wstring
;
3611 switch (wc
= *wpat
++)
3614 return (*wstring
== wc
);
3616 return (*wstring
== *wpat
);
3618 return (*wpat
== LPAREN
? 1 : (*wstring
!= L
'\0'));
3624 return (*wpat
== LPAREN
? 1 : (*wstring
== wc
));
3626 return (*wstring
!= L
'\0');
3630 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3631 This returns 1 in case of a successful match, 0 otherwise. Wide
3632 character version. */
3634 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
3642 wchar_t wc
, *wp
, *nwpat
, *wp1
;
3645 size_t n
, n1
; /* Apple's gcc seems to miscompile this badly */
3650 /* If the pattern doesn't match anywhere in the string, go ahead and
3651 short-circuit right away. A minor optimization, saves a bunch of
3652 unnecessary calls to strmatch (up to N calls for a string of N
3653 characters) if the match is unsuccessful. To preserve the semantics
3654 of the substring matches below, we make sure that the pattern has
3655 `*' as first and last character, making a new pattern if necessary. */
3656 /* XXX - check this later if I ever implement `**' with special meaning,
3657 since this will potentially result in `**' at the beginning or end */
3658 len
= wcslen (wpat
);
3659 if (wpat
[0] != L
'*' || wpat
[len
- 1] != L
'*')
3661 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
3665 while (*wp1
!= L
'\0')
3667 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
3673 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
3676 if (len
== FNM_NOMATCH
)
3682 for (n
= 0; n
<= wstrlen
; n
++)
3684 if (match_pattern_wchar (wpat
, wstring
+ n
))
3686 for (n1
= wstrlen
; n1
>= n
; n1
--)
3688 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
3689 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3704 if (match_pattern_wchar (wpat
, wstring
) == 0)
3707 for (n
= wstrlen
; n
>= 0; n
--)
3709 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
3710 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
3723 for (n
= 0; n
<= wstrlen
; n
++)
3725 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3728 *ep
= indices
[wstrlen
];
3738 #endif /* HANDLE_MULTIBYTE */
3741 match_pattern (string
, pat
, mtype
, sp
, ep
)
3746 #if defined (HANDLE_MULTIBYTE)
3749 wchar_t *wstring
, *wpat
;
3753 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
3756 #if defined (HANDLE_MULTIBYTE)
3759 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
3760 if (n
== (size_t)-1)
3761 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3762 n
= xdupmbstowcs (&wstring
, &indices
, string
);
3763 if (n
== (size_t)-1)
3766 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3768 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
3778 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3782 getpatspec (c
, value
)
3787 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
3789 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
3792 /* Posix.2 says that the WORD should be run through tilde expansion,
3793 parameter expansion, command substitution and arithmetic expansion.
3794 This leaves the result quoted, so quote_string_for_globbing () has
3795 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3796 it means that the entire expression was enclosed in double quotes.
3797 This means that quoting characters in the pattern do not make any
3798 special pattern characters quoted. For example, the `*' in the
3799 following retains its special meaning: "${foo#'*'}". */
3801 getpattern (value
, quoted
, expandpat
)
3803 int quoted
, expandpat
;
3811 /* There is a problem here: how to handle single or double quotes in the
3812 pattern string when the whole expression is between double quotes?
3813 POSIX.2 says that enclosing double quotes do not cause the pattern to
3814 be quoted, but does that leave us a problem with @ and array[@] and their
3815 expansions inside a pattern? */
3817 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
3820 pat
= string_extract_double_quoted (tword
, &i
, 1);
3826 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3828 l
= *value
? expand_string_for_rhs (value
,
3829 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
3830 (int *)NULL
, (int *)NULL
)
3832 pat
= string_list (l
);
3836 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
3844 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3845 or ${name#[#]value}. */
3847 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
3848 char *value
, *pattern
;
3849 int patspec
, quoted
;
3853 tword
= remove_pattern (value
, pattern
, patspec
);
3860 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
3863 int patspec
, itype
, quoted
;
3869 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
3871 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
3872 w
= alloc_word_desc ();
3873 w
->word
= tword
? tword
: savestring ("");
3874 new = make_word_list (w
, new);
3877 l
= REVERSE_LIST (new, WORD_LIST
*);
3879 tword
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (l
) : string_list (l
);
3881 tword
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (l
) : l
);
3888 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
3891 int patspec
, quoted
;
3896 list
= list_rest_of_args ();
3898 return ((char *)NULL
);
3899 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3900 dispose_words (list
);
3904 #if defined (ARRAY_VARS)
3906 array_remove_pattern (a
, pattern
, patspec
, varname
, quoted
)
3910 char *varname
; /* so we can figure out how it's indexed */
3918 /* compute itype from varname here */
3919 v
= array_variable_part (varname
, &ret
, 0);
3922 list
= array_to_word_list (a
);
3924 return ((char *)NULL
);
3925 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3926 dispose_words (list
);
3930 #endif /* ARRAY_VARS */
3933 parameter_brace_remove_pattern (varname
, value
, patstr
, rtype
, quoted
)
3934 char *varname
, *value
, *patstr
;
3937 int vtype
, patspec
, starsub
;
3938 char *temp1
, *val
, *pattern
;
3942 return ((char *)NULL
);
3944 this_command_name
= varname
;
3946 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
3948 return ((char *)NULL
);
3950 starsub
= vtype
& VT_STARSUB
;
3951 vtype
&= ~VT_STARSUB
;
3953 patspec
= getpatspec (rtype
, patstr
);
3954 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
3957 pattern
= getpattern (patstr
, quoted
, 1);
3959 temp1
= (char *)NULL
; /* shut up gcc */
3963 case VT_ARRAYMEMBER
:
3964 temp1
= remove_pattern (val
, pattern
, patspec
);
3965 if (vtype
== VT_VARIABLE
)
3969 val
= quote_escapes (temp1
);
3974 #if defined (ARRAY_VARS)
3976 temp1
= array_remove_pattern (array_cell (v
), pattern
, patspec
, varname
, quoted
);
3977 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3979 val
= quote_escapes (temp1
);
3986 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
3987 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3989 val
= quote_escapes (temp1
);
4000 /*******************************************
4002 * Functions to expand WORD_DESCs *
4004 *******************************************/
4006 /* Expand WORD, performing word splitting on the result. This does
4007 parameter expansion, command substitution, arithmetic expansion,
4008 word splitting, and quote removal. */
4011 expand_word (word
, quoted
)
4015 WORD_LIST
*result
, *tresult
;
4017 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4018 result
= word_list_split (tresult
);
4019 dispose_words (tresult
);
4020 return (result
? dequote_list (result
) : result
);
4023 /* Expand WORD, but do not perform word splitting on the result. This
4024 does parameter expansion, command substitution, arithmetic expansion,
4025 and quote removal. */
4027 expand_word_unsplit (word
, quoted
)
4033 expand_no_split_dollar_star
= 1;
4034 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4035 expand_no_split_dollar_star
= 0;
4037 return (result
? dequote_list (result
) : result
);
4040 /* Perform shell expansions on WORD, but do not perform word splitting or
4041 quote removal on the result. */
4043 expand_word_leave_quoted (word
, quoted
)
4047 return (call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
));
4050 #if defined (PROCESS_SUBSTITUTION)
4052 /*****************************************************************/
4054 /* Hacking Process Substitution */
4056 /*****************************************************************/
4058 #if !defined (HAVE_DEV_FD)
4059 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4060 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4061 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4062 list. NFIFO is a count of the number of FIFOs in the list. */
4063 #define FIFO_INCR 20
4070 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4072 static int fifo_list_size
;
4075 add_fifo_list (pathname
)
4078 if (nfifo
>= fifo_list_size
- 1)
4080 fifo_list_size
+= FIFO_INCR
;
4081 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4082 fifo_list_size
* sizeof (struct temp_fifo
));
4085 fifo_list
[nfifo
].file
= savestring (pathname
);
4097 for (i
= saved
= 0; i
< nfifo
; i
++)
4099 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4101 unlink (fifo_list
[i
].file
);
4102 free (fifo_list
[i
].file
);
4103 fifo_list
[i
].file
= (char *)NULL
;
4104 fifo_list
[i
].proc
= -1;
4110 /* If we didn't remove some of the FIFOs, compact the list. */
4113 for (i
= j
= 0; i
< nfifo
; i
++)
4114 if (fifo_list
[i
].file
)
4116 fifo_list
[j
].file
= fifo_list
[i
].file
;
4117 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4131 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
);
4132 if (mkfifo (tname
, 0600) < 0)
4135 return ((char *)NULL
);
4138 add_fifo_list (tname
);
4142 #else /* HAVE_DEV_FD */
4144 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4145 has open to children. NFDS is a count of the number of bits currently
4146 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4148 static char *dev_fd_list
= (char *)NULL
;
4150 static int totfds
; /* The highest possible number of open files. */
4156 if (!dev_fd_list
|| fd
>= totfds
)
4161 totfds
= getdtablesize ();
4162 if (totfds
< 0 || totfds
> 256)
4167 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4168 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4171 dev_fd_list
[fd
] = 1;
4183 for (i
= 0; nfds
&& i
< totfds
; i
++)
4194 #if defined (NOTDEF)
4195 print_dev_fd_list ()
4199 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4202 for (i
= 0; i
< totfds
; i
++)
4205 fprintf (stderr
, " %d", i
);
4207 fprintf (stderr
, "\n");
4212 make_dev_fd_filename (fd
)
4215 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4217 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 4);
4219 strcpy (ret
, DEV_FD_PREFIX
);
4220 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4221 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4227 #endif /* HAVE_DEV_FD */
4229 /* Return a filename that will open a connection to the process defined by
4230 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4231 a filename in /dev/fd corresponding to a descriptor that is one of the
4232 ends of the pipe. If not defined, we use named pipes on systems that have
4233 them. Systems without /dev/fd and named pipes are out of luck.
4235 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4236 use the read end of the pipe and dup that file descriptor to fd 0 in
4237 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4238 writing or use the write end of the pipe in the child, and dup that
4239 file descriptor to fd 1 in the child. The parent does the opposite. */
4242 process_substitute (string
, open_for_read_in_child
)
4244 int open_for_read_in_child
;
4249 #if defined (HAVE_DEV_FD)
4250 int parent_pipe_fd
, child_pipe_fd
;
4252 #endif /* HAVE_DEV_FD */
4253 #if defined (JOB_CONTROL)
4254 pid_t old_pipeline_pgrp
;
4257 if (!string
|| !*string
|| wordexp_only
)
4258 return ((char *)NULL
);
4260 #if !defined (HAVE_DEV_FD)
4261 pathname
= make_named_pipe ();
4262 #else /* HAVE_DEV_FD */
4263 if (pipe (fildes
) < 0)
4265 sys_error (_("cannot make pipe for process substitution"));
4266 return ((char *)NULL
);
4268 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4269 the pipe in the parent, otherwise the read end. */
4270 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4271 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4272 /* Move the parent end of the pipe to some high file descriptor, to
4273 avoid clashes with FDs used by the script. */
4274 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4276 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4277 #endif /* HAVE_DEV_FD */
4281 sys_error (_("cannot make pipe for process substitution"));
4282 return ((char *)NULL
);
4285 old_pid
= last_made_pid
;
4287 #if defined (JOB_CONTROL)
4288 old_pipeline_pgrp
= pipeline_pgrp
;
4289 pipeline_pgrp
= shell_pgrp
;
4291 #endif /* JOB_CONTROL */
4293 pid
= make_child ((char *)NULL
, 1);
4296 reset_terminating_signals (); /* XXX */
4297 free_pushed_string_input ();
4298 /* Cancel traps, in trap.c. */
4299 restore_original_signals ();
4300 setup_async_signals ();
4301 subshell_environment
|= SUBSHELL_COMSUB
;
4304 #if defined (JOB_CONTROL)
4305 set_sigchld_handler ();
4306 stop_making_children ();
4307 pipeline_pgrp
= old_pipeline_pgrp
;
4308 #endif /* JOB_CONTROL */
4312 sys_error (_("cannot make child for process substitution"));
4314 #if defined (HAVE_DEV_FD)
4315 close (parent_pipe_fd
);
4316 close (child_pipe_fd
);
4317 #endif /* HAVE_DEV_FD */
4318 return ((char *)NULL
);
4323 #if defined (JOB_CONTROL)
4324 restore_pipeline (1);
4327 #if !defined (HAVE_DEV_FD)
4328 fifo_list
[nfifo
-1].proc
= pid
;
4331 last_made_pid
= old_pid
;
4333 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4335 #endif /* JOB_CONTROL && PGRP_PIPE */
4337 #if defined (HAVE_DEV_FD)
4338 close (child_pipe_fd
);
4339 #endif /* HAVE_DEV_FD */
4344 set_sigint_handler ();
4346 #if defined (JOB_CONTROL)
4347 set_job_control (0);
4348 #endif /* JOB_CONTROL */
4350 #if !defined (HAVE_DEV_FD)
4351 /* Open the named pipe in the child. */
4352 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4355 /* Two separate strings for ease of translation. */
4356 if (open_for_read_in_child
)
4357 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4359 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4363 if (open_for_read_in_child
)
4365 if (sh_unset_nodelay_mode (fd
) < 0)
4367 sys_error (_("cannout reset nodelay mode for fd %d"), fd
);
4371 #else /* HAVE_DEV_FD */
4373 #endif /* HAVE_DEV_FD */
4375 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4377 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4378 open_for_read_in_child
? 0 : 1);
4382 if (fd
!= (open_for_read_in_child
? 0 : 1))
4385 /* Need to close any files that this process has open to pipes inherited
4387 if (current_fds_to_close
)
4389 close_fd_bitmap (current_fds_to_close
);
4390 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4393 #if defined (HAVE_DEV_FD)
4394 /* Make sure we close the parent's end of the pipe and clear the slot
4395 in the fd list so it is not closed later, if reallocated by, for
4396 instance, pipe(2). */
4397 close (parent_pipe_fd
);
4398 dev_fd_list
[parent_pipe_fd
] = 0;
4399 #endif /* HAVE_DEV_FD */
4401 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4403 #if !defined (HAVE_DEV_FD)
4404 /* Make sure we close the named pipe in the child before we exit. */
4405 close (open_for_read_in_child
? 0 : 1);
4406 #endif /* !HAVE_DEV_FD */
4411 #endif /* PROCESS_SUBSTITUTION */
4413 /***********************************/
4415 /* Command Substitution */
4417 /***********************************/
4420 read_comsub (fd
, quoted
)
4423 char *istring
, buf
[128], *bufp
;
4424 int istring_index
, istring_size
, c
;
4427 istring
= (char *)NULL
;
4428 istring_index
= istring_size
= bufn
= 0;
4431 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4434 /* Read the output of the command through the pipe. */
4441 bufn
= zread (fd
, buf
, sizeof (buf
));
4451 internal_warning ("read_comsub: ignored null byte in input");
4456 /* Add the character to ISTRING, possibly after resizing it. */
4457 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4459 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || c
== CTLESC
|| c
== CTLNUL
)
4460 istring
[istring_index
++] = CTLESC
;
4462 istring
[istring_index
++] = c
;
4465 #if defined (__CYGWIN__)
4466 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4469 istring
[istring_index
- 1] = '\n';
4476 istring
[istring_index
] = '\0';
4478 /* If we read no output, just return now and save ourselves some
4480 if (istring_index
== 0)
4483 return (char *)NULL
;
4486 /* Strip trailing newlines from the output of the command. */
4487 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4489 while (istring_index
> 0)
4491 if (istring
[istring_index
- 1] == '\n')
4495 /* If the newline was quoted, remove the quoting char. */
4496 if (istring
[istring_index
- 1] == CTLESC
)
4502 istring
[istring_index
] = '\0';
4505 strip_trailing (istring
, istring_index
- 1, 1);
4510 /* Perform command substitution on STRING. This returns a string,
4513 command_substitute (string
, quoted
)
4517 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4519 int result
, fildes
[2], function_value
, pflags
, rc
;
4521 istring
= (char *)NULL
;
4523 /* Don't fork () if there is no need to. In the case of no command to
4524 run, just return NULL. */
4525 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
4526 return ((char *)NULL
);
4528 if (wordexp_only
&& read_but_dont_execute
)
4530 last_command_exit_value
= 125;
4531 jump_to_top_level (EXITPROG
);
4534 /* We're making the assumption here that the command substitution will
4535 eventually run a command from the file system. Since we'll run
4536 maybe_make_export_env in this subshell before executing that command,
4537 the parent shell and any other shells it starts will have to remake
4538 the environment. If we make it before we fork, other shells won't
4539 have to. Don't bother if we have any temporary variable assignments,
4540 though, because the export environment will be remade after this
4541 command completes anyway, but do it if all the words to be expanded
4542 are variable assignments. */
4543 if (subst_assign_varlist
== 0 || garglist
== 0)
4544 maybe_make_export_env (); /* XXX */
4546 /* Flags to pass to parse_and_execute() */
4547 pflags
= interactive
? SEVAL_RESETLINE
: 0;
4549 /* Pipe the output of executing STRING into the current shell. */
4550 if (pipe (fildes
) < 0)
4552 sys_error (_("cannot make pipe for command substitution"));
4556 old_pid
= last_made_pid
;
4557 #if defined (JOB_CONTROL)
4558 old_pipeline_pgrp
= pipeline_pgrp
;
4559 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4560 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
4561 pipeline_pgrp
= shell_pgrp
;
4562 cleanup_the_pipeline ();
4563 #endif /* JOB_CONTROL */
4565 old_async_pid
= last_asynchronous_pid
;
4567 pid
= make_child ((char *)NULL
, 0);
4569 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
4571 last_asynchronous_pid
= old_async_pid
;
4574 /* Reset the signal handlers in the child, but don't free the
4576 reset_signal_handlers ();
4578 #if defined (JOB_CONTROL)
4579 set_sigchld_handler ();
4580 stop_making_children ();
4581 pipeline_pgrp
= old_pipeline_pgrp
;
4583 stop_making_children ();
4584 #endif /* JOB_CONTROL */
4588 sys_error (_("cannot make child for command substitution"));
4594 return ((char *)NULL
);
4599 set_sigint_handler (); /* XXX */
4601 free_pushed_string_input ();
4603 if (dup2 (fildes
[1], 1) < 0)
4605 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4606 exit (EXECUTION_FAILURE
);
4609 /* If standard output is closed in the parent shell
4610 (such as after `exec >&-'), file descriptor 1 will be
4611 the lowest available file descriptor, and end up in
4612 fildes[0]. This can happen for stdin and stderr as well,
4613 but stdout is more important -- it will cause no output
4614 to be generated from this command. */
4615 if ((fildes
[1] != fileno (stdin
)) &&
4616 (fildes
[1] != fileno (stdout
)) &&
4617 (fildes
[1] != fileno (stderr
)))
4620 if ((fildes
[0] != fileno (stdin
)) &&
4621 (fildes
[0] != fileno (stdout
)) &&
4622 (fildes
[0] != fileno (stderr
)))
4625 /* The currently executing shell is not interactive. */
4628 /* This is a subshell environment. */
4629 subshell_environment
|= SUBSHELL_COMSUB
;
4631 /* When not in POSIX mode, command substitution does not inherit
4633 if (posixly_correct
== 0)
4634 exit_immediately_on_error
= 0;
4636 remove_quoted_escapes (string
);
4638 startup_state
= 2; /* see if we can avoid a fork */
4639 /* Give command substitution a place to jump back to on failure,
4640 so we don't go back up to main (). */
4641 result
= setjmp (top_level
);
4643 /* If we're running a command substitution inside a shell function,
4644 trap `return' so we don't return from the function in the subshell
4645 and go off to never-never land. */
4646 if (result
== 0 && return_catch_flag
)
4647 function_value
= setjmp (return_catch
);
4651 if (result
== ERREXIT
)
4652 rc
= last_command_exit_value
;
4653 else if (result
== EXITPROG
)
4654 rc
= last_command_exit_value
;
4656 rc
= EXECUTION_FAILURE
;
4657 else if (function_value
)
4658 rc
= return_catch_value
;
4662 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
4666 last_command_exit_value
= rc
;
4667 rc
= run_exit_trap ();
4672 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4674 #endif /* JOB_CONTROL && PGRP_PIPE */
4678 istring
= read_comsub (fildes
[0], quoted
);
4682 current_command_subst_pid
= pid
;
4683 last_command_exit_value
= wait_for (pid
);
4684 last_command_subst_pid
= pid
;
4685 last_made_pid
= old_pid
;
4687 #if defined (JOB_CONTROL)
4688 /* If last_command_exit_value > 128, then the substituted command
4689 was terminated by a signal. If that signal was SIGINT, then send
4690 SIGINT to ourselves. This will break out of loops, for instance. */
4691 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
4692 kill (getpid (), SIGINT
);
4694 /* wait_for gives the terminal back to shell_pgrp. If some other
4695 process group should have it, give it away to that group here.
4696 pipeline_pgrp is non-zero only while we are constructing a
4697 pipline, so what we are concerned about is whether or not that
4698 pipeline was started in the background. A pipeline started in
4699 the background should never get the tty back here. */
4701 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
4703 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
4705 give_terminal_to (pipeline_pgrp
, 0);
4706 #endif /* JOB_CONTROL */
4712 /********************************************************
4714 * Utility functions for parameter expansion *
4716 ********************************************************/
4718 #if defined (ARRAY_VARS)
4721 array_length_reference (s
)
4730 var
= array_variable_part (s
, &t
, &len
);
4732 /* If unbound variables should generate an error, report one and return
4734 if ((var
== 0 || array_p (var
) == 0) && unbound_vars_is_error
)
4745 /* We support a couple of expansions for variables that are not arrays.
4746 We'll return the length of the value for v[0], and 1 for v[@] or
4747 v[*]. Return 0 for everything else. */
4749 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
4751 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
4752 return (array_p (var
) ? array_num_elements (array
) : 1);
4754 ind
= array_expand_index (t
, len
);
4757 err_badarraysub (t
);
4762 t
= array_reference (array
, ind
);
4764 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
4769 #endif /* ARRAY_VARS */
4772 valid_brace_expansion_word (name
, var_is_special
)
4776 if (DIGIT (*name
) && all_digits (name
))
4778 else if (var_is_special
)
4780 #if defined (ARRAY_VARS)
4781 else if (valid_array_reference (name
))
4783 #endif /* ARRAY_VARS */
4784 else if (legal_identifier (name
))
4791 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4794 int *quoted_dollar_atp
, *contains_dollar_at
;
4800 if (quoted_dollar_atp
)
4801 *quoted_dollar_atp
= 0;
4802 if (contains_dollar_at
)
4803 *contains_dollar_at
= 0;
4807 /* check for $@ and $* */
4808 if (name
[0] == '@' && name
[1] == 0)
4810 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4811 *quoted_dollar_atp
= 1;
4812 if (contains_dollar_at
)
4813 *contains_dollar_at
= 1;
4816 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
4818 if (contains_dollar_at
)
4819 *contains_dollar_at
= 1;
4823 /* Now check for ${array[@]} and ${array[*]} */
4824 #if defined (ARRAY_VARS)
4825 else if (valid_array_reference (name
))
4827 temp1
= xstrchr (name
, '[');
4828 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
4830 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4831 *quoted_dollar_atp
= 1;
4832 if (contains_dollar_at
)
4833 *contains_dollar_at
= 1;
4836 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4837 which should result in separate words even when IFS is unset. */
4838 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
4840 if (contains_dollar_at
)
4841 *contains_dollar_at
= 1;
4849 /* Parameter expand NAME, and return a new string which is the expansion,
4850 or NULL if there was no expansion.
4851 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4852 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4853 NAME was found inside of a double-quoted expression. */
4855 parameter_brace_expand_word (name
, var_is_special
, quoted
)
4857 int var_is_special
, quoted
;
4868 /* Handle multiple digit arguments, as in ${11}. */
4869 if (legal_number (name
, &arg_index
))
4871 tt
= get_dollar_var_value (arg_index
);
4873 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4875 : quote_escapes (tt
);
4877 temp
= (char *)NULL
;
4880 else if (var_is_special
) /* ${@} */
4883 tt
= (char *)xmalloc (2 + strlen (name
));
4884 tt
[sindex
= 0] = '$';
4885 strcpy (tt
+ 1, name
);
4887 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
4888 (int *)NULL
, (int *)NULL
, 0);
4891 #if defined (ARRAY_VARS)
4892 else if (valid_array_reference (name
))
4894 temp
= array_value (name
, quoted
, &atype
);
4895 if (atype
== 0 && temp
)
4896 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4897 ? quote_string (temp
)
4898 : quote_escapes (temp
);
4901 else if (var
= find_variable (name
))
4903 if (var_isset (var
) && invisible_p (var
) == 0)
4905 #if defined (ARRAY_VARS)
4906 temp
= array_p (var
) ? array_reference (array_cell (var
), 0) : value_cell (var
);
4908 temp
= value_cell (var
);
4912 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4913 ? quote_string (temp
)
4914 : quote_escapes (temp
);
4917 temp
= (char *)NULL
;
4920 temp
= (char *)NULL
;
4924 ret
= alloc_word_desc ();
4930 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4931 value of the variable whose name is the value of NAME. */
4933 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4935 int var_is_special
, quoted
;
4936 int *quoted_dollar_atp
, *contains_dollar_at
;
4941 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
4943 /* Have to dequote here if necessary */
4946 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
4947 ? dequote_string (t
)
4948 : dequote_escapes (t
);
4952 dispose_word_desc (w
);
4954 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
4956 return (WORD_DESC
*)NULL
;
4958 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
);
4964 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
4965 depending on the value of C, the separating character. C can be one of
4966 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
4967 between double quotes. */
4969 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
4971 int c
, quoted
, *qdollaratp
, *hasdollarat
;
4975 char *t
, *t1
, *temp
;
4978 /* If the entire expression is between double quotes, we want to treat
4979 the value as a double-quoted string, with the exception that we strip
4980 embedded unescaped double quotes. */
4981 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
4984 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
4989 w
= alloc_word_desc ();
4991 /* XXX was 0 not quoted */
4992 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
4995 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5000 /* The expansion of TEMP returned something. We need to treat things
5001 slightly differently if HASDOL is non-zero. If we have "$@", the
5002 individual words have already been quoted. We need to turn them
5003 into a string with the words separated by the first character of
5004 $IFS without any additional quoting, so string_list_dollar_at won't
5005 do the right thing. We use string_list_dollar_star instead. */
5006 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5008 /* If l->next is not null, we know that TEMP contained "$@", since that
5009 is the only expansion that creates more than one word. */
5010 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5014 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5016 /* The brace expansion occurred between double quotes and there was
5017 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5018 it does not expand to anything. In this case, we want to return
5019 a quoted empty string. */
5020 temp
= make_quoted_char ('\0');
5021 w
->flags
|= W_HASQUOTEDNULL
;
5024 temp
= (char *)NULL
;
5026 if (c
== '-' || c
== '+')
5033 t
= temp
? savestring (temp
) : savestring ("");
5034 t1
= dequote_string (t
);
5036 #if defined (ARRAY_VARS)
5037 if (valid_array_reference (name
))
5038 assign_array_element (name
, t1
, 0);
5040 #endif /* ARRAY_VARS */
5041 bind_variable (name
, t1
, 0);
5048 /* Deal with the right hand side of a ${name:?value} expansion in the case
5049 that NAME is null or not set. If VALUE is non-null it is expanded and
5050 used as the error message to print, otherwise a standard message is
5053 parameter_brace_expand_error (name
, value
)
5059 if (value
&& *value
)
5061 l
= expand_string (value
, 0);
5062 temp
= string_list (l
);
5063 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5068 report_error (_("%s: parameter null or not set"), name
);
5070 /* Free the data we have allocated during this expansion, since we
5071 are about to longjmp out. */
5076 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5079 valid_length_expression (name
)
5082 return (name
[1] == '\0' || /* ${#} */
5083 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5084 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5085 #if defined (ARRAY_VARS)
5086 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5088 legal_identifier (name
+ 1)); /* ${#PS1} */
5091 #if defined (HANDLE_MULTIBYTE)
5097 mbstate_t mbs
, mbsbak
;
5100 memset (&mbs
, 0, sizeof (mbs
));
5102 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5104 if (MB_INVALIDCH(clen
))
5106 clen
= 1; /* assume single byte */
5119 /* Handle the parameter brace expansion that requires us to return the
5120 length of a parameter. */
5122 parameter_brace_expand_length (name
)
5126 intmax_t number
, arg_index
;
5128 #if defined (ARRAY_VARS)
5132 if (name
[1] == '\0') /* ${#} */
5133 number
= number_of_args ();
5134 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5135 number
= number_of_args ();
5136 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5138 /* Take the lengths of some of the shell's special parameters. */
5142 t
= which_set_flags ();
5145 t
= itos (last_command_exit_value
);
5148 t
= itos (dollar_dollar_pid
);
5151 if (last_asynchronous_pid
== NO_PID
)
5154 t
= itos (last_asynchronous_pid
);
5157 t
= itos (number_of_args ());
5160 number
= STRLEN (t
);
5163 #if defined (ARRAY_VARS)
5164 else if (valid_array_reference (name
+ 1))
5165 number
= array_length_reference (name
+ 1);
5166 #endif /* ARRAY_VARS */
5171 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5173 t
= get_dollar_var_value (arg_index
);
5174 number
= MB_STRLEN (t
);
5177 #if defined (ARRAY_VARS)
5178 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && array_p (var
))
5180 t
= array_reference (array_cell (var
), 0);
5181 number
= MB_STRLEN (t
);
5186 newname
= savestring (name
);
5188 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5189 t
= list
? string_list (list
) : (char *)NULL
;
5192 dispose_words (list
);
5194 number
= MB_STRLEN (t
);
5202 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5203 so we do some ad-hoc parsing of an arithmetic expression to find
5204 the first DELIM, instead of using strchr(3). Two rules:
5205 1. If the substring contains a `(', read until closing `)'.
5206 2. If the substring contains a `?', read past one `:' for each `?'.
5210 skiparith (substr
, delim
)
5215 int skipcol
, pcount
, i
;
5218 sublen
= strlen (substr
);
5219 i
= skipcol
= pcount
= 0;
5222 /* Balance parens */
5223 if (substr
[i
] == LPAREN
)
5229 if (substr
[i
] == RPAREN
&& pcount
)
5237 ADVANCE_CHAR (substr
, sublen
, i
);
5241 /* Skip one `:' for each `?' */
5242 if (substr
[i
] == ':' && skipcol
)
5248 if (substr
[i
] == delim
)
5250 if (substr
[i
] == '?')
5256 ADVANCE_CHAR (substr
, sublen
, i
);
5259 return (substr
+ i
);
5262 /* Verify and limit the start and end of the desired substring. If
5263 VTYPE == 0, a regular shell variable is being used; if it is 1,
5264 then the positional parameters are being used; if it is 2, then
5265 VALUE is really a pointer to an array variable that should be used.
5266 Return value is 1 if both values were OK, 0 if there was a problem
5267 with an invalid expression, or -1 if the values were out of range. */
5269 verify_substring_values (value
, substr
, vtype
, e1p
, e2p
)
5270 char *value
, *substr
;
5272 intmax_t *e1p
, *e2p
;
5274 char *t
, *temp1
, *temp2
;
5277 #if defined (ARRAY_VARS)
5281 /* duplicate behavior of strchr(3) */
5282 t
= skiparith (substr
, ':');
5283 if (*t
&& *t
== ':')
5288 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5289 *e1p
= evalexp (temp1
, &expok
);
5294 len
= -1; /* paranoia */
5298 case VT_ARRAYMEMBER
:
5299 len
= MB_STRLEN (value
);
5302 len
= number_of_args () + 1;
5304 #if defined (ARRAY_VARS)
5307 /* For arrays, the first value deals with array indices. Negative
5308 offsets count from one past the array's maximum index. */
5309 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5314 if (len
== -1) /* paranoia */
5317 if (*e1p
< 0) /* negative offsets count from end */
5320 if (*e1p
> len
|| *e1p
< 0)
5323 #if defined (ARRAY_VARS)
5324 /* For arrays, the second offset deals with the number of elements. */
5325 if (vtype
== VT_ARRAYVAR
)
5326 len
= array_num_elements (a
);
5332 temp2
= savestring (t
);
5333 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5336 *e2p
= evalexp (temp1
, &expok
);
5342 internal_error (_("%s: substring expression < 0"), t
);
5345 #if defined (ARRAY_VARS)
5346 /* In order to deal with sparse arrays, push the intelligence about how
5347 to deal with the number of elements desired down to the array-
5348 specific functions. */
5349 if (vtype
!= VT_ARRAYVAR
)
5352 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5363 /* Return the type of variable specified by VARNAME (simple variable,
5364 positional param, or array variable). Also return the value specified
5365 by VARNAME (value of a variable or a reference to an array element).
5366 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5367 characters in the value are quoted with CTLESC and takes appropriate
5368 steps. For convenience, *VALP is set to the dequoted VALUE. */
5370 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5371 char *varname
, *value
;
5378 #if defined (ARRAY_VARS)
5382 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5383 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5384 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5385 vtype
|= VT_STARSUB
;
5386 *varp
= (SHELL_VAR
*)NULL
;
5388 #if defined (ARRAY_VARS)
5389 if (valid_array_reference (varname
))
5391 v
= array_variable_part (varname
, &temp
, (int *)0);
5392 if (v
&& array_p (v
))
5394 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5396 vtype
= VT_ARRAYVAR
;
5398 vtype
|= VT_STARSUB
;
5399 *valp
= (char *)array_cell (v
);
5403 vtype
= VT_ARRAYMEMBER
;
5404 *valp
= array_value (varname
, 1, (int *)NULL
);
5408 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5410 vtype
= VT_VARIABLE
;
5412 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5413 *valp
= dequote_string (value
);
5415 *valp
= dequote_escapes (value
);
5420 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && array_p (v
))
5422 vtype
= VT_ARRAYMEMBER
;
5424 *valp
= array_reference (array_cell (v
), 0);
5429 if (value
&& vtype
== VT_VARIABLE
)
5431 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5432 *valp
= dequote_string (value
);
5434 *valp
= dequote_escapes (value
);
5443 /******************************************************/
5445 /* Functions to extract substrings of variable values */
5447 /******************************************************/
5449 #if defined (HANDLE_MULTIBYTE)
5450 /* Character-oriented rather than strictly byte-oriented substrings. S and
5451 E, rather being strict indices into STRING, indicate character (possibly
5452 multibyte character) positions that require calculation.
5453 Used by the ${param:offset[:length]} expansion. */
5455 mb_substring (string
, s
, e
)
5460 int start
, stop
, i
, slen
;
5464 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5465 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
5468 while (string
[start
] && i
--)
5469 ADVANCE_CHAR (string
, slen
, start
);
5472 while (string
[stop
] && i
--)
5473 ADVANCE_CHAR (string
, slen
, stop
);
5474 tt
= substring (string
, start
, stop
);
5479 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5480 is `@', use the positional parameters; otherwise, use the value of
5481 VARNAME. If VARNAME is an array variable, use the array elements. */
5484 parameter_brace_substring (varname
, value
, substr
, quoted
)
5485 char *varname
, *value
, *substr
;
5489 int vtype
, r
, starsub
;
5490 char *temp
, *val
, *tt
, *oname
;
5494 return ((char *)NULL
);
5496 oname
= this_command_name
;
5497 this_command_name
= varname
;
5499 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5502 this_command_name
= oname
;
5503 return ((char *)NULL
);
5506 starsub
= vtype
& VT_STARSUB
;
5507 vtype
&= ~VT_STARSUB
;
5509 r
= verify_substring_values (val
, substr
, vtype
, &e1
, &e2
);
5510 this_command_name
= oname
;
5512 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
5517 case VT_ARRAYMEMBER
:
5518 #if defined (HANDLE_MULTIBYTE)
5520 tt
= mb_substring (val
, e1
, e2
);
5523 tt
= substring (val
, e1
, e2
);
5525 if (vtype
== VT_VARIABLE
)
5527 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5528 temp
= quote_string (tt
);
5530 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5534 tt
= pos_params (varname
, e1
, e2
, quoted
);
5535 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5537 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5543 #if defined (ARRAY_VARS)
5545 /* We want E2 to be the number of elements desired (arrays can be sparse,
5546 so verify_substring_values just returns the numbers specified and we
5547 rely on array_subrange to understand how to deal with them). */
5548 tt
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
5549 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5551 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5559 temp
= (char *)NULL
;
5565 /****************************************************************/
5567 /* Functions to perform pattern substitution on variable values */
5569 /****************************************************************/
5572 pat_subst (string
, pat
, rep
, mflags
)
5573 char *string
, *pat
, *rep
;
5576 char *ret
, *s
, *e
, *str
;
5577 int rsize
, rptr
, l
, replen
, mtype
;
5579 mtype
= mflags
& MATCH_TYPEMASK
;
5582 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5583 * with REP and return the result.
5584 * 2. A null pattern with mtype == MATCH_END means to append REP to
5585 * STRING and return the result.
5587 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
5589 replen
= STRLEN (rep
);
5590 l
= strlen (string
);
5591 ret
= (char *)xmalloc (replen
+ l
+ 2);
5593 strcpy (ret
, string
);
5594 else if (mtype
== MATCH_BEG
)
5597 strcpy (ret
+ replen
, string
);
5601 strcpy (ret
, string
);
5602 strcpy (ret
+ l
, rep
);
5607 ret
= (char *)xmalloc (rsize
= 64);
5610 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
5612 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
5615 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
5617 /* OK, now copy the leading unmatched portion of the string (from
5618 str to s) to ret starting at rptr (the current offset). Then copy
5619 the replacement string at ret + rptr + (s - str). Increment
5620 rptr (if necessary) and str and go on. */
5623 strncpy (ret
+ rptr
, str
, l
);
5628 strncpy (ret
+ rptr
, rep
, replen
);
5631 str
= e
; /* e == end of match */
5633 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
5637 e
++, str
++; /* avoid infinite recursion on zero-length match */
5640 /* Now copy the unmatched portion of the input string */
5643 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
5644 strcpy (ret
+ rptr
, str
);
5652 /* Do pattern match and replacement on the positional parameters. */
5654 pos_params_pat_subst (string
, pat
, rep
, mflags
)
5655 char *string
, *pat
, *rep
;
5658 WORD_LIST
*save
, *params
;
5662 save
= params
= list_rest_of_args ();
5664 return ((char *)NULL
);
5666 for ( ; params
; params
= params
->next
)
5668 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
5669 w
= alloc_word_desc ();
5670 w
->word
= ret
? ret
: savestring ("");
5671 dispose_word (params
->word
);
5675 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
5676 ret
= string_list_dollar_star (quote_list (save
));
5678 ret
= string_list ((mflags
& MATCH_QUOTED
) ? quote_list (save
) : save
);
5679 dispose_words (save
);
5684 /* Perform pattern substitution on VALUE, which is the expansion of
5685 VARNAME. PATSUB is an expression supplying the pattern to match
5686 and the string to substitute. QUOTED is a flags word containing
5687 the type of quoting currently in effect. */
5689 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
5690 char *varname
, *value
, *patsub
;
5693 int vtype
, mflags
, starsub
;
5694 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
5698 return ((char *)NULL
);
5700 this_command_name
= varname
;
5702 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5704 return ((char *)NULL
);
5706 starsub
= vtype
& VT_STARSUB
;
5707 vtype
&= ~VT_STARSUB
;
5710 if (patsub
&& *patsub
== '/')
5712 mflags
|= MATCH_GLOBREP
;
5716 /* Malloc this because expand_string_if_necessary or one of the expansion
5717 functions in its call chain may free it on a substitution error. */
5718 lpatsub
= savestring (patsub
);
5720 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5721 mflags
|= MATCH_QUOTED
;
5724 mflags
|= MATCH_STARSUB
;
5726 /* If the pattern starts with a `/', make sure we skip over it when looking
5727 for the replacement delimiter. */
5728 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
5733 if (rep
&& *rep
== '\0')
5736 /* Perform the same expansions on the pattern as performed by the
5737 pattern removal expansions. */
5738 pat
= getpattern (lpatsub
, quoted
, 1);
5742 if ((mflags
& MATCH_QUOTED
) == 0)
5743 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
5745 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
5748 /* ksh93 doesn't allow the match specifier to be a part of the expanded
5749 pattern. This is an extension. Make sure we don't anchor the pattern
5750 at the beginning or end of the string if we're doing global replacement,
5753 if (mflags
& MATCH_GLOBREP
)
5754 mflags
|= MATCH_ANY
;
5755 else if (pat
&& pat
[0] == '#')
5757 mflags
|= MATCH_BEG
;
5760 else if (pat
&& pat
[0] == '%')
5762 mflags
|= MATCH_END
;
5766 mflags
|= MATCH_ANY
;
5768 /* OK, we now want to substitute REP for PAT in VAL. If
5769 flags & MATCH_GLOBREP is non-zero, the substitution is done
5770 everywhere, otherwise only the first occurrence of PAT is
5771 replaced. The pattern matching code doesn't understand
5772 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5773 values passed in (VT_VARIABLE) so the pattern substitution
5774 code works right. We need to requote special chars after
5775 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5776 other cases if QUOTED == 0, since the posparams and arrays
5777 indexed by * or @ do special things when QUOTED != 0. */
5782 case VT_ARRAYMEMBER
:
5783 temp
= pat_subst (val
, p
, rep
, mflags
);
5784 if (vtype
== VT_VARIABLE
)
5788 tt
= quote_escapes (temp
);
5794 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
5795 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5797 tt
= quote_escapes (temp
);
5802 #if defined (ARRAY_VARS)
5804 temp
= array_patsub (array_cell (v
), p
, rep
, mflags
);
5805 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5807 tt
= quote_escapes (temp
);
5822 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
5823 any occur, this must be a nested command substitution, so return 0.
5824 Otherwise, return 1. A valid arithmetic expression must always have a
5825 ( before a matching ), so any cases where there are more right parens
5826 means that this must not be an arithmetic expression, though the parser
5827 will not accept it without a balanced total number of parens. */
5829 chk_arithsub (s
, len
)
5841 else if (s
[i
] == ')')
5851 ADVANCE_CHAR (s
, len
, i
);
5857 ADVANCE_CHAR (s
, len
, i
);
5861 i
= skip_single_quoted (s
, len
, ++i
);
5865 i
= skip_double_quoted ((char *)s
, len
, ++i
);
5870 return (count
== 0);
5873 /****************************************************************/
5875 /* Functions to perform parameter expansion on a string */
5877 /****************************************************************/
5879 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5881 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5883 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
5885 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
5886 int want_substring
, want_indir
, want_patsub
;
5887 char *name
, *value
, *temp
, *temp1
;
5888 WORD_DESC
*tdesc
, *ret
;
5889 int t_index
, sindex
, c
, tflag
;
5892 value
= (char *)NULL
;
5893 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
5894 want_substring
= want_indir
= want_patsub
= 0;
5898 /* ${#var} doesn't have any of the other parameter expansions on it. */
5899 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
5900 name
= string_extract (string
, &t_index
, "}", EX_VARNAME
);
5902 name
= string_extract (string
, &t_index
, "#%:-=?+/}", EX_VARNAME
);
5907 /* If the name really consists of a special variable, then make sure
5908 that we have the entire name. We don't allow indirect references
5909 to special variables except `#', `?', `@' and `*'. */
5910 if ((sindex
== t_index
&&
5911 (string
[t_index
] == '-' ||
5912 string
[t_index
] == '?' ||
5913 string
[t_index
] == '#')) ||
5914 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
5915 (string
[t_index
] == '#' ||
5916 string
[t_index
] == '?' ||
5917 string
[t_index
] == '@' ||
5918 string
[t_index
] == '*')))
5922 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
5923 name
= (char *)xmalloc (3 + (strlen (temp1
)));
5924 *name
= string
[sindex
];
5925 if (string
[sindex
] == '!')
5927 /* indirect reference of $#, $?, $@, or $* */
5928 name
[1] = string
[sindex
+ 1];
5929 strcpy (name
+ 2, temp1
);
5932 strcpy (name
+ 1, temp1
);
5937 /* Find out what character ended the variable name. Then
5938 do the appropriate thing. */
5939 if (c
= string
[sindex
])
5942 /* If c is followed by one of the valid parameter expansion
5943 characters, move past it as normal. If not, assume that
5944 a substring specification is being given, and do not move
5946 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
5949 if (c
= string
[sindex
])
5952 else if (c
== ':' && string
[sindex
] != RBRACE
)
5954 else if (c
== '/' && string
[sindex
] != RBRACE
)
5957 /* Catch the valid and invalid brace expressions that made it through the
5959 /* ${#-} is a valid expansion and means to take the length of $-.
5960 Similarly for ${#?} and ${##}... */
5961 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
5962 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
5964 name
= (char *)xrealloc (name
, 3);
5967 c
= string
[sindex
++];
5970 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
5971 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
5972 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
5974 temp
= (char *)NULL
;
5975 goto bad_substitution
;
5978 /* Indirect expansion begins with a `!'. A valid indirect expansion is
5979 either a variable name, one of the positional parameters or a special
5980 variable that expands to one of the positional parameters. */
5981 want_indir
= *name
== '!' &&
5982 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
5983 || VALID_INDIR_PARAM (name
[1]));
5985 /* Determine the value of this variable. */
5987 /* Check for special variables, directly referenced. */
5988 if (SPECIAL_VAR (name
, want_indir
))
5991 /* Check for special expansion things, like the length of a parameter */
5992 if (*name
== '#' && name
[1])
5994 /* If we are not pointing at the character just after the
5995 closing brace, then we haven't gotten all of the name.
5996 Since it begins with a special character, this is a bad
5997 substitution. Also check NAME for validity before trying
5999 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6001 temp
= (char *)NULL
;
6002 goto bad_substitution
;
6005 number
= parameter_brace_expand_length (name
);
6010 return (&expand_wdesc_error
);
6013 ret
= alloc_word_desc ();
6014 ret
->word
= itos (number
);
6019 /* ${@} is identical to $@. */
6020 if (name
[0] == '@' && name
[1] == '\0')
6022 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6023 *quoted_dollar_atp
= 1;
6025 if (contains_dollar_at
)
6026 *contains_dollar_at
= 1;
6029 /* Process ${!PREFIX*} expansion. */
6030 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6031 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6032 legal_variable_starter ((unsigned char) name
[1]))
6037 temp1
= savestring (name
+ 1);
6038 number
= strlen (temp1
);
6039 temp1
[number
- 1] = '\0';
6040 x
= all_variables_matching_prefix (temp1
);
6041 xlist
= strvec_to_word_list (x
, 0, 0);
6042 if (string
[sindex
- 2] == '*')
6043 temp
= string_list_dollar_star (xlist
);
6046 temp
= string_list_dollar_at (xlist
, quoted
);
6047 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6048 *quoted_dollar_atp
= 1;
6049 if (contains_dollar_at
)
6050 *contains_dollar_at
= 1;
6057 ret
= alloc_word_desc ();
6062 #if defined (ARRAY_VARS)
6063 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6064 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6065 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6069 temp1
= savestring (name
+ 1);
6070 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6072 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6074 temp
= array_keys (temp1
, quoted
);
6077 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6078 *quoted_dollar_atp
= 1;
6079 if (contains_dollar_at
)
6080 *contains_dollar_at
= 1;
6086 ret
= alloc_word_desc ();
6093 #endif /* ARRAY_VARS */
6095 /* Make sure that NAME is valid before trying to go on. */
6096 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6097 var_is_special
) == 0)
6099 temp
= (char *)NULL
;
6100 goto bad_substitution
;
6104 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6106 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
6111 tflag
= tdesc
->flags
;
6112 dispose_word_desc (tdesc
);
6117 #if defined (ARRAY_VARS)
6118 if (valid_array_reference (name
))
6119 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6122 var_is_set
= temp
!= (char *)0;
6123 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6125 /* Get the rest of the stuff inside the braces. */
6126 if (c
&& c
!= RBRACE
)
6128 /* Extract the contents of the ${ ... } expansion
6129 according to the Posix.2 rules. */
6130 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6131 if (string
[sindex
] == RBRACE
)
6134 goto bad_substitution
;
6137 value
= (char *)NULL
;
6141 /* If this is a substring spec, process it and add the result. */
6144 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6149 if (temp1
== &expand_param_error
)
6150 return (&expand_wdesc_error
);
6151 else if (temp1
== &expand_param_fatal
)
6152 return (&expand_wdesc_fatal
);
6154 ret
= alloc_word_desc ();
6156 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6157 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6160 else if (want_patsub
)
6162 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6167 if (temp1
== &expand_param_error
)
6168 return (&expand_wdesc_error
);
6169 else if (temp1
== &expand_param_fatal
)
6170 return (&expand_wdesc_fatal
);
6172 ret
= alloc_word_desc ();
6177 /* Do the right thing based on which character ended the variable name. */
6183 report_error (_("%s: bad substitution"), string
? string
: "??");
6187 return &expand_wdesc_error
;
6190 if (var_is_set
== 0 && unbound_vars_is_error
)
6192 err_unboundvar (name
);
6196 last_command_exit_value
= EXECUTION_FAILURE
;
6197 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6201 case '#': /* ${param#[#]pattern} */
6202 case '%': /* ${param%[%]pattern} */
6203 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6208 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6218 if (var_is_set
&& var_is_null
== 0)
6220 /* If the operator is `+', we don't want the value of the named
6221 variable for anything, just the value of the right hand side. */
6225 /* XXX -- if we're double-quoted and the named variable is "$@",
6226 we want to turn off any special handling of "$@" --
6227 we're not using it, so whatever is on the rhs applies. */
6228 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6229 *quoted_dollar_atp
= 0;
6230 if (contains_dollar_at
)
6231 *contains_dollar_at
= 0;
6236 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6239 contains_dollar_at
);
6240 /* XXX - fix up later, esp. noting presence of
6241 W_HASQUOTEDNULL in ret->flags */
6245 temp
= (char *)NULL
;
6251 /* Otherwise do nothing; just use the value in TEMP. */
6253 else /* VAR not set or VAR is NULL. */
6256 temp
= (char *)NULL
;
6257 if (c
== '=' && var_is_special
)
6259 report_error (_("$%s: cannot assign in this way"), name
);
6262 return &expand_wdesc_error
;
6266 parameter_brace_expand_error (name
, value
);
6267 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6271 /* XXX -- if we're double-quoted and the named variable is "$@",
6272 we want to turn off any special handling of "$@" --
6273 we're not using it, so whatever is on the rhs applies. */
6274 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6275 *quoted_dollar_atp
= 0;
6276 if (contains_dollar_at
)
6277 *contains_dollar_at
= 0;
6279 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
6281 contains_dollar_at
);
6282 /* XXX - fix up later, esp. noting presence of
6283 W_HASQUOTEDNULL in tdesc->flags */
6294 ret
= alloc_word_desc ();
6301 /* Expand a single ${xxx} expansion. The braces are optional. When
6302 the braces are used, parameter_brace_expand() does the work,
6303 possibly calling param_expand recursively. */
6305 param_expand (string
, sindex
, quoted
, expanded_something
,
6306 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
6309 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
6310 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
6312 char *temp
, *temp1
, uerror
[3];
6313 int zindex
, t_index
, expok
;
6318 WORD_DESC
*tdesc
, *ret
;
6322 c
= string
[++zindex
];
6324 temp
= (char *)NULL
;
6325 ret
= tdesc
= (WORD_DESC
*)NULL
;
6328 /* Do simple cases first. Switch on what follows '$'. */
6342 temp1
= dollar_vars
[TODIGIT (c
)];
6343 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
6348 err_unboundvar (uerror
);
6349 last_command_exit_value
= EXECUTION_FAILURE
;
6350 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6353 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6354 ? quote_string (temp1
)
6355 : quote_escapes (temp1
);
6357 temp
= (char *)NULL
;
6361 /* $$ -- pid of the invoking shell. */
6363 temp
= itos (dollar_dollar_pid
);
6366 /* $# -- number of positional parameters. */
6368 temp
= itos (number_of_args ());
6371 /* $? -- return value of the last synchronous command. */
6373 temp
= itos (last_command_exit_value
);
6376 /* $- -- flags supplied to the shell on invocation or by `set'. */
6378 temp
= which_set_flags ();
6381 /* $! -- Pid of the last asynchronous command. */
6383 /* If no asynchronous pids have been created, expand to nothing.
6384 If `set -u' has been executed, and no async processes have
6385 been created, this is an expansion error. */
6386 if (last_asynchronous_pid
== NO_PID
)
6388 if (expanded_something
)
6389 *expanded_something
= 0;
6390 temp
= (char *)NULL
;
6391 if (unbound_vars_is_error
)
6396 err_unboundvar (uerror
);
6397 last_command_exit_value
= EXECUTION_FAILURE
;
6398 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6402 temp
= itos (last_asynchronous_pid
);
6405 /* The only difference between this and $@ is when the arg is quoted. */
6406 case '*': /* `$*' */
6407 list
= list_rest_of_args ();
6409 /* If there are no command-line arguments, this should just
6410 disappear if there are other characters in the expansion,
6411 even if it's quoted. */
6412 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
6413 temp
= (char *)NULL
;
6414 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6416 /* If we have "$*" we want to make a string of the positional
6417 parameters, separated by the first character of $IFS, and
6418 quote the whole string, including the separators. If IFS
6419 is unset, the parameters are separated by ' '; if $IFS is
6420 null, the parameters are concatenated. */
6421 temp
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (list
) : string_list (list
);
6422 temp1
= quote_string (temp
);
6424 tflag
|= W_HASQUOTEDNULL
;
6430 /* We check whether or not we're eventually going to split $* here,
6431 for example when IFS is empty and we are processing the rhs of
6432 an assignment statement. In that case, we don't separate the
6433 arguments at all. Otherwise, if the $* is not quoted it is
6436 # if defined (HANDLE_MULTIBYTE)
6437 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
6439 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
6441 temp
= string_list_dollar_star (list
);
6443 temp
= string_list_dollar_at (list
, quoted
);
6445 temp
= string_list_dollar_at (list
, quoted
);
6447 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
6448 *contains_dollar_at
= 1;
6451 dispose_words (list
);
6454 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
6455 means that we have to turn quoting off after we split into
6456 the individually quoted arguments so that the final split
6457 on the first character of $IFS is still done. */
6458 case '@': /* `$@' */
6459 list
= list_rest_of_args ();
6461 /* We want to flag the fact that we saw this. We can't turn
6462 off quoting entirely, because other characters in the
6463 string might need it (consider "\"$@\""), but we need some
6464 way to signal that the final split on the first character
6465 of $IFS should be done, even though QUOTED is 1. */
6466 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6467 *quoted_dollar_at_p
= 1;
6468 if (contains_dollar_at
)
6469 *contains_dollar_at
= 1;
6471 /* We want to separate the positional parameters with the first
6472 character of $IFS in case $IFS is something other than a space.
6473 We also want to make sure that splitting is done no matter what --
6474 according to POSIX.2, this expands to a list of the positional
6475 parameters no matter what IFS is set to. */
6476 temp
= string_list_dollar_at (list
, quoted
);
6478 dispose_words (list
);
6482 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
6484 contains_dollar_at
);
6486 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
6488 temp
= tdesc
? tdesc
->word
: (char *)0;
6491 /* Quoted nulls should be removed if there is anything else
6493 /* Note that we saw the quoted null so we can add one back at
6494 the end of this function if there are no other characters
6495 in the string, discard TEMP, and go on. The exception to
6496 this is when we have "${@}" and $1 is '', since $@ needs
6497 special handling. */
6498 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
6500 if (had_quoted_null_p
)
6501 *had_quoted_null_p
= 1;
6502 if (*quoted_dollar_at_p
== 0)
6505 tdesc
->word
= temp
= (char *)NULL
;
6513 /* Do command or arithmetic substitution. */
6515 /* We have to extract the contents of this paren substitution. */
6516 t_index
= zindex
+ 1;
6517 temp
= extract_command_subst (string
, &t_index
);
6520 /* For Posix.2-style `$(( ))' arithmetic substitution,
6521 extract the expression and pass it to the evaluator. */
6522 if (temp
&& *temp
== LPAREN
)
6526 temp2
= savestring (temp1
);
6527 t_index
= strlen (temp2
) - 1;
6529 if (temp2
[t_index
] != RPAREN
)
6535 /* Cut off ending `)' */
6536 temp2
[t_index
] = '\0';
6538 if (chk_arithsub (temp2
, t_index
) == 0)
6544 /* Expand variables found inside the expression. */
6545 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6549 /* No error messages. */
6550 this_command_name
= (char *)NULL
;
6551 number
= evalexp (temp1
, &expok
);
6556 if (interactive_shell
== 0 && posixly_correct
)
6558 last_command_exit_value
= EXECUTION_FAILURE
;
6559 return (&expand_wdesc_fatal
);
6562 return (&expand_wdesc_error
);
6564 temp
= itos (number
);
6569 if (pflags
& PF_NOCOMSUB
)
6570 /* we need zindex+1 because string[zindex] == RPAREN */
6571 temp1
= substring (string
, *sindex
, zindex
+1);
6573 temp1
= command_substitute (temp
, quoted
);
6578 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6579 away in a future bash release. */
6581 /* Extract the contents of this arithmetic substitution. */
6582 t_index
= zindex
+ 1;
6583 temp
= extract_arithmetic_subst (string
, &t_index
);
6586 /* Do initial variable expansion. */
6587 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
6592 /* Find the variable in VARIABLE_LIST. */
6593 temp
= (char *)NULL
;
6595 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
6597 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
6599 /* If this isn't a variable name, then just output the `$'. */
6600 if (temp1
== 0 || *temp1
== '\0')
6603 temp
= (char *)xmalloc (2);
6606 if (expanded_something
)
6607 *expanded_something
= 0;
6611 /* If the variable exists, return its value cell. */
6612 var
= find_variable (temp1
);
6614 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
6616 #if defined (ARRAY_VARS)
6619 temp
= array_reference (array_cell (var
), 0);
6621 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6622 ? quote_string (temp
)
6623 : quote_escapes (temp
);
6624 else if (unbound_vars_is_error
)
6625 goto unbound_variable
;
6630 temp
= value_cell (var
);
6632 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6633 ? quote_string (temp
)
6634 : quote_escapes (temp
);
6642 temp
= (char *)NULL
;
6645 if (unbound_vars_is_error
)
6646 err_unboundvar (temp1
);
6654 last_command_exit_value
= EXECUTION_FAILURE
;
6655 return ((unbound_vars_is_error
&& interactive_shell
== 0)
6656 ? &expand_wdesc_fatal
6657 : &expand_wdesc_error
);
6668 ret
= alloc_word_desc ();
6669 ret
->flags
= tflag
; /* XXX */
6675 /* Make a word list which is the result of parameter and variable
6676 expansion, command substitution, arithmetic substitution, and
6677 quote removal of WORD. Return a pointer to a WORD_LIST which is
6678 the result of the expansion. If WORD contains a null word, the
6679 word list returned is also null.
6681 QUOTED contains flag values defined in shell.h.
6683 ISEXP is used to tell expand_word_internal that the word should be
6684 treated as the result of an expansion. This has implications for
6685 how IFS characters in the word are treated.
6687 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6688 they point to an integer value which receives information about expansion.
6689 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6690 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6693 This only does word splitting in the case of $@ expansion. In that
6694 case, we split on ' '. */
6696 /* Values for the local variable quoted_state. */
6698 #define PARTIALLY_QUOTED 1
6699 #define WHOLLY_QUOTED 2
6702 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
6705 int *contains_dollar_at
;
6706 int *expanded_something
;
6711 /* The intermediate string that we build while expanding. */
6714 /* The current size of the above object. */
6717 /* Index into ISTRING. */
6720 /* Temporary string storage. */
6723 /* The text of WORD. */
6724 register char *string
;
6726 /* The size of STRING. */
6729 /* The index into STRING. */
6732 /* This gets 1 if we see a $@ while quoted. */
6733 int quoted_dollar_at
;
6735 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6736 whether WORD contains no quoting characters, a partially quoted
6737 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6741 int had_quoted_null
;
6745 int assignoff
; /* If assignment, offset of `=' */
6747 register unsigned char c
; /* Current character. */
6748 int t_index
; /* For calls to string_extract_xxx. */
6754 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
6755 istring
[istring_index
= 0] = '\0';
6756 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
6757 quoted_state
= UNQUOTED
;
6759 string
= word
->word
;
6761 goto finished_with_string
;
6762 /* Don't need the string length for the SADD... and COPY_ macros unless
6763 multibyte characters are possible. */
6764 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
6766 if (contains_dollar_at
)
6767 *contains_dollar_at
= 0;
6771 /* Begin the expansion. */
6777 /* Case on toplevel character. */
6781 goto finished_with_string
;
6785 #if HANDLE_MULTIBYTE
6786 if (MB_CUR_MAX
> 1 && string
[sindex
])
6788 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
6793 temp
= (char *)xmalloc (3);
6795 temp
[1] = c
= string
[sindex
];
6806 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
6812 #if defined (PROCESS_SUBSTITUTION)
6813 /* Process substitution. */
6817 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
6819 sindex
--; /* add_character: label increments sindex */
6823 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
6825 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
6828 /* If the process substitution specification is `<()', we want to
6829 open the pipe for writing in the child and produce output; if
6830 it is `>()', we want to open the pipe for reading in the child
6831 and consume input. */
6832 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
6836 goto dollar_add_string
;
6838 #endif /* PROCESS_SUBSTITUTION */
6841 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6842 which are not assignment statements are not expanded. If the
6843 shell isn't in posix mode, though, we perform tilde expansion
6844 on `likely candidate' unquoted assignment statements (flags
6845 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
6846 contains an unquoted :~ or =~. Something to think about: we
6847 now have a flag that says to perform tilde expansion on arguments
6848 to `assignment builtins' like declare and export that look like
6849 assignment statements. We now do tilde expansion on such words
6850 even in POSIX mode. */
6851 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
6853 /* If we're not in posix mode or forcing assignment-statement tilde
6854 expansion, note where the `=' appears in the word and prepare to
6855 do tilde expansion following the first `='. */
6856 if ((word
->flags
& W_ASSIGNMENT
) &&
6857 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6858 assignoff
== -1 && sindex
> 0)
6860 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
6861 word
->flags
|= W_ITILDE
;
6863 else if ((word
->flags
& W_ASSIGNMENT
) &&
6864 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6865 string
[sindex
+1] == '~')
6866 word
->flags
|= W_ITILDE
;
6871 if (word
->flags
& W_NOTILDE
)
6874 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
6875 string
[sindex
+1] == '~')
6876 word
->flags
|= W_ITILDE
;
6880 /* If the word isn't supposed to be tilde expanded, or we're not
6881 at the start of a word or after an unquoted : or = in an
6882 assignment statement, we don't do tilde expansion. */
6883 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
6884 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
6885 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6887 word
->flags
&= ~W_ITILDE
;
6891 if (word
->flags
& W_ASSIGNRHS
)
6893 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
6898 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
6900 word
->flags
&= ~W_ITILDE
;
6902 if (temp
&& *temp
&& t_index
> 0)
6904 temp1
= bash_tilde_expand (temp
, tflag
);
6905 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
6909 goto add_character
; /* tilde expansion failed */
6923 if (expanded_something
)
6924 *expanded_something
= 1;
6927 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
6928 &has_dollar_at
, "ed_dollar_at
,
6930 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
6932 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
6936 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
6937 : &expand_word_fatal
);
6939 if (contains_dollar_at
&& has_dollar_at
)
6940 *contains_dollar_at
= 1;
6942 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
6943 had_quoted_null
= 1;
6946 dispose_word_desc (tword
);
6951 case '`': /* Backquoted command substitution. */
6955 temp
= string_extract (string
, &sindex
, "`", EX_REQMATCH
);
6956 /* The test of sindex against t_index is to allow bare instances of
6957 ` to pass through, for backwards compatibility. */
6958 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
6960 if (sindex
- 1 == t_index
)
6965 report_error ("bad substitution: no closing \"`\" in %s", string
+t_index
);
6968 return ((temp
== &extract_string_error
) ? &expand_word_error
6969 : &expand_word_fatal
);
6972 if (expanded_something
)
6973 *expanded_something
= 1;
6975 if (word
->flags
& W_NOCOMSUB
)
6976 /* sindex + 1 because string[sindex] == '`' */
6977 temp1
= substring (string
, t_index
, sindex
+ 1);
6980 de_backslash (temp
);
6981 temp1
= command_substitute (temp
, quoted
);
6985 goto dollar_add_string
;
6989 if (string
[sindex
+ 1] == '\n')
6995 c
= string
[++sindex
];
6997 if (quoted
& Q_HERE_DOCUMENT
)
6999 else if (quoted
& Q_DOUBLE_QUOTES
)
7004 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7006 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7011 sindex
--; /* add_character: label increments sindex */
7016 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7021 /* BEFORE jumping here, we need to increment sindex if appropriate */
7022 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7023 DEFAULT_ARRAY_SIZE
);
7024 istring
[istring_index
++] = twochars
[0];
7025 istring
[istring_index
++] = twochars
[1];
7026 istring
[istring_index
] = '\0';
7032 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7034 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7039 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7041 /* If the quotes surrounded the entire string, then the
7042 whole word was quoted. */
7043 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7049 tword
= alloc_word_desc ();
7052 temp
= (char *)NULL
;
7055 /* Need to get W_HASQUOTEDNULL flag through this function. */
7056 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7058 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7062 /* expand_word_internal has already freed temp_word->word
7063 for us because of the way it prints error messages. */
7064 tword
->word
= (char *)NULL
;
7065 dispose_word (tword
);
7069 dispose_word (tword
);
7071 /* "$@" (a double-quoted dollar-at) expands into nothing,
7072 not even a NULL word, when there are no positional
7074 if (list
== 0 && has_dollar_at
)
7080 /* If we get "$@", we know we have expanded something, so we
7081 need to remember it for the final split on $IFS. This is
7082 a special case; it's the only case where a quoted string
7083 can expand into more than one word. It's going to come back
7084 from the above call to expand_word_internal as a list with
7085 a single word, in which all characters are quoted and
7086 separated by blanks. What we want to do is to turn it back
7087 into a list for the next piece of code. */
7089 dequote_list (list
);
7091 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7092 had_quoted_null
= 1;
7097 if (contains_dollar_at
)
7098 *contains_dollar_at
= 1;
7099 if (expanded_something
)
7100 *expanded_something
= 1;
7105 /* What we have is "". This is a minor optimization. */
7107 list
= (WORD_LIST
*)NULL
;
7110 /* The code above *might* return a list (consider the case of "$@",
7111 where it returns "$1", "$2", etc.). We can't throw away the
7112 rest of the list, and we have to make sure each word gets added
7113 as quoted. We test on tresult->next: if it is non-NULL, we
7114 quote the whole list, save it to a string with string_list, and
7115 add that string. We don't need to quote the results of this
7116 (and it would be wrong, since that would quote the separators
7117 as well), so we go directly to add_string. */
7122 /* Testing quoted_dollar_at makes sure that "$@" is
7123 split correctly when $IFS does not contain a space. */
7124 temp
= quoted_dollar_at
7125 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7126 : string_list (quote_list (list
));
7127 dispose_words (list
);
7132 temp
= savestring (list
->word
->word
);
7133 tflag
= list
->word
->flags
;
7134 dispose_words (list
);
7136 /* If the string is not a quoted null string, we want
7137 to remove any embedded unquoted CTLNUL characters.
7138 We do not want to turn quoted null strings back into
7139 the empty string, though. We do this because we
7140 want to remove any quoted nulls from expansions that
7141 contain other characters. For example, if we have
7142 x"$*"y or "x$*y" and there are no positional parameters,
7143 the $* should expand into nothing. */
7144 /* We use the W_HASQUOTEDNULL flag to differentiate the
7145 cases: a quoted null character as above and when
7146 CTLNUL is contained in the (non-null) expansion
7147 of some variable. We use the had_quoted_null flag to
7148 pass the value through this function to its caller. */
7149 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7150 remove_quoted_nulls (temp
); /* XXX */
7154 temp
= (char *)NULL
;
7156 /* We do not want to add quoted nulls to strings that are only
7157 partially quoted; we can throw them away. */
7158 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7166 temp
= quote_string (temp
);
7174 sindex
--; /* add_character: label increments sindex */
7182 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7184 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7189 temp
= string_extract_single_quoted (string
, &sindex
);
7191 /* If the entire STRING was surrounded by single quotes,
7192 then the string is wholly quoted. */
7193 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7197 /* If all we had was '', it is a null expansion. */
7201 temp
= (char *)NULL
;
7204 remove_quoted_escapes (temp
); /* ??? */
7206 /* We do not want to add quoted nulls to strings that are only
7207 partially quoted; such nulls are discarded. */
7208 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7211 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7215 sindex
--; /* add_character: label increments sindex */
7219 goto add_quoted_string
;
7224 /* This is the fix for " $@ " */
7225 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7227 if (string
[sindex
]) /* from old goto dollar_add_string */
7236 #if HANDLE_MULTIBYTE
7242 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7247 twochars
[0] = CTLESC
;
7254 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7257 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7258 DEFAULT_ARRAY_SIZE
);
7259 istring
[istring_index
++] = c
;
7260 istring
[istring_index
] = '\0';
7262 /* Next character. */
7267 finished_with_string
:
7268 /* OK, we're ready to return. If we have a quoted string, and
7269 quoted_dollar_at is not set, we do no splitting at all; otherwise
7270 we split on ' '. The routines that call this will handle what to
7271 do if nothing has been expanded. */
7273 /* Partially and wholly quoted strings which expand to the empty
7274 string are retained as an empty arguments. Unquoted strings
7275 which expand to the empty string are discarded. The single
7276 exception is the case of expanding "$@" when there are no
7277 positional parameters. In that case, we discard the expansion. */
7279 /* Because of how the code that handles "" and '' in partially
7280 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7281 if we saw quoting characters, but the expansion was empty.
7282 "" and '' are tossed away before we get to this point when
7283 processing partially quoted strings. This makes "" and $xxx""
7284 equivalent when xxx is unset. We also look to see whether we
7285 saw a quoted null from a ${} expansion and add one back if we
7288 /* If we expand to nothing and there were no single or double quotes
7289 in the word, we throw it away. Otherwise, we return a NULL word.
7290 The single exception is for $@ surrounded by double quotes when
7291 there are no positional parameters. In that case, we also throw
7294 if (*istring
== '\0')
7296 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7298 istring
[0] = CTLNUL
;
7300 tword
= make_bare_word (istring
);
7301 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7302 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7303 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7304 tword
->flags
|= W_QUOTED
;
7306 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7307 and a double-quoted "$@" appears anywhere in it, then the entire
7309 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
7310 list
= (WORD_LIST
*)NULL
;
7314 tword
= make_bare_word (istring
);
7315 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7316 tword
->flags
|= W_QUOTED
;
7317 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7321 list
= (WORD_LIST
*)NULL
;
7324 else if (word
->flags
& W_NOSPLIT
)
7326 tword
= make_bare_word (istring
);
7327 if (word
->flags
& W_ASSIGNMENT
)
7328 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
7329 if (word
->flags
& W_COMPASSIGN
)
7330 tword
->flags
|= W_COMPASSIGN
; /* XXX */
7331 if (word
->flags
& W_NOGLOB
)
7332 tword
->flags
|= W_NOGLOB
; /* XXX */
7333 if (word
->flags
& W_NOEXPAND
)
7334 tword
->flags
|= W_NOEXPAND
; /* XXX */
7335 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7336 tword
->flags
|= W_QUOTED
;
7337 if (had_quoted_null
)
7338 tword
->flags
|= W_HASQUOTEDNULL
;
7339 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7345 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
7347 /* If we have $@, we need to split the results no matter what. If
7348 IFS is unset or NULL, string_list_dollar_at has separated the
7349 positional parameters with a space, so we split on space (we have
7350 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7351 string_list_dollar_at has separated the positional parameters
7352 with the first character of $IFS, so we split on $IFS. */
7353 if (has_dollar_at
&& ifs_chars
)
7354 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
7357 tword
= make_bare_word (istring
);
7358 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
7359 tword
->flags
|= W_QUOTED
;
7360 if (word
->flags
& W_ASSIGNMENT
)
7361 tword
->flags
|= W_ASSIGNMENT
;
7362 if (word
->flags
& W_COMPASSIGN
)
7363 tword
->flags
|= W_COMPASSIGN
;
7364 if (word
->flags
& W_NOGLOB
)
7365 tword
->flags
|= W_NOGLOB
;
7366 if (word
->flags
& W_NOEXPAND
)
7367 tword
->flags
|= W_NOEXPAND
;
7368 if (had_quoted_null
)
7369 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7370 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7378 /* **************************************************************** */
7380 /* Functions for Quote Removal */
7382 /* **************************************************************** */
7384 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7385 backslash quoting rules for within double quotes or a here document. */
7387 string_quote_removal (string
, quoted
)
7392 char *r
, *result_string
, *temp
, *send
;
7393 int sindex
, tindex
, dquote
;
7397 /* The result can be no longer than the original string. */
7398 slen
= strlen (string
);
7399 send
= string
+ slen
;
7401 r
= result_string
= (char *)xmalloc (slen
+ 1);
7403 for (dquote
= sindex
= 0; c
= string
[sindex
];)
7408 c
= string
[++sindex
];
7409 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
7414 SCOPY_CHAR_M (r
, string
, send
, sindex
);
7418 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
7424 tindex
= sindex
+ 1;
7425 temp
= string_extract_single_quoted (string
, &tindex
);
7436 dquote
= 1 - dquote
;
7442 return (result_string
);
7447 /* Perform quote removal on word WORD. This allocates and returns a new
7450 word_quote_removal (word
, quoted
)
7457 t
= string_quote_removal (word
->word
, quoted
);
7458 w
= alloc_word_desc ();
7459 w
->word
= t
? t
: savestring ("");
7463 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
7464 the members of the list are treated as if they are surrounded by
7465 double quotes. Return a new list, or NULL if LIST is NULL. */
7467 word_list_quote_removal (list
, quoted
)
7471 WORD_LIST
*result
, *t
, *tresult
, *e
;
7473 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7475 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
7477 result
= (WORD_LIST
*) list_append (result
, tresult
);
7480 result
= e
= tresult
;
7493 /*******************************************
7495 * Functions to perform word splitting *
7497 *******************************************/
7508 ifs_value
= v
? value_cell (v
) : " \t\n";
7510 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
7513 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
7514 handle multibyte chars in IFS */
7515 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
7516 for (t
= ifs_value
; t
&& *t
; t
++)
7522 #if defined (HANDLE_MULTIBYTE)
7525 ifs_firstc
[0] = '\0';
7531 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
7532 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
7533 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
7535 ifs_firstc
[0] = ifs_value
[0];
7536 ifs_firstc
[1] = '\0';
7540 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
7543 ifs_firstc
= ifs_value
? *ifs_value
: 0;
7553 /* This splits a single word into a WORD LIST on $IFS, but only if the word
7554 is not quoted. list_string () performs quote removal for us, even if we
7555 don't do any splitting. */
7557 word_split (w
, ifs_chars
)
7567 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
7568 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
7571 result
= (WORD_LIST
*)NULL
;
7576 /* Perform word splitting on LIST and return the RESULT. It is possible
7577 to return (WORD_LIST *)NULL. */
7579 word_list_split (list
)
7582 WORD_LIST
*result
, *t
, *tresult
, *e
;
7584 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7586 tresult
= word_split (t
->word
, ifs_value
);
7588 result
= e
= tresult
;
7599 /**************************************************
7601 * Functions to expand an entire WORD_LIST *
7603 **************************************************/
7605 /* Do any word-expansion-specific cleanup and jump to top_level */
7607 exp_jump_to_top_level (v
)
7610 /* Cleanup code goes here. */
7611 expand_no_split_dollar_star
= 0; /* XXX */
7612 expanding_redir
= 0;
7614 jump_to_top_level (v
);
7617 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
7618 ELIST, and set ELIST to the new list. */
7619 #define PREPEND_LIST(nlist, elist) \
7620 do { nlist->next = elist; elist = nlist; } while (0)
7622 /* Separate out any initial variable assignments from TLIST. If set -k has
7623 been executed, remove all assignment statements from TLIST. Initial
7624 variable assignments and other environment assignments are placed
7625 on SUBST_ASSIGN_VARLIST. */
7627 separate_out_assignments (tlist
)
7630 register WORD_LIST
*vp
, *lp
;
7633 return ((WORD_LIST
*)NULL
);
7635 if (subst_assign_varlist
)
7636 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
7638 subst_assign_varlist
= (WORD_LIST
*)NULL
;
7641 /* Separate out variable assignments at the start of the command.
7642 Loop invariant: vp->next == lp
7644 lp = list of words left after assignment statements skipped
7645 tlist = original list of words
7647 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
7653 /* If lp != tlist, we have some initial assignment statements.
7654 We make SUBST_ASSIGN_VARLIST point to the list of assignment
7655 words and TLIST point to the remaining words. */
7658 subst_assign_varlist
= tlist
;
7659 /* ASSERT(vp->next == lp); */
7660 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
7661 tlist
= lp
; /* remainder of word list */
7664 /* vp == end of variable list */
7665 /* tlist == remainder of original word list without variable assignments */
7667 /* All the words in tlist were assignment statements */
7668 return ((WORD_LIST
*)NULL
);
7670 /* ASSERT(tlist != NULL); */
7671 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
7673 /* If the -k option is in effect, we need to go through the remaining
7674 words, separate out the assignment words, and place them on
7675 SUBST_ASSIGN_VARLIST. */
7676 if (place_keywords_in_env
)
7678 WORD_LIST
*tp
; /* tp == running pointer into tlist */
7683 /* Loop Invariant: tp->next == lp */
7684 /* Loop postcondition: tlist == word list without assignment statements */
7687 if (lp
->word
->flags
& W_ASSIGNMENT
)
7689 /* Found an assignment statement, add this word to end of
7690 subst_assign_varlist (vp). */
7691 if (!subst_assign_varlist
)
7692 subst_assign_varlist
= vp
= lp
;
7699 /* Remove the word pointed to by LP from TLIST. */
7700 tp
->next
= lp
->next
;
7701 /* ASSERT(vp == lp); */
7702 lp
->next
= (WORD_LIST
*)NULL
;
7715 #define WEXP_VARASSIGN 0x001
7716 #define WEXP_BRACEEXP 0x002
7717 #define WEXP_TILDEEXP 0x004
7718 #define WEXP_PARAMEXP 0x008
7719 #define WEXP_PATHEXP 0x010
7721 /* All of the expansions, including variable assignments at the start of
7723 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7725 /* All of the expansions except variable assignments at the start of
7727 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7729 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
7730 expansion, command substitution, arithmetic expansion, word splitting, and
7732 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7734 /* Take the list of words in LIST and do the various substitutions. Return
7735 a new list of words which is the expanded list, and without things like
7736 variable assignments. */
7742 return (expand_word_list_internal (list
, WEXP_ALL
));
7745 /* Same as expand_words (), but doesn't hack variable or environment
7748 expand_words_no_vars (list
)
7751 return (expand_word_list_internal (list
, WEXP_NOVARS
));
7755 expand_words_shellexp (list
)
7758 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
7762 glob_expand_word_list (tlist
, eflags
)
7766 char **glob_array
, *temp_string
;
7767 register int glob_index
;
7768 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
7771 output_list
= disposables
= (WORD_LIST
*)NULL
;
7772 glob_array
= (char **)NULL
;
7775 /* For each word, either globbing is attempted or the word is
7776 added to orig_list. If globbing succeeds, the results are
7777 added to orig_list and the word (tlist) is added to the list
7778 of disposable words. If globbing fails and failed glob
7779 expansions are left unchanged (the shell default), the
7780 original word is added to orig_list. If globbing fails and
7781 failed glob expansions are removed, the original word is
7782 added to the list of disposable words. orig_list ends up
7783 in reverse order and requires a call to REVERSE_LIST to
7784 be set right. After all words are examined, the disposable
7788 /* If the word isn't an assignment and contains an unquoted
7789 pattern matching character, then glob it. */
7790 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
7791 unquoted_glob_pattern_p (tlist
->word
->word
))
7793 glob_array
= shell_glob_filename (tlist
->word
->word
);
7795 /* Handle error cases.
7796 I don't think we should report errors like "No such file
7797 or directory". However, I would like to report errors
7798 like "Read failed". */
7800 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
7802 glob_array
= (char **)xmalloc (sizeof (char *));
7803 glob_array
[0] = (char *)NULL
;
7806 /* Dequote the current word in case we have to use it. */
7807 if (glob_array
[0] == NULL
)
7809 temp_string
= dequote_string (tlist
->word
->word
);
7810 free (tlist
->word
->word
);
7811 tlist
->word
->word
= temp_string
;
7814 /* Make the array into a word list. */
7815 glob_list
= (WORD_LIST
*)NULL
;
7816 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
7818 tword
= make_bare_word (glob_array
[glob_index
]);
7819 tword
->flags
|= W_GLOBEXP
; /* XXX */
7820 glob_list
= make_word_list (tword
, glob_list
);
7825 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
7826 PREPEND_LIST (tlist
, disposables
);
7828 else if (fail_glob_expansion
!= 0)
7830 report_error (_("no match: %s"), tlist
->word
->word
);
7831 jump_to_top_level (DISCARD
);
7833 else if (allow_null_glob_expansion
== 0)
7835 /* Failed glob expressions are left unchanged. */
7836 PREPEND_LIST (tlist
, output_list
);
7840 /* Failed glob expressions are removed. */
7841 PREPEND_LIST (tlist
, disposables
);
7846 /* Dequote the string. */
7847 temp_string
= dequote_string (tlist
->word
->word
);
7848 free (tlist
->word
->word
);
7849 tlist
->word
->word
= temp_string
;
7850 PREPEND_LIST (tlist
, output_list
);
7853 strvec_dispose (glob_array
);
7854 glob_array
= (char **)NULL
;
7860 dispose_words (disposables
);
7863 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7865 return (output_list
);
7868 #if defined (BRACE_EXPANSION)
7870 brace_expand_word_list (tlist
, eflags
)
7874 register char **expansions
;
7876 WORD_LIST
*disposables
, *output_list
, *next
;
7880 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
7884 /* Only do brace expansion if the word has a brace character. If
7885 not, just add the word list element to BRACES and continue. In
7886 the common case, at least when running shell scripts, this will
7887 degenerate to a bunch of calls to `xstrchr', and then what is
7888 basically a reversal of TLIST into BRACES, which is corrected
7889 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7891 if (xstrchr (tlist
->word
->word
, LBRACE
))
7893 expansions
= brace_expand (tlist
->word
->word
);
7895 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
7897 w
= make_word (temp_string
);
7898 /* If brace expansion didn't change the word, preserve
7899 the flags. We may want to preserve the flags
7900 unconditionally someday -- XXX */
7901 if (STREQ (temp_string
, tlist
->word
->word
))
7902 w
->flags
= tlist
->word
->flags
;
7903 output_list
= make_word_list (w
, output_list
);
7904 free (expansions
[eindex
]);
7908 /* Add TLIST to the list of words to be freed after brace
7909 expansion has been performed. */
7910 PREPEND_LIST (tlist
, disposables
);
7913 PREPEND_LIST (tlist
, output_list
);
7917 dispose_words (disposables
);
7920 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7922 return (output_list
);
7927 shell_expand_word_list (tlist
, eflags
)
7931 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
7932 int expanded_something
, has_dollar_at
;
7935 /* We do tilde expansion all the time. This is what 1003.2 says. */
7936 new_list
= (WORD_LIST
*)NULL
;
7937 for (orig_list
= tlist
; tlist
; tlist
= next
)
7939 temp_string
= tlist
->word
->word
;
7943 #if defined (ARRAY_VARS)
7944 /* If this is a compound array assignment to a builtin that accepts
7945 such assignments (e.g., `declare'), take the assignment and perform
7946 it separately, handling the semantics of declarations inside shell
7947 functions. This avoids the double-evaluation of such arguments,
7948 because `declare' does some evaluation of compound assignments on
7950 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
7954 t
= do_word_assignment (tlist
->word
);
7957 last_command_exit_value
= EXECUTION_FAILURE
;
7958 exp_jump_to_top_level (DISCARD
);
7961 /* Now transform the word as ksh93 appears to do and go on */
7962 t
= assignment (tlist
->word
->word
, 0);
7963 tlist
->word
->word
[t
] = '\0';
7964 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
);
7968 expanded_something
= 0;
7969 expanded
= expand_word_internal
7970 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
7972 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
7974 /* By convention, each time this error is returned,
7975 tlist->word->word has already been freed. */
7976 tlist
->word
->word
= (char *)NULL
;
7978 /* Dispose our copy of the original list. */
7979 dispose_words (orig_list
);
7980 /* Dispose the new list we're building. */
7981 dispose_words (new_list
);
7983 last_command_exit_value
= EXECUTION_FAILURE
;
7984 if (expanded
== &expand_word_error
)
7985 exp_jump_to_top_level (DISCARD
);
7987 exp_jump_to_top_level (FORCE_EOF
);
7990 /* Don't split words marked W_NOSPLIT. */
7991 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
7993 temp_list
= word_list_split (expanded
);
7994 dispose_words (expanded
);
7998 /* If no parameter expansion, command substitution, process
7999 substitution, or arithmetic substitution took place, then
8000 do not do word splitting. We still have to remove quoted
8001 null characters from the result. */
8002 word_list_remove_quoted_nulls (expanded
);
8003 temp_list
= expanded
;
8006 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8007 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8011 dispose_words (orig_list
);
8014 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8019 /* The workhorse for expand_words () and expand_words_no_vars ().
8020 First arg is LIST, a WORD_LIST of words.
8021 Second arg EFLAGS is a flags word controlling which expansions are
8024 This does all of the substitutions: brace expansion, tilde expansion,
8025 parameter expansion, command substitution, arithmetic expansion,
8026 process substitution, word splitting, and pathname expansion, according
8027 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8028 set, or for which no expansion is done, do not undergo word splitting.
8029 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8031 expand_word_list_internal (list
, eflags
)
8035 WORD_LIST
*new_list
, *temp_list
;
8039 return ((WORD_LIST
*)NULL
);
8041 garglist
= new_list
= copy_word_list (list
);
8042 if (eflags
& WEXP_VARASSIGN
)
8044 garglist
= new_list
= separate_out_assignments (new_list
);
8047 if (subst_assign_varlist
)
8049 /* All the words were variable assignments, so they are placed
8050 into the shell's environment. */
8051 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8053 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8054 tint
= do_word_assignment (temp_list
->word
);
8055 /* Variable assignment errors in non-interactive shells
8056 running in Posix.2 mode cause the shell to exit. */
8059 last_command_exit_value
= EXECUTION_FAILURE
;
8060 if (interactive_shell
== 0 && posixly_correct
)
8061 exp_jump_to_top_level (FORCE_EOF
);
8063 exp_jump_to_top_level (DISCARD
);
8066 dispose_words (subst_assign_varlist
);
8067 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8069 return ((WORD_LIST
*)NULL
);
8073 /* Begin expanding the words that remain. The expansions take place on
8074 things that aren't really variable assignments. */
8076 #if defined (BRACE_EXPANSION)
8077 /* Do brace expansion on this word if there are any brace characters
8079 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8080 new_list
= brace_expand_word_list (new_list
, eflags
);
8081 #endif /* BRACE_EXPANSION */
8083 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8084 variable substitution, command substitution, arithmetic expansion,
8085 and word splitting. */
8086 new_list
= shell_expand_word_list (new_list
, eflags
);
8088 /* Okay, we're almost done. Now let's just do some filename
8092 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8093 /* Glob expand the word list unless globbing has been disabled. */
8094 new_list
= glob_expand_word_list (new_list
, eflags
);
8096 /* Dequote the words, because we're not performing globbing. */
8097 new_list
= dequote_list (new_list
);
8100 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8102 sh_wassign_func_t
*assign_func
;
8104 /* If the remainder of the words expand to nothing, Posix.2 requires
8105 that the variable and environment assignments affect the shell's
8107 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8108 tempenv_assign_error
= 0;
8110 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8112 this_command_name
= (char *)NULL
;
8113 tint
= (*assign_func
) (temp_list
->word
);
8114 /* Variable assignment errors in non-interactive shells running
8115 in Posix.2 mode cause the shell to exit. */
8118 if (assign_func
== do_word_assignment
)
8120 last_command_exit_value
= EXECUTION_FAILURE
;
8121 if (interactive_shell
== 0 && posixly_correct
)
8122 exp_jump_to_top_level (FORCE_EOF
);
8124 exp_jump_to_top_level (DISCARD
);
8127 tempenv_assign_error
++;
8131 dispose_words (subst_assign_varlist
);
8132 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8136 tint
= list_length (new_list
) + 1;
8137 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8138 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8139 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8140 glob_argv_flags
[tint
] = '\0';