1 /* subst.c -- The part of the shell that does parameter, command, arithmetic,
2 and globbing substitutions. */
4 /* ``Have a little faith, there's magic in the night. You ain't a
5 beauty, but, hey, you're alright.'' */
7 /* Copyright (C) 1987-2007 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License along
22 with Bash; see the file COPYING. If not, write to the Free Software
23 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
27 #include "bashtypes.h"
29 #include "chartypes.h"
34 #if defined (HAVE_UNISTD_H)
39 #include "posixstat.h"
45 #include "execute_cmd.h"
49 #include "mailcheck.h"
53 #include "builtins/getopt.h"
54 #include "builtins/common.h"
56 #include <tilde/tilde.h>
57 #include <glob/strmatch.h>
63 /* The size that strings change by. */
64 #define DEFAULT_INITIAL_ARRAY_SIZE 112
65 #define DEFAULT_ARRAY_SIZE 128
71 #define VT_ARRAYMEMBER 3
73 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
75 /* Flags for quoted_strchr */
76 #define ST_BACKSL 0x01
77 #define ST_CTLESC 0x02
78 #define ST_SQUOTE 0x04 /* unused yet */
79 #define ST_DQUOTE 0x08 /* unused yet */
81 /* Flags for the string extraction functions. */
82 #define EX_NOALLOC 0x01 /* just skip; don't return substring */
83 #define EX_VARNAME 0x02 /* variable name; for string_extract () */
84 #define EX_REQMATCH 0x04 /* closing/matching delimiter required */
85 #define EX_COMMAND 0x08 /* extracting a shell script/command */
87 /* Flags for the `pflags' argument to param_expand() */
88 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 /* These defs make it easier to use the editor. */
96 /* Evaluates to 1 if C is one of the shell's special parameters whose length
97 can be taken, but is also one of the special expansion characters. */
98 #define VALID_SPECIAL_LENGTH_PARAM(c) \
99 ((c) == '-' || (c) == '?' || (c) == '#')
101 /* Evaluates to 1 if C is one of the shell's special parameters for which an
102 indirect variable reference may be made. */
103 #define VALID_INDIR_PARAM(c) \
104 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
106 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
107 in ${parameter[:]OPword}. */
108 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
110 /* Evaluates to 1 if this is one of the shell's special variables. */
111 #define SPECIAL_VAR(name, wi) \
112 ((DIGIT (*name) && all_digits (name)) || \
113 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
114 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
116 /* An expansion function that takes a string and a quoted flag and returns
117 a WORD_LIST *. Used as the type of the third argument to
118 expand_string_if_necessary(). */
119 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
121 /* Process ID of the last command executed within command substitution. */
122 pid_t last_command_subst_pid
= NO_PID
;
123 pid_t current_command_subst_pid
= NO_PID
;
125 /* Variables used to keep track of the characters in IFS. */
128 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
130 #if defined (HANDLE_MULTIBYTE)
131 unsigned char ifs_firstc
[MB_LEN_MAX
];
132 size_t ifs_firstc_len
;
134 unsigned char ifs_firstc
;
137 /* Extern functions and variables from different files. */
138 extern int last_command_exit_value
, last_command_exit_signal
;
139 extern int subshell_environment
;
140 extern int subshell_level
;
141 extern int eof_encountered
;
142 extern int return_catch_flag
, return_catch_value
;
143 extern pid_t dollar_dollar_pid
;
144 extern int posixly_correct
;
145 extern char *this_command_name
;
146 extern struct fd_bitmap
*current_fds_to_close
;
147 extern int wordexp_only
;
148 extern int expanding_redir
;
149 extern int tempenv_assign_error
;
151 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
152 extern wchar_t *wcsdup
__P((const wchar_t *));
155 /* Non-zero means to allow unmatched globbed filenames to expand to
157 int allow_null_glob_expansion
;
159 /* Non-zero means to throw an error when globbing fails to match anything. */
160 int fail_glob_expansion
;
163 /* Variables to keep track of which words in an expanded word list (the
164 output of expand_word_list_internal) are the result of globbing
165 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
166 (CURRENTLY UNUSED). */
167 char *glob_argv_flags
;
168 static int glob_argv_flags_size
;
171 static WORD_LIST expand_word_error
, expand_word_fatal
;
172 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
173 static char expand_param_error
, expand_param_fatal
;
174 static char extract_string_error
, extract_string_fatal
;
176 /* Tell the expansion functions to not longjmp back to top_level on fatal
177 errors. Enabled when doing completion and prompt string expansion. */
178 static int no_longjmp_on_fatal_error
= 0;
180 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
181 $* on $IFS, primarily when doing assignment statements. */
182 static int expand_no_split_dollar_star
= 0;
184 /* Used to hold a list of variable assignments preceding a command. Global
185 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
187 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
189 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
190 without any leading variable assignments. */
191 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
193 static char *quoted_substring
__P((char *, int, int));
194 static int quoted_strlen
__P((char *));
195 static char *quoted_strchr
__P((char *, int, int));
197 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
198 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
199 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
200 static WORD_LIST
*expand_string_internal
__P((char *, int));
201 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
202 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
204 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
205 static char *dequote_escapes
__P((char *));
206 static char *make_quoted_char
__P((int));
207 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
208 static char *remove_quoted_escapes
__P((char *));
209 static char *remove_quoted_nulls
__P((char *));
211 static int unquoted_substring
__P((char *, char *));
212 static int unquoted_member
__P((int, char *));
214 #if defined (ARRAY_VARS)
215 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
217 static int do_assignment_internal
__P((const WORD_DESC
*, int));
219 static char *string_extract_verbatim
__P((char *, size_t, int *, char *));
220 static char *string_extract
__P((char *, int *, char *, int));
221 static char *string_extract_double_quoted
__P((char *, int *, int));
222 static inline char *string_extract_single_quoted
__P((char *, int *));
223 static inline int skip_single_quoted
__P((const char *, size_t, int));
224 static int skip_double_quoted
__P((char *, size_t, int));
225 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
226 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
228 static char *pos_params
__P((char *, int, int, int));
230 static unsigned char *mb_getcharlens
__P((char *, int));
232 static char *remove_upattern
__P((char *, char *, int));
233 #if defined (HANDLE_MULTIBYTE)
234 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
236 static char *remove_pattern
__P((char *, char *, int));
238 static int match_pattern_char
__P((char *, char *));
239 static int match_upattern
__P((char *, char *, int, char **, char **));
240 #if defined (HANDLE_MULTIBYTE)
241 static int match_pattern_wchar
__P((wchar_t *, wchar_t *));
242 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
244 static int match_pattern
__P((char *, char *, int, char **, char **));
245 static int getpatspec
__P((int, char *));
246 static char *getpattern
__P((char *, int, int));
247 static char *variable_remove_pattern
__P((char *, char *, int, int));
248 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
249 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
251 static char *array_remove_pattern
__P((ARRAY
*, char *, int, char *, int));
253 static char *parameter_brace_remove_pattern
__P((char *, char *, char *, int, int));
255 static char *process_substitute
__P((char *, int));
257 static char *read_comsub
__P((int, int));
260 static arrayind_t array_length_reference
__P((char *));
263 static int valid_brace_expansion_word
__P((char *, int));
264 static int chk_atstar
__P((char *, int, int *, int *));
265 static int chk_arithsub
__P((const char *, int));
267 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int));
268 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
269 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
270 static void parameter_brace_expand_error
__P((char *, char *));
272 static int valid_length_expression
__P((char *));
273 static intmax_t parameter_brace_expand_length
__P((char *));
275 static char *skiparith
__P((char *, int));
276 static int verify_substring_values
__P((char *, char *, int, intmax_t *, intmax_t *));
277 static int get_var_and_type
__P((char *, char *, int, SHELL_VAR
**, char **));
278 static char *mb_substring
__P((char *, int, int));
279 static char *parameter_brace_substring
__P((char *, char *, char *, int));
281 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
283 static char *parameter_brace_patsub
__P((char *, char *, char *, int));
285 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int *, int *));
286 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
288 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
290 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
292 static void exp_jump_to_top_level
__P((int));
294 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
295 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
296 #ifdef BRACE_EXPANSION
297 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
299 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
300 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
302 /* **************************************************************** */
304 /* Utility Functions */
306 /* **************************************************************** */
308 #ifdef INCLUDE_UNUSED
310 quoted_substring (string
, start
, end
)
315 register char *result
, *s
, *r
;
319 /* Move to string[start], skipping quoted characters. */
320 for (s
= string
, l
= 0; *s
&& l
< start
; )
332 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
334 /* Copy LEN characters, including quote characters. */
336 for (l
= 0; l
< len
; s
++)
350 #ifdef INCLUDE_UNUSED
351 /* Return the length of S, skipping over quoted characters */
375 /* Find the first occurrence of character C in string S, obeying shell
376 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
377 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
378 escaped with CTLESC are skipped. */
380 quoted_strchr (s
, c
, flags
)
388 if (((flags
& ST_BACKSL
) && *p
== '\\')
389 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
393 return ((char *)NULL
);
399 return ((char *)NULL
);
402 /* Return 1 if CHARACTER appears in an unquoted portion of
403 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
405 unquoted_member (character
, string
)
413 slen
= strlen (string
);
415 while (c
= string
[sindex
])
423 ADVANCE_CHAR (string
, slen
, sindex
);
429 ADVANCE_CHAR (string
, slen
, sindex
);
433 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
437 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
444 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
446 unquoted_substring (substr
, string
)
447 char *substr
, *string
;
450 int sindex
, c
, sublen
;
453 if (substr
== 0 || *substr
== '\0')
456 slen
= strlen (string
);
457 sublen
= strlen (substr
);
458 for (sindex
= 0; c
= string
[sindex
]; )
460 if (STREQN (string
+ sindex
, substr
, sublen
))
469 ADVANCE_CHAR (string
, slen
, sindex
);
473 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
477 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
481 ADVANCE_CHAR (string
, slen
, sindex
);
488 /* Most of the substitutions must be done in parallel. In order
489 to avoid using tons of unclear goto's, I have some functions
490 for manipulating malloc'ed strings. They all take INDX, a
491 pointer to an integer which is the offset into the string
492 where manipulation is taking place. They also take SIZE, a
493 pointer to an integer which is the current length of the
494 character array for this string. */
496 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
497 of space allocated to TARGET. SOURCE can be NULL, in which
498 case nothing happens. Gets rid of SOURCE by freeing it.
499 Returns TARGET in case the location has changed. */
501 sub_append_string (source
, target
, indx
, size
)
502 char *source
, *target
;
509 srclen
= STRLEN (source
);
510 if (srclen
>= (int)(*size
- *indx
))
513 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
514 target
= (char *)xrealloc (target
, (*size
= n
));
517 FASTCOPY (source
, target
+ *indx
, srclen
);
519 target
[*indx
] = '\0';
528 /* Append the textual representation of NUMBER to TARGET.
529 INDX and SIZE are as in SUB_APPEND_STRING. */
531 sub_append_number (number
, target
, indx
, size
)
538 temp
= itos (number
);
539 return (sub_append_string (temp
, target
, indx
, size
));
543 /* Extract a substring from STRING, starting at SINDEX and ending with
544 one of the characters in CHARLIST. Don't make the ending character
545 part of the string. Leave SINDEX pointing at the ending character.
546 Understand about backslashes in the string. If (flags & EX_VARNAME)
547 is non-zero, and array variables have been compiled into the shell,
548 everything between a `[' and a corresponding `]' is skipped over.
549 If (flags & EX_NOALLOC) is non-zero, don't return the substring, just
550 update SINDEX. If (flags & EX_REQMATCH) is non-zero, the string must
551 contain a closing character from CHARLIST. */
553 string_extract (string
, sindex
, charlist
, flags
)
565 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
568 while (c
= string
[i
])
577 #if defined (ARRAY_VARS)
578 else if ((flags
& EX_VARNAME
) && c
== '[')
581 /* If this is an array subscript, skip over it and continue. */
582 ni
= skipsubscript (string
, i
);
583 if (string
[ni
] == ']')
587 else if (MEMBER (c
, charlist
))
593 ADVANCE_CHAR (string
, slen
, i
);
596 /* If we had to have a matching delimiter and didn't find one, return an
597 error and let the caller deal with it. */
598 if ((flags
& EX_REQMATCH
) && found
== 0)
601 return (&extract_string_error
);
604 temp
= (flags
& EX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
610 /* Extract the contents of STRING as if it is enclosed in double quotes.
611 SINDEX, when passed in, is the offset of the character immediately
612 following the opening double quote; on exit, SINDEX is left pointing after
613 the closing double quote. If STRIPDQ is non-zero, unquoted double
614 quotes are stripped and the string is terminated by a null byte.
615 Backslashes between the embedded double quotes are processed. If STRIPDQ
616 is zero, an unquoted `"' terminates the string. */
618 string_extract_double_quoted (string
, sindex
, stripdq
)
620 int *sindex
, stripdq
;
626 char *temp
, *ret
; /* The new string we return. */
627 int pass_next
, backquote
, si
; /* State variables for the machine. */
631 slen
= strlen (string
+ *sindex
) + *sindex
;
632 send
= string
+ slen
;
634 pass_next
= backquote
= dquote
= 0;
635 temp
= (char *)xmalloc (1 + slen
- *sindex
);
639 while (c
= string
[i
])
641 /* Process a character that was quoted by a backslash. */
646 ``The backslash shall retain its special meaning as an escape
647 character only when followed by one of the characters:
650 If STRIPDQ is zero, we handle the double quotes here and let
651 expand_word_internal handle the rest. If STRIPDQ is non-zero,
652 we have already been through one round of backslash stripping,
653 and want to strip these backslashes only if DQUOTE is non-zero,
654 indicating that we are inside an embedded double-quoted string. */
656 /* If we are in an embedded quoted string, then don't strip
657 backslashes before characters for which the backslash
658 retains its special meaning, but remove backslashes in
659 front of other characters. If we are not in an
660 embedded quoted string, don't strip backslashes at all.
661 This mess is necessary because the string was already
662 surrounded by double quotes (and sh has some really weird
664 The returned string will be run through expansion as if
665 it were double-quoted. */
666 if ((stripdq
== 0 && c
!= '"') ||
667 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
672 COPY_CHAR_I (temp
, j
, string
, send
, i
);
676 /* A backslash protects the next character. The code just above
677 handles preserving the backslash in front of any character but
686 /* Inside backquotes, ``the portion of the quoted string from the
687 initial backquote and the characters up to the next backquote
688 that is not preceded by a backslash, having escape characters
689 removed, defines that command''. */
707 /* Pass everything between `$(' and the matching `)' or a quoted
708 ${ ... } pair through according to the Posix.2 specification. */
709 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
714 if (string
[i
+ 1] == LPAREN
)
715 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_COMMAND
); /*)*/
717 ret
= extract_dollar_brace_string (string
, &si
, 1, 0);
720 temp
[j
++] = string
[i
+ 1];
722 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
724 if (ret
== 0 && no_longjmp_on_fatal_error
)
727 ret
= string
+ i
+ 2;
730 for (t
= 0; ret
[t
]; t
++, j
++)
732 temp
[j
] = string
[si
];
747 /* Add any character but a double quote to the quoted string we're
750 goto add_one_character
;
764 /* Point to after the closing quote. */
772 /* This should really be another option to string_extract_double_quoted. */
774 skip_double_quoted (string
, slen
, sind
)
781 int pass_next
, backquote
, si
;
784 pass_next
= backquote
= 0;
786 while (c
= string
[i
])
791 ADVANCE_CHAR (string
, slen
, i
);
804 ADVANCE_CHAR (string
, slen
, i
);
813 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
816 if (string
[i
+ 1] == LPAREN
)
817 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_NOALLOC
|EX_COMMAND
); /* ) */
819 ret
= extract_dollar_brace_string (string
, &si
, 0, EX_NOALLOC
);
826 ADVANCE_CHAR (string
, slen
, i
);
839 /* Extract the contents of STRING as if it is enclosed in single quotes.
840 SINDEX, when passed in, is the offset of the character immediately
841 following the opening single quote; on exit, SINDEX is left pointing after
842 the closing single quote. */
844 string_extract_single_quoted (string
, sindex
)
853 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
854 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
856 while (string
[i
] && string
[i
] != '\'')
857 ADVANCE_CHAR (string
, slen
, i
);
859 t
= substring (string
, *sindex
, i
);
869 skip_single_quoted (string
, slen
, sind
)
878 while (string
[c
] && string
[c
] != '\'')
879 ADVANCE_CHAR (string
, slen
, c
);
886 /* Just like string_extract, but doesn't hack backslashes or any of
887 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
889 string_extract_verbatim (string
, slen
, sindex
, charlist
)
895 register int i
= *sindex
;
896 #if defined (HANDLE_MULTIBYTE)
904 if (charlist
[0] == '\'' && charlist
[1] == '\0')
906 temp
= string_extract_single_quoted (string
, sindex
);
907 --*sindex
; /* leave *sindex at separator character */
913 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
914 this only if MB_CUR_MAX > 1. */
915 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
917 #if defined (HANDLE_MULTIBYTE)
918 clen
= strlen (charlist
);
921 while (c
= string
[i
])
923 #if defined (HANDLE_MULTIBYTE)
932 #if defined (HANDLE_MULTIBYTE)
933 mblength
= MBLEN (string
+ i
, slen
- i
);
937 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
938 if (MB_INVALIDCH (mblength
))
940 if (MEMBER (c
, charlist
))
948 len
= mbstowcs (wcharlist
, charlist
, 0);
951 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
952 mbstowcs (wcharlist
, charlist
, len
+ 1);
955 if (wcschr (wcharlist
, wc
))
961 if (MEMBER (c
, charlist
))
964 ADVANCE_CHAR (string
, slen
, i
);
967 #if defined (HANDLE_MULTIBYTE)
971 temp
= substring (string
, *sindex
, i
);
977 /* Extract the $( construct in STRING, and return a new string.
978 Start extracting at (SINDEX) as if we had just seen "$(".
979 Make (SINDEX) get the position of the matching ")". ) */
981 extract_command_subst (string
, sindex
)
985 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", EX_COMMAND
)); /*)*/
988 /* Extract the $[ construct in STRING, and return a new string. (])
989 Start extracting at (SINDEX) as if we had just seen "$[".
990 Make (SINDEX) get the position of the matching "]". */
992 extract_arithmetic_subst (string
, sindex
)
996 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
999 #if defined (PROCESS_SUBSTITUTION)
1000 /* Extract the <( or >( construct in STRING, and return a new string.
1001 Start extracting at (SINDEX) as if we had just seen "<(".
1002 Make (SINDEX) get the position of the matching ")". */ /*))*/
1004 extract_process_subst (string
, starter
, sindex
)
1009 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", 0));
1011 #endif /* PROCESS_SUBSTITUTION */
1013 #if defined (ARRAY_VARS)
1014 /* This can be fooled by unquoted right parens in the passed string. If
1015 each caller verifies that the last character in STRING is a right paren,
1016 we don't even need to call extract_delimited_string. */
1018 extract_array_assignment_list (string
, sindex
)
1025 slen
= strlen (string
); /* ( */
1026 if (string
[slen
- 1] == ')')
1028 ret
= substring (string
, *sindex
, slen
- 1);
1036 /* Extract and create a new string from the contents of STRING, a
1037 character string delimited with OPENER and CLOSER. SINDEX is
1038 the address of an int describing the current offset in STRING;
1039 it should point to just after the first OPENER found. On exit,
1040 SINDEX gets the position of the last character of the matching CLOSER.
1041 If OPENER is more than a single character, ALT_OPENER, if non-null,
1042 contains a character string that can also match CLOSER and thus
1043 needs to be skipped. */
1045 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1048 char *opener
, *alt_opener
, *closer
;
1054 int pass_character
, nesting_level
, in_comment
;
1055 int len_closer
, len_opener
, len_alt_opener
;
1058 slen
= strlen (string
+ *sindex
) + *sindex
;
1059 len_opener
= STRLEN (opener
);
1060 len_alt_opener
= STRLEN (alt_opener
);
1061 len_closer
= STRLEN (closer
);
1063 pass_character
= in_comment
= 0;
1068 while (nesting_level
)
1079 ADVANCE_CHAR (string
, slen
, i
);
1083 if (pass_character
) /* previous char was backslash */
1086 ADVANCE_CHAR (string
, slen
, i
);
1090 /* Not exactly right yet; should handle shell metacharacters and
1091 multibyte characters, too. */
1092 if ((flags
& EX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || whitespace (string
[i
- 1])))
1095 ADVANCE_CHAR (string
, slen
, i
);
1099 if (c
== CTLESC
|| c
== '\\')
1106 /* Process a nested OPENER. */
1107 if (STREQN (string
+ i
, opener
, len_opener
))
1109 si
= i
+ len_opener
;
1110 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|EX_NOALLOC
);
1115 /* Process a nested ALT_OPENER */
1116 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1118 si
= i
+ len_alt_opener
;
1119 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|EX_NOALLOC
);
1124 /* If the current substring terminates the delimited string, decrement
1125 the nesting level. */
1126 if (STREQN (string
+ i
, closer
, len_closer
))
1128 i
+= len_closer
- 1; /* move to last byte of the closer */
1130 if (nesting_level
== 0)
1134 /* Pass old-style command substitution through verbatim. */
1138 t
= string_extract (string
, &si
, "`", flags
|EX_NOALLOC
);
1143 /* Pass single-quoted and double-quoted strings through verbatim. */
1144 if (c
== '\'' || c
== '"')
1147 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1148 : skip_double_quoted (string
, slen
, si
);
1152 /* move past this character, which was not special. */
1153 ADVANCE_CHAR (string
, slen
, i
);
1156 if (c
== 0 && nesting_level
)
1158 if (no_longjmp_on_fatal_error
== 0)
1160 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1161 last_command_exit_value
= EXECUTION_FAILURE
;
1162 exp_jump_to_top_level (DISCARD
);
1167 return (char *)NULL
;
1171 si
= i
- *sindex
- len_closer
+ 1;
1172 if (flags
& EX_NOALLOC
)
1173 result
= (char *)NULL
;
1176 result
= (char *)xmalloc (1 + si
);
1177 strncpy (result
, string
+ *sindex
, si
);
1185 /* Extract a parameter expansion expression within ${ and } from STRING.
1186 Obey the Posix.2 rules for finding the ending `}': count braces while
1187 skipping over enclosed quoted strings and command substitutions.
1188 SINDEX is the address of an int describing the current offset in STRING;
1189 it should point to just after the first `{' found. On exit, SINDEX
1190 gets the position of the matching `}'. QUOTED is non-zero if this
1191 occurs inside double quotes. */
1192 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1194 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1196 int *sindex
, quoted
, flags
;
1200 int pass_character
, nesting_level
, si
;
1206 slen
= strlen (string
+ *sindex
) + *sindex
;
1209 while (c
= string
[i
])
1214 ADVANCE_CHAR (string
, slen
, i
);
1218 /* CTLESCs and backslashes quote the next character. */
1219 if (c
== CTLESC
|| c
== '\\')
1226 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1236 if (nesting_level
== 0)
1242 /* Pass the contents of old-style command substitutions through
1247 t
= string_extract (string
, &si
, "`", flags
|EX_NOALLOC
);
1252 /* Pass the contents of new-style command substitutions and
1253 arithmetic substitutions through verbatim. */
1254 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1257 t
= extract_delimited_string (string
, &si
, "$(", "(", ")", flags
|EX_NOALLOC
|EX_COMMAND
); /*)*/
1262 /* Pass the contents of single-quoted and double-quoted strings
1263 through verbatim. */
1264 if (c
== '\'' || c
== '"')
1267 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1268 : skip_double_quoted (string
, slen
, si
);
1269 /* skip_XXX_quoted leaves index one past close quote */
1273 /* move past this character, which was not special. */
1274 ADVANCE_CHAR (string
, slen
, i
);
1277 if (c
== 0 && nesting_level
)
1279 if (no_longjmp_on_fatal_error
== 0)
1281 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1282 last_command_exit_value
= EXECUTION_FAILURE
;
1283 exp_jump_to_top_level (DISCARD
);
1288 return ((char *)NULL
);
1292 result
= (flags
& EX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1298 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1299 STRING, and returns a pointer to it. */
1301 de_backslash (string
)
1304 register size_t slen
;
1305 register int i
, j
, prev_i
;
1308 slen
= strlen (string
);
1311 /* Loop copying string[i] to string[j], i >= j. */
1314 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1315 string
[i
+ 1] == '$'))
1318 ADVANCE_CHAR (string
, slen
, i
);
1320 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1331 /* Replace instances of \! in a string with !. */
1333 unquote_bang (string
)
1337 register char *temp
;
1339 temp
= (char *)xmalloc (1 + strlen (string
));
1341 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1343 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1349 strcpy (string
, temp
);
1354 #if defined (READLINE)
1355 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1356 an unclosed quoted string), or if the character at EINDEX is quoted
1357 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1358 single and double-quoted string parsing functions should not return an
1359 error if there are unclosed quotes or braces. The characters that this
1360 recognizes need to be the same as the contents of
1361 rl_completer_quote_characters. */
1363 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1366 char_is_quoted (string
, eindex
)
1370 int i
, pass_next
, c
;
1374 slen
= strlen (string
);
1375 no_longjmp_on_fatal_error
= 1;
1384 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1386 ADVANCE_CHAR (string
, slen
, i
);
1395 else if (c
== '\'' || c
== '"')
1397 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1398 : skip_double_quoted (string
, slen
, ++i
);
1401 /* no increment, the skip_xxx functions go one past end */
1404 ADVANCE_CHAR (string
, slen
, i
);
1411 unclosed_pair (string
, eindex
, openstr
)
1416 int i
, pass_next
, openc
, olen
;
1420 slen
= strlen (string
);
1421 olen
= strlen (openstr
);
1422 i
= pass_next
= openc
= 0;
1428 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1430 ADVANCE_CHAR (string
, slen
, i
);
1433 else if (string
[i
] == '\\')
1439 else if (STREQN (string
+ i
, openstr
, olen
))
1444 else if (string
[i
] == '\'' || string
[i
] == '"')
1446 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1447 : skip_double_quoted (string
, slen
, i
);
1452 ADVANCE_CHAR (string
, slen
, i
);
1457 /* Skip characters in STRING until we find a character in DELIMS, and return
1458 the index of that character. START is the index into string at which we
1459 begin. This is similar in spirit to strpbrk, but it returns an index into
1460 STRING and takes a starting index. This little piece of code knows quite
1461 a lot of shell syntax. It's very similar to skip_double_quoted and other
1462 functions of that ilk. */
1464 skip_to_delim (string
, start
, delims
)
1469 int i
, pass_next
, backq
, si
, c
;
1474 slen
= strlen (string
+ start
) + start
;
1475 no_longjmp_on_fatal_error
= 1;
1477 pass_next
= backq
= 0;
1478 while (c
= string
[i
])
1485 ADVANCE_CHAR (string
, slen
, i
);
1498 ADVANCE_CHAR (string
, slen
, i
);
1507 else if (c
== '\'' || c
== '"')
1509 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1510 : skip_double_quoted (string
, slen
, ++i
);
1511 /* no increment, the skip functions increment past the closing quote. */
1513 else if (c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1516 if (string
[si
] == '\0')
1519 if (string
[i
+1] == LPAREN
)
1520 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", EX_NOALLOC
|EX_COMMAND
); /* ) */
1522 temp
= extract_dollar_brace_string (string
, &si
, 0, EX_NOALLOC
);
1524 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1529 else if (member (c
, delims
))
1532 ADVANCE_CHAR (string
, slen
, i
);
1538 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1539 individual words. If DELIMS is NULL, the current value of $IFS is used
1540 to split the string, and the function follows the shell field splitting
1541 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1542 gets the number of words in the returned list. CWP, if non-NULL, gets
1543 the index of the word containing SENTINEL. Non-whitespace chars in
1544 DELIMS delimit separate fields. */
1546 split_at_delims (string
, slen
, delims
, sentinel
, nwp
, cwp
)
1553 int ts
, te
, i
, nw
, cw
, ifs_split
;
1554 char *token
, *d
, *d2
;
1555 WORD_LIST
*ret
, *tl
;
1557 if (string
== 0 || *string
== '\0')
1563 return ((WORD_LIST
*)NULL
);
1566 d
= (delims
== 0) ? ifs_value
: delims
;
1567 ifs_split
= delims
== 0;
1569 /* Make d2 the non-whitespace characters in delims */
1574 #if defined (HANDLE_MULTIBYTE)
1575 size_t mblength
= 1;
1579 slength
= strlen (delims
);
1580 d2
= (char *)xmalloc (slength
+ 1);
1584 #if defined (HANDLE_MULTIBYTE)
1585 mbstate_t state_bak
;
1587 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1588 if (MB_INVALIDCH (mblength
))
1590 else if (mblength
> 1)
1592 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1595 slength
-= mblength
;
1599 if (whitespace (delims
[i
]) == 0)
1600 d2
[ts
++] = delims
[i
];
1608 ret
= (WORD_LIST
*)NULL
;
1610 /* Remove sequences of whitspace characters at the start of the string, as
1611 long as those characters are delimiters. */
1612 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1614 if (string
[i
] == '\0')
1622 te
= skip_to_delim (string
, ts
, d
);
1624 /* If we have a non-whitespace delimiter character, use it to make a
1625 separate field. This is just about what $IFS splitting does and
1626 is closer to the behavior of the shell parser. */
1627 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
1630 /* If we're using IFS splitting, the non-whitespace delimiter char
1631 and any additional IFS whitespace delimits a field. */
1633 while (member (string
[te
], d
) && spctabnl (string
[te
]))
1636 while (member (string
[te
], d2
))
1640 token
= substring (string
, ts
, te
);
1642 ret
= add_string_to_list (token
, ret
);
1646 if (sentinel
>= ts
&& sentinel
<= te
)
1649 /* If the cursor is at whitespace just before word start, set the
1650 sentinel word to the current word. */
1651 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
1654 /* If the cursor is at whitespace between two words, make a new, empty
1655 word, add it before (well, after, since the list is in reverse order)
1656 the word we just added, and set the current word to that one. */
1657 if (cwp
&& cw
== -1 && sentinel
< ts
)
1659 tl
= make_word_list (make_word (""), ret
->next
);
1665 if (string
[te
] == 0)
1669 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
1678 /* Special case for SENTINEL at the end of STRING. If we haven't found
1679 the word containing SENTINEL yet, and the index we're looking for is at
1680 the end of STRING, add an additional null argument and set the current
1681 word pointer to that. */
1682 if (cwp
&& cw
== -1 && sentinel
>= slen
)
1684 if (whitespace (string
[sentinel
- 1]))
1687 ret
= add_string_to_list (token
, ret
);
1698 return (REVERSE_LIST (ret
, WORD_LIST
*));
1700 #endif /* READLINE */
1704 /* Extract the name of the variable to bind to from the assignment string. */
1706 assignment_name (string
)
1712 offset
= assignment (string
, 0);
1714 return (char *)NULL
;
1715 temp
= substring (string
, 0, offset
);
1720 /* **************************************************************** */
1722 /* Functions to convert strings to WORD_LISTs and vice versa */
1724 /* **************************************************************** */
1726 /* Return a single string of all the words in LIST. SEP is the separator
1727 to put between individual elements of LIST in the output string. */
1729 string_list_internal (list
, sep
)
1733 register WORD_LIST
*t
;
1735 int word_len
, sep_len
, result_size
;
1738 return ((char *)NULL
);
1740 /* Short-circuit quickly if we don't need to separate anything. */
1741 if (list
->next
== 0)
1742 return (savestring (list
->word
->word
));
1744 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1745 sep_len
= STRLEN (sep
);
1748 for (t
= list
; t
; t
= t
->next
)
1751 result_size
+= sep_len
;
1752 result_size
+= strlen (t
->word
->word
);
1755 r
= result
= (char *)xmalloc (result_size
+ 1);
1757 for (t
= list
; t
; t
= t
->next
)
1759 if (t
!= list
&& sep_len
)
1763 FASTCOPY (sep
, r
, sep_len
);
1770 word_len
= strlen (t
->word
->word
);
1771 FASTCOPY (t
->word
->word
, r
, word_len
);
1779 /* Return a single string of all the words present in LIST, separating
1780 each word with a space. */
1785 return (string_list_internal (list
, " "));
1788 /* Return a single string of all the words present in LIST, obeying the
1789 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1790 expansion [of $*] appears within a double quoted string, it expands
1791 to a single field with the value of each parameter separated by the
1792 first character of the IFS variable, or by a <space> if IFS is unset." */
1794 string_list_dollar_star (list
)
1798 #if defined (HANDLE_MULTIBYTE)
1799 # if defined (__GNUC__)
1800 char sep
[MB_CUR_MAX
+ 1];
1808 #if defined (HANDLE_MULTIBYTE)
1809 # if !defined (__GNUC__)
1810 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
1811 # endif /* !__GNUC__ */
1812 if (ifs_firstc_len
== 1)
1814 sep
[0] = ifs_firstc
[0];
1819 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
1820 sep
[ifs_firstc_len
] = '\0';
1823 sep
[0] = ifs_firstc
;
1827 ret
= string_list_internal (list
, sep
);
1828 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1834 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1835 is non-zero, the $@ appears within double quotes, and we should quote
1836 the list before converting it into a string. If IFS is unset, and the
1837 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1838 in the words in the list, because the default value of $IFS is
1839 <space><tab><newline>, IFS characters in the words in the list should
1840 also be split. If IFS is null, and the word is not quoted, we need
1841 to quote the words in the list to preserve the positional parameters
1844 string_list_dollar_at (list
, quoted
)
1849 #if defined (HANDLE_MULTIBYTE)
1850 # if defined (__GNUC__)
1851 char sep
[MB_CUR_MAX
+ 1];
1854 # endif /* !__GNUC__ */
1860 /* XXX this could just be ifs = ifs_value; */
1861 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
1863 #if defined (HANDLE_MULTIBYTE)
1864 # if !defined (__GNUC__)
1865 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
1866 # endif /* !__GNUC__ */
1869 if (ifs_firstc_len
== 1)
1871 sep
[0] = ifs_firstc
[0];
1876 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
1877 sep
[ifs_firstc_len
] = '\0';
1886 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
1890 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
1891 it now that quote_escapes quotes spaces */
1893 tlist
= ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (ifs
&& *ifs
== 0))
1895 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
1898 : list_quote_escapes (list
);
1900 ret
= string_list_internal (tlist
, sep
);
1901 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1907 /* Return the list of words present in STRING. Separate the string into
1908 words at any of the characters found in SEPARATORS. If QUOTED is
1909 non-zero then word in the list will have its quoted flag set, otherwise
1910 the quoted flag is left as make_word () deemed fit.
1912 This obeys the P1003.2 word splitting semantics. If `separators' is
1913 exactly <space><tab><newline>, then the splitting algorithm is that of
1914 the Bourne shell, which treats any sequence of characters from `separators'
1915 as a delimiter. If IFS is unset, which results in `separators' being set
1916 to "", no splitting occurs. If separators has some other value, the
1917 following rules are applied (`IFS white space' means zero or more
1918 occurrences of <space>, <tab>, or <newline>, as long as those characters
1919 are in `separators'):
1921 1) IFS white space is ignored at the start and the end of the
1923 2) Each occurrence of a character in `separators' that is not
1924 IFS white space, along with any adjacent occurrences of
1925 IFS white space delimits a field.
1926 3) Any nonzero-length sequence of IFS white space delimits a field.
1929 /* BEWARE! list_string strips null arguments. Don't call it twice and
1930 expect to have "" preserved! */
1932 /* This performs word splitting and quoted null character removal on
1935 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1936 : (c) == (separators)[0]) \
1940 list_string (string
, separators
, quoted
)
1941 register char *string
, *separators
;
1946 char *current_word
, *s
;
1947 int sindex
, sh_style_split
, whitesep
;
1950 if (!string
|| !*string
)
1951 return ((WORD_LIST
*)NULL
);
1953 sh_style_split
= separators
&& separators
[0] == ' ' &&
1954 separators
[1] == '\t' &&
1955 separators
[2] == '\n' &&
1956 separators
[3] == '\0';
1959 /* Remove sequences of whitespace at the beginning of STRING, as
1960 long as those characters appear in IFS. Do not do this if
1961 STRING is quoted or if there are no separator characters. */
1962 if (!quoted
|| !separators
|| !*separators
)
1964 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
1967 return ((WORD_LIST
*)NULL
);
1972 /* OK, now STRING points to a word that does not begin with white space.
1973 The splitting algorithm is:
1974 extract a word, stopping at a separator
1975 skip sequences of spc, tab, or nl as long as they are separators
1976 This obeys the field splitting rules in Posix.2. */
1977 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
1978 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
1980 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
1981 unless multibyte chars are possible. */
1982 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
);
1983 if (current_word
== 0)
1986 /* If we have a quoted empty string, add a quoted null argument. We
1987 want to preserve the quoted null character iff this is a quoted
1988 empty string; otherwise the quoted null characters are removed
1990 if (QUOTED_NULL (current_word
))
1992 t
= alloc_word_desc ();
1993 t
->word
= make_quoted_char ('\0');
1994 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
1995 result
= make_word_list (t
, result
);
1997 else if (current_word
[0] != '\0')
1999 /* If we have something, then add it regardless. However,
2000 perform quoted null character removal on the current word. */
2001 remove_quoted_nulls (current_word
);
2002 result
= add_string_to_list (current_word
, result
);
2003 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2004 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2005 result
->word
->flags
|= W_QUOTED
;
2008 /* If we're not doing sequences of separators in the traditional
2009 Bourne shell style, then add a quoted null argument. */
2010 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2012 t
= alloc_word_desc ();
2013 t
->word
= make_quoted_char ('\0');
2014 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2015 result
= make_word_list (t
, result
);
2018 free (current_word
);
2020 /* Note whether or not the separator is IFS whitespace, used later. */
2021 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2023 /* Move past the current separator character. */
2027 ADVANCE_CHAR (string
, slen
, sindex
);
2030 /* Now skip sequences of space, tab, or newline characters if they are
2031 in the list of separators. */
2032 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2035 /* If the first separator was IFS whitespace and the current character
2036 is a non-whitespace IFS character, it should be part of the current
2037 field delimiter, not a separate delimiter that would result in an
2038 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2039 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2042 /* An IFS character that is not IFS white space, along with any
2043 adjacent IFS white space, shall delimit a field. (SUSv3) */
2044 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2048 return (REVERSE_LIST (result
, WORD_LIST
*));
2051 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2052 ENDPTR is set to the first character after the word. This is used by
2053 the `read' builtin. This is never called with SEPARATORS != $IFS;
2054 it should be simplified.
2056 XXX - this function is very similar to list_string; they should be
2059 get_word_from_string (stringp
, separators
, endptr
)
2060 char **stringp
, *separators
, **endptr
;
2064 int sindex
, sh_style_split
, whitesep
;
2067 if (!stringp
|| !*stringp
|| !**stringp
)
2068 return ((char *)NULL
);
2072 sh_style_split
= separators
&& separators
[0] == ' ' &&
2073 separators
[1] == '\t' &&
2074 separators
[2] == '\n' &&
2075 separators
[3] == '\0';
2079 /* Remove sequences of whitespace at the beginning of STRING, as
2080 long as those characters appear in IFS. */
2081 if (sh_style_split
|| !separators
|| !*separators
)
2083 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2085 /* If the string is nothing but whitespace, update it and return. */
2091 return ((char *)NULL
);
2095 /* OK, S points to a word that does not begin with white space.
2096 Now extract a word, stopping at a separator, save a pointer to
2097 the first character after the word, then skip sequences of spc,
2098 tab, or nl as long as they are separators.
2100 This obeys the field splitting rules in Posix.2. */
2102 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2103 unless multibyte chars are possible. */
2104 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2105 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
);
2107 /* Set ENDPTR to the first character after the end of the word. */
2109 *endptr
= s
+ sindex
;
2111 /* Note whether or not the separator is IFS whitespace, used later. */
2112 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2114 /* Move past the current separator character. */
2118 ADVANCE_CHAR (s
, slen
, sindex
);
2121 /* Now skip sequences of space, tab, or newline characters if they are
2122 in the list of separators. */
2123 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2126 /* If the first separator was IFS whitespace and the current character is
2127 a non-whitespace IFS character, it should be part of the current field
2128 delimiter, not a separate delimiter that would result in an empty field.
2129 Look at POSIX.2, 3.6.5, (3)(b). */
2130 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2133 /* An IFS character that is not IFS white space, along with any adjacent
2134 IFS white space, shall delimit a field. */
2135 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2139 /* Update STRING to point to the next field. */
2140 *stringp
= s
+ sindex
;
2141 return (current_word
);
2144 /* Remove IFS white space at the end of STRING. Start at the end
2145 of the string and walk backwards until the beginning of the string
2146 or we find a character that's not IFS white space and not CTLESC.
2147 Only let CTLESC escape a white space character if SAW_ESCAPE is
2150 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2151 char *string
, *separators
;
2156 s
= string
+ STRLEN (string
) - 1;
2157 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2158 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2166 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2167 backslashes, single and double quotes. */
2169 list_string_with_quotes (string
)
2175 int c
, i
, tokstart
, len
;
2177 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2179 if (s
== 0 || *s
== 0)
2180 return ((WORD_LIST
*)NULL
);
2184 list
= (WORD_LIST
*)NULL
;
2195 i
= skip_single_quoted (s
, s_len
, ++i
);
2197 i
= skip_double_quoted (s
, s_len
, ++i
);
2198 else if (c
== 0 || spctabnl (c
))
2200 /* We have found the end of a token. Make a word out of it and
2201 add it to the word list. */
2202 token
= substring (s
, tokstart
, i
);
2203 list
= add_string_to_list (token
, list
);
2205 while (spctabnl (s
[i
]))
2213 i
++; /* normal character */
2215 return (REVERSE_LIST (list
, WORD_LIST
*));
2219 /********************************************************/
2221 /* Functions to perform assignment statements */
2223 /********************************************************/
2225 #if defined (ARRAY_VARS)
2227 do_compound_assignment (name
, value
, flags
)
2235 mklocal
= flags
& ASS_MKLOCAL
;
2237 if (mklocal
&& variable_context
)
2239 list
= expand_compound_array_assignment (value
, flags
);
2240 v
= find_variable (name
);
2241 if (v
== 0 || array_p (v
) == 0 || v
->context
!= variable_context
)
2242 v
= make_local_array_variable (name
);
2243 assign_compound_array_list (v
, list
, flags
);
2246 v
= assign_array_from_string (name
, value
, flags
);
2252 /* Given STRING, an assignment string, get the value of the right side
2253 of the `=', and bind it to the left side. If EXPAND is true, then
2254 perform parameter expansion, command substitution, and arithmetic
2255 expansion on the right-hand side. Perform tilde expansion in any
2256 case. Do not perform word splitting on the result of expansion. */
2258 do_assignment_internal (word
, expand
)
2259 const WORD_DESC
*word
;
2262 int offset
, tlen
, appendop
, assign_list
, aflags
;
2265 #if defined (ARRAY_VARS)
2271 if (word
== 0 || word
->word
== 0)
2274 appendop
= assign_list
= aflags
= 0;
2275 string
= word
->word
;
2276 offset
= assignment (string
, 0);
2277 name
= savestring (string
);
2278 value
= (char *)NULL
;
2280 if (name
[offset
] == '=')
2284 if (name
[offset
- 1] == '+')
2287 name
[offset
- 1] = '\0';
2290 name
[offset
] = 0; /* might need this set later */
2291 temp
= name
+ offset
+ 1;
2292 tlen
= STRLEN (temp
);
2294 #if defined (ARRAY_VARS)
2295 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2297 assign_list
= ni
= 1;
2298 value
= extract_array_assignment_list (temp
, &ni
);
2303 if (expand
&& temp
[0])
2304 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2306 value
= savestring (temp
);
2311 value
= (char *)xmalloc (1);
2315 if (echo_command_at_execute
)
2318 name
[offset
- 1] = '+';
2319 xtrace_print_assignment (name
, value
, assign_list
, 1);
2321 name
[offset
- 1] = '\0';
2324 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2327 aflags
|= ASS_APPEND
;
2329 #if defined (ARRAY_VARS)
2330 if (t
= xstrchr (name
, '[')) /*]*/
2334 report_error (_("%s: cannot assign list to array member"), name
);
2337 entry
= assign_array_element (name
, value
, aflags
);
2341 else if (assign_list
)
2343 if (word
->flags
& W_ASSIGNARG
)
2344 aflags
|= ASS_MKLOCAL
;
2345 entry
= do_compound_assignment (name
, value
, aflags
);
2348 #endif /* ARRAY_VARS */
2349 entry
= bind_variable (name
, value
, aflags
);
2351 stupidly_hack_special_variables (name
);
2354 VUNSETATTR (entry
, att_invisible
);
2356 /* Return 1 if the assignment seems to have been performed correctly. */
2357 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2360 /* Perform the assignment statement in STRING, and expand the
2361 right side by doing tilde, command and parameter expansion. */
2363 do_assignment (string
)
2368 td
.flags
= W_ASSIGNMENT
;
2371 return do_assignment_internal (&td
, 1);
2375 do_word_assignment (word
)
2378 return do_assignment_internal (word
, 1);
2381 /* Given STRING, an assignment string, get the value of the right side
2382 of the `=', and bind it to the left side. Do not perform any word
2383 expansions on the right hand side. */
2385 do_assignment_no_expand (string
)
2390 td
.flags
= W_ASSIGNMENT
;
2393 return (do_assignment_internal (&td
, 0));
2396 /***************************************************
2398 * Functions to manage the positional parameters *
2400 ***************************************************/
2402 /* Return the word list that corresponds to `$*'. */
2404 list_rest_of_args ()
2406 register WORD_LIST
*list
, *args
;
2409 /* Break out of the loop as soon as one of the dollar variables is null. */
2410 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2411 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2413 for (args
= rest_of_args
; args
; args
= args
->next
)
2414 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2416 return (REVERSE_LIST (list
, WORD_LIST
*));
2422 register WORD_LIST
*list
;
2425 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2427 for (list
= rest_of_args
; list
; list
= list
->next
)
2432 /* Return the value of a positional parameter. This handles values > 10. */
2434 get_dollar_var_value (ind
)
2441 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2442 else /* We want something like ${11} */
2445 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2447 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2452 /* Make a single large string out of the dollar digit variables,
2453 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2454 case of "$*" with respect to IFS. */
2456 string_rest_of_args (dollar_star
)
2459 register WORD_LIST
*list
;
2462 list
= list_rest_of_args ();
2463 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2464 dispose_words (list
);
2468 /* Return a string containing the positional parameters from START to
2469 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2470 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2471 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2472 no quoting chars are added. */
2474 pos_params (string
, start
, end
, quoted
)
2476 int start
, end
, quoted
;
2478 WORD_LIST
*save
, *params
, *h
, *t
;
2482 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2484 return ((char *)NULL
);
2486 save
= params
= list_rest_of_args ();
2488 return ((char *)NULL
);
2490 for (i
= 1; params
&& i
< start
; i
++)
2491 params
= params
->next
;
2493 return ((char *)NULL
);
2494 for (h
= t
= params
; params
&& i
< end
; i
++)
2497 params
= params
->next
;
2500 t
->next
= (WORD_LIST
*)NULL
;
2501 if (string
[0] == '*')
2503 if (quoted
& Q_DOUBLE_QUOTES
)
2504 ret
= string_list_dollar_star (quote_list (h
));
2505 else if (quoted
& Q_HERE_DOCUMENT
)
2506 ret
= string_list (quote_list (h
));
2508 ret
= string_list (h
);
2511 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (h
) : h
);
2515 dispose_words (save
);
2519 /******************************************************************/
2521 /* Functions to expand strings to strings or WORD_LISTs */
2523 /******************************************************************/
2525 #if defined (PROCESS_SUBSTITUTION)
2526 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2528 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2531 /* If there are any characters in STRING that require full expansion,
2532 then call FUNC to expand STRING; otherwise just perform quote
2533 removal if necessary. This returns a new string. */
2535 expand_string_if_necessary (string
, quoted
, func
)
2546 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2547 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
2551 if (EXP_CHAR (string
[i
]))
2553 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
2555 ADVANCE_CHAR (string
, slen
, i
);
2560 list
= (*func
) (string
, quoted
);
2563 ret
= string_list (list
);
2564 dispose_words (list
);
2569 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
2570 ret
= string_quote_removal (string
, quoted
);
2572 ret
= savestring (string
);
2577 static inline char *
2578 expand_string_to_string_internal (string
, quoted
, func
)
2586 if (string
== 0 || *string
== '\0')
2587 return ((char *)NULL
);
2589 list
= (*func
) (string
, quoted
);
2592 ret
= string_list (list
);
2593 dispose_words (list
);
2602 expand_string_to_string (string
, quoted
)
2606 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
2610 expand_string_unsplit_to_string (string
, quoted
)
2614 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
2618 expand_assignment_string_to_string (string
, quoted
)
2622 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
2626 expand_arith_string (string
, quoted
)
2629 return (expand_string_if_necessary (string
, quoted
, expand_string
));
2632 #if defined (COND_COMMAND)
2633 /* Just remove backslashes in STRING. Returns a new string. */
2635 remove_backslashes (string
)
2640 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
2641 for (s
= string
; s
&& *s
; )
2653 /* This needs better error handling. */
2654 /* Expand W for use as an argument to a unary or binary operator in a
2655 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2656 to the != or == operator, and should be treated as a pattern. In
2657 this case, we quote the string specially for the globbing code. If
2658 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2659 be quoted appropriately for regcomp/regexec. The caller is responsible
2660 for removing the backslashes if the unquoted word is needed later. */
2662 cond_expand_word (w
, special
)
2670 if (w
->word
== 0 || w
->word
[0] == '\0')
2671 return ((char *)NULL
);
2673 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
2679 r
= string_list (l
);
2683 qflags
= QGLOB_CVTNULL
;
2685 qflags
|= QGLOB_REGEXP
;
2686 p
= string_list (l
);
2687 r
= quote_string_for_globbing (p
, qflags
);
2699 /* Call expand_word_internal to expand W and handle error returns.
2700 A convenience function for functions that don't want to handle
2701 any errors or free any memory before aborting. */
2703 call_expand_word_internal (w
, q
, i
, c
, e
)
2709 result
= expand_word_internal (w
, q
, i
, c
, e
);
2710 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
2712 /* By convention, each time this error is returned, w->word has
2713 already been freed (it sometimes may not be in the fatal case,
2714 but that doesn't result in a memory leak because we're going
2715 to exit in most cases). */
2716 w
->word
= (char *)NULL
;
2717 last_command_exit_value
= EXECUTION_FAILURE
;
2718 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
2725 /* Perform parameter expansion, command substitution, and arithmetic
2726 expansion on STRING, as if it were a word. Leave the result quoted. */
2728 expand_string_internal (string
, quoted
)
2735 if (string
== 0 || *string
== 0)
2736 return ((WORD_LIST
*)NULL
);
2739 td
.word
= savestring (string
);
2741 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2747 /* Expand STRING by performing parameter expansion, command substitution,
2748 and arithmetic expansion. Dequote the resulting WORD_LIST before
2749 returning it, but do not perform word splitting. The call to
2750 remove_quoted_nulls () is in here because word splitting normally
2751 takes care of quote removal. */
2753 expand_string_unsplit (string
, quoted
)
2759 if (string
== 0 || *string
== '\0')
2760 return ((WORD_LIST
*)NULL
);
2762 expand_no_split_dollar_star
= 1;
2763 value
= expand_string_internal (string
, quoted
);
2764 expand_no_split_dollar_star
= 0;
2770 remove_quoted_nulls (value
->word
->word
);
2771 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2773 dequote_list (value
);
2778 /* Expand the rhs of an assignment statement */
2780 expand_string_assignment (string
, quoted
)
2787 if (string
== 0 || *string
== '\0')
2788 return ((WORD_LIST
*)NULL
);
2790 expand_no_split_dollar_star
= 1;
2792 td
.flags
= W_ASSIGNRHS
;
2793 td
.word
= savestring (string
);
2794 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2797 expand_no_split_dollar_star
= 0;
2803 remove_quoted_nulls (value
->word
->word
);
2804 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2806 dequote_list (value
);
2812 /* Expand one of the PS? prompt strings. This is a sort of combination of
2813 expand_string_unsplit and expand_string_internal, but returns the
2814 passed string when an error occurs. Might want to trap other calls
2815 to jump_to_top_level here so we don't endlessly loop. */
2817 expand_prompt_string (string
, quoted
)
2824 if (string
== 0 || *string
== 0)
2825 return ((WORD_LIST
*)NULL
);
2828 td
.word
= savestring (string
);
2830 no_longjmp_on_fatal_error
= 1;
2831 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2832 no_longjmp_on_fatal_error
= 0;
2834 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
2836 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
2844 remove_quoted_nulls (value
->word
->word
);
2845 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2847 dequote_list (value
);
2852 /* Expand STRING just as if you were expanding a word, but do not dequote
2853 the resultant WORD_LIST. This is called only from within this file,
2854 and is used to correctly preserve quoted characters when expanding
2855 things like ${1+"$@"}. This does parameter expansion, command
2856 substitution, arithmetic expansion, and word splitting. */
2858 expand_string_leave_quoted (string
, quoted
)
2865 if (string
== 0 || *string
== '\0')
2866 return ((WORD_LIST
*)NULL
);
2868 tlist
= expand_string_internal (string
, quoted
);
2872 tresult
= word_list_split (tlist
);
2873 dispose_words (tlist
);
2876 return ((WORD_LIST
*)NULL
);
2879 /* This does not perform word splitting or dequote the WORD_LIST
2882 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
2884 int quoted
, *dollar_at_p
, *has_dollar_at
;
2889 if (string
== 0 || *string
== '\0')
2890 return (WORD_LIST
*)NULL
;
2894 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
2898 /* Expand STRING just as if you were expanding a word. This also returns
2899 a list of words. Note that filename globbing is *NOT* done for word
2900 or string expansion, just when the shell is expanding a command. This
2901 does parameter expansion, command substitution, arithmetic expansion,
2902 and word splitting. Dequote the resultant WORD_LIST before returning. */
2904 expand_string (string
, quoted
)
2910 if (string
== 0 || *string
== '\0')
2911 return ((WORD_LIST
*)NULL
);
2913 result
= expand_string_leave_quoted (string
, quoted
);
2914 return (result
? dequote_list (result
) : result
);
2917 /***************************************************
2919 * Functions to handle quoting chars *
2921 ***************************************************/
2925 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2926 The parser passes CTLNUL as CTLESC CTLNUL. */
2928 /* Quote escape characters in string s, but no other characters. This is
2929 used to protect CTLESC and CTLNUL in variable values from the rest of
2930 the word expansion process after the variable is expanded. If IFS is
2931 null, we quote spaces as well, just in case we split on spaces later
2932 (in the case of unquoted $@, we will eventually attempt to split the
2933 entire word on spaces). Corresponding code exists in dequote_escapes.
2934 Even if we don't end up splitting on spaces, quoting spaces is not a
2937 quote_escapes (string
)
2940 register char *s
, *t
;
2942 char *result
, *send
;
2946 slen
= strlen (string
);
2947 send
= string
+ slen
;
2949 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
2950 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
2955 if (*s
== CTLESC
|| *s
== CTLNUL
|| (quote_spaces
&& *s
== ' '))
2957 COPY_CHAR_P (t
, s
, send
);
2964 list_quote_escapes (list
)
2967 register WORD_LIST
*w
;
2970 for (w
= list
; w
; w
= w
->next
)
2973 w
->word
->word
= quote_escapes (t
);
2979 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2981 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2982 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2983 data stream pass through properly.
2985 We need to remove doubled CTLESC characters inside quoted strings before
2986 quoting the entire string, so we do not double the number of CTLESC
2989 Also used by parts of the pattern substitution code. */
2991 dequote_escapes (string
)
2994 register char *s
, *t
;
2996 char *result
, *send
;
3003 slen
= strlen (string
);
3004 send
= string
+ slen
;
3006 t
= result
= (char *)xmalloc (slen
+ 1);
3009 if (strchr (string
, CTLESC
) == 0)
3010 return (strcpy (result
, s
));
3012 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3015 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3021 COPY_CHAR_P (t
, s
, send
);
3027 /* Return a new string with the quoted representation of character C.
3028 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3029 set in any resultant WORD_DESC where this value is the word. */
3031 make_quoted_char (c
)
3036 temp
= (char *)xmalloc (3);
3051 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3052 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3053 this value is the word. */
3055 quote_string (string
)
3060 char *result
, *send
;
3064 result
= (char *)xmalloc (2);
3072 slen
= strlen (string
);
3073 send
= string
+ slen
;
3075 result
= (char *)xmalloc ((slen
* 2) + 1);
3077 for (t
= result
; string
< send
; )
3080 COPY_CHAR_P (t
, string
, send
);
3087 /* De-quote quoted characters in STRING. */
3089 dequote_string (string
)
3092 register char *s
, *t
;
3094 char *result
, *send
;
3097 slen
= strlen (string
);
3099 t
= result
= (char *)xmalloc (slen
+ 1);
3101 if (QUOTED_NULL (string
))
3107 /* If no character in the string can be quoted, don't bother examining
3108 each character. Just return a copy of the string passed to us. */
3109 if (strchr (string
, CTLESC
) == NULL
)
3110 return (strcpy (result
, string
));
3112 send
= string
+ slen
;
3122 COPY_CHAR_P (t
, s
, send
);
3129 /* Quote the entire WORD_LIST list. */
3134 register WORD_LIST
*w
;
3137 for (w
= list
; w
; w
= w
->next
)
3140 w
->word
->word
= quote_string (t
);
3142 w
->word
->flags
|= W_QUOTED
;
3143 /* XXX - turn on W_HAVEQUOTEDNULL here? */
3148 /* De-quote quoted characters in each word in LIST. */
3154 register WORD_LIST
*tlist
;
3156 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3158 s
= dequote_string (tlist
->word
->word
);
3159 free (tlist
->word
->word
);
3160 tlist
->word
->word
= s
;
3161 /* XXX - turn off W_HAVEQUOTEDNULL here? */
3166 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3169 remove_quoted_escapes (string
)
3176 t
= dequote_escapes (string
);
3184 /* Perform quoted null character removal on STRING. We don't allow any
3185 quoted null characters in the middle or at the ends of strings because
3186 of how expand_word_internal works. remove_quoted_nulls () turns
3187 STRING into an empty string iff it only consists of a quoted null,
3188 and removes all unquoted CTLNUL characters. */
3190 remove_quoted_nulls (string
)
3193 register size_t slen
;
3194 register int i
, j
, prev_i
;
3197 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3198 return string
; /* XXX */
3200 slen
= strlen (string
);
3205 if (string
[i
] == CTLESC
)
3207 /* Old code had j++, but we cannot assume that i == j at this
3208 point -- what if a CTLNUL has already been removed from the
3209 string? We don't want to drop the CTLESC or recopy characters
3210 that we've already copied down. */
3211 i
++; string
[j
++] = CTLESC
;
3215 else if (string
[i
] == CTLNUL
)
3219 ADVANCE_CHAR (string
, slen
, i
);
3222 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3232 /* Perform quoted null character removal on each element of LIST.
3233 This modifies LIST. */
3235 word_list_remove_quoted_nulls (list
)
3238 register WORD_LIST
*t
;
3240 for (t
= list
; t
; t
= t
->next
)
3242 remove_quoted_nulls (t
->word
->word
);
3243 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3247 /* **************************************************************** */
3249 /* Functions for Matching and Removing Patterns */
3251 /* **************************************************************** */
3253 #if defined (HANDLE_MULTIBYTE)
3254 #if 0 /* Currently unused */
3255 static unsigned char *
3256 mb_getcharlens (string
, len
)
3260 int i
, offset
, last
;
3267 ret
= (unsigned char *)xmalloc (len
);
3268 memset (ret
, 0, len
);
3269 while (string
[last
])
3271 ADVANCE_CHAR (string
, len
, offset
);
3272 ret
[last
] = offset
- last
;
3280 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3281 can have one of 4 values:
3282 RP_LONG_LEFT remove longest matching portion at start of PARAM
3283 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3284 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3285 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3288 #define RP_LONG_LEFT 1
3289 #define RP_SHORT_LEFT 2
3290 #define RP_LONG_RIGHT 3
3291 #define RP_SHORT_RIGHT 4
3294 remove_upattern (param
, pattern
, op
)
3295 char *param
, *pattern
;
3300 register char *p
, *ret
, c
;
3302 len
= STRLEN (param
);
3307 case RP_LONG_LEFT
: /* remove longest match at start */
3308 for (p
= end
; p
>= param
; p
--)
3311 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3314 return (savestring (p
));
3321 case RP_SHORT_LEFT
: /* remove shortest match at start */
3322 for (p
= param
; p
<= end
; p
++)
3325 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3328 return (savestring (p
));
3334 case RP_LONG_RIGHT
: /* remove longest match at end */
3335 for (p
= param
; p
<= end
; p
++)
3337 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3340 ret
= savestring (param
);
3347 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3348 for (p
= end
; p
>= param
; p
--)
3350 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3353 ret
= savestring (param
);
3361 return (savestring (param
)); /* no match, return original string */
3364 #if defined (HANDLE_MULTIBYTE)
3366 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3377 case RP_LONG_LEFT
: /* remove longest match at start */
3378 for (n
= wstrlen
; n
>= 0; n
--)
3380 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3381 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3384 return (wcsdup (wparam
+ n
));
3390 case RP_SHORT_LEFT
: /* remove shortest match at start */
3391 for (n
= 0; n
<= wstrlen
; n
++)
3393 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3394 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3397 return (wcsdup (wparam
+ n
));
3403 case RP_LONG_RIGHT
: /* remove longest match at end */
3404 for (n
= 0; n
<= wstrlen
; n
++)
3406 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3408 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3409 ret
= wcsdup (wparam
);
3416 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3417 for (n
= wstrlen
; n
>= 0; n
--)
3419 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3421 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3422 ret
= wcsdup (wparam
);
3430 return (wcsdup (wparam
)); /* no match, return original string */
3432 #endif /* HANDLE_MULTIBYTE */
3435 remove_pattern (param
, pattern
, op
)
3436 char *param
, *pattern
;
3441 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3442 return (savestring (param
));
3444 #if defined (HANDLE_MULTIBYTE)
3447 wchar_t *ret
, *oret
;
3449 wchar_t *wparam
, *wpattern
;
3453 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3454 if (n
== (size_t)-1)
3455 return (remove_upattern (param
, pattern
, op
));
3456 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3457 if (n
== (size_t)-1)
3460 return (remove_upattern (param
, pattern
, op
));
3462 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3468 xret
= (char *)xmalloc (n
+ 1);
3469 memset (&ps
, '\0', sizeof (mbstate_t));
3470 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3471 xret
[n
] = '\0'; /* just to make sure */
3477 return (remove_upattern (param
, pattern
, op
));
3480 /* Return 1 of the first character of STRING could match the first
3481 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3483 match_pattern_char (pat
, string
)
3494 return (*string
== c
);
3496 return (*string
== *pat
);
3498 return (*pat
== LPAREN
? 1 : (*string
!= '\0'));
3504 return (*pat
== LPAREN
? 1 : (*string
== c
));
3506 return (*string
!= '\0');
3510 /* Match PAT anywhere in STRING and return the match boundaries.
3511 This returns 1 in case of a successful match, 0 otherwise. SP
3512 and EP are pointers into the string where the match begins and
3513 ends, respectively. MTYPE controls what kind of match is attempted.
3514 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3515 of the string, respectively. The longest match is returned. */
3517 match_upattern (string
, pat
, mtype
, sp
, ep
)
3523 register char *p
, *p1
, *npat
;
3526 /* If the pattern doesn't match anywhere in the string, go ahead and
3527 short-circuit right away. A minor optimization, saves a bunch of
3528 unnecessary calls to strmatch (up to N calls for a string of N
3529 characters) if the match is unsuccessful. To preserve the semantics
3530 of the substring matches below, we make sure that the pattern has
3531 `*' as first and last character, making a new pattern if necessary. */
3532 /* XXX - check this later if I ever implement `**' with special meaning,
3533 since this will potentially result in `**' at the beginning or end */
3535 if (pat
[0] != '*' || pat
[len
- 1] != '*')
3537 p
= npat
= (char *)xmalloc (len
+ 3);
3543 if (p1
[-1] != '*' || p
[-2] == '\\')
3549 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
3552 if (c
== FNM_NOMATCH
)
3555 len
= STRLEN (string
);
3561 for (p
= string
; p
<= end
; p
++)
3563 if (match_pattern_char (pat
, p
))
3565 for (p1
= end
; p1
>= p
; p1
--)
3567 c
= *p1
; *p1
= '\0';
3568 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3583 if (match_pattern_char (pat
, string
) == 0)
3586 for (p
= end
; p
>= string
; p
--)
3589 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
3602 for (p
= string
; p
<= end
; p
++)
3604 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3619 #if defined (HANDLE_MULTIBYTE)
3620 /* Return 1 of the first character of WSTRING could match the first
3621 character of pattern WPAT. Wide character version. */
3623 match_pattern_wchar (wpat
, wstring
)
3624 wchar_t *wpat
, *wstring
;
3631 switch (wc
= *wpat
++)
3634 return (*wstring
== wc
);
3636 return (*wstring
== *wpat
);
3638 return (*wpat
== LPAREN
? 1 : (*wstring
!= L
'\0'));
3644 return (*wpat
== LPAREN
? 1 : (*wstring
== wc
));
3646 return (*wstring
!= L
'\0');
3650 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3651 This returns 1 in case of a successful match, 0 otherwise. Wide
3652 character version. */
3654 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
3662 wchar_t wc
, *wp
, *nwpat
, *wp1
;
3665 size_t n
, n1
; /* Apple's gcc seems to miscompile this badly */
3670 /* If the pattern doesn't match anywhere in the string, go ahead and
3671 short-circuit right away. A minor optimization, saves a bunch of
3672 unnecessary calls to strmatch (up to N calls for a string of N
3673 characters) if the match is unsuccessful. To preserve the semantics
3674 of the substring matches below, we make sure that the pattern has
3675 `*' as first and last character, making a new pattern if necessary. */
3676 /* XXX - check this later if I ever implement `**' with special meaning,
3677 since this will potentially result in `**' at the beginning or end */
3678 len
= wcslen (wpat
);
3679 if (wpat
[0] != L
'*' || wpat
[len
- 1] != L
'*')
3681 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
3685 while (*wp1
!= L
'\0')
3687 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
3693 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
3696 if (len
== FNM_NOMATCH
)
3702 for (n
= 0; n
<= wstrlen
; n
++)
3704 if (match_pattern_wchar (wpat
, wstring
+ n
))
3706 for (n1
= wstrlen
; n1
>= n
; n1
--)
3708 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
3709 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3724 if (match_pattern_wchar (wpat
, wstring
) == 0)
3727 for (n
= wstrlen
; n
>= 0; n
--)
3729 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
3730 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
3743 for (n
= 0; n
<= wstrlen
; n
++)
3745 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3748 *ep
= indices
[wstrlen
];
3758 #endif /* HANDLE_MULTIBYTE */
3761 match_pattern (string
, pat
, mtype
, sp
, ep
)
3766 #if defined (HANDLE_MULTIBYTE)
3769 wchar_t *wstring
, *wpat
;
3773 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
3776 #if defined (HANDLE_MULTIBYTE)
3779 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
3780 if (n
== (size_t)-1)
3781 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3782 n
= xdupmbstowcs (&wstring
, &indices
, string
);
3783 if (n
== (size_t)-1)
3786 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3788 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
3798 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3802 getpatspec (c
, value
)
3807 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
3809 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
3812 /* Posix.2 says that the WORD should be run through tilde expansion,
3813 parameter expansion, command substitution and arithmetic expansion.
3814 This leaves the result quoted, so quote_string_for_globbing () has
3815 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3816 it means that the entire expression was enclosed in double quotes.
3817 This means that quoting characters in the pattern do not make any
3818 special pattern characters quoted. For example, the `*' in the
3819 following retains its special meaning: "${foo#'*'}". */
3821 getpattern (value
, quoted
, expandpat
)
3823 int quoted
, expandpat
;
3831 /* There is a problem here: how to handle single or double quotes in the
3832 pattern string when the whole expression is between double quotes?
3833 POSIX.2 says that enclosing double quotes do not cause the pattern to
3834 be quoted, but does that leave us a problem with @ and array[@] and their
3835 expansions inside a pattern? */
3837 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
3840 pat
= string_extract_double_quoted (tword
, &i
, 1);
3846 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3848 l
= *value
? expand_string_for_rhs (value
,
3849 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
3850 (int *)NULL
, (int *)NULL
)
3852 pat
= string_list (l
);
3856 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
3864 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3865 or ${name#[#]value}. */
3867 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
3868 char *value
, *pattern
;
3869 int patspec
, quoted
;
3873 tword
= remove_pattern (value
, pattern
, patspec
);
3880 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
3883 int patspec
, itype
, quoted
;
3889 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
3891 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
3892 w
= alloc_word_desc ();
3893 w
->word
= tword
? tword
: savestring ("");
3894 new = make_word_list (w
, new);
3897 l
= REVERSE_LIST (new, WORD_LIST
*);
3899 tword
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (l
) : string_list (l
);
3901 tword
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (l
) : l
);
3908 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
3911 int patspec
, quoted
;
3916 list
= list_rest_of_args ();
3918 return ((char *)NULL
);
3919 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3920 dispose_words (list
);
3924 #if defined (ARRAY_VARS)
3926 array_remove_pattern (a
, pattern
, patspec
, varname
, quoted
)
3930 char *varname
; /* so we can figure out how it's indexed */
3938 /* compute itype from varname here */
3939 v
= array_variable_part (varname
, &ret
, 0);
3942 list
= array_to_word_list (a
);
3944 return ((char *)NULL
);
3945 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3946 dispose_words (list
);
3950 #endif /* ARRAY_VARS */
3953 parameter_brace_remove_pattern (varname
, value
, patstr
, rtype
, quoted
)
3954 char *varname
, *value
, *patstr
;
3957 int vtype
, patspec
, starsub
;
3958 char *temp1
, *val
, *pattern
;
3962 return ((char *)NULL
);
3964 this_command_name
= varname
;
3966 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
3968 return ((char *)NULL
);
3970 starsub
= vtype
& VT_STARSUB
;
3971 vtype
&= ~VT_STARSUB
;
3973 patspec
= getpatspec (rtype
, patstr
);
3974 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
3977 /* Need to pass getpattern newly-allocated memory in case of expansion --
3978 the expansion code will free the passed string on an error. */
3979 temp1
= savestring (patstr
);
3980 pattern
= getpattern (temp1
, quoted
, 1);
3983 temp1
= (char *)NULL
; /* shut up gcc */
3987 case VT_ARRAYMEMBER
:
3988 temp1
= remove_pattern (val
, pattern
, patspec
);
3989 if (vtype
== VT_VARIABLE
)
3993 val
= quote_escapes (temp1
);
3998 #if defined (ARRAY_VARS)
4000 temp1
= array_remove_pattern (array_cell (v
), pattern
, patspec
, varname
, quoted
);
4001 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4003 val
= quote_escapes (temp1
);
4010 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4011 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4013 val
= quote_escapes (temp1
);
4024 /*******************************************
4026 * Functions to expand WORD_DESCs *
4028 *******************************************/
4030 /* Expand WORD, performing word splitting on the result. This does
4031 parameter expansion, command substitution, arithmetic expansion,
4032 word splitting, and quote removal. */
4035 expand_word (word
, quoted
)
4039 WORD_LIST
*result
, *tresult
;
4041 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4042 result
= word_list_split (tresult
);
4043 dispose_words (tresult
);
4044 return (result
? dequote_list (result
) : result
);
4047 /* Expand WORD, but do not perform word splitting on the result. This
4048 does parameter expansion, command substitution, arithmetic expansion,
4049 and quote removal. */
4051 expand_word_unsplit (word
, quoted
)
4057 expand_no_split_dollar_star
= 1;
4058 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4059 expand_no_split_dollar_star
= 0;
4061 return (result
? dequote_list (result
) : result
);
4064 /* Perform shell expansions on WORD, but do not perform word splitting or
4065 quote removal on the result. */
4067 expand_word_leave_quoted (word
, quoted
)
4071 return (call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
));
4074 #if defined (PROCESS_SUBSTITUTION)
4076 /*****************************************************************/
4078 /* Hacking Process Substitution */
4080 /*****************************************************************/
4082 #if !defined (HAVE_DEV_FD)
4083 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4084 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4085 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4086 list. NFIFO is a count of the number of FIFOs in the list. */
4087 #define FIFO_INCR 20
4094 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4096 static int fifo_list_size
;
4099 add_fifo_list (pathname
)
4102 if (nfifo
>= fifo_list_size
- 1)
4104 fifo_list_size
+= FIFO_INCR
;
4105 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4106 fifo_list_size
* sizeof (struct temp_fifo
));
4109 fifo_list
[nfifo
].file
= savestring (pathname
);
4121 for (i
= saved
= 0; i
< nfifo
; i
++)
4123 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4125 unlink (fifo_list
[i
].file
);
4126 free (fifo_list
[i
].file
);
4127 fifo_list
[i
].file
= (char *)NULL
;
4128 fifo_list
[i
].proc
= -1;
4134 /* If we didn't remove some of the FIFOs, compact the list. */
4137 for (i
= j
= 0; i
< nfifo
; i
++)
4138 if (fifo_list
[i
].file
)
4140 fifo_list
[j
].file
= fifo_list
[i
].file
;
4141 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4161 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
);
4162 if (mkfifo (tname
, 0600) < 0)
4165 return ((char *)NULL
);
4168 add_fifo_list (tname
);
4172 #else /* HAVE_DEV_FD */
4174 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4175 has open to children. NFDS is a count of the number of bits currently
4176 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4178 static char *dev_fd_list
= (char *)NULL
;
4180 static int totfds
; /* The highest possible number of open files. */
4186 if (!dev_fd_list
|| fd
>= totfds
)
4191 totfds
= getdtablesize ();
4192 if (totfds
< 0 || totfds
> 256)
4197 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4198 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4201 dev_fd_list
[fd
] = 1;
4208 return 0; /* used for cleanup; not needed with /dev/fd */
4219 for (i
= 0; nfds
&& i
< totfds
; i
++)
4230 #if defined (NOTDEF)
4231 print_dev_fd_list ()
4235 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4238 for (i
= 0; i
< totfds
; i
++)
4241 fprintf (stderr
, " %d", i
);
4243 fprintf (stderr
, "\n");
4248 make_dev_fd_filename (fd
)
4251 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4253 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 4);
4255 strcpy (ret
, DEV_FD_PREFIX
);
4256 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4257 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4263 #endif /* HAVE_DEV_FD */
4265 /* Return a filename that will open a connection to the process defined by
4266 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4267 a filename in /dev/fd corresponding to a descriptor that is one of the
4268 ends of the pipe. If not defined, we use named pipes on systems that have
4269 them. Systems without /dev/fd and named pipes are out of luck.
4271 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4272 use the read end of the pipe and dup that file descriptor to fd 0 in
4273 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4274 writing or use the write end of the pipe in the child, and dup that
4275 file descriptor to fd 1 in the child. The parent does the opposite. */
4278 process_substitute (string
, open_for_read_in_child
)
4280 int open_for_read_in_child
;
4285 #if defined (HAVE_DEV_FD)
4286 int parent_pipe_fd
, child_pipe_fd
;
4288 #endif /* HAVE_DEV_FD */
4289 #if defined (JOB_CONTROL)
4290 pid_t old_pipeline_pgrp
;
4293 if (!string
|| !*string
|| wordexp_only
)
4294 return ((char *)NULL
);
4296 #if !defined (HAVE_DEV_FD)
4297 pathname
= make_named_pipe ();
4298 #else /* HAVE_DEV_FD */
4299 if (pipe (fildes
) < 0)
4301 sys_error (_("cannot make pipe for process substitution"));
4302 return ((char *)NULL
);
4304 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4305 the pipe in the parent, otherwise the read end. */
4306 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4307 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4308 /* Move the parent end of the pipe to some high file descriptor, to
4309 avoid clashes with FDs used by the script. */
4310 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4312 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4313 #endif /* HAVE_DEV_FD */
4317 sys_error (_("cannot make pipe for process substitution"));
4318 return ((char *)NULL
);
4321 old_pid
= last_made_pid
;
4323 #if defined (JOB_CONTROL)
4324 old_pipeline_pgrp
= pipeline_pgrp
;
4325 pipeline_pgrp
= shell_pgrp
;
4327 #endif /* JOB_CONTROL */
4329 pid
= make_child ((char *)NULL
, 1);
4332 reset_terminating_signals (); /* XXX */
4333 free_pushed_string_input ();
4334 /* Cancel traps, in trap.c. */
4335 restore_original_signals ();
4336 setup_async_signals ();
4337 subshell_environment
|= SUBSHELL_COMSUB
;
4340 #if defined (JOB_CONTROL)
4341 set_sigchld_handler ();
4342 stop_making_children ();
4343 pipeline_pgrp
= old_pipeline_pgrp
;
4344 #endif /* JOB_CONTROL */
4348 sys_error (_("cannot make child for process substitution"));
4350 #if defined (HAVE_DEV_FD)
4351 close (parent_pipe_fd
);
4352 close (child_pipe_fd
);
4353 #endif /* HAVE_DEV_FD */
4354 return ((char *)NULL
);
4359 #if defined (JOB_CONTROL)
4360 restore_pipeline (1);
4363 #if !defined (HAVE_DEV_FD)
4364 fifo_list
[nfifo
-1].proc
= pid
;
4367 last_made_pid
= old_pid
;
4369 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4371 #endif /* JOB_CONTROL && PGRP_PIPE */
4373 #if defined (HAVE_DEV_FD)
4374 close (child_pipe_fd
);
4375 #endif /* HAVE_DEV_FD */
4380 set_sigint_handler ();
4382 #if defined (JOB_CONTROL)
4383 set_job_control (0);
4384 #endif /* JOB_CONTROL */
4386 #if !defined (HAVE_DEV_FD)
4387 /* Open the named pipe in the child. */
4388 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4391 /* Two separate strings for ease of translation. */
4392 if (open_for_read_in_child
)
4393 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4395 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4399 if (open_for_read_in_child
)
4401 if (sh_unset_nodelay_mode (fd
) < 0)
4403 sys_error (_("cannout reset nodelay mode for fd %d"), fd
);
4407 #else /* HAVE_DEV_FD */
4409 #endif /* HAVE_DEV_FD */
4411 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4413 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4414 open_for_read_in_child
? 0 : 1);
4418 if (fd
!= (open_for_read_in_child
? 0 : 1))
4421 /* Need to close any files that this process has open to pipes inherited
4423 if (current_fds_to_close
)
4425 close_fd_bitmap (current_fds_to_close
);
4426 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4429 #if defined (HAVE_DEV_FD)
4430 /* Make sure we close the parent's end of the pipe and clear the slot
4431 in the fd list so it is not closed later, if reallocated by, for
4432 instance, pipe(2). */
4433 close (parent_pipe_fd
);
4434 dev_fd_list
[parent_pipe_fd
] = 0;
4435 #endif /* HAVE_DEV_FD */
4437 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4439 #if !defined (HAVE_DEV_FD)
4440 /* Make sure we close the named pipe in the child before we exit. */
4441 close (open_for_read_in_child
? 0 : 1);
4442 #endif /* !HAVE_DEV_FD */
4447 #endif /* PROCESS_SUBSTITUTION */
4449 /***********************************/
4451 /* Command Substitution */
4453 /***********************************/
4456 read_comsub (fd
, quoted
)
4459 char *istring
, buf
[128], *bufp
;
4460 int istring_index
, istring_size
, c
;
4463 istring
= (char *)NULL
;
4464 istring_index
= istring_size
= bufn
= 0;
4467 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4470 /* Read the output of the command through the pipe. */
4477 bufn
= zread (fd
, buf
, sizeof (buf
));
4487 internal_warning ("read_comsub: ignored null byte in input");
4492 /* Add the character to ISTRING, possibly after resizing it. */
4493 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4495 /* This is essentially quote_string inline */
4496 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
4497 istring
[istring_index
++] = CTLESC
;
4498 /* Escape CTLESC and CTLNUL in the output to protect those characters
4499 from the rest of the word expansions (word splitting and globbing.)
4500 This is essentially quote_escapes inline. */
4501 else if (c
== CTLESC
)
4502 istring
[istring_index
++] = CTLESC
;
4503 else if (c
== CTLNUL
|| (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
4504 istring
[istring_index
++] = CTLESC
;
4506 istring
[istring_index
++] = c
;
4509 #if defined (__CYGWIN__)
4510 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4513 istring
[istring_index
- 1] = '\n';
4520 istring
[istring_index
] = '\0';
4522 /* If we read no output, just return now and save ourselves some
4524 if (istring_index
== 0)
4527 return (char *)NULL
;
4530 /* Strip trailing newlines from the output of the command. */
4531 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4533 while (istring_index
> 0)
4535 if (istring
[istring_index
- 1] == '\n')
4539 /* If the newline was quoted, remove the quoting char. */
4540 if (istring
[istring_index
- 1] == CTLESC
)
4546 istring
[istring_index
] = '\0';
4549 strip_trailing (istring
, istring_index
- 1, 1);
4554 /* Perform command substitution on STRING. This returns a string,
4557 command_substitute (string
, quoted
)
4561 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4563 int result
, fildes
[2], function_value
, pflags
, rc
;
4565 istring
= (char *)NULL
;
4567 /* Don't fork () if there is no need to. In the case of no command to
4568 run, just return NULL. */
4569 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
4570 return ((char *)NULL
);
4572 if (wordexp_only
&& read_but_dont_execute
)
4574 last_command_exit_value
= 125;
4575 jump_to_top_level (EXITPROG
);
4578 /* We're making the assumption here that the command substitution will
4579 eventually run a command from the file system. Since we'll run
4580 maybe_make_export_env in this subshell before executing that command,
4581 the parent shell and any other shells it starts will have to remake
4582 the environment. If we make it before we fork, other shells won't
4583 have to. Don't bother if we have any temporary variable assignments,
4584 though, because the export environment will be remade after this
4585 command completes anyway, but do it if all the words to be expanded
4586 are variable assignments. */
4587 if (subst_assign_varlist
== 0 || garglist
== 0)
4588 maybe_make_export_env (); /* XXX */
4590 /* Flags to pass to parse_and_execute() */
4591 pflags
= interactive
? SEVAL_RESETLINE
: 0;
4593 /* Pipe the output of executing STRING into the current shell. */
4594 if (pipe (fildes
) < 0)
4596 sys_error (_("cannot make pipe for command substitution"));
4600 old_pid
= last_made_pid
;
4601 #if defined (JOB_CONTROL)
4602 old_pipeline_pgrp
= pipeline_pgrp
;
4603 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4604 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
4605 pipeline_pgrp
= shell_pgrp
;
4606 cleanup_the_pipeline ();
4607 #endif /* JOB_CONTROL */
4609 old_async_pid
= last_asynchronous_pid
;
4611 pid
= make_child ((char *)NULL
, 0);
4613 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
4615 last_asynchronous_pid
= old_async_pid
;
4618 /* Reset the signal handlers in the child, but don't free the
4620 reset_signal_handlers ();
4622 #if defined (JOB_CONTROL)
4623 set_sigchld_handler ();
4624 stop_making_children ();
4625 pipeline_pgrp
= old_pipeline_pgrp
;
4627 stop_making_children ();
4628 #endif /* JOB_CONTROL */
4632 sys_error (_("cannot make child for command substitution"));
4638 return ((char *)NULL
);
4643 set_sigint_handler (); /* XXX */
4645 free_pushed_string_input ();
4647 if (dup2 (fildes
[1], 1) < 0)
4649 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4650 exit (EXECUTION_FAILURE
);
4653 /* If standard output is closed in the parent shell
4654 (such as after `exec >&-'), file descriptor 1 will be
4655 the lowest available file descriptor, and end up in
4656 fildes[0]. This can happen for stdin and stderr as well,
4657 but stdout is more important -- it will cause no output
4658 to be generated from this command. */
4659 if ((fildes
[1] != fileno (stdin
)) &&
4660 (fildes
[1] != fileno (stdout
)) &&
4661 (fildes
[1] != fileno (stderr
)))
4664 if ((fildes
[0] != fileno (stdin
)) &&
4665 (fildes
[0] != fileno (stdout
)) &&
4666 (fildes
[0] != fileno (stderr
)))
4669 /* The currently executing shell is not interactive. */
4672 /* This is a subshell environment. */
4673 subshell_environment
|= SUBSHELL_COMSUB
;
4675 /* When not in POSIX mode, command substitution does not inherit
4677 if (posixly_correct
== 0)
4678 exit_immediately_on_error
= 0;
4680 remove_quoted_escapes (string
);
4682 startup_state
= 2; /* see if we can avoid a fork */
4683 /* Give command substitution a place to jump back to on failure,
4684 so we don't go back up to main (). */
4685 result
= setjmp (top_level
);
4687 /* If we're running a command substitution inside a shell function,
4688 trap `return' so we don't return from the function in the subshell
4689 and go off to never-never land. */
4690 if (result
== 0 && return_catch_flag
)
4691 function_value
= setjmp (return_catch
);
4695 if (result
== ERREXIT
)
4696 rc
= last_command_exit_value
;
4697 else if (result
== EXITPROG
)
4698 rc
= last_command_exit_value
;
4700 rc
= EXECUTION_FAILURE
;
4701 else if (function_value
)
4702 rc
= return_catch_value
;
4706 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
4710 last_command_exit_value
= rc
;
4711 rc
= run_exit_trap ();
4712 #if defined (PROCESS_SUBSTITUTION)
4713 unlink_fifo_list ();
4719 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4721 #endif /* JOB_CONTROL && PGRP_PIPE */
4725 istring
= read_comsub (fildes
[0], quoted
);
4729 current_command_subst_pid
= pid
;
4730 last_command_exit_value
= wait_for (pid
);
4731 last_command_subst_pid
= pid
;
4732 last_made_pid
= old_pid
;
4734 #if defined (JOB_CONTROL)
4735 /* If last_command_exit_value > 128, then the substituted command
4736 was terminated by a signal. If that signal was SIGINT, then send
4737 SIGINT to ourselves. This will break out of loops, for instance. */
4738 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
4739 kill (getpid (), SIGINT
);
4741 /* wait_for gives the terminal back to shell_pgrp. If some other
4742 process group should have it, give it away to that group here.
4743 pipeline_pgrp is non-zero only while we are constructing a
4744 pipline, so what we are concerned about is whether or not that
4745 pipeline was started in the background. A pipeline started in
4746 the background should never get the tty back here. */
4748 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
4750 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
4752 give_terminal_to (pipeline_pgrp
, 0);
4753 #endif /* JOB_CONTROL */
4759 /********************************************************
4761 * Utility functions for parameter expansion *
4763 ********************************************************/
4765 #if defined (ARRAY_VARS)
4768 array_length_reference (s
)
4777 var
= array_variable_part (s
, &t
, &len
);
4779 /* If unbound variables should generate an error, report one and return
4781 if ((var
== 0 || array_p (var
) == 0) && unbound_vars_is_error
)
4792 /* We support a couple of expansions for variables that are not arrays.
4793 We'll return the length of the value for v[0], and 1 for v[@] or
4794 v[*]. Return 0 for everything else. */
4796 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
4798 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
4799 return (array_p (var
) ? array_num_elements (array
) : 1);
4801 ind
= array_expand_index (t
, len
);
4804 err_badarraysub (t
);
4809 t
= array_reference (array
, ind
);
4811 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
4816 #endif /* ARRAY_VARS */
4819 valid_brace_expansion_word (name
, var_is_special
)
4823 if (DIGIT (*name
) && all_digits (name
))
4825 else if (var_is_special
)
4827 #if defined (ARRAY_VARS)
4828 else if (valid_array_reference (name
))
4830 #endif /* ARRAY_VARS */
4831 else if (legal_identifier (name
))
4838 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4841 int *quoted_dollar_atp
, *contains_dollar_at
;
4847 if (quoted_dollar_atp
)
4848 *quoted_dollar_atp
= 0;
4849 if (contains_dollar_at
)
4850 *contains_dollar_at
= 0;
4854 /* check for $@ and $* */
4855 if (name
[0] == '@' && name
[1] == 0)
4857 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4858 *quoted_dollar_atp
= 1;
4859 if (contains_dollar_at
)
4860 *contains_dollar_at
= 1;
4863 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
4865 if (contains_dollar_at
)
4866 *contains_dollar_at
= 1;
4870 /* Now check for ${array[@]} and ${array[*]} */
4871 #if defined (ARRAY_VARS)
4872 else if (valid_array_reference (name
))
4874 temp1
= xstrchr (name
, '[');
4875 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
4877 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4878 *quoted_dollar_atp
= 1;
4879 if (contains_dollar_at
)
4880 *contains_dollar_at
= 1;
4883 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4884 which should result in separate words even when IFS is unset. */
4885 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
4887 if (contains_dollar_at
)
4888 *contains_dollar_at
= 1;
4896 /* Parameter expand NAME, and return a new string which is the expansion,
4897 or NULL if there was no expansion.
4898 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4899 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4900 NAME was found inside of a double-quoted expression. */
4902 parameter_brace_expand_word (name
, var_is_special
, quoted
)
4904 int var_is_special
, quoted
;
4915 /* Handle multiple digit arguments, as in ${11}. */
4916 if (legal_number (name
, &arg_index
))
4918 tt
= get_dollar_var_value (arg_index
);
4920 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4922 : quote_escapes (tt
);
4924 temp
= (char *)NULL
;
4927 else if (var_is_special
) /* ${@} */
4930 tt
= (char *)xmalloc (2 + strlen (name
));
4931 tt
[sindex
= 0] = '$';
4932 strcpy (tt
+ 1, name
);
4934 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
4935 (int *)NULL
, (int *)NULL
, 0);
4938 #if defined (ARRAY_VARS)
4939 else if (valid_array_reference (name
))
4941 temp
= array_value (name
, quoted
, &atype
);
4942 if (atype
== 0 && temp
)
4943 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4944 ? quote_string (temp
)
4945 : quote_escapes (temp
);
4948 else if (var
= find_variable (name
))
4950 if (var_isset (var
) && invisible_p (var
) == 0)
4952 #if defined (ARRAY_VARS)
4953 temp
= array_p (var
) ? array_reference (array_cell (var
), 0) : value_cell (var
);
4955 temp
= value_cell (var
);
4959 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4960 ? quote_string (temp
)
4961 : quote_escapes (temp
);
4964 temp
= (char *)NULL
;
4967 temp
= (char *)NULL
;
4971 ret
= alloc_word_desc ();
4977 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4978 value of the variable whose name is the value of NAME. */
4980 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4982 int var_is_special
, quoted
;
4983 int *quoted_dollar_atp
, *contains_dollar_at
;
4988 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
4990 /* Have to dequote here if necessary */
4993 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
4994 ? dequote_string (t
)
4995 : dequote_escapes (t
);
4999 dispose_word_desc (w
);
5001 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5003 return (WORD_DESC
*)NULL
;
5005 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
);
5011 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5012 depending on the value of C, the separating character. C can be one of
5013 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5014 between double quotes. */
5016 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5018 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5022 char *t
, *t1
, *temp
;
5025 /* If the entire expression is between double quotes, we want to treat
5026 the value as a double-quoted string, with the exception that we strip
5027 embedded unescaped double quotes. */
5028 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5031 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5036 w
= alloc_word_desc ();
5038 /* XXX was 0 not quoted */
5039 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5042 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5047 /* The expansion of TEMP returned something. We need to treat things
5048 slightly differently if HASDOL is non-zero. If we have "$@", the
5049 individual words have already been quoted. We need to turn them
5050 into a string with the words separated by the first character of
5051 $IFS without any additional quoting, so string_list_dollar_at won't
5052 do the right thing. We use string_list_dollar_star instead. */
5053 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5055 /* If l->next is not null, we know that TEMP contained "$@", since that
5056 is the only expansion that creates more than one word. */
5057 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5061 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5063 /* The brace expansion occurred between double quotes and there was
5064 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5065 it does not expand to anything. In this case, we want to return
5066 a quoted empty string. */
5067 temp
= make_quoted_char ('\0');
5068 w
->flags
|= W_HASQUOTEDNULL
;
5071 temp
= (char *)NULL
;
5073 if (c
== '-' || c
== '+')
5080 t
= temp
? savestring (temp
) : savestring ("");
5081 t1
= dequote_string (t
);
5083 #if defined (ARRAY_VARS)
5084 if (valid_array_reference (name
))
5085 assign_array_element (name
, t1
, 0);
5087 #endif /* ARRAY_VARS */
5088 bind_variable (name
, t1
, 0);
5095 /* Deal with the right hand side of a ${name:?value} expansion in the case
5096 that NAME is null or not set. If VALUE is non-null it is expanded and
5097 used as the error message to print, otherwise a standard message is
5100 parameter_brace_expand_error (name
, value
)
5106 if (value
&& *value
)
5108 l
= expand_string (value
, 0);
5109 temp
= string_list (l
);
5110 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5115 report_error (_("%s: parameter null or not set"), name
);
5117 /* Free the data we have allocated during this expansion, since we
5118 are about to longjmp out. */
5123 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5126 valid_length_expression (name
)
5129 return (name
[1] == '\0' || /* ${#} */
5130 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5131 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5132 #if defined (ARRAY_VARS)
5133 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5135 legal_identifier (name
+ 1)); /* ${#PS1} */
5138 #if defined (HANDLE_MULTIBYTE)
5144 mbstate_t mbs
, mbsbak
;
5147 memset (&mbs
, 0, sizeof (mbs
));
5149 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5151 if (MB_INVALIDCH(clen
))
5153 clen
= 1; /* assume single byte */
5166 /* Handle the parameter brace expansion that requires us to return the
5167 length of a parameter. */
5169 parameter_brace_expand_length (name
)
5173 intmax_t number
, arg_index
;
5175 #if defined (ARRAY_VARS)
5179 if (name
[1] == '\0') /* ${#} */
5180 number
= number_of_args ();
5181 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5182 number
= number_of_args ();
5183 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5185 /* Take the lengths of some of the shell's special parameters. */
5189 t
= which_set_flags ();
5192 t
= itos (last_command_exit_value
);
5195 t
= itos (dollar_dollar_pid
);
5198 if (last_asynchronous_pid
== NO_PID
)
5201 t
= itos (last_asynchronous_pid
);
5204 t
= itos (number_of_args ());
5207 number
= STRLEN (t
);
5210 #if defined (ARRAY_VARS)
5211 else if (valid_array_reference (name
+ 1))
5212 number
= array_length_reference (name
+ 1);
5213 #endif /* ARRAY_VARS */
5218 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5220 t
= get_dollar_var_value (arg_index
);
5221 number
= MB_STRLEN (t
);
5224 #if defined (ARRAY_VARS)
5225 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && array_p (var
))
5227 t
= array_reference (array_cell (var
), 0);
5228 number
= MB_STRLEN (t
);
5233 newname
= savestring (name
);
5235 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5236 t
= list
? string_list (list
) : (char *)NULL
;
5239 dispose_words (list
);
5241 number
= MB_STRLEN (t
);
5249 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5250 so we do some ad-hoc parsing of an arithmetic expression to find
5251 the first DELIM, instead of using strchr(3). Two rules:
5252 1. If the substring contains a `(', read until closing `)'.
5253 2. If the substring contains a `?', read past one `:' for each `?'.
5257 skiparith (substr
, delim
)
5262 int skipcol
, pcount
, i
;
5265 sublen
= strlen (substr
);
5266 i
= skipcol
= pcount
= 0;
5269 /* Balance parens */
5270 if (substr
[i
] == LPAREN
)
5276 if (substr
[i
] == RPAREN
&& pcount
)
5284 ADVANCE_CHAR (substr
, sublen
, i
);
5288 /* Skip one `:' for each `?' */
5289 if (substr
[i
] == ':' && skipcol
)
5295 if (substr
[i
] == delim
)
5297 if (substr
[i
] == '?')
5303 ADVANCE_CHAR (substr
, sublen
, i
);
5306 return (substr
+ i
);
5309 /* Verify and limit the start and end of the desired substring. If
5310 VTYPE == 0, a regular shell variable is being used; if it is 1,
5311 then the positional parameters are being used; if it is 2, then
5312 VALUE is really a pointer to an array variable that should be used.
5313 Return value is 1 if both values were OK, 0 if there was a problem
5314 with an invalid expression, or -1 if the values were out of range. */
5316 verify_substring_values (value
, substr
, vtype
, e1p
, e2p
)
5317 char *value
, *substr
;
5319 intmax_t *e1p
, *e2p
;
5321 char *t
, *temp1
, *temp2
;
5324 #if defined (ARRAY_VARS)
5328 /* duplicate behavior of strchr(3) */
5329 t
= skiparith (substr
, ':');
5330 if (*t
&& *t
== ':')
5335 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5336 *e1p
= evalexp (temp1
, &expok
);
5341 len
= -1; /* paranoia */
5345 case VT_ARRAYMEMBER
:
5346 len
= MB_STRLEN (value
);
5349 len
= number_of_args () + 1;
5351 #if defined (ARRAY_VARS)
5354 /* For arrays, the first value deals with array indices. Negative
5355 offsets count from one past the array's maximum index. */
5356 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5361 if (len
== -1) /* paranoia */
5364 if (*e1p
< 0) /* negative offsets count from end */
5367 if (*e1p
> len
|| *e1p
< 0)
5370 #if defined (ARRAY_VARS)
5371 /* For arrays, the second offset deals with the number of elements. */
5372 if (vtype
== VT_ARRAYVAR
)
5373 len
= array_num_elements (a
);
5379 temp2
= savestring (t
);
5380 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5383 *e2p
= evalexp (temp1
, &expok
);
5389 internal_error (_("%s: substring expression < 0"), t
);
5392 #if defined (ARRAY_VARS)
5393 /* In order to deal with sparse arrays, push the intelligence about how
5394 to deal with the number of elements desired down to the array-
5395 specific functions. */
5396 if (vtype
!= VT_ARRAYVAR
)
5399 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5410 /* Return the type of variable specified by VARNAME (simple variable,
5411 positional param, or array variable). Also return the value specified
5412 by VARNAME (value of a variable or a reference to an array element).
5413 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5414 characters in the value are quoted with CTLESC and takes appropriate
5415 steps. For convenience, *VALP is set to the dequoted VALUE. */
5417 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5418 char *varname
, *value
;
5425 #if defined (ARRAY_VARS)
5429 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5430 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5431 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5432 vtype
|= VT_STARSUB
;
5433 *varp
= (SHELL_VAR
*)NULL
;
5435 #if defined (ARRAY_VARS)
5436 if (valid_array_reference (varname
))
5438 v
= array_variable_part (varname
, &temp
, (int *)0);
5439 if (v
&& array_p (v
))
5441 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5443 vtype
= VT_ARRAYVAR
;
5445 vtype
|= VT_STARSUB
;
5446 *valp
= (char *)array_cell (v
);
5450 vtype
= VT_ARRAYMEMBER
;
5451 *valp
= array_value (varname
, 1, (int *)NULL
);
5455 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5457 vtype
= VT_VARIABLE
;
5459 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5460 *valp
= dequote_string (value
);
5462 *valp
= dequote_escapes (value
);
5467 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && array_p (v
))
5469 vtype
= VT_ARRAYMEMBER
;
5471 *valp
= array_reference (array_cell (v
), 0);
5476 if (value
&& vtype
== VT_VARIABLE
)
5478 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5479 *valp
= dequote_string (value
);
5481 *valp
= dequote_escapes (value
);
5490 /******************************************************/
5492 /* Functions to extract substrings of variable values */
5494 /******************************************************/
5496 #if defined (HANDLE_MULTIBYTE)
5497 /* Character-oriented rather than strictly byte-oriented substrings. S and
5498 E, rather being strict indices into STRING, indicate character (possibly
5499 multibyte character) positions that require calculation.
5500 Used by the ${param:offset[:length]} expansion. */
5502 mb_substring (string
, s
, e
)
5507 int start
, stop
, i
, slen
;
5511 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5512 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
5515 while (string
[start
] && i
--)
5516 ADVANCE_CHAR (string
, slen
, start
);
5519 while (string
[stop
] && i
--)
5520 ADVANCE_CHAR (string
, slen
, stop
);
5521 tt
= substring (string
, start
, stop
);
5526 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5527 is `@', use the positional parameters; otherwise, use the value of
5528 VARNAME. If VARNAME is an array variable, use the array elements. */
5531 parameter_brace_substring (varname
, value
, substr
, quoted
)
5532 char *varname
, *value
, *substr
;
5536 int vtype
, r
, starsub
;
5537 char *temp
, *val
, *tt
, *oname
;
5541 return ((char *)NULL
);
5543 oname
= this_command_name
;
5544 this_command_name
= varname
;
5546 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5549 this_command_name
= oname
;
5550 return ((char *)NULL
);
5553 starsub
= vtype
& VT_STARSUB
;
5554 vtype
&= ~VT_STARSUB
;
5556 r
= verify_substring_values (val
, substr
, vtype
, &e1
, &e2
);
5557 this_command_name
= oname
;
5559 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
5564 case VT_ARRAYMEMBER
:
5565 #if defined (HANDLE_MULTIBYTE)
5567 tt
= mb_substring (val
, e1
, e2
);
5570 tt
= substring (val
, e1
, e2
);
5572 if (vtype
== VT_VARIABLE
)
5574 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5575 temp
= quote_string (tt
);
5577 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5581 tt
= pos_params (varname
, e1
, e2
, quoted
);
5582 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5584 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5590 #if defined (ARRAY_VARS)
5592 /* We want E2 to be the number of elements desired (arrays can be sparse,
5593 so verify_substring_values just returns the numbers specified and we
5594 rely on array_subrange to understand how to deal with them). */
5595 tt
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
5597 /* array_subrange now calls array_quote_escapes as appropriate, so the
5598 caller no longer needs to. */
5599 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5601 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5610 temp
= (char *)NULL
;
5616 /****************************************************************/
5618 /* Functions to perform pattern substitution on variable values */
5620 /****************************************************************/
5623 pat_subst (string
, pat
, rep
, mflags
)
5624 char *string
, *pat
, *rep
;
5627 char *ret
, *s
, *e
, *str
;
5628 int rsize
, rptr
, l
, replen
, mtype
;
5630 mtype
= mflags
& MATCH_TYPEMASK
;
5633 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5634 * with REP and return the result.
5635 * 2. A null pattern with mtype == MATCH_END means to append REP to
5636 * STRING and return the result.
5638 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
5640 replen
= STRLEN (rep
);
5641 l
= strlen (string
);
5642 ret
= (char *)xmalloc (replen
+ l
+ 2);
5644 strcpy (ret
, string
);
5645 else if (mtype
== MATCH_BEG
)
5648 strcpy (ret
+ replen
, string
);
5652 strcpy (ret
, string
);
5653 strcpy (ret
+ l
, rep
);
5658 ret
= (char *)xmalloc (rsize
= 64);
5661 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
5663 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
5666 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
5668 /* OK, now copy the leading unmatched portion of the string (from
5669 str to s) to ret starting at rptr (the current offset). Then copy
5670 the replacement string at ret + rptr + (s - str). Increment
5671 rptr (if necessary) and str and go on. */
5674 strncpy (ret
+ rptr
, str
, l
);
5679 strncpy (ret
+ rptr
, rep
, replen
);
5682 str
= e
; /* e == end of match */
5684 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
5688 e
++, str
++; /* avoid infinite recursion on zero-length match */
5691 /* Now copy the unmatched portion of the input string */
5694 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
5695 strcpy (ret
+ rptr
, str
);
5703 /* Do pattern match and replacement on the positional parameters. */
5705 pos_params_pat_subst (string
, pat
, rep
, mflags
)
5706 char *string
, *pat
, *rep
;
5709 WORD_LIST
*save
, *params
;
5713 save
= params
= list_rest_of_args ();
5715 return ((char *)NULL
);
5717 for ( ; params
; params
= params
->next
)
5719 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
5720 w
= alloc_word_desc ();
5721 w
->word
= ret
? ret
: savestring ("");
5722 dispose_word (params
->word
);
5726 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
5727 ret
= string_list_dollar_star (quote_list (save
));
5729 ret
= string_list ((mflags
& MATCH_QUOTED
) ? quote_list (save
) : save
);
5730 dispose_words (save
);
5735 /* Perform pattern substitution on VALUE, which is the expansion of
5736 VARNAME. PATSUB is an expression supplying the pattern to match
5737 and the string to substitute. QUOTED is a flags word containing
5738 the type of quoting currently in effect. */
5740 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
5741 char *varname
, *value
, *patsub
;
5744 int vtype
, mflags
, starsub
;
5745 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
5749 return ((char *)NULL
);
5751 this_command_name
= varname
;
5753 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5755 return ((char *)NULL
);
5757 starsub
= vtype
& VT_STARSUB
;
5758 vtype
&= ~VT_STARSUB
;
5761 if (patsub
&& *patsub
== '/')
5763 mflags
|= MATCH_GLOBREP
;
5767 /* Malloc this because expand_string_if_necessary or one of the expansion
5768 functions in its call chain may free it on a substitution error. */
5769 lpatsub
= savestring (patsub
);
5771 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5772 mflags
|= MATCH_QUOTED
;
5775 mflags
|= MATCH_STARSUB
;
5777 /* If the pattern starts with a `/', make sure we skip over it when looking
5778 for the replacement delimiter. */
5779 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
5784 if (rep
&& *rep
== '\0')
5787 /* Perform the same expansions on the pattern as performed by the
5788 pattern removal expansions. */
5789 pat
= getpattern (lpatsub
, quoted
, 1);
5793 if ((mflags
& MATCH_QUOTED
) == 0)
5794 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
5796 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
5799 /* ksh93 doesn't allow the match specifier to be a part of the expanded
5800 pattern. This is an extension. Make sure we don't anchor the pattern
5801 at the beginning or end of the string if we're doing global replacement,
5804 if (mflags
& MATCH_GLOBREP
)
5805 mflags
|= MATCH_ANY
;
5806 else if (pat
&& pat
[0] == '#')
5808 mflags
|= MATCH_BEG
;
5811 else if (pat
&& pat
[0] == '%')
5813 mflags
|= MATCH_END
;
5817 mflags
|= MATCH_ANY
;
5819 /* OK, we now want to substitute REP for PAT in VAL. If
5820 flags & MATCH_GLOBREP is non-zero, the substitution is done
5821 everywhere, otherwise only the first occurrence of PAT is
5822 replaced. The pattern matching code doesn't understand
5823 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5824 values passed in (VT_VARIABLE) so the pattern substitution
5825 code works right. We need to requote special chars after
5826 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5827 other cases if QUOTED == 0, since the posparams and arrays
5828 indexed by * or @ do special things when QUOTED != 0. */
5833 case VT_ARRAYMEMBER
:
5834 temp
= pat_subst (val
, p
, rep
, mflags
);
5835 if (vtype
== VT_VARIABLE
)
5839 tt
= quote_escapes (temp
);
5845 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
5846 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5848 tt
= quote_escapes (temp
);
5853 #if defined (ARRAY_VARS)
5855 temp
= array_patsub (array_cell (v
), p
, rep
, mflags
);
5857 /* Don't need to do this anymore; array_patsub calls array_quote_escapes
5858 as appropriate before adding the space separators. */
5859 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5861 tt
= quote_escapes (temp
);
5877 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
5878 any occur, this must be a nested command substitution, so return 0.
5879 Otherwise, return 1. A valid arithmetic expression must always have a
5880 ( before a matching ), so any cases where there are more right parens
5881 means that this must not be an arithmetic expression, though the parser
5882 will not accept it without a balanced total number of parens. */
5884 chk_arithsub (s
, len
)
5896 else if (s
[i
] == ')')
5906 ADVANCE_CHAR (s
, len
, i
);
5912 ADVANCE_CHAR (s
, len
, i
);
5916 i
= skip_single_quoted (s
, len
, ++i
);
5920 i
= skip_double_quoted ((char *)s
, len
, ++i
);
5925 return (count
== 0);
5928 /****************************************************************/
5930 /* Functions to perform parameter expansion on a string */
5932 /****************************************************************/
5934 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5936 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5938 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
5940 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
5941 int want_substring
, want_indir
, want_patsub
;
5942 char *name
, *value
, *temp
, *temp1
;
5943 WORD_DESC
*tdesc
, *ret
;
5944 int t_index
, sindex
, c
, tflag
;
5947 value
= (char *)NULL
;
5948 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
5949 want_substring
= want_indir
= want_patsub
= 0;
5953 /* ${#var} doesn't have any of the other parameter expansions on it. */
5954 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
5955 name
= string_extract (string
, &t_index
, "}", EX_VARNAME
);
5957 name
= string_extract (string
, &t_index
, "#%:-=?+/}", EX_VARNAME
);
5962 /* If the name really consists of a special variable, then make sure
5963 that we have the entire name. We don't allow indirect references
5964 to special variables except `#', `?', `@' and `*'. */
5965 if ((sindex
== t_index
&&
5966 (string
[t_index
] == '-' ||
5967 string
[t_index
] == '?' ||
5968 string
[t_index
] == '#')) ||
5969 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
5970 (string
[t_index
] == '#' ||
5971 string
[t_index
] == '?' ||
5972 string
[t_index
] == '@' ||
5973 string
[t_index
] == '*')))
5977 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
5978 name
= (char *)xmalloc (3 + (strlen (temp1
)));
5979 *name
= string
[sindex
];
5980 if (string
[sindex
] == '!')
5982 /* indirect reference of $#, $?, $@, or $* */
5983 name
[1] = string
[sindex
+ 1];
5984 strcpy (name
+ 2, temp1
);
5987 strcpy (name
+ 1, temp1
);
5992 /* Find out what character ended the variable name. Then
5993 do the appropriate thing. */
5994 if (c
= string
[sindex
])
5997 /* If c is followed by one of the valid parameter expansion
5998 characters, move past it as normal. If not, assume that
5999 a substring specification is being given, and do not move
6001 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
6004 if (c
= string
[sindex
])
6007 else if (c
== ':' && string
[sindex
] != RBRACE
)
6009 else if (c
== '/' && string
[sindex
] != RBRACE
)
6012 /* Catch the valid and invalid brace expressions that made it through the
6014 /* ${#-} is a valid expansion and means to take the length of $-.
6015 Similarly for ${#?} and ${##}... */
6016 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6017 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
6019 name
= (char *)xrealloc (name
, 3);
6022 c
= string
[sindex
++];
6025 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6026 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6027 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
6029 temp
= (char *)NULL
;
6030 goto bad_substitution
;
6033 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6034 either a variable name, one of the positional parameters or a special
6035 variable that expands to one of the positional parameters. */
6036 want_indir
= *name
== '!' &&
6037 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
6038 || VALID_INDIR_PARAM (name
[1]));
6040 /* Determine the value of this variable. */
6042 /* Check for special variables, directly referenced. */
6043 if (SPECIAL_VAR (name
, want_indir
))
6046 /* Check for special expansion things, like the length of a parameter */
6047 if (*name
== '#' && name
[1])
6049 /* If we are not pointing at the character just after the
6050 closing brace, then we haven't gotten all of the name.
6051 Since it begins with a special character, this is a bad
6052 substitution. Also check NAME for validity before trying
6054 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6056 temp
= (char *)NULL
;
6057 goto bad_substitution
;
6060 number
= parameter_brace_expand_length (name
);
6065 return (&expand_wdesc_error
);
6068 ret
= alloc_word_desc ();
6069 ret
->word
= itos (number
);
6074 /* ${@} is identical to $@. */
6075 if (name
[0] == '@' && name
[1] == '\0')
6077 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6078 *quoted_dollar_atp
= 1;
6080 if (contains_dollar_at
)
6081 *contains_dollar_at
= 1;
6084 /* Process ${!PREFIX*} expansion. */
6085 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6086 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6087 legal_variable_starter ((unsigned char) name
[1]))
6092 temp1
= savestring (name
+ 1);
6093 number
= strlen (temp1
);
6094 temp1
[number
- 1] = '\0';
6095 x
= all_variables_matching_prefix (temp1
);
6096 xlist
= strvec_to_word_list (x
, 0, 0);
6097 if (string
[sindex
- 2] == '*')
6098 temp
= string_list_dollar_star (xlist
);
6101 temp
= string_list_dollar_at (xlist
, quoted
);
6102 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6103 *quoted_dollar_atp
= 1;
6104 if (contains_dollar_at
)
6105 *contains_dollar_at
= 1;
6112 ret
= alloc_word_desc ();
6117 #if defined (ARRAY_VARS)
6118 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6119 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6120 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6124 temp1
= savestring (name
+ 1);
6125 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6127 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6129 temp
= array_keys (temp1
, quoted
);
6132 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6133 *quoted_dollar_atp
= 1;
6134 if (contains_dollar_at
)
6135 *contains_dollar_at
= 1;
6141 ret
= alloc_word_desc ();
6148 #endif /* ARRAY_VARS */
6150 /* Make sure that NAME is valid before trying to go on. */
6151 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6152 var_is_special
) == 0)
6154 temp
= (char *)NULL
;
6155 goto bad_substitution
;
6159 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6161 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
6166 tflag
= tdesc
->flags
;
6167 dispose_word_desc (tdesc
);
6172 #if defined (ARRAY_VARS)
6173 if (valid_array_reference (name
))
6174 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6177 var_is_set
= temp
!= (char *)0;
6178 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6180 /* Get the rest of the stuff inside the braces. */
6181 if (c
&& c
!= RBRACE
)
6183 /* Extract the contents of the ${ ... } expansion
6184 according to the Posix.2 rules. */
6185 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6186 if (string
[sindex
] == RBRACE
)
6189 goto bad_substitution
;
6192 value
= (char *)NULL
;
6196 /* If this is a substring spec, process it and add the result. */
6199 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6204 if (temp1
== &expand_param_error
)
6205 return (&expand_wdesc_error
);
6206 else if (temp1
== &expand_param_fatal
)
6207 return (&expand_wdesc_fatal
);
6209 ret
= alloc_word_desc ();
6211 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6212 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6215 else if (want_patsub
)
6217 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6222 if (temp1
== &expand_param_error
)
6223 return (&expand_wdesc_error
);
6224 else if (temp1
== &expand_param_fatal
)
6225 return (&expand_wdesc_fatal
);
6227 ret
= alloc_word_desc ();
6232 /* Do the right thing based on which character ended the variable name. */
6238 report_error (_("%s: bad substitution"), string
? string
: "??");
6242 return &expand_wdesc_error
;
6245 if (var_is_set
== 0 && unbound_vars_is_error
)
6247 err_unboundvar (name
);
6251 last_command_exit_value
= EXECUTION_FAILURE
;
6252 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6256 case '#': /* ${param#[#]pattern} */
6257 case '%': /* ${param%[%]pattern} */
6258 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6263 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6273 if (var_is_set
&& var_is_null
== 0)
6275 /* If the operator is `+', we don't want the value of the named
6276 variable for anything, just the value of the right hand side. */
6280 /* XXX -- if we're double-quoted and the named variable is "$@",
6281 we want to turn off any special handling of "$@" --
6282 we're not using it, so whatever is on the rhs applies. */
6283 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6284 *quoted_dollar_atp
= 0;
6285 if (contains_dollar_at
)
6286 *contains_dollar_at
= 0;
6291 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6294 contains_dollar_at
);
6295 /* XXX - fix up later, esp. noting presence of
6296 W_HASQUOTEDNULL in ret->flags */
6300 temp
= (char *)NULL
;
6306 /* Otherwise do nothing; just use the value in TEMP. */
6308 else /* VAR not set or VAR is NULL. */
6311 temp
= (char *)NULL
;
6312 if (c
== '=' && var_is_special
)
6314 report_error (_("$%s: cannot assign in this way"), name
);
6317 return &expand_wdesc_error
;
6321 parameter_brace_expand_error (name
, value
);
6322 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6326 /* XXX -- if we're double-quoted and the named variable is "$@",
6327 we want to turn off any special handling of "$@" --
6328 we're not using it, so whatever is on the rhs applies. */
6329 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6330 *quoted_dollar_atp
= 0;
6331 if (contains_dollar_at
)
6332 *contains_dollar_at
= 0;
6334 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
6336 contains_dollar_at
);
6337 /* XXX - fix up later, esp. noting presence of
6338 W_HASQUOTEDNULL in tdesc->flags */
6349 ret
= alloc_word_desc ();
6356 /* Expand a single ${xxx} expansion. The braces are optional. When
6357 the braces are used, parameter_brace_expand() does the work,
6358 possibly calling param_expand recursively. */
6360 param_expand (string
, sindex
, quoted
, expanded_something
,
6361 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
6364 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
6365 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
6367 char *temp
, *temp1
, uerror
[3];
6368 int zindex
, t_index
, expok
;
6373 WORD_DESC
*tdesc
, *ret
;
6377 c
= string
[++zindex
];
6379 temp
= (char *)NULL
;
6380 ret
= tdesc
= (WORD_DESC
*)NULL
;
6383 /* Do simple cases first. Switch on what follows '$'. */
6397 temp1
= dollar_vars
[TODIGIT (c
)];
6398 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
6403 err_unboundvar (uerror
);
6404 last_command_exit_value
= EXECUTION_FAILURE
;
6405 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6408 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6409 ? quote_string (temp1
)
6410 : quote_escapes (temp1
);
6412 temp
= (char *)NULL
;
6416 /* $$ -- pid of the invoking shell. */
6418 temp
= itos (dollar_dollar_pid
);
6421 /* $# -- number of positional parameters. */
6423 temp
= itos (number_of_args ());
6426 /* $? -- return value of the last synchronous command. */
6428 temp
= itos (last_command_exit_value
);
6431 /* $- -- flags supplied to the shell on invocation or by `set'. */
6433 temp
= which_set_flags ();
6436 /* $! -- Pid of the last asynchronous command. */
6438 /* If no asynchronous pids have been created, expand to nothing.
6439 If `set -u' has been executed, and no async processes have
6440 been created, this is an expansion error. */
6441 if (last_asynchronous_pid
== NO_PID
)
6443 if (expanded_something
)
6444 *expanded_something
= 0;
6445 temp
= (char *)NULL
;
6446 if (unbound_vars_is_error
)
6451 err_unboundvar (uerror
);
6452 last_command_exit_value
= EXECUTION_FAILURE
;
6453 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6457 temp
= itos (last_asynchronous_pid
);
6460 /* The only difference between this and $@ is when the arg is quoted. */
6461 case '*': /* `$*' */
6462 list
= list_rest_of_args ();
6464 /* If there are no command-line arguments, this should just
6465 disappear if there are other characters in the expansion,
6466 even if it's quoted. */
6467 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
6468 temp
= (char *)NULL
;
6469 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6471 /* If we have "$*" we want to make a string of the positional
6472 parameters, separated by the first character of $IFS, and
6473 quote the whole string, including the separators. If IFS
6474 is unset, the parameters are separated by ' '; if $IFS is
6475 null, the parameters are concatenated. */
6476 temp
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (list
) : string_list (list
);
6477 temp1
= quote_string (temp
);
6479 tflag
|= W_HASQUOTEDNULL
;
6485 /* We check whether or not we're eventually going to split $* here,
6486 for example when IFS is empty and we are processing the rhs of
6487 an assignment statement. In that case, we don't separate the
6488 arguments at all. Otherwise, if the $* is not quoted it is
6491 # if defined (HANDLE_MULTIBYTE)
6492 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
6494 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
6496 temp
= string_list_dollar_star (list
);
6498 temp
= string_list_dollar_at (list
, quoted
);
6500 temp
= string_list_dollar_at (list
, quoted
);
6502 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
6503 *contains_dollar_at
= 1;
6506 dispose_words (list
);
6509 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
6510 means that we have to turn quoting off after we split into
6511 the individually quoted arguments so that the final split
6512 on the first character of $IFS is still done. */
6513 case '@': /* `$@' */
6514 list
= list_rest_of_args ();
6516 /* We want to flag the fact that we saw this. We can't turn
6517 off quoting entirely, because other characters in the
6518 string might need it (consider "\"$@\""), but we need some
6519 way to signal that the final split on the first character
6520 of $IFS should be done, even though QUOTED is 1. */
6521 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6522 *quoted_dollar_at_p
= 1;
6523 if (contains_dollar_at
)
6524 *contains_dollar_at
= 1;
6526 /* We want to separate the positional parameters with the first
6527 character of $IFS in case $IFS is something other than a space.
6528 We also want to make sure that splitting is done no matter what --
6529 according to POSIX.2, this expands to a list of the positional
6530 parameters no matter what IFS is set to. */
6531 temp
= string_list_dollar_at (list
, quoted
);
6533 dispose_words (list
);
6537 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
6539 contains_dollar_at
);
6541 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
6543 temp
= tdesc
? tdesc
->word
: (char *)0;
6546 /* Quoted nulls should be removed if there is anything else
6548 /* Note that we saw the quoted null so we can add one back at
6549 the end of this function if there are no other characters
6550 in the string, discard TEMP, and go on. The exception to
6551 this is when we have "${@}" and $1 is '', since $@ needs
6552 special handling. */
6553 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
6555 if (had_quoted_null_p
)
6556 *had_quoted_null_p
= 1;
6557 if (*quoted_dollar_at_p
== 0)
6560 tdesc
->word
= temp
= (char *)NULL
;
6568 /* Do command or arithmetic substitution. */
6570 /* We have to extract the contents of this paren substitution. */
6571 t_index
= zindex
+ 1;
6572 temp
= extract_command_subst (string
, &t_index
);
6575 /* For Posix.2-style `$(( ))' arithmetic substitution,
6576 extract the expression and pass it to the evaluator. */
6577 if (temp
&& *temp
== LPAREN
)
6581 temp2
= savestring (temp1
);
6582 t_index
= strlen (temp2
) - 1;
6584 if (temp2
[t_index
] != RPAREN
)
6590 /* Cut off ending `)' */
6591 temp2
[t_index
] = '\0';
6593 if (chk_arithsub (temp2
, t_index
) == 0)
6599 /* Expand variables found inside the expression. */
6600 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6604 /* No error messages. */
6605 this_command_name
= (char *)NULL
;
6606 number
= evalexp (temp1
, &expok
);
6611 if (interactive_shell
== 0 && posixly_correct
)
6613 last_command_exit_value
= EXECUTION_FAILURE
;
6614 return (&expand_wdesc_fatal
);
6617 return (&expand_wdesc_error
);
6619 temp
= itos (number
);
6624 if (pflags
& PF_NOCOMSUB
)
6625 /* we need zindex+1 because string[zindex] == RPAREN */
6626 temp1
= substring (string
, *sindex
, zindex
+1);
6628 temp1
= command_substitute (temp
, quoted
);
6633 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6634 away in a future bash release. */
6636 /* Extract the contents of this arithmetic substitution. */
6637 t_index
= zindex
+ 1;
6638 temp
= extract_arithmetic_subst (string
, &t_index
);
6641 /* Do initial variable expansion. */
6642 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
6647 /* Find the variable in VARIABLE_LIST. */
6648 temp
= (char *)NULL
;
6650 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
6652 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
6654 /* If this isn't a variable name, then just output the `$'. */
6655 if (temp1
== 0 || *temp1
== '\0')
6658 temp
= (char *)xmalloc (2);
6661 if (expanded_something
)
6662 *expanded_something
= 0;
6666 /* If the variable exists, return its value cell. */
6667 var
= find_variable (temp1
);
6669 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
6671 #if defined (ARRAY_VARS)
6674 temp
= array_reference (array_cell (var
), 0);
6676 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6677 ? quote_string (temp
)
6678 : quote_escapes (temp
);
6679 else if (unbound_vars_is_error
)
6680 goto unbound_variable
;
6685 temp
= value_cell (var
);
6687 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6688 ? quote_string (temp
)
6689 : quote_escapes (temp
);
6697 temp
= (char *)NULL
;
6700 if (unbound_vars_is_error
)
6701 err_unboundvar (temp1
);
6709 last_command_exit_value
= EXECUTION_FAILURE
;
6710 return ((unbound_vars_is_error
&& interactive_shell
== 0)
6711 ? &expand_wdesc_fatal
6712 : &expand_wdesc_error
);
6723 ret
= alloc_word_desc ();
6724 ret
->flags
= tflag
; /* XXX */
6730 /* Make a word list which is the result of parameter and variable
6731 expansion, command substitution, arithmetic substitution, and
6732 quote removal of WORD. Return a pointer to a WORD_LIST which is
6733 the result of the expansion. If WORD contains a null word, the
6734 word list returned is also null.
6736 QUOTED contains flag values defined in shell.h.
6738 ISEXP is used to tell expand_word_internal that the word should be
6739 treated as the result of an expansion. This has implications for
6740 how IFS characters in the word are treated.
6742 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6743 they point to an integer value which receives information about expansion.
6744 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6745 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6748 This only does word splitting in the case of $@ expansion. In that
6749 case, we split on ' '. */
6751 /* Values for the local variable quoted_state. */
6753 #define PARTIALLY_QUOTED 1
6754 #define WHOLLY_QUOTED 2
6757 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
6760 int *contains_dollar_at
;
6761 int *expanded_something
;
6766 /* The intermediate string that we build while expanding. */
6769 /* The current size of the above object. */
6772 /* Index into ISTRING. */
6775 /* Temporary string storage. */
6778 /* The text of WORD. */
6779 register char *string
;
6781 /* The size of STRING. */
6784 /* The index into STRING. */
6787 /* This gets 1 if we see a $@ while quoted. */
6788 int quoted_dollar_at
;
6790 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6791 whether WORD contains no quoting characters, a partially quoted
6792 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6796 int had_quoted_null
;
6800 int assignoff
; /* If assignment, offset of `=' */
6802 register unsigned char c
; /* Current character. */
6803 int t_index
; /* For calls to string_extract_xxx. */
6809 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
6810 istring
[istring_index
= 0] = '\0';
6811 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
6812 quoted_state
= UNQUOTED
;
6814 string
= word
->word
;
6816 goto finished_with_string
;
6817 /* Don't need the string length for the SADD... and COPY_ macros unless
6818 multibyte characters are possible. */
6819 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
6821 if (contains_dollar_at
)
6822 *contains_dollar_at
= 0;
6826 /* Begin the expansion. */
6832 /* Case on toplevel character. */
6836 goto finished_with_string
;
6840 #if HANDLE_MULTIBYTE
6841 if (MB_CUR_MAX
> 1 && string
[sindex
])
6843 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
6848 temp
= (char *)xmalloc (3);
6850 temp
[1] = c
= string
[sindex
];
6861 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
6867 #if defined (PROCESS_SUBSTITUTION)
6868 /* Process substitution. */
6872 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
6874 sindex
--; /* add_character: label increments sindex */
6878 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
6880 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
6883 /* If the process substitution specification is `<()', we want to
6884 open the pipe for writing in the child and produce output; if
6885 it is `>()', we want to open the pipe for reading in the child
6886 and consume input. */
6887 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
6891 goto dollar_add_string
;
6893 #endif /* PROCESS_SUBSTITUTION */
6896 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6897 which are not assignment statements are not expanded. If the
6898 shell isn't in posix mode, though, we perform tilde expansion
6899 on `likely candidate' unquoted assignment statements (flags
6900 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
6901 contains an unquoted :~ or =~. Something to think about: we
6902 now have a flag that says to perform tilde expansion on arguments
6903 to `assignment builtins' like declare and export that look like
6904 assignment statements. We now do tilde expansion on such words
6905 even in POSIX mode. */
6906 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
6908 /* If we're not in posix mode or forcing assignment-statement tilde
6909 expansion, note where the `=' appears in the word and prepare to
6910 do tilde expansion following the first `='. */
6911 if ((word
->flags
& W_ASSIGNMENT
) &&
6912 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6913 assignoff
== -1 && sindex
> 0)
6915 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
6916 word
->flags
|= W_ITILDE
;
6918 else if ((word
->flags
& W_ASSIGNMENT
) &&
6919 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6920 string
[sindex
+1] == '~')
6921 word
->flags
|= W_ITILDE
;
6926 if (word
->flags
& W_NOTILDE
)
6929 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
6930 string
[sindex
+1] == '~')
6931 word
->flags
|= W_ITILDE
;
6935 /* If the word isn't supposed to be tilde expanded, or we're not
6936 at the start of a word or after an unquoted : or = in an
6937 assignment statement, we don't do tilde expansion. */
6938 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
6939 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
6940 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6942 word
->flags
&= ~W_ITILDE
;
6946 if (word
->flags
& W_ASSIGNRHS
)
6948 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
6953 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
6955 word
->flags
&= ~W_ITILDE
;
6957 if (temp
&& *temp
&& t_index
> 0)
6959 temp1
= bash_tilde_expand (temp
, tflag
);
6960 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
6964 goto add_character
; /* tilde expansion failed */
6978 if (expanded_something
)
6979 *expanded_something
= 1;
6982 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
6983 &has_dollar_at
, "ed_dollar_at
,
6985 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
6987 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
6991 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
6992 : &expand_word_fatal
);
6994 if (contains_dollar_at
&& has_dollar_at
)
6995 *contains_dollar_at
= 1;
6997 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
6998 had_quoted_null
= 1;
7001 dispose_word_desc (tword
);
7006 case '`': /* Backquoted command substitution. */
7010 temp
= string_extract (string
, &sindex
, "`", EX_REQMATCH
);
7011 /* The test of sindex against t_index is to allow bare instances of
7012 ` to pass through, for backwards compatibility. */
7013 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
7015 if (sindex
- 1 == t_index
)
7020 report_error ("bad substitution: no closing \"`\" in %s", string
+t_index
);
7023 return ((temp
== &extract_string_error
) ? &expand_word_error
7024 : &expand_word_fatal
);
7027 if (expanded_something
)
7028 *expanded_something
= 1;
7030 if (word
->flags
& W_NOCOMSUB
)
7031 /* sindex + 1 because string[sindex] == '`' */
7032 temp1
= substring (string
, t_index
, sindex
+ 1);
7035 de_backslash (temp
);
7036 temp1
= command_substitute (temp
, quoted
);
7040 goto dollar_add_string
;
7044 if (string
[sindex
+ 1] == '\n')
7050 c
= string
[++sindex
];
7052 if (quoted
& Q_HERE_DOCUMENT
)
7054 else if (quoted
& Q_DOUBLE_QUOTES
)
7059 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7061 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7066 sindex
--; /* add_character: label increments sindex */
7071 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7076 /* BEFORE jumping here, we need to increment sindex if appropriate */
7077 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7078 DEFAULT_ARRAY_SIZE
);
7079 istring
[istring_index
++] = twochars
[0];
7080 istring
[istring_index
++] = twochars
[1];
7081 istring
[istring_index
] = '\0';
7087 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7089 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7094 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7096 /* If the quotes surrounded the entire string, then the
7097 whole word was quoted. */
7098 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7104 tword
= alloc_word_desc ();
7107 temp
= (char *)NULL
;
7110 /* Need to get W_HASQUOTEDNULL flag through this function. */
7111 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7113 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7117 /* expand_word_internal has already freed temp_word->word
7118 for us because of the way it prints error messages. */
7119 tword
->word
= (char *)NULL
;
7120 dispose_word (tword
);
7124 dispose_word (tword
);
7126 /* "$@" (a double-quoted dollar-at) expands into nothing,
7127 not even a NULL word, when there are no positional
7129 if (list
== 0 && has_dollar_at
)
7135 /* If we get "$@", we know we have expanded something, so we
7136 need to remember it for the final split on $IFS. This is
7137 a special case; it's the only case where a quoted string
7138 can expand into more than one word. It's going to come back
7139 from the above call to expand_word_internal as a list with
7140 a single word, in which all characters are quoted and
7141 separated by blanks. What we want to do is to turn it back
7142 into a list for the next piece of code. */
7144 dequote_list (list
);
7146 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7147 had_quoted_null
= 1;
7152 if (contains_dollar_at
)
7153 *contains_dollar_at
= 1;
7154 if (expanded_something
)
7155 *expanded_something
= 1;
7160 /* What we have is "". This is a minor optimization. */
7162 list
= (WORD_LIST
*)NULL
;
7165 /* The code above *might* return a list (consider the case of "$@",
7166 where it returns "$1", "$2", etc.). We can't throw away the
7167 rest of the list, and we have to make sure each word gets added
7168 as quoted. We test on tresult->next: if it is non-NULL, we
7169 quote the whole list, save it to a string with string_list, and
7170 add that string. We don't need to quote the results of this
7171 (and it would be wrong, since that would quote the separators
7172 as well), so we go directly to add_string. */
7177 /* Testing quoted_dollar_at makes sure that "$@" is
7178 split correctly when $IFS does not contain a space. */
7179 temp
= quoted_dollar_at
7180 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7181 : string_list (quote_list (list
));
7182 dispose_words (list
);
7187 temp
= savestring (list
->word
->word
);
7188 tflag
= list
->word
->flags
;
7189 dispose_words (list
);
7191 /* If the string is not a quoted null string, we want
7192 to remove any embedded unquoted CTLNUL characters.
7193 We do not want to turn quoted null strings back into
7194 the empty string, though. We do this because we
7195 want to remove any quoted nulls from expansions that
7196 contain other characters. For example, if we have
7197 x"$*"y or "x$*y" and there are no positional parameters,
7198 the $* should expand into nothing. */
7199 /* We use the W_HASQUOTEDNULL flag to differentiate the
7200 cases: a quoted null character as above and when
7201 CTLNUL is contained in the (non-null) expansion
7202 of some variable. We use the had_quoted_null flag to
7203 pass the value through this function to its caller. */
7204 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7205 remove_quoted_nulls (temp
); /* XXX */
7209 temp
= (char *)NULL
;
7211 /* We do not want to add quoted nulls to strings that are only
7212 partially quoted; we can throw them away. */
7213 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7221 temp
= quote_string (temp
);
7229 sindex
--; /* add_character: label increments sindex */
7237 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7239 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7244 temp
= string_extract_single_quoted (string
, &sindex
);
7246 /* If the entire STRING was surrounded by single quotes,
7247 then the string is wholly quoted. */
7248 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7252 /* If all we had was '', it is a null expansion. */
7256 temp
= (char *)NULL
;
7259 remove_quoted_escapes (temp
); /* ??? */
7261 /* We do not want to add quoted nulls to strings that are only
7262 partially quoted; such nulls are discarded. */
7263 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7266 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7270 sindex
--; /* add_character: label increments sindex */
7274 goto add_quoted_string
;
7279 /* This is the fix for " $@ " */
7280 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7282 if (string
[sindex
]) /* from old goto dollar_add_string */
7291 #if HANDLE_MULTIBYTE
7297 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7302 twochars
[0] = CTLESC
;
7309 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7312 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7313 DEFAULT_ARRAY_SIZE
);
7314 istring
[istring_index
++] = c
;
7315 istring
[istring_index
] = '\0';
7317 /* Next character. */
7322 finished_with_string
:
7323 /* OK, we're ready to return. If we have a quoted string, and
7324 quoted_dollar_at is not set, we do no splitting at all; otherwise
7325 we split on ' '. The routines that call this will handle what to
7326 do if nothing has been expanded. */
7328 /* Partially and wholly quoted strings which expand to the empty
7329 string are retained as an empty arguments. Unquoted strings
7330 which expand to the empty string are discarded. The single
7331 exception is the case of expanding "$@" when there are no
7332 positional parameters. In that case, we discard the expansion. */
7334 /* Because of how the code that handles "" and '' in partially
7335 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7336 if we saw quoting characters, but the expansion was empty.
7337 "" and '' are tossed away before we get to this point when
7338 processing partially quoted strings. This makes "" and $xxx""
7339 equivalent when xxx is unset. We also look to see whether we
7340 saw a quoted null from a ${} expansion and add one back if we
7343 /* If we expand to nothing and there were no single or double quotes
7344 in the word, we throw it away. Otherwise, we return a NULL word.
7345 The single exception is for $@ surrounded by double quotes when
7346 there are no positional parameters. In that case, we also throw
7349 if (*istring
== '\0')
7351 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7353 istring
[0] = CTLNUL
;
7355 tword
= make_bare_word (istring
);
7356 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7357 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7358 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7359 tword
->flags
|= W_QUOTED
;
7361 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7362 and a double-quoted "$@" appears anywhere in it, then the entire
7364 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
7365 list
= (WORD_LIST
*)NULL
;
7369 tword
= make_bare_word (istring
);
7370 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7371 tword
->flags
|= W_QUOTED
;
7372 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7376 list
= (WORD_LIST
*)NULL
;
7379 else if (word
->flags
& W_NOSPLIT
)
7381 tword
= make_bare_word (istring
);
7382 if (word
->flags
& W_ASSIGNMENT
)
7383 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
7384 if (word
->flags
& W_COMPASSIGN
)
7385 tword
->flags
|= W_COMPASSIGN
; /* XXX */
7386 if (word
->flags
& W_NOGLOB
)
7387 tword
->flags
|= W_NOGLOB
; /* XXX */
7388 if (word
->flags
& W_NOEXPAND
)
7389 tword
->flags
|= W_NOEXPAND
; /* XXX */
7390 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7391 tword
->flags
|= W_QUOTED
;
7392 if (had_quoted_null
)
7393 tword
->flags
|= W_HASQUOTEDNULL
;
7394 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7400 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
7402 /* If we have $@, we need to split the results no matter what. If
7403 IFS is unset or NULL, string_list_dollar_at has separated the
7404 positional parameters with a space, so we split on space (we have
7405 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7406 string_list_dollar_at has separated the positional parameters
7407 with the first character of $IFS, so we split on $IFS. */
7408 if (has_dollar_at
&& ifs_chars
)
7409 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
7412 tword
= make_bare_word (istring
);
7413 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
7414 tword
->flags
|= W_QUOTED
;
7415 if (word
->flags
& W_ASSIGNMENT
)
7416 tword
->flags
|= W_ASSIGNMENT
;
7417 if (word
->flags
& W_COMPASSIGN
)
7418 tword
->flags
|= W_COMPASSIGN
;
7419 if (word
->flags
& W_NOGLOB
)
7420 tword
->flags
|= W_NOGLOB
;
7421 if (word
->flags
& W_NOEXPAND
)
7422 tword
->flags
|= W_NOEXPAND
;
7423 if (had_quoted_null
)
7424 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7425 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7433 /* **************************************************************** */
7435 /* Functions for Quote Removal */
7437 /* **************************************************************** */
7439 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7440 backslash quoting rules for within double quotes or a here document. */
7442 string_quote_removal (string
, quoted
)
7447 char *r
, *result_string
, *temp
, *send
;
7448 int sindex
, tindex
, dquote
;
7452 /* The result can be no longer than the original string. */
7453 slen
= strlen (string
);
7454 send
= string
+ slen
;
7456 r
= result_string
= (char *)xmalloc (slen
+ 1);
7458 for (dquote
= sindex
= 0; c
= string
[sindex
];)
7463 c
= string
[++sindex
];
7464 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
7469 SCOPY_CHAR_M (r
, string
, send
, sindex
);
7473 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
7479 tindex
= sindex
+ 1;
7480 temp
= string_extract_single_quoted (string
, &tindex
);
7491 dquote
= 1 - dquote
;
7497 return (result_string
);
7502 /* Perform quote removal on word WORD. This allocates and returns a new
7505 word_quote_removal (word
, quoted
)
7512 t
= string_quote_removal (word
->word
, quoted
);
7513 w
= alloc_word_desc ();
7514 w
->word
= t
? t
: savestring ("");
7518 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
7519 the members of the list are treated as if they are surrounded by
7520 double quotes. Return a new list, or NULL if LIST is NULL. */
7522 word_list_quote_removal (list
, quoted
)
7526 WORD_LIST
*result
, *t
, *tresult
, *e
;
7528 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7530 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
7532 result
= (WORD_LIST
*) list_append (result
, tresult
);
7535 result
= e
= tresult
;
7548 /*******************************************
7550 * Functions to perform word splitting *
7552 *******************************************/
7563 ifs_value
= v
? value_cell (v
) : " \t\n";
7565 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
7568 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
7569 handle multibyte chars in IFS */
7570 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
7571 for (t
= ifs_value
; t
&& *t
; t
++)
7577 #if defined (HANDLE_MULTIBYTE)
7580 ifs_firstc
[0] = '\0';
7586 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
7587 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
7588 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
7590 ifs_firstc
[0] = ifs_value
[0];
7591 ifs_firstc
[1] = '\0';
7595 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
7598 ifs_firstc
= ifs_value
? *ifs_value
: 0;
7608 /* This splits a single word into a WORD LIST on $IFS, but only if the word
7609 is not quoted. list_string () performs quote removal for us, even if we
7610 don't do any splitting. */
7612 word_split (w
, ifs_chars
)
7622 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
7623 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
7626 result
= (WORD_LIST
*)NULL
;
7631 /* Perform word splitting on LIST and return the RESULT. It is possible
7632 to return (WORD_LIST *)NULL. */
7634 word_list_split (list
)
7637 WORD_LIST
*result
, *t
, *tresult
, *e
;
7639 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7641 tresult
= word_split (t
->word
, ifs_value
);
7643 result
= e
= tresult
;
7654 /**************************************************
7656 * Functions to expand an entire WORD_LIST *
7658 **************************************************/
7660 /* Do any word-expansion-specific cleanup and jump to top_level */
7662 exp_jump_to_top_level (v
)
7665 /* Cleanup code goes here. */
7666 expand_no_split_dollar_star
= 0; /* XXX */
7667 expanding_redir
= 0;
7669 top_level_cleanup (); /* from sig.c */
7671 jump_to_top_level (v
);
7674 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
7675 ELIST, and set ELIST to the new list. */
7676 #define PREPEND_LIST(nlist, elist) \
7677 do { nlist->next = elist; elist = nlist; } while (0)
7679 /* Separate out any initial variable assignments from TLIST. If set -k has
7680 been executed, remove all assignment statements from TLIST. Initial
7681 variable assignments and other environment assignments are placed
7682 on SUBST_ASSIGN_VARLIST. */
7684 separate_out_assignments (tlist
)
7687 register WORD_LIST
*vp
, *lp
;
7690 return ((WORD_LIST
*)NULL
);
7692 if (subst_assign_varlist
)
7693 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
7695 subst_assign_varlist
= (WORD_LIST
*)NULL
;
7698 /* Separate out variable assignments at the start of the command.
7699 Loop invariant: vp->next == lp
7701 lp = list of words left after assignment statements skipped
7702 tlist = original list of words
7704 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
7710 /* If lp != tlist, we have some initial assignment statements.
7711 We make SUBST_ASSIGN_VARLIST point to the list of assignment
7712 words and TLIST point to the remaining words. */
7715 subst_assign_varlist
= tlist
;
7716 /* ASSERT(vp->next == lp); */
7717 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
7718 tlist
= lp
; /* remainder of word list */
7721 /* vp == end of variable list */
7722 /* tlist == remainder of original word list without variable assignments */
7724 /* All the words in tlist were assignment statements */
7725 return ((WORD_LIST
*)NULL
);
7727 /* ASSERT(tlist != NULL); */
7728 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
7730 /* If the -k option is in effect, we need to go through the remaining
7731 words, separate out the assignment words, and place them on
7732 SUBST_ASSIGN_VARLIST. */
7733 if (place_keywords_in_env
)
7735 WORD_LIST
*tp
; /* tp == running pointer into tlist */
7740 /* Loop Invariant: tp->next == lp */
7741 /* Loop postcondition: tlist == word list without assignment statements */
7744 if (lp
->word
->flags
& W_ASSIGNMENT
)
7746 /* Found an assignment statement, add this word to end of
7747 subst_assign_varlist (vp). */
7748 if (!subst_assign_varlist
)
7749 subst_assign_varlist
= vp
= lp
;
7756 /* Remove the word pointed to by LP from TLIST. */
7757 tp
->next
= lp
->next
;
7758 /* ASSERT(vp == lp); */
7759 lp
->next
= (WORD_LIST
*)NULL
;
7772 #define WEXP_VARASSIGN 0x001
7773 #define WEXP_BRACEEXP 0x002
7774 #define WEXP_TILDEEXP 0x004
7775 #define WEXP_PARAMEXP 0x008
7776 #define WEXP_PATHEXP 0x010
7778 /* All of the expansions, including variable assignments at the start of
7780 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7782 /* All of the expansions except variable assignments at the start of
7784 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7786 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
7787 expansion, command substitution, arithmetic expansion, word splitting, and
7789 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7791 /* Take the list of words in LIST and do the various substitutions. Return
7792 a new list of words which is the expanded list, and without things like
7793 variable assignments. */
7799 return (expand_word_list_internal (list
, WEXP_ALL
));
7802 /* Same as expand_words (), but doesn't hack variable or environment
7805 expand_words_no_vars (list
)
7808 return (expand_word_list_internal (list
, WEXP_NOVARS
));
7812 expand_words_shellexp (list
)
7815 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
7819 glob_expand_word_list (tlist
, eflags
)
7823 char **glob_array
, *temp_string
;
7824 register int glob_index
;
7825 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
7828 output_list
= disposables
= (WORD_LIST
*)NULL
;
7829 glob_array
= (char **)NULL
;
7832 /* For each word, either globbing is attempted or the word is
7833 added to orig_list. If globbing succeeds, the results are
7834 added to orig_list and the word (tlist) is added to the list
7835 of disposable words. If globbing fails and failed glob
7836 expansions are left unchanged (the shell default), the
7837 original word is added to orig_list. If globbing fails and
7838 failed glob expansions are removed, the original word is
7839 added to the list of disposable words. orig_list ends up
7840 in reverse order and requires a call to REVERSE_LIST to
7841 be set right. After all words are examined, the disposable
7845 /* If the word isn't an assignment and contains an unquoted
7846 pattern matching character, then glob it. */
7847 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
7848 unquoted_glob_pattern_p (tlist
->word
->word
))
7850 glob_array
= shell_glob_filename (tlist
->word
->word
);
7852 /* Handle error cases.
7853 I don't think we should report errors like "No such file
7854 or directory". However, I would like to report errors
7855 like "Read failed". */
7857 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
7859 glob_array
= (char **)xmalloc (sizeof (char *));
7860 glob_array
[0] = (char *)NULL
;
7863 /* Dequote the current word in case we have to use it. */
7864 if (glob_array
[0] == NULL
)
7866 temp_string
= dequote_string (tlist
->word
->word
);
7867 free (tlist
->word
->word
);
7868 tlist
->word
->word
= temp_string
;
7871 /* Make the array into a word list. */
7872 glob_list
= (WORD_LIST
*)NULL
;
7873 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
7875 tword
= make_bare_word (glob_array
[glob_index
]);
7876 tword
->flags
|= W_GLOBEXP
; /* XXX */
7877 glob_list
= make_word_list (tword
, glob_list
);
7882 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
7883 PREPEND_LIST (tlist
, disposables
);
7885 else if (fail_glob_expansion
!= 0)
7887 report_error (_("no match: %s"), tlist
->word
->word
);
7888 exp_jump_to_top_level (DISCARD
);
7890 else if (allow_null_glob_expansion
== 0)
7892 /* Failed glob expressions are left unchanged. */
7893 PREPEND_LIST (tlist
, output_list
);
7897 /* Failed glob expressions are removed. */
7898 PREPEND_LIST (tlist
, disposables
);
7903 /* Dequote the string. */
7904 temp_string
= dequote_string (tlist
->word
->word
);
7905 free (tlist
->word
->word
);
7906 tlist
->word
->word
= temp_string
;
7907 PREPEND_LIST (tlist
, output_list
);
7910 strvec_dispose (glob_array
);
7911 glob_array
= (char **)NULL
;
7917 dispose_words (disposables
);
7920 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7922 return (output_list
);
7925 #if defined (BRACE_EXPANSION)
7927 brace_expand_word_list (tlist
, eflags
)
7931 register char **expansions
;
7933 WORD_LIST
*disposables
, *output_list
, *next
;
7937 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
7941 /* Only do brace expansion if the word has a brace character. If
7942 not, just add the word list element to BRACES and continue. In
7943 the common case, at least when running shell scripts, this will
7944 degenerate to a bunch of calls to `xstrchr', and then what is
7945 basically a reversal of TLIST into BRACES, which is corrected
7946 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7948 if (xstrchr (tlist
->word
->word
, LBRACE
))
7950 expansions
= brace_expand (tlist
->word
->word
);
7952 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
7954 w
= make_word (temp_string
);
7955 /* If brace expansion didn't change the word, preserve
7956 the flags. We may want to preserve the flags
7957 unconditionally someday -- XXX */
7958 if (STREQ (temp_string
, tlist
->word
->word
))
7959 w
->flags
= tlist
->word
->flags
;
7960 output_list
= make_word_list (w
, output_list
);
7961 free (expansions
[eindex
]);
7965 /* Add TLIST to the list of words to be freed after brace
7966 expansion has been performed. */
7967 PREPEND_LIST (tlist
, disposables
);
7970 PREPEND_LIST (tlist
, output_list
);
7974 dispose_words (disposables
);
7977 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7979 return (output_list
);
7984 shell_expand_word_list (tlist
, eflags
)
7988 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
7989 int expanded_something
, has_dollar_at
;
7992 /* We do tilde expansion all the time. This is what 1003.2 says. */
7993 new_list
= (WORD_LIST
*)NULL
;
7994 for (orig_list
= tlist
; tlist
; tlist
= next
)
7996 temp_string
= tlist
->word
->word
;
8000 #if defined (ARRAY_VARS)
8001 /* If this is a compound array assignment to a builtin that accepts
8002 such assignments (e.g., `declare'), take the assignment and perform
8003 it separately, handling the semantics of declarations inside shell
8004 functions. This avoids the double-evaluation of such arguments,
8005 because `declare' does some evaluation of compound assignments on
8007 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8011 t
= do_word_assignment (tlist
->word
);
8014 last_command_exit_value
= EXECUTION_FAILURE
;
8015 exp_jump_to_top_level (DISCARD
);
8018 /* Now transform the word as ksh93 appears to do and go on */
8019 t
= assignment (tlist
->word
->word
, 0);
8020 tlist
->word
->word
[t
] = '\0';
8021 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
);
8025 expanded_something
= 0;
8026 expanded
= expand_word_internal
8027 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
8029 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
8031 /* By convention, each time this error is returned,
8032 tlist->word->word has already been freed. */
8033 tlist
->word
->word
= (char *)NULL
;
8035 /* Dispose our copy of the original list. */
8036 dispose_words (orig_list
);
8037 /* Dispose the new list we're building. */
8038 dispose_words (new_list
);
8040 last_command_exit_value
= EXECUTION_FAILURE
;
8041 if (expanded
== &expand_word_error
)
8042 exp_jump_to_top_level (DISCARD
);
8044 exp_jump_to_top_level (FORCE_EOF
);
8047 /* Don't split words marked W_NOSPLIT. */
8048 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
8050 temp_list
= word_list_split (expanded
);
8051 dispose_words (expanded
);
8055 /* If no parameter expansion, command substitution, process
8056 substitution, or arithmetic substitution took place, then
8057 do not do word splitting. We still have to remove quoted
8058 null characters from the result. */
8059 word_list_remove_quoted_nulls (expanded
);
8060 temp_list
= expanded
;
8063 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8064 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8068 dispose_words (orig_list
);
8071 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8076 /* The workhorse for expand_words () and expand_words_no_vars ().
8077 First arg is LIST, a WORD_LIST of words.
8078 Second arg EFLAGS is a flags word controlling which expansions are
8081 This does all of the substitutions: brace expansion, tilde expansion,
8082 parameter expansion, command substitution, arithmetic expansion,
8083 process substitution, word splitting, and pathname expansion, according
8084 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8085 set, or for which no expansion is done, do not undergo word splitting.
8086 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8088 expand_word_list_internal (list
, eflags
)
8092 WORD_LIST
*new_list
, *temp_list
;
8096 return ((WORD_LIST
*)NULL
);
8098 garglist
= new_list
= copy_word_list (list
);
8099 if (eflags
& WEXP_VARASSIGN
)
8101 garglist
= new_list
= separate_out_assignments (new_list
);
8104 if (subst_assign_varlist
)
8106 /* All the words were variable assignments, so they are placed
8107 into the shell's environment. */
8108 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8110 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8111 tint
= do_word_assignment (temp_list
->word
);
8112 /* Variable assignment errors in non-interactive shells
8113 running in Posix.2 mode cause the shell to exit. */
8116 last_command_exit_value
= EXECUTION_FAILURE
;
8117 if (interactive_shell
== 0 && posixly_correct
)
8118 exp_jump_to_top_level (FORCE_EOF
);
8120 exp_jump_to_top_level (DISCARD
);
8123 dispose_words (subst_assign_varlist
);
8124 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8126 return ((WORD_LIST
*)NULL
);
8130 /* Begin expanding the words that remain. The expansions take place on
8131 things that aren't really variable assignments. */
8133 #if defined (BRACE_EXPANSION)
8134 /* Do brace expansion on this word if there are any brace characters
8136 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8137 new_list
= brace_expand_word_list (new_list
, eflags
);
8138 #endif /* BRACE_EXPANSION */
8140 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8141 variable substitution, command substitution, arithmetic expansion,
8142 and word splitting. */
8143 new_list
= shell_expand_word_list (new_list
, eflags
);
8145 /* Okay, we're almost done. Now let's just do some filename
8149 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8150 /* Glob expand the word list unless globbing has been disabled. */
8151 new_list
= glob_expand_word_list (new_list
, eflags
);
8153 /* Dequote the words, because we're not performing globbing. */
8154 new_list
= dequote_list (new_list
);
8157 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8159 sh_wassign_func_t
*assign_func
;
8161 /* If the remainder of the words expand to nothing, Posix.2 requires
8162 that the variable and environment assignments affect the shell's
8164 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8165 tempenv_assign_error
= 0;
8167 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8169 this_command_name
= (char *)NULL
;
8170 tint
= (*assign_func
) (temp_list
->word
);
8171 /* Variable assignment errors in non-interactive shells running
8172 in Posix.2 mode cause the shell to exit. */
8175 if (assign_func
== do_word_assignment
)
8177 last_command_exit_value
= EXECUTION_FAILURE
;
8178 if (interactive_shell
== 0 && posixly_correct
)
8179 exp_jump_to_top_level (FORCE_EOF
);
8181 exp_jump_to_top_level (DISCARD
);
8184 tempenv_assign_error
++;
8188 dispose_words (subst_assign_varlist
);
8189 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8193 tint
= list_length (new_list
) + 1;
8194 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8195 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8196 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8197 glob_argv_flags
[tint
] = '\0';