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 tlist
= ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (ifs
&& *ifs
== 0))
1892 : list_quote_escapes (list
);
1894 ret
= string_list_internal (tlist
, sep
);
1895 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
1901 /* Return the list of words present in STRING. Separate the string into
1902 words at any of the characters found in SEPARATORS. If QUOTED is
1903 non-zero then word in the list will have its quoted flag set, otherwise
1904 the quoted flag is left as make_word () deemed fit.
1906 This obeys the P1003.2 word splitting semantics. If `separators' is
1907 exactly <space><tab><newline>, then the splitting algorithm is that of
1908 the Bourne shell, which treats any sequence of characters from `separators'
1909 as a delimiter. If IFS is unset, which results in `separators' being set
1910 to "", no splitting occurs. If separators has some other value, the
1911 following rules are applied (`IFS white space' means zero or more
1912 occurrences of <space>, <tab>, or <newline>, as long as those characters
1913 are in `separators'):
1915 1) IFS white space is ignored at the start and the end of the
1917 2) Each occurrence of a character in `separators' that is not
1918 IFS white space, along with any adjacent occurrences of
1919 IFS white space delimits a field.
1920 3) Any nonzero-length sequence of IFS white space delimits a field.
1923 /* BEWARE! list_string strips null arguments. Don't call it twice and
1924 expect to have "" preserved! */
1926 /* This performs word splitting and quoted null character removal on
1929 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
1930 : (c) == (separators)[0]) \
1934 list_string (string
, separators
, quoted
)
1935 register char *string
, *separators
;
1940 char *current_word
, *s
;
1941 int sindex
, sh_style_split
, whitesep
;
1944 if (!string
|| !*string
)
1945 return ((WORD_LIST
*)NULL
);
1947 sh_style_split
= separators
&& separators
[0] == ' ' &&
1948 separators
[1] == '\t' &&
1949 separators
[2] == '\n' &&
1950 separators
[3] == '\0';
1953 /* Remove sequences of whitespace at the beginning of STRING, as
1954 long as those characters appear in IFS. Do not do this if
1955 STRING is quoted or if there are no separator characters. */
1956 if (!quoted
|| !separators
|| !*separators
)
1958 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
1961 return ((WORD_LIST
*)NULL
);
1966 /* OK, now STRING points to a word that does not begin with white space.
1967 The splitting algorithm is:
1968 extract a word, stopping at a separator
1969 skip sequences of spc, tab, or nl as long as they are separators
1970 This obeys the field splitting rules in Posix.2. */
1971 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
1972 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
1974 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
1975 unless multibyte chars are possible. */
1976 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
);
1977 if (current_word
== 0)
1980 /* If we have a quoted empty string, add a quoted null argument. We
1981 want to preserve the quoted null character iff this is a quoted
1982 empty string; otherwise the quoted null characters are removed
1984 if (QUOTED_NULL (current_word
))
1986 t
= alloc_word_desc ();
1987 t
->word
= make_quoted_char ('\0');
1988 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
1989 result
= make_word_list (t
, result
);
1991 else if (current_word
[0] != '\0')
1993 /* If we have something, then add it regardless. However,
1994 perform quoted null character removal on the current word. */
1995 remove_quoted_nulls (current_word
);
1996 result
= add_string_to_list (current_word
, result
);
1997 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
1998 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
1999 result
->word
->flags
|= W_QUOTED
;
2002 /* If we're not doing sequences of separators in the traditional
2003 Bourne shell style, then add a quoted null argument. */
2004 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2006 t
= alloc_word_desc ();
2007 t
->word
= make_quoted_char ('\0');
2008 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2009 result
= make_word_list (t
, result
);
2012 free (current_word
);
2014 /* Note whether or not the separator is IFS whitespace, used later. */
2015 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2017 /* Move past the current separator character. */
2021 ADVANCE_CHAR (string
, slen
, sindex
);
2024 /* Now skip sequences of space, tab, or newline characters if they are
2025 in the list of separators. */
2026 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2029 /* If the first separator was IFS whitespace and the current character
2030 is a non-whitespace IFS character, it should be part of the current
2031 field delimiter, not a separate delimiter that would result in an
2032 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2033 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2036 /* An IFS character that is not IFS white space, along with any
2037 adjacent IFS white space, shall delimit a field. (SUSv3) */
2038 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2042 return (REVERSE_LIST (result
, WORD_LIST
*));
2045 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2046 ENDPTR is set to the first character after the word. This is used by
2047 the `read' builtin. This is never called with SEPARATORS != $IFS;
2048 it should be simplified.
2050 XXX - this function is very similar to list_string; they should be
2053 get_word_from_string (stringp
, separators
, endptr
)
2054 char **stringp
, *separators
, **endptr
;
2058 int sindex
, sh_style_split
, whitesep
;
2061 if (!stringp
|| !*stringp
|| !**stringp
)
2062 return ((char *)NULL
);
2066 sh_style_split
= separators
&& separators
[0] == ' ' &&
2067 separators
[1] == '\t' &&
2068 separators
[2] == '\n' &&
2069 separators
[3] == '\0';
2073 /* Remove sequences of whitespace at the beginning of STRING, as
2074 long as those characters appear in IFS. */
2075 if (sh_style_split
|| !separators
|| !*separators
)
2077 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2079 /* If the string is nothing but whitespace, update it and return. */
2085 return ((char *)NULL
);
2089 /* OK, S points to a word that does not begin with white space.
2090 Now extract a word, stopping at a separator, save a pointer to
2091 the first character after the word, then skip sequences of spc,
2092 tab, or nl as long as they are separators.
2094 This obeys the field splitting rules in Posix.2. */
2096 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2097 unless multibyte chars are possible. */
2098 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2099 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
);
2101 /* Set ENDPTR to the first character after the end of the word. */
2103 *endptr
= s
+ sindex
;
2105 /* Note whether or not the separator is IFS whitespace, used later. */
2106 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2108 /* Move past the current separator character. */
2112 ADVANCE_CHAR (s
, slen
, sindex
);
2115 /* Now skip sequences of space, tab, or newline characters if they are
2116 in the list of separators. */
2117 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2120 /* If the first separator was IFS whitespace and the current character is
2121 a non-whitespace IFS character, it should be part of the current field
2122 delimiter, not a separate delimiter that would result in an empty field.
2123 Look at POSIX.2, 3.6.5, (3)(b). */
2124 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2127 /* An IFS character that is not IFS white space, along with any adjacent
2128 IFS white space, shall delimit a field. */
2129 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2133 /* Update STRING to point to the next field. */
2134 *stringp
= s
+ sindex
;
2135 return (current_word
);
2138 /* Remove IFS white space at the end of STRING. Start at the end
2139 of the string and walk backwards until the beginning of the string
2140 or we find a character that's not IFS white space and not CTLESC.
2141 Only let CTLESC escape a white space character if SAW_ESCAPE is
2144 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2145 char *string
, *separators
;
2150 s
= string
+ STRLEN (string
) - 1;
2151 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2152 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2160 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2161 backslashes, single and double quotes. */
2163 list_string_with_quotes (string
)
2169 int c
, i
, tokstart
, len
;
2171 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2173 if (s
== 0 || *s
== 0)
2174 return ((WORD_LIST
*)NULL
);
2178 list
= (WORD_LIST
*)NULL
;
2189 i
= skip_single_quoted (s
, s_len
, ++i
);
2191 i
= skip_double_quoted (s
, s_len
, ++i
);
2192 else if (c
== 0 || spctabnl (c
))
2194 /* We have found the end of a token. Make a word out of it and
2195 add it to the word list. */
2196 token
= substring (s
, tokstart
, i
);
2197 list
= add_string_to_list (token
, list
);
2199 while (spctabnl (s
[i
]))
2207 i
++; /* normal character */
2209 return (REVERSE_LIST (list
, WORD_LIST
*));
2213 /********************************************************/
2215 /* Functions to perform assignment statements */
2217 /********************************************************/
2219 #if defined (ARRAY_VARS)
2221 do_compound_assignment (name
, value
, flags
)
2229 mklocal
= flags
& ASS_MKLOCAL
;
2231 if (mklocal
&& variable_context
)
2233 list
= expand_compound_array_assignment (value
, flags
);
2234 v
= find_variable (name
);
2235 if (v
== 0 || array_p (v
) == 0 || v
->context
!= variable_context
)
2236 v
= make_local_array_variable (name
);
2237 assign_compound_array_list (v
, list
, flags
);
2240 v
= assign_array_from_string (name
, value
, flags
);
2246 /* Given STRING, an assignment string, get the value of the right side
2247 of the `=', and bind it to the left side. If EXPAND is true, then
2248 perform parameter expansion, command substitution, and arithmetic
2249 expansion on the right-hand side. Perform tilde expansion in any
2250 case. Do not perform word splitting on the result of expansion. */
2252 do_assignment_internal (word
, expand
)
2253 const WORD_DESC
*word
;
2256 int offset
, tlen
, appendop
, assign_list
, aflags
;
2259 #if defined (ARRAY_VARS)
2265 if (word
== 0 || word
->word
== 0)
2268 appendop
= assign_list
= aflags
= 0;
2269 string
= word
->word
;
2270 offset
= assignment (string
, 0);
2271 name
= savestring (string
);
2272 value
= (char *)NULL
;
2274 if (name
[offset
] == '=')
2278 if (name
[offset
- 1] == '+')
2281 name
[offset
- 1] = '\0';
2284 name
[offset
] = 0; /* might need this set later */
2285 temp
= name
+ offset
+ 1;
2286 tlen
= STRLEN (temp
);
2288 #if defined (ARRAY_VARS)
2289 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2291 assign_list
= ni
= 1;
2292 value
= extract_array_assignment_list (temp
, &ni
);
2297 if (expand
&& temp
[0])
2298 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2300 value
= savestring (temp
);
2305 value
= (char *)xmalloc (1);
2309 if (echo_command_at_execute
)
2312 name
[offset
- 1] = '+';
2313 xtrace_print_assignment (name
, value
, assign_list
, 1);
2315 name
[offset
- 1] = '\0';
2318 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2321 aflags
|= ASS_APPEND
;
2323 #if defined (ARRAY_VARS)
2324 if (t
= xstrchr (name
, '[')) /*]*/
2328 report_error (_("%s: cannot assign list to array member"), name
);
2331 entry
= assign_array_element (name
, value
, aflags
);
2335 else if (assign_list
)
2337 if (word
->flags
& W_ASSIGNARG
)
2338 aflags
|= ASS_MKLOCAL
;
2339 entry
= do_compound_assignment (name
, value
, aflags
);
2342 #endif /* ARRAY_VARS */
2343 entry
= bind_variable (name
, value
, aflags
);
2345 stupidly_hack_special_variables (name
);
2348 VUNSETATTR (entry
, att_invisible
);
2350 /* Return 1 if the assignment seems to have been performed correctly. */
2351 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2354 /* Perform the assignment statement in STRING, and expand the
2355 right side by doing tilde, command and parameter expansion. */
2357 do_assignment (string
)
2362 td
.flags
= W_ASSIGNMENT
;
2365 return do_assignment_internal (&td
, 1);
2369 do_word_assignment (word
)
2372 return do_assignment_internal (word
, 1);
2375 /* Given STRING, an assignment string, get the value of the right side
2376 of the `=', and bind it to the left side. Do not perform any word
2377 expansions on the right hand side. */
2379 do_assignment_no_expand (string
)
2384 td
.flags
= W_ASSIGNMENT
;
2387 return (do_assignment_internal (&td
, 0));
2390 /***************************************************
2392 * Functions to manage the positional parameters *
2394 ***************************************************/
2396 /* Return the word list that corresponds to `$*'. */
2398 list_rest_of_args ()
2400 register WORD_LIST
*list
, *args
;
2403 /* Break out of the loop as soon as one of the dollar variables is null. */
2404 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2405 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2407 for (args
= rest_of_args
; args
; args
= args
->next
)
2408 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2410 return (REVERSE_LIST (list
, WORD_LIST
*));
2416 register WORD_LIST
*list
;
2419 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2421 for (list
= rest_of_args
; list
; list
= list
->next
)
2426 /* Return the value of a positional parameter. This handles values > 10. */
2428 get_dollar_var_value (ind
)
2435 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2436 else /* We want something like ${11} */
2439 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2441 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2446 /* Make a single large string out of the dollar digit variables,
2447 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2448 case of "$*" with respect to IFS. */
2450 string_rest_of_args (dollar_star
)
2453 register WORD_LIST
*list
;
2456 list
= list_rest_of_args ();
2457 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2458 dispose_words (list
);
2462 /* Return a string containing the positional parameters from START to
2463 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2464 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2465 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2466 no quoting chars are added. */
2468 pos_params (string
, start
, end
, quoted
)
2470 int start
, end
, quoted
;
2472 WORD_LIST
*save
, *params
, *h
, *t
;
2476 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2478 return ((char *)NULL
);
2480 save
= params
= list_rest_of_args ();
2482 return ((char *)NULL
);
2484 for (i
= 1; params
&& i
< start
; i
++)
2485 params
= params
->next
;
2487 return ((char *)NULL
);
2488 for (h
= t
= params
; params
&& i
< end
; i
++)
2491 params
= params
->next
;
2494 t
->next
= (WORD_LIST
*)NULL
;
2495 if (string
[0] == '*')
2497 if (quoted
& Q_DOUBLE_QUOTES
)
2498 ret
= string_list_dollar_star (quote_list (h
));
2499 else if (quoted
& Q_HERE_DOCUMENT
)
2500 ret
= string_list (quote_list (h
));
2502 ret
= string_list (h
);
2505 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (h
) : h
);
2509 dispose_words (save
);
2513 /******************************************************************/
2515 /* Functions to expand strings to strings or WORD_LISTs */
2517 /******************************************************************/
2519 #if defined (PROCESS_SUBSTITUTION)
2520 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2522 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2525 /* If there are any characters in STRING that require full expansion,
2526 then call FUNC to expand STRING; otherwise just perform quote
2527 removal if necessary. This returns a new string. */
2529 expand_string_if_necessary (string
, quoted
, func
)
2540 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2541 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
2545 if (EXP_CHAR (string
[i
]))
2547 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
2549 ADVANCE_CHAR (string
, slen
, i
);
2554 list
= (*func
) (string
, quoted
);
2557 ret
= string_list (list
);
2558 dispose_words (list
);
2563 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
2564 ret
= string_quote_removal (string
, quoted
);
2566 ret
= savestring (string
);
2571 static inline char *
2572 expand_string_to_string_internal (string
, quoted
, func
)
2580 if (string
== 0 || *string
== '\0')
2581 return ((char *)NULL
);
2583 list
= (*func
) (string
, quoted
);
2586 ret
= string_list (list
);
2587 dispose_words (list
);
2596 expand_string_to_string (string
, quoted
)
2600 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
2604 expand_string_unsplit_to_string (string
, quoted
)
2608 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
2612 expand_assignment_string_to_string (string
, quoted
)
2616 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
2620 expand_arith_string (string
, quoted
)
2623 return (expand_string_if_necessary (string
, quoted
, expand_string
));
2626 #if defined (COND_COMMAND)
2627 /* Just remove backslashes in STRING. Returns a new string. */
2629 remove_backslashes (string
)
2634 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
2635 for (s
= string
; s
&& *s
; )
2647 /* This needs better error handling. */
2648 /* Expand W for use as an argument to a unary or binary operator in a
2649 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2650 to the != or == operator, and should be treated as a pattern. In
2651 this case, we quote the string specially for the globbing code. If
2652 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2653 be quoted appropriately for regcomp/regexec. The caller is responsible
2654 for removing the backslashes if the unquoted word is needed later. */
2656 cond_expand_word (w
, special
)
2664 if (w
->word
== 0 || w
->word
[0] == '\0')
2665 return ((char *)NULL
);
2667 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
2673 r
= string_list (l
);
2677 qflags
= QGLOB_CVTNULL
;
2679 qflags
|= QGLOB_REGEXP
;
2680 p
= string_list (l
);
2681 r
= quote_string_for_globbing (p
, qflags
);
2693 /* Call expand_word_internal to expand W and handle error returns.
2694 A convenience function for functions that don't want to handle
2695 any errors or free any memory before aborting. */
2697 call_expand_word_internal (w
, q
, i
, c
, e
)
2703 result
= expand_word_internal (w
, q
, i
, c
, e
);
2704 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
2706 /* By convention, each time this error is returned, w->word has
2707 already been freed (it sometimes may not be in the fatal case,
2708 but that doesn't result in a memory leak because we're going
2709 to exit in most cases). */
2710 w
->word
= (char *)NULL
;
2711 last_command_exit_value
= EXECUTION_FAILURE
;
2712 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
2719 /* Perform parameter expansion, command substitution, and arithmetic
2720 expansion on STRING, as if it were a word. Leave the result quoted. */
2722 expand_string_internal (string
, quoted
)
2729 if (string
== 0 || *string
== 0)
2730 return ((WORD_LIST
*)NULL
);
2733 td
.word
= savestring (string
);
2735 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2741 /* Expand STRING by performing parameter expansion, command substitution,
2742 and arithmetic expansion. Dequote the resulting WORD_LIST before
2743 returning it, but do not perform word splitting. The call to
2744 remove_quoted_nulls () is in here because word splitting normally
2745 takes care of quote removal. */
2747 expand_string_unsplit (string
, quoted
)
2753 if (string
== 0 || *string
== '\0')
2754 return ((WORD_LIST
*)NULL
);
2756 expand_no_split_dollar_star
= 1;
2757 value
= expand_string_internal (string
, quoted
);
2758 expand_no_split_dollar_star
= 0;
2764 remove_quoted_nulls (value
->word
->word
);
2765 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2767 dequote_list (value
);
2772 /* Expand the rhs of an assignment statement */
2774 expand_string_assignment (string
, quoted
)
2781 if (string
== 0 || *string
== '\0')
2782 return ((WORD_LIST
*)NULL
);
2784 expand_no_split_dollar_star
= 1;
2786 td
.flags
= W_ASSIGNRHS
;
2787 td
.word
= savestring (string
);
2788 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2791 expand_no_split_dollar_star
= 0;
2797 remove_quoted_nulls (value
->word
->word
);
2798 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2800 dequote_list (value
);
2806 /* Expand one of the PS? prompt strings. This is a sort of combination of
2807 expand_string_unsplit and expand_string_internal, but returns the
2808 passed string when an error occurs. Might want to trap other calls
2809 to jump_to_top_level here so we don't endlessly loop. */
2811 expand_prompt_string (string
, quoted
)
2818 if (string
== 0 || *string
== 0)
2819 return ((WORD_LIST
*)NULL
);
2822 td
.word
= savestring (string
);
2824 no_longjmp_on_fatal_error
= 1;
2825 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2826 no_longjmp_on_fatal_error
= 0;
2828 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
2830 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
2838 remove_quoted_nulls (value
->word
->word
);
2839 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
2841 dequote_list (value
);
2846 /* Expand STRING just as if you were expanding a word, but do not dequote
2847 the resultant WORD_LIST. This is called only from within this file,
2848 and is used to correctly preserve quoted characters when expanding
2849 things like ${1+"$@"}. This does parameter expansion, command
2850 substitution, arithmetic expansion, and word splitting. */
2852 expand_string_leave_quoted (string
, quoted
)
2859 if (string
== 0 || *string
== '\0')
2860 return ((WORD_LIST
*)NULL
);
2862 tlist
= expand_string_internal (string
, quoted
);
2866 tresult
= word_list_split (tlist
);
2867 dispose_words (tlist
);
2870 return ((WORD_LIST
*)NULL
);
2873 /* This does not perform word splitting or dequote the WORD_LIST
2876 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
2878 int quoted
, *dollar_at_p
, *has_dollar_at
;
2883 if (string
== 0 || *string
== '\0')
2884 return (WORD_LIST
*)NULL
;
2888 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
2892 /* Expand STRING just as if you were expanding a word. This also returns
2893 a list of words. Note that filename globbing is *NOT* done for word
2894 or string expansion, just when the shell is expanding a command. This
2895 does parameter expansion, command substitution, arithmetic expansion,
2896 and word splitting. Dequote the resultant WORD_LIST before returning. */
2898 expand_string (string
, quoted
)
2904 if (string
== 0 || *string
== '\0')
2905 return ((WORD_LIST
*)NULL
);
2907 result
= expand_string_leave_quoted (string
, quoted
);
2908 return (result
? dequote_list (result
) : result
);
2911 /***************************************************
2913 * Functions to handle quoting chars *
2915 ***************************************************/
2919 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2920 The parser passes CTLNUL as CTLESC CTLNUL. */
2922 /* Quote escape characters in string s, but no other characters. This is
2923 used to protect CTLESC and CTLNUL in variable values from the rest of
2924 the word expansion process after the variable is expanded. */
2926 quote_escapes (string
)
2929 register char *s
, *t
;
2931 char *result
, *send
;
2934 slen
= strlen (string
);
2935 send
= string
+ slen
;
2937 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
2942 if (*s
== CTLESC
|| *s
== CTLNUL
)
2944 COPY_CHAR_P (t
, s
, send
);
2951 list_quote_escapes (list
)
2954 register WORD_LIST
*w
;
2957 for (w
= list
; w
; w
= w
->next
)
2960 w
->word
->word
= quote_escapes (t
);
2966 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
2968 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2969 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2970 data stream pass through properly.
2972 We need to remove doubled CTLESC characters inside quoted strings before
2973 quoting the entire string, so we do not double the number of CTLESC
2976 Also used by parts of the pattern substitution code. */
2978 dequote_escapes (string
)
2981 register char *s
, *t
;
2983 char *result
, *send
;
2989 slen
= strlen (string
);
2990 send
= string
+ slen
;
2992 t
= result
= (char *)xmalloc (slen
+ 1);
2995 if (strchr (string
, CTLESC
) == 0)
2996 return (strcpy (result
, s
));
3000 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
))
3006 COPY_CHAR_P (t
, s
, send
);
3012 /* Return a new string with the quoted representation of character C.
3013 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3014 set in any resultant WORD_DESC where this value is the word. */
3016 make_quoted_char (c
)
3021 temp
= (char *)xmalloc (3);
3036 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3037 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3038 this value is the word. */
3040 quote_string (string
)
3045 char *result
, *send
;
3049 result
= (char *)xmalloc (2);
3057 slen
= strlen (string
);
3058 send
= string
+ slen
;
3060 result
= (char *)xmalloc ((slen
* 2) + 1);
3062 for (t
= result
; string
< send
; )
3065 COPY_CHAR_P (t
, string
, send
);
3072 /* De-quote quoted characters in STRING. */
3074 dequote_string (string
)
3077 register char *s
, *t
;
3079 char *result
, *send
;
3082 slen
= strlen (string
);
3084 t
= result
= (char *)xmalloc (slen
+ 1);
3086 if (QUOTED_NULL (string
))
3092 /* If no character in the string can be quoted, don't bother examining
3093 each character. Just return a copy of the string passed to us. */
3094 if (strchr (string
, CTLESC
) == NULL
)
3095 return (strcpy (result
, string
));
3097 send
= string
+ slen
;
3107 COPY_CHAR_P (t
, s
, send
);
3114 /* Quote the entire WORD_LIST list. */
3119 register WORD_LIST
*w
;
3122 for (w
= list
; w
; w
= w
->next
)
3125 w
->word
->word
= quote_string (t
);
3127 w
->word
->flags
|= W_QUOTED
;
3128 /* XXX - turn on W_HAVEQUOTEDNULL here? */
3133 /* De-quote quoted characters in each word in LIST. */
3139 register WORD_LIST
*tlist
;
3141 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3143 s
= dequote_string (tlist
->word
->word
);
3144 free (tlist
->word
->word
);
3145 tlist
->word
->word
= s
;
3146 /* XXX - turn off W_HAVEQUOTEDNULL here? */
3151 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3154 remove_quoted_escapes (string
)
3161 t
= dequote_escapes (string
);
3169 /* Perform quoted null character removal on STRING. We don't allow any
3170 quoted null characters in the middle or at the ends of strings because
3171 of how expand_word_internal works. remove_quoted_nulls () turns
3172 STRING into an empty string iff it only consists of a quoted null,
3173 and removes all unquoted CTLNUL characters. */
3175 remove_quoted_nulls (string
)
3178 register size_t slen
;
3179 register int i
, j
, prev_i
;
3182 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3183 return string
; /* XXX */
3185 slen
= strlen (string
);
3190 if (string
[i
] == CTLESC
)
3192 /* Old code had j++, but we cannot assume that i == j at this
3193 point -- what if a CTLNUL has already been removed from the
3194 string? We don't want to drop the CTLESC or recopy characters
3195 that we've already copied down. */
3196 i
++; string
[j
++] = CTLESC
;
3200 else if (string
[i
] == CTLNUL
)
3204 ADVANCE_CHAR (string
, slen
, i
);
3207 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3217 /* Perform quoted null character removal on each element of LIST.
3218 This modifies LIST. */
3220 word_list_remove_quoted_nulls (list
)
3223 register WORD_LIST
*t
;
3225 for (t
= list
; t
; t
= t
->next
)
3227 remove_quoted_nulls (t
->word
->word
);
3228 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3232 /* **************************************************************** */
3234 /* Functions for Matching and Removing Patterns */
3236 /* **************************************************************** */
3238 #if defined (HANDLE_MULTIBYTE)
3239 #if 0 /* Currently unused */
3240 static unsigned char *
3241 mb_getcharlens (string
, len
)
3245 int i
, offset
, last
;
3252 ret
= (unsigned char *)xmalloc (len
);
3253 memset (ret
, 0, len
);
3254 while (string
[last
])
3256 ADVANCE_CHAR (string
, len
, offset
);
3257 ret
[last
] = offset
- last
;
3265 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3266 can have one of 4 values:
3267 RP_LONG_LEFT remove longest matching portion at start of PARAM
3268 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3269 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3270 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3273 #define RP_LONG_LEFT 1
3274 #define RP_SHORT_LEFT 2
3275 #define RP_LONG_RIGHT 3
3276 #define RP_SHORT_RIGHT 4
3279 remove_upattern (param
, pattern
, op
)
3280 char *param
, *pattern
;
3285 register char *p
, *ret
, c
;
3287 len
= STRLEN (param
);
3292 case RP_LONG_LEFT
: /* remove longest match at start */
3293 for (p
= end
; p
>= param
; p
--)
3296 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3299 return (savestring (p
));
3306 case RP_SHORT_LEFT
: /* remove shortest match at start */
3307 for (p
= param
; p
<= end
; p
++)
3310 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3313 return (savestring (p
));
3319 case RP_LONG_RIGHT
: /* remove longest match at end */
3320 for (p
= param
; p
<= end
; p
++)
3322 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3325 ret
= savestring (param
);
3332 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3333 for (p
= end
; p
>= param
; p
--)
3335 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3338 ret
= savestring (param
);
3346 return (savestring (param
)); /* no match, return original string */
3349 #if defined (HANDLE_MULTIBYTE)
3351 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3362 case RP_LONG_LEFT
: /* remove longest match at start */
3363 for (n
= wstrlen
; n
>= 0; n
--)
3365 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3366 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3369 return (wcsdup (wparam
+ n
));
3375 case RP_SHORT_LEFT
: /* remove shortest match at start */
3376 for (n
= 0; n
<= wstrlen
; n
++)
3378 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3379 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3382 return (wcsdup (wparam
+ n
));
3388 case RP_LONG_RIGHT
: /* remove longest match at end */
3389 for (n
= 0; n
<= wstrlen
; n
++)
3391 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3393 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3394 ret
= wcsdup (wparam
);
3401 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3402 for (n
= wstrlen
; n
>= 0; n
--)
3404 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3406 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3407 ret
= wcsdup (wparam
);
3415 return (wcsdup (wparam
)); /* no match, return original string */
3417 #endif /* HANDLE_MULTIBYTE */
3420 remove_pattern (param
, pattern
, op
)
3421 char *param
, *pattern
;
3426 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3427 return (savestring (param
));
3429 #if defined (HANDLE_MULTIBYTE)
3432 wchar_t *ret
, *oret
;
3434 wchar_t *wparam
, *wpattern
;
3438 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3439 if (n
== (size_t)-1)
3440 return (remove_upattern (param
, pattern
, op
));
3441 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3442 if (n
== (size_t)-1)
3445 return (remove_upattern (param
, pattern
, op
));
3447 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3453 xret
= (char *)xmalloc (n
+ 1);
3454 memset (&ps
, '\0', sizeof (mbstate_t));
3455 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3456 xret
[n
] = '\0'; /* just to make sure */
3462 return (remove_upattern (param
, pattern
, op
));
3465 /* Return 1 of the first character of STRING could match the first
3466 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3468 match_pattern_char (pat
, string
)
3479 return (*string
== c
);
3481 return (*string
== *pat
);
3483 return (*pat
== LPAREN
? 1 : (*string
!= '\0'));
3489 return (*pat
== LPAREN
? 1 : (*string
== c
));
3491 return (*string
!= '\0');
3495 /* Match PAT anywhere in STRING and return the match boundaries.
3496 This returns 1 in case of a successful match, 0 otherwise. SP
3497 and EP are pointers into the string where the match begins and
3498 ends, respectively. MTYPE controls what kind of match is attempted.
3499 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3500 of the string, respectively. The longest match is returned. */
3502 match_upattern (string
, pat
, mtype
, sp
, ep
)
3508 register char *p
, *p1
, *npat
;
3511 /* If the pattern doesn't match anywhere in the string, go ahead and
3512 short-circuit right away. A minor optimization, saves a bunch of
3513 unnecessary calls to strmatch (up to N calls for a string of N
3514 characters) if the match is unsuccessful. To preserve the semantics
3515 of the substring matches below, we make sure that the pattern has
3516 `*' as first and last character, making a new pattern if necessary. */
3517 /* XXX - check this later if I ever implement `**' with special meaning,
3518 since this will potentially result in `**' at the beginning or end */
3520 if (pat
[0] != '*' || pat
[len
- 1] != '*')
3522 p
= npat
= (char *)xmalloc (len
+ 3);
3528 if (p1
[-1] != '*' || p
[-2] == '\\')
3534 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
3537 if (c
== FNM_NOMATCH
)
3540 len
= STRLEN (string
);
3546 for (p
= string
; p
<= end
; p
++)
3548 if (match_pattern_char (pat
, p
))
3550 for (p1
= end
; p1
>= p
; p1
--)
3552 c
= *p1
; *p1
= '\0';
3553 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3568 if (match_pattern_char (pat
, string
) == 0)
3571 for (p
= end
; p
>= string
; p
--)
3574 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
3587 for (p
= string
; p
<= end
; p
++)
3589 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3604 #if defined (HANDLE_MULTIBYTE)
3605 /* Return 1 of the first character of WSTRING could match the first
3606 character of pattern WPAT. Wide character version. */
3608 match_pattern_wchar (wpat
, wstring
)
3609 wchar_t *wpat
, *wstring
;
3616 switch (wc
= *wpat
++)
3619 return (*wstring
== wc
);
3621 return (*wstring
== *wpat
);
3623 return (*wpat
== LPAREN
? 1 : (*wstring
!= L
'\0'));
3629 return (*wpat
== LPAREN
? 1 : (*wstring
== wc
));
3631 return (*wstring
!= L
'\0');
3635 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3636 This returns 1 in case of a successful match, 0 otherwise. Wide
3637 character version. */
3639 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
3647 wchar_t wc
, *wp
, *nwpat
, *wp1
;
3650 size_t n
, n1
; /* Apple's gcc seems to miscompile this badly */
3655 /* If the pattern doesn't match anywhere in the string, go ahead and
3656 short-circuit right away. A minor optimization, saves a bunch of
3657 unnecessary calls to strmatch (up to N calls for a string of N
3658 characters) if the match is unsuccessful. To preserve the semantics
3659 of the substring matches below, we make sure that the pattern has
3660 `*' as first and last character, making a new pattern if necessary. */
3661 /* XXX - check this later if I ever implement `**' with special meaning,
3662 since this will potentially result in `**' at the beginning or end */
3663 len
= wcslen (wpat
);
3664 if (wpat
[0] != L
'*' || wpat
[len
- 1] != L
'*')
3666 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
3670 while (*wp1
!= L
'\0')
3672 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
3678 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
3681 if (len
== FNM_NOMATCH
)
3687 for (n
= 0; n
<= wstrlen
; n
++)
3689 if (match_pattern_wchar (wpat
, wstring
+ n
))
3691 for (n1
= wstrlen
; n1
>= n
; n1
--)
3693 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
3694 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3709 if (match_pattern_wchar (wpat
, wstring
) == 0)
3712 for (n
= wstrlen
; n
>= 0; n
--)
3714 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
3715 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
3728 for (n
= 0; n
<= wstrlen
; n
++)
3730 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3733 *ep
= indices
[wstrlen
];
3743 #endif /* HANDLE_MULTIBYTE */
3746 match_pattern (string
, pat
, mtype
, sp
, ep
)
3751 #if defined (HANDLE_MULTIBYTE)
3754 wchar_t *wstring
, *wpat
;
3758 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
3761 #if defined (HANDLE_MULTIBYTE)
3764 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
3765 if (n
== (size_t)-1)
3766 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3767 n
= xdupmbstowcs (&wstring
, &indices
, string
);
3768 if (n
== (size_t)-1)
3771 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3773 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
3783 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
3787 getpatspec (c
, value
)
3792 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
3794 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
3797 /* Posix.2 says that the WORD should be run through tilde expansion,
3798 parameter expansion, command substitution and arithmetic expansion.
3799 This leaves the result quoted, so quote_string_for_globbing () has
3800 to be called to fix it up for strmatch (). If QUOTED is non-zero,
3801 it means that the entire expression was enclosed in double quotes.
3802 This means that quoting characters in the pattern do not make any
3803 special pattern characters quoted. For example, the `*' in the
3804 following retains its special meaning: "${foo#'*'}". */
3806 getpattern (value
, quoted
, expandpat
)
3808 int quoted
, expandpat
;
3816 /* There is a problem here: how to handle single or double quotes in the
3817 pattern string when the whole expression is between double quotes?
3818 POSIX.2 says that enclosing double quotes do not cause the pattern to
3819 be quoted, but does that leave us a problem with @ and array[@] and their
3820 expansions inside a pattern? */
3822 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
3825 pat
= string_extract_double_quoted (tword
, &i
, 1);
3831 /* expand_string_for_rhs () leaves WORD quoted and does not perform
3833 l
= *value
? expand_string_for_rhs (value
,
3834 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
3835 (int *)NULL
, (int *)NULL
)
3837 pat
= string_list (l
);
3841 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
3849 /* Handle removing a pattern from a string as a result of ${name%[%]value}
3850 or ${name#[#]value}. */
3852 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
3853 char *value
, *pattern
;
3854 int patspec
, quoted
;
3858 tword
= remove_pattern (value
, pattern
, patspec
);
3865 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
3868 int patspec
, itype
, quoted
;
3874 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
3876 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
3877 w
= alloc_word_desc ();
3878 w
->word
= tword
? tword
: savestring ("");
3879 new = make_word_list (w
, new);
3882 l
= REVERSE_LIST (new, WORD_LIST
*);
3884 tword
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (l
) : string_list (l
);
3886 tword
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (l
) : l
);
3893 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
3896 int patspec
, quoted
;
3901 list
= list_rest_of_args ();
3903 return ((char *)NULL
);
3904 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3905 dispose_words (list
);
3909 #if defined (ARRAY_VARS)
3911 array_remove_pattern (a
, pattern
, patspec
, varname
, quoted
)
3915 char *varname
; /* so we can figure out how it's indexed */
3923 /* compute itype from varname here */
3924 v
= array_variable_part (varname
, &ret
, 0);
3927 list
= array_to_word_list (a
);
3929 return ((char *)NULL
);
3930 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
3931 dispose_words (list
);
3935 #endif /* ARRAY_VARS */
3938 parameter_brace_remove_pattern (varname
, value
, patstr
, rtype
, quoted
)
3939 char *varname
, *value
, *patstr
;
3942 int vtype
, patspec
, starsub
;
3943 char *temp1
, *val
, *pattern
;
3947 return ((char *)NULL
);
3949 this_command_name
= varname
;
3951 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
3953 return ((char *)NULL
);
3955 starsub
= vtype
& VT_STARSUB
;
3956 vtype
&= ~VT_STARSUB
;
3958 patspec
= getpatspec (rtype
, patstr
);
3959 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
3962 pattern
= getpattern (patstr
, quoted
, 1);
3964 temp1
= (char *)NULL
; /* shut up gcc */
3968 case VT_ARRAYMEMBER
:
3969 temp1
= remove_pattern (val
, pattern
, patspec
);
3970 if (vtype
== VT_VARIABLE
)
3974 val
= quote_escapes (temp1
);
3979 #if defined (ARRAY_VARS)
3981 temp1
= array_remove_pattern (array_cell (v
), pattern
, patspec
, varname
, quoted
);
3982 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3984 val
= quote_escapes (temp1
);
3991 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
3992 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3994 val
= quote_escapes (temp1
);
4005 /*******************************************
4007 * Functions to expand WORD_DESCs *
4009 *******************************************/
4011 /* Expand WORD, performing word splitting on the result. This does
4012 parameter expansion, command substitution, arithmetic expansion,
4013 word splitting, and quote removal. */
4016 expand_word (word
, quoted
)
4020 WORD_LIST
*result
, *tresult
;
4022 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4023 result
= word_list_split (tresult
);
4024 dispose_words (tresult
);
4025 return (result
? dequote_list (result
) : result
);
4028 /* Expand WORD, but do not perform word splitting on the result. This
4029 does parameter expansion, command substitution, arithmetic expansion,
4030 and quote removal. */
4032 expand_word_unsplit (word
, quoted
)
4038 expand_no_split_dollar_star
= 1;
4039 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4040 expand_no_split_dollar_star
= 0;
4042 return (result
? dequote_list (result
) : result
);
4045 /* Perform shell expansions on WORD, but do not perform word splitting or
4046 quote removal on the result. */
4048 expand_word_leave_quoted (word
, quoted
)
4052 return (call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
));
4055 #if defined (PROCESS_SUBSTITUTION)
4057 /*****************************************************************/
4059 /* Hacking Process Substitution */
4061 /*****************************************************************/
4063 #if !defined (HAVE_DEV_FD)
4064 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4065 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4066 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4067 list. NFIFO is a count of the number of FIFOs in the list. */
4068 #define FIFO_INCR 20
4075 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4077 static int fifo_list_size
;
4080 add_fifo_list (pathname
)
4083 if (nfifo
>= fifo_list_size
- 1)
4085 fifo_list_size
+= FIFO_INCR
;
4086 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4087 fifo_list_size
* sizeof (struct temp_fifo
));
4090 fifo_list
[nfifo
].file
= savestring (pathname
);
4102 for (i
= saved
= 0; i
< nfifo
; i
++)
4104 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4106 unlink (fifo_list
[i
].file
);
4107 free (fifo_list
[i
].file
);
4108 fifo_list
[i
].file
= (char *)NULL
;
4109 fifo_list
[i
].proc
= -1;
4115 /* If we didn't remove some of the FIFOs, compact the list. */
4118 for (i
= j
= 0; i
< nfifo
; i
++)
4119 if (fifo_list
[i
].file
)
4121 fifo_list
[j
].file
= fifo_list
[i
].file
;
4122 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4136 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
);
4137 if (mkfifo (tname
, 0600) < 0)
4140 return ((char *)NULL
);
4143 add_fifo_list (tname
);
4147 #else /* HAVE_DEV_FD */
4149 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4150 has open to children. NFDS is a count of the number of bits currently
4151 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4153 static char *dev_fd_list
= (char *)NULL
;
4155 static int totfds
; /* The highest possible number of open files. */
4161 if (!dev_fd_list
|| fd
>= totfds
)
4166 totfds
= getdtablesize ();
4167 if (totfds
< 0 || totfds
> 256)
4172 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4173 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4176 dev_fd_list
[fd
] = 1;
4188 for (i
= 0; nfds
&& i
< totfds
; i
++)
4199 #if defined (NOTDEF)
4200 print_dev_fd_list ()
4204 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4207 for (i
= 0; i
< totfds
; i
++)
4210 fprintf (stderr
, " %d", i
);
4212 fprintf (stderr
, "\n");
4217 make_dev_fd_filename (fd
)
4220 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4222 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 4);
4224 strcpy (ret
, DEV_FD_PREFIX
);
4225 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4226 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4232 #endif /* HAVE_DEV_FD */
4234 /* Return a filename that will open a connection to the process defined by
4235 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4236 a filename in /dev/fd corresponding to a descriptor that is one of the
4237 ends of the pipe. If not defined, we use named pipes on systems that have
4238 them. Systems without /dev/fd and named pipes are out of luck.
4240 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4241 use the read end of the pipe and dup that file descriptor to fd 0 in
4242 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4243 writing or use the write end of the pipe in the child, and dup that
4244 file descriptor to fd 1 in the child. The parent does the opposite. */
4247 process_substitute (string
, open_for_read_in_child
)
4249 int open_for_read_in_child
;
4254 #if defined (HAVE_DEV_FD)
4255 int parent_pipe_fd
, child_pipe_fd
;
4257 #endif /* HAVE_DEV_FD */
4258 #if defined (JOB_CONTROL)
4259 pid_t old_pipeline_pgrp
;
4262 if (!string
|| !*string
|| wordexp_only
)
4263 return ((char *)NULL
);
4265 #if !defined (HAVE_DEV_FD)
4266 pathname
= make_named_pipe ();
4267 #else /* HAVE_DEV_FD */
4268 if (pipe (fildes
) < 0)
4270 sys_error (_("cannot make pipe for process substitution"));
4271 return ((char *)NULL
);
4273 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4274 the pipe in the parent, otherwise the read end. */
4275 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4276 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4277 /* Move the parent end of the pipe to some high file descriptor, to
4278 avoid clashes with FDs used by the script. */
4279 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4281 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4282 #endif /* HAVE_DEV_FD */
4286 sys_error (_("cannot make pipe for process substitution"));
4287 return ((char *)NULL
);
4290 old_pid
= last_made_pid
;
4292 #if defined (JOB_CONTROL)
4293 old_pipeline_pgrp
= pipeline_pgrp
;
4294 pipeline_pgrp
= shell_pgrp
;
4296 #endif /* JOB_CONTROL */
4298 pid
= make_child ((char *)NULL
, 1);
4301 reset_terminating_signals (); /* XXX */
4302 free_pushed_string_input ();
4303 /* Cancel traps, in trap.c. */
4304 restore_original_signals ();
4305 setup_async_signals ();
4306 subshell_environment
|= SUBSHELL_COMSUB
;
4309 #if defined (JOB_CONTROL)
4310 set_sigchld_handler ();
4311 stop_making_children ();
4312 pipeline_pgrp
= old_pipeline_pgrp
;
4313 #endif /* JOB_CONTROL */
4317 sys_error (_("cannot make child for process substitution"));
4319 #if defined (HAVE_DEV_FD)
4320 close (parent_pipe_fd
);
4321 close (child_pipe_fd
);
4322 #endif /* HAVE_DEV_FD */
4323 return ((char *)NULL
);
4328 #if defined (JOB_CONTROL)
4329 restore_pipeline (1);
4332 #if !defined (HAVE_DEV_FD)
4333 fifo_list
[nfifo
-1].proc
= pid
;
4336 last_made_pid
= old_pid
;
4338 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4340 #endif /* JOB_CONTROL && PGRP_PIPE */
4342 #if defined (HAVE_DEV_FD)
4343 close (child_pipe_fd
);
4344 #endif /* HAVE_DEV_FD */
4349 set_sigint_handler ();
4351 #if defined (JOB_CONTROL)
4352 set_job_control (0);
4353 #endif /* JOB_CONTROL */
4355 #if !defined (HAVE_DEV_FD)
4356 /* Open the named pipe in the child. */
4357 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4360 /* Two separate strings for ease of translation. */
4361 if (open_for_read_in_child
)
4362 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4364 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4368 if (open_for_read_in_child
)
4370 if (sh_unset_nodelay_mode (fd
) < 0)
4372 sys_error (_("cannout reset nodelay mode for fd %d"), fd
);
4376 #else /* HAVE_DEV_FD */
4378 #endif /* HAVE_DEV_FD */
4380 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4382 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4383 open_for_read_in_child
? 0 : 1);
4387 if (fd
!= (open_for_read_in_child
? 0 : 1))
4390 /* Need to close any files that this process has open to pipes inherited
4392 if (current_fds_to_close
)
4394 close_fd_bitmap (current_fds_to_close
);
4395 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4398 #if defined (HAVE_DEV_FD)
4399 /* Make sure we close the parent's end of the pipe and clear the slot
4400 in the fd list so it is not closed later, if reallocated by, for
4401 instance, pipe(2). */
4402 close (parent_pipe_fd
);
4403 dev_fd_list
[parent_pipe_fd
] = 0;
4404 #endif /* HAVE_DEV_FD */
4406 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4408 #if !defined (HAVE_DEV_FD)
4409 /* Make sure we close the named pipe in the child before we exit. */
4410 close (open_for_read_in_child
? 0 : 1);
4411 #endif /* !HAVE_DEV_FD */
4416 #endif /* PROCESS_SUBSTITUTION */
4418 /***********************************/
4420 /* Command Substitution */
4422 /***********************************/
4425 read_comsub (fd
, quoted
)
4428 char *istring
, buf
[128], *bufp
;
4429 int istring_index
, istring_size
, c
;
4432 istring
= (char *)NULL
;
4433 istring_index
= istring_size
= bufn
= 0;
4436 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4439 /* Read the output of the command through the pipe. */
4446 bufn
= zread (fd
, buf
, sizeof (buf
));
4456 internal_warning ("read_comsub: ignored null byte in input");
4461 /* Add the character to ISTRING, possibly after resizing it. */
4462 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4464 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || c
== CTLESC
|| c
== CTLNUL
)
4465 istring
[istring_index
++] = CTLESC
;
4467 istring
[istring_index
++] = c
;
4470 #if defined (__CYGWIN__)
4471 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4474 istring
[istring_index
- 1] = '\n';
4481 istring
[istring_index
] = '\0';
4483 /* If we read no output, just return now and save ourselves some
4485 if (istring_index
== 0)
4488 return (char *)NULL
;
4491 /* Strip trailing newlines from the output of the command. */
4492 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4494 while (istring_index
> 0)
4496 if (istring
[istring_index
- 1] == '\n')
4500 /* If the newline was quoted, remove the quoting char. */
4501 if (istring
[istring_index
- 1] == CTLESC
)
4507 istring
[istring_index
] = '\0';
4510 strip_trailing (istring
, istring_index
- 1, 1);
4515 /* Perform command substitution on STRING. This returns a string,
4518 command_substitute (string
, quoted
)
4522 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4524 int result
, fildes
[2], function_value
, pflags
, rc
;
4526 istring
= (char *)NULL
;
4528 /* Don't fork () if there is no need to. In the case of no command to
4529 run, just return NULL. */
4530 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
4531 return ((char *)NULL
);
4533 if (wordexp_only
&& read_but_dont_execute
)
4535 last_command_exit_value
= 125;
4536 jump_to_top_level (EXITPROG
);
4539 /* We're making the assumption here that the command substitution will
4540 eventually run a command from the file system. Since we'll run
4541 maybe_make_export_env in this subshell before executing that command,
4542 the parent shell and any other shells it starts will have to remake
4543 the environment. If we make it before we fork, other shells won't
4544 have to. Don't bother if we have any temporary variable assignments,
4545 though, because the export environment will be remade after this
4546 command completes anyway, but do it if all the words to be expanded
4547 are variable assignments. */
4548 if (subst_assign_varlist
== 0 || garglist
== 0)
4549 maybe_make_export_env (); /* XXX */
4551 /* Flags to pass to parse_and_execute() */
4552 pflags
= interactive
? SEVAL_RESETLINE
: 0;
4554 /* Pipe the output of executing STRING into the current shell. */
4555 if (pipe (fildes
) < 0)
4557 sys_error (_("cannot make pipe for command substitution"));
4561 old_pid
= last_made_pid
;
4562 #if defined (JOB_CONTROL)
4563 old_pipeline_pgrp
= pipeline_pgrp
;
4564 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4565 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
4566 pipeline_pgrp
= shell_pgrp
;
4567 cleanup_the_pipeline ();
4568 #endif /* JOB_CONTROL */
4570 old_async_pid
= last_asynchronous_pid
;
4572 pid
= make_child ((char *)NULL
, 0);
4574 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
4576 last_asynchronous_pid
= old_async_pid
;
4579 /* Reset the signal handlers in the child, but don't free the
4581 reset_signal_handlers ();
4583 #if defined (JOB_CONTROL)
4584 set_sigchld_handler ();
4585 stop_making_children ();
4586 pipeline_pgrp
= old_pipeline_pgrp
;
4588 stop_making_children ();
4589 #endif /* JOB_CONTROL */
4593 sys_error (_("cannot make child for command substitution"));
4599 return ((char *)NULL
);
4604 set_sigint_handler (); /* XXX */
4606 free_pushed_string_input ();
4608 if (dup2 (fildes
[1], 1) < 0)
4610 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4611 exit (EXECUTION_FAILURE
);
4614 /* If standard output is closed in the parent shell
4615 (such as after `exec >&-'), file descriptor 1 will be
4616 the lowest available file descriptor, and end up in
4617 fildes[0]. This can happen for stdin and stderr as well,
4618 but stdout is more important -- it will cause no output
4619 to be generated from this command. */
4620 if ((fildes
[1] != fileno (stdin
)) &&
4621 (fildes
[1] != fileno (stdout
)) &&
4622 (fildes
[1] != fileno (stderr
)))
4625 if ((fildes
[0] != fileno (stdin
)) &&
4626 (fildes
[0] != fileno (stdout
)) &&
4627 (fildes
[0] != fileno (stderr
)))
4630 /* The currently executing shell is not interactive. */
4633 /* This is a subshell environment. */
4634 subshell_environment
|= SUBSHELL_COMSUB
;
4636 /* When not in POSIX mode, command substitution does not inherit
4638 if (posixly_correct
== 0)
4639 exit_immediately_on_error
= 0;
4641 remove_quoted_escapes (string
);
4643 startup_state
= 2; /* see if we can avoid a fork */
4644 /* Give command substitution a place to jump back to on failure,
4645 so we don't go back up to main (). */
4646 result
= setjmp (top_level
);
4648 /* If we're running a command substitution inside a shell function,
4649 trap `return' so we don't return from the function in the subshell
4650 and go off to never-never land. */
4651 if (result
== 0 && return_catch_flag
)
4652 function_value
= setjmp (return_catch
);
4656 if (result
== ERREXIT
)
4657 rc
= last_command_exit_value
;
4658 else if (result
== EXITPROG
)
4659 rc
= last_command_exit_value
;
4661 rc
= EXECUTION_FAILURE
;
4662 else if (function_value
)
4663 rc
= return_catch_value
;
4667 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
4671 last_command_exit_value
= rc
;
4672 rc
= run_exit_trap ();
4677 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4679 #endif /* JOB_CONTROL && PGRP_PIPE */
4683 istring
= read_comsub (fildes
[0], quoted
);
4687 current_command_subst_pid
= pid
;
4688 last_command_exit_value
= wait_for (pid
);
4689 last_command_subst_pid
= pid
;
4690 last_made_pid
= old_pid
;
4692 #if defined (JOB_CONTROL)
4693 /* If last_command_exit_value > 128, then the substituted command
4694 was terminated by a signal. If that signal was SIGINT, then send
4695 SIGINT to ourselves. This will break out of loops, for instance. */
4696 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
4697 kill (getpid (), SIGINT
);
4699 /* wait_for gives the terminal back to shell_pgrp. If some other
4700 process group should have it, give it away to that group here.
4701 pipeline_pgrp is non-zero only while we are constructing a
4702 pipline, so what we are concerned about is whether or not that
4703 pipeline was started in the background. A pipeline started in
4704 the background should never get the tty back here. */
4706 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
4708 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
4710 give_terminal_to (pipeline_pgrp
, 0);
4711 #endif /* JOB_CONTROL */
4717 /********************************************************
4719 * Utility functions for parameter expansion *
4721 ********************************************************/
4723 #if defined (ARRAY_VARS)
4726 array_length_reference (s
)
4735 var
= array_variable_part (s
, &t
, &len
);
4737 /* If unbound variables should generate an error, report one and return
4739 if ((var
== 0 || array_p (var
) == 0) && unbound_vars_is_error
)
4750 /* We support a couple of expansions for variables that are not arrays.
4751 We'll return the length of the value for v[0], and 1 for v[@] or
4752 v[*]. Return 0 for everything else. */
4754 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
4756 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
4757 return (array_p (var
) ? array_num_elements (array
) : 1);
4759 ind
= array_expand_index (t
, len
);
4762 err_badarraysub (t
);
4767 t
= array_reference (array
, ind
);
4769 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
4774 #endif /* ARRAY_VARS */
4777 valid_brace_expansion_word (name
, var_is_special
)
4781 if (DIGIT (*name
) && all_digits (name
))
4783 else if (var_is_special
)
4785 #if defined (ARRAY_VARS)
4786 else if (valid_array_reference (name
))
4788 #endif /* ARRAY_VARS */
4789 else if (legal_identifier (name
))
4796 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4799 int *quoted_dollar_atp
, *contains_dollar_at
;
4805 if (quoted_dollar_atp
)
4806 *quoted_dollar_atp
= 0;
4807 if (contains_dollar_at
)
4808 *contains_dollar_at
= 0;
4812 /* check for $@ and $* */
4813 if (name
[0] == '@' && name
[1] == 0)
4815 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4816 *quoted_dollar_atp
= 1;
4817 if (contains_dollar_at
)
4818 *contains_dollar_at
= 1;
4821 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
4823 if (contains_dollar_at
)
4824 *contains_dollar_at
= 1;
4828 /* Now check for ${array[@]} and ${array[*]} */
4829 #if defined (ARRAY_VARS)
4830 else if (valid_array_reference (name
))
4832 temp1
= xstrchr (name
, '[');
4833 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
4835 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4836 *quoted_dollar_atp
= 1;
4837 if (contains_dollar_at
)
4838 *contains_dollar_at
= 1;
4841 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4842 which should result in separate words even when IFS is unset. */
4843 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
4845 if (contains_dollar_at
)
4846 *contains_dollar_at
= 1;
4854 /* Parameter expand NAME, and return a new string which is the expansion,
4855 or NULL if there was no expansion.
4856 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
4857 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
4858 NAME was found inside of a double-quoted expression. */
4860 parameter_brace_expand_word (name
, var_is_special
, quoted
)
4862 int var_is_special
, quoted
;
4873 /* Handle multiple digit arguments, as in ${11}. */
4874 if (legal_number (name
, &arg_index
))
4876 tt
= get_dollar_var_value (arg_index
);
4878 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4880 : quote_escapes (tt
);
4882 temp
= (char *)NULL
;
4885 else if (var_is_special
) /* ${@} */
4888 tt
= (char *)xmalloc (2 + strlen (name
));
4889 tt
[sindex
= 0] = '$';
4890 strcpy (tt
+ 1, name
);
4892 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
4893 (int *)NULL
, (int *)NULL
, 0);
4896 #if defined (ARRAY_VARS)
4897 else if (valid_array_reference (name
))
4899 temp
= array_value (name
, quoted
, &atype
);
4900 if (atype
== 0 && temp
)
4901 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4902 ? quote_string (temp
)
4903 : quote_escapes (temp
);
4906 else if (var
= find_variable (name
))
4908 if (var_isset (var
) && invisible_p (var
) == 0)
4910 #if defined (ARRAY_VARS)
4911 temp
= array_p (var
) ? array_reference (array_cell (var
), 0) : value_cell (var
);
4913 temp
= value_cell (var
);
4917 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
4918 ? quote_string (temp
)
4919 : quote_escapes (temp
);
4922 temp
= (char *)NULL
;
4925 temp
= (char *)NULL
;
4929 ret
= alloc_word_desc ();
4935 /* Expand an indirect reference to a variable: ${!NAME} expands to the
4936 value of the variable whose name is the value of NAME. */
4938 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
4940 int var_is_special
, quoted
;
4941 int *quoted_dollar_atp
, *contains_dollar_at
;
4946 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
4948 /* Have to dequote here if necessary */
4951 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
4952 ? dequote_string (t
)
4953 : dequote_escapes (t
);
4957 dispose_word_desc (w
);
4959 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
4961 return (WORD_DESC
*)NULL
;
4963 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
);
4969 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
4970 depending on the value of C, the separating character. C can be one of
4971 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
4972 between double quotes. */
4974 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
4976 int c
, quoted
, *qdollaratp
, *hasdollarat
;
4980 char *t
, *t1
, *temp
;
4983 /* If the entire expression is between double quotes, we want to treat
4984 the value as a double-quoted string, with the exception that we strip
4985 embedded unescaped double quotes. */
4986 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
4989 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
4994 w
= alloc_word_desc ();
4996 /* XXX was 0 not quoted */
4997 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5000 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5005 /* The expansion of TEMP returned something. We need to treat things
5006 slightly differently if HASDOL is non-zero. If we have "$@", the
5007 individual words have already been quoted. We need to turn them
5008 into a string with the words separated by the first character of
5009 $IFS without any additional quoting, so string_list_dollar_at won't
5010 do the right thing. We use string_list_dollar_star instead. */
5011 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5013 /* If l->next is not null, we know that TEMP contained "$@", since that
5014 is the only expansion that creates more than one word. */
5015 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5019 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5021 /* The brace expansion occurred between double quotes and there was
5022 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5023 it does not expand to anything. In this case, we want to return
5024 a quoted empty string. */
5025 temp
= make_quoted_char ('\0');
5026 w
->flags
|= W_HASQUOTEDNULL
;
5029 temp
= (char *)NULL
;
5031 if (c
== '-' || c
== '+')
5038 t
= temp
? savestring (temp
) : savestring ("");
5039 t1
= dequote_string (t
);
5041 #if defined (ARRAY_VARS)
5042 if (valid_array_reference (name
))
5043 assign_array_element (name
, t1
, 0);
5045 #endif /* ARRAY_VARS */
5046 bind_variable (name
, t1
, 0);
5053 /* Deal with the right hand side of a ${name:?value} expansion in the case
5054 that NAME is null or not set. If VALUE is non-null it is expanded and
5055 used as the error message to print, otherwise a standard message is
5058 parameter_brace_expand_error (name
, value
)
5064 if (value
&& *value
)
5066 l
= expand_string (value
, 0);
5067 temp
= string_list (l
);
5068 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5073 report_error (_("%s: parameter null or not set"), name
);
5075 /* Free the data we have allocated during this expansion, since we
5076 are about to longjmp out. */
5081 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5084 valid_length_expression (name
)
5087 return (name
[1] == '\0' || /* ${#} */
5088 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5089 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5090 #if defined (ARRAY_VARS)
5091 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5093 legal_identifier (name
+ 1)); /* ${#PS1} */
5096 #if defined (HANDLE_MULTIBYTE)
5102 mbstate_t mbs
, mbsbak
;
5105 memset (&mbs
, 0, sizeof (mbs
));
5107 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5109 if (MB_INVALIDCH(clen
))
5111 clen
= 1; /* assume single byte */
5124 /* Handle the parameter brace expansion that requires us to return the
5125 length of a parameter. */
5127 parameter_brace_expand_length (name
)
5131 intmax_t number
, arg_index
;
5133 #if defined (ARRAY_VARS)
5137 if (name
[1] == '\0') /* ${#} */
5138 number
= number_of_args ();
5139 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5140 number
= number_of_args ();
5141 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5143 /* Take the lengths of some of the shell's special parameters. */
5147 t
= which_set_flags ();
5150 t
= itos (last_command_exit_value
);
5153 t
= itos (dollar_dollar_pid
);
5156 if (last_asynchronous_pid
== NO_PID
)
5159 t
= itos (last_asynchronous_pid
);
5162 t
= itos (number_of_args ());
5165 number
= STRLEN (t
);
5168 #if defined (ARRAY_VARS)
5169 else if (valid_array_reference (name
+ 1))
5170 number
= array_length_reference (name
+ 1);
5171 #endif /* ARRAY_VARS */
5176 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5178 t
= get_dollar_var_value (arg_index
);
5179 number
= MB_STRLEN (t
);
5182 #if defined (ARRAY_VARS)
5183 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && array_p (var
))
5185 t
= array_reference (array_cell (var
), 0);
5186 number
= MB_STRLEN (t
);
5191 newname
= savestring (name
);
5193 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5194 t
= list
? string_list (list
) : (char *)NULL
;
5197 dispose_words (list
);
5199 number
= MB_STRLEN (t
);
5207 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5208 so we do some ad-hoc parsing of an arithmetic expression to find
5209 the first DELIM, instead of using strchr(3). Two rules:
5210 1. If the substring contains a `(', read until closing `)'.
5211 2. If the substring contains a `?', read past one `:' for each `?'.
5215 skiparith (substr
, delim
)
5220 int skipcol
, pcount
, i
;
5223 sublen
= strlen (substr
);
5224 i
= skipcol
= pcount
= 0;
5227 /* Balance parens */
5228 if (substr
[i
] == LPAREN
)
5234 if (substr
[i
] == RPAREN
&& pcount
)
5242 ADVANCE_CHAR (substr
, sublen
, i
);
5246 /* Skip one `:' for each `?' */
5247 if (substr
[i
] == ':' && skipcol
)
5253 if (substr
[i
] == delim
)
5255 if (substr
[i
] == '?')
5261 ADVANCE_CHAR (substr
, sublen
, i
);
5264 return (substr
+ i
);
5267 /* Verify and limit the start and end of the desired substring. If
5268 VTYPE == 0, a regular shell variable is being used; if it is 1,
5269 then the positional parameters are being used; if it is 2, then
5270 VALUE is really a pointer to an array variable that should be used.
5271 Return value is 1 if both values were OK, 0 if there was a problem
5272 with an invalid expression, or -1 if the values were out of range. */
5274 verify_substring_values (value
, substr
, vtype
, e1p
, e2p
)
5275 char *value
, *substr
;
5277 intmax_t *e1p
, *e2p
;
5279 char *t
, *temp1
, *temp2
;
5282 #if defined (ARRAY_VARS)
5286 /* duplicate behavior of strchr(3) */
5287 t
= skiparith (substr
, ':');
5288 if (*t
&& *t
== ':')
5293 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5294 *e1p
= evalexp (temp1
, &expok
);
5299 len
= -1; /* paranoia */
5303 case VT_ARRAYMEMBER
:
5304 len
= MB_STRLEN (value
);
5307 len
= number_of_args () + 1;
5309 #if defined (ARRAY_VARS)
5312 /* For arrays, the first value deals with array indices. Negative
5313 offsets count from one past the array's maximum index. */
5314 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5319 if (len
== -1) /* paranoia */
5322 if (*e1p
< 0) /* negative offsets count from end */
5325 if (*e1p
> len
|| *e1p
< 0)
5328 #if defined (ARRAY_VARS)
5329 /* For arrays, the second offset deals with the number of elements. */
5330 if (vtype
== VT_ARRAYVAR
)
5331 len
= array_num_elements (a
);
5337 temp2
= savestring (t
);
5338 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5341 *e2p
= evalexp (temp1
, &expok
);
5347 internal_error (_("%s: substring expression < 0"), t
);
5350 #if defined (ARRAY_VARS)
5351 /* In order to deal with sparse arrays, push the intelligence about how
5352 to deal with the number of elements desired down to the array-
5353 specific functions. */
5354 if (vtype
!= VT_ARRAYVAR
)
5357 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5368 /* Return the type of variable specified by VARNAME (simple variable,
5369 positional param, or array variable). Also return the value specified
5370 by VARNAME (value of a variable or a reference to an array element).
5371 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5372 characters in the value are quoted with CTLESC and takes appropriate
5373 steps. For convenience, *VALP is set to the dequoted VALUE. */
5375 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5376 char *varname
, *value
;
5383 #if defined (ARRAY_VARS)
5387 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5388 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5389 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5390 vtype
|= VT_STARSUB
;
5391 *varp
= (SHELL_VAR
*)NULL
;
5393 #if defined (ARRAY_VARS)
5394 if (valid_array_reference (varname
))
5396 v
= array_variable_part (varname
, &temp
, (int *)0);
5397 if (v
&& array_p (v
))
5399 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5401 vtype
= VT_ARRAYVAR
;
5403 vtype
|= VT_STARSUB
;
5404 *valp
= (char *)array_cell (v
);
5408 vtype
= VT_ARRAYMEMBER
;
5409 *valp
= array_value (varname
, 1, (int *)NULL
);
5413 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5415 vtype
= VT_VARIABLE
;
5417 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5418 *valp
= dequote_string (value
);
5420 *valp
= dequote_escapes (value
);
5425 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && array_p (v
))
5427 vtype
= VT_ARRAYMEMBER
;
5429 *valp
= array_reference (array_cell (v
), 0);
5434 if (value
&& vtype
== VT_VARIABLE
)
5436 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5437 *valp
= dequote_string (value
);
5439 *valp
= dequote_escapes (value
);
5448 /******************************************************/
5450 /* Functions to extract substrings of variable values */
5452 /******************************************************/
5454 #if defined (HANDLE_MULTIBYTE)
5455 /* Character-oriented rather than strictly byte-oriented substrings. S and
5456 E, rather being strict indices into STRING, indicate character (possibly
5457 multibyte character) positions that require calculation.
5458 Used by the ${param:offset[:length]} expansion. */
5460 mb_substring (string
, s
, e
)
5465 int start
, stop
, i
, slen
;
5469 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5470 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
5473 while (string
[start
] && i
--)
5474 ADVANCE_CHAR (string
, slen
, start
);
5477 while (string
[stop
] && i
--)
5478 ADVANCE_CHAR (string
, slen
, stop
);
5479 tt
= substring (string
, start
, stop
);
5484 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5485 is `@', use the positional parameters; otherwise, use the value of
5486 VARNAME. If VARNAME is an array variable, use the array elements. */
5489 parameter_brace_substring (varname
, value
, substr
, quoted
)
5490 char *varname
, *value
, *substr
;
5494 int vtype
, r
, starsub
;
5495 char *temp
, *val
, *tt
, *oname
;
5499 return ((char *)NULL
);
5501 oname
= this_command_name
;
5502 this_command_name
= varname
;
5504 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5507 this_command_name
= oname
;
5508 return ((char *)NULL
);
5511 starsub
= vtype
& VT_STARSUB
;
5512 vtype
&= ~VT_STARSUB
;
5514 r
= verify_substring_values (val
, substr
, vtype
, &e1
, &e2
);
5515 this_command_name
= oname
;
5517 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
5522 case VT_ARRAYMEMBER
:
5523 #if defined (HANDLE_MULTIBYTE)
5525 tt
= mb_substring (val
, e1
, e2
);
5528 tt
= substring (val
, e1
, e2
);
5530 if (vtype
== VT_VARIABLE
)
5532 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5533 temp
= quote_string (tt
);
5535 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5539 tt
= pos_params (varname
, e1
, e2
, quoted
);
5540 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5542 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5548 #if defined (ARRAY_VARS)
5550 /* We want E2 to be the number of elements desired (arrays can be sparse,
5551 so verify_substring_values just returns the numbers specified and we
5552 rely on array_subrange to understand how to deal with them). */
5553 tt
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
5554 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5556 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5564 temp
= (char *)NULL
;
5570 /****************************************************************/
5572 /* Functions to perform pattern substitution on variable values */
5574 /****************************************************************/
5577 pat_subst (string
, pat
, rep
, mflags
)
5578 char *string
, *pat
, *rep
;
5581 char *ret
, *s
, *e
, *str
;
5582 int rsize
, rptr
, l
, replen
, mtype
;
5584 mtype
= mflags
& MATCH_TYPEMASK
;
5587 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5588 * with REP and return the result.
5589 * 2. A null pattern with mtype == MATCH_END means to append REP to
5590 * STRING and return the result.
5592 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
5594 replen
= STRLEN (rep
);
5595 l
= strlen (string
);
5596 ret
= (char *)xmalloc (replen
+ l
+ 2);
5598 strcpy (ret
, string
);
5599 else if (mtype
== MATCH_BEG
)
5602 strcpy (ret
+ replen
, string
);
5606 strcpy (ret
, string
);
5607 strcpy (ret
+ l
, rep
);
5612 ret
= (char *)xmalloc (rsize
= 64);
5615 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
5617 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
5620 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
5622 /* OK, now copy the leading unmatched portion of the string (from
5623 str to s) to ret starting at rptr (the current offset). Then copy
5624 the replacement string at ret + rptr + (s - str). Increment
5625 rptr (if necessary) and str and go on. */
5628 strncpy (ret
+ rptr
, str
, l
);
5633 strncpy (ret
+ rptr
, rep
, replen
);
5636 str
= e
; /* e == end of match */
5638 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
5642 e
++, str
++; /* avoid infinite recursion on zero-length match */
5645 /* Now copy the unmatched portion of the input string */
5648 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
5649 strcpy (ret
+ rptr
, str
);
5657 /* Do pattern match and replacement on the positional parameters. */
5659 pos_params_pat_subst (string
, pat
, rep
, mflags
)
5660 char *string
, *pat
, *rep
;
5663 WORD_LIST
*save
, *params
;
5667 save
= params
= list_rest_of_args ();
5669 return ((char *)NULL
);
5671 for ( ; params
; params
= params
->next
)
5673 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
5674 w
= alloc_word_desc ();
5675 w
->word
= ret
? ret
: savestring ("");
5676 dispose_word (params
->word
);
5680 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
5681 ret
= string_list_dollar_star (quote_list (save
));
5683 ret
= string_list ((mflags
& MATCH_QUOTED
) ? quote_list (save
) : save
);
5684 dispose_words (save
);
5689 /* Perform pattern substitution on VALUE, which is the expansion of
5690 VARNAME. PATSUB is an expression supplying the pattern to match
5691 and the string to substitute. QUOTED is a flags word containing
5692 the type of quoting currently in effect. */
5694 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
5695 char *varname
, *value
, *patsub
;
5698 int vtype
, mflags
, starsub
;
5699 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
5703 return ((char *)NULL
);
5705 this_command_name
= varname
;
5707 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5709 return ((char *)NULL
);
5711 starsub
= vtype
& VT_STARSUB
;
5712 vtype
&= ~VT_STARSUB
;
5715 if (patsub
&& *patsub
== '/')
5717 mflags
|= MATCH_GLOBREP
;
5721 /* Malloc this because expand_string_if_necessary or one of the expansion
5722 functions in its call chain may free it on a substitution error. */
5723 lpatsub
= savestring (patsub
);
5725 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5726 mflags
|= MATCH_QUOTED
;
5729 mflags
|= MATCH_STARSUB
;
5731 /* If the pattern starts with a `/', make sure we skip over it when looking
5732 for the replacement delimiter. */
5733 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
5738 if (rep
&& *rep
== '\0')
5741 /* Perform the same expansions on the pattern as performed by the
5742 pattern removal expansions. */
5743 pat
= getpattern (lpatsub
, quoted
, 1);
5747 if ((mflags
& MATCH_QUOTED
) == 0)
5748 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
5750 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
5753 /* ksh93 doesn't allow the match specifier to be a part of the expanded
5754 pattern. This is an extension. Make sure we don't anchor the pattern
5755 at the beginning or end of the string if we're doing global replacement,
5758 if (mflags
& MATCH_GLOBREP
)
5759 mflags
|= MATCH_ANY
;
5760 else if (pat
&& pat
[0] == '#')
5762 mflags
|= MATCH_BEG
;
5765 else if (pat
&& pat
[0] == '%')
5767 mflags
|= MATCH_END
;
5771 mflags
|= MATCH_ANY
;
5773 /* OK, we now want to substitute REP for PAT in VAL. If
5774 flags & MATCH_GLOBREP is non-zero, the substitution is done
5775 everywhere, otherwise only the first occurrence of PAT is
5776 replaced. The pattern matching code doesn't understand
5777 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
5778 values passed in (VT_VARIABLE) so the pattern substitution
5779 code works right. We need to requote special chars after
5780 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
5781 other cases if QUOTED == 0, since the posparams and arrays
5782 indexed by * or @ do special things when QUOTED != 0. */
5787 case VT_ARRAYMEMBER
:
5788 temp
= pat_subst (val
, p
, rep
, mflags
);
5789 if (vtype
== VT_VARIABLE
)
5793 tt
= quote_escapes (temp
);
5799 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
5800 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5802 tt
= quote_escapes (temp
);
5807 #if defined (ARRAY_VARS)
5809 temp
= array_patsub (array_cell (v
), p
, rep
, mflags
);
5810 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
5812 tt
= quote_escapes (temp
);
5827 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
5828 any occur, this must be a nested command substitution, so return 0.
5829 Otherwise, return 1. A valid arithmetic expression must always have a
5830 ( before a matching ), so any cases where there are more right parens
5831 means that this must not be an arithmetic expression, though the parser
5832 will not accept it without a balanced total number of parens. */
5834 chk_arithsub (s
, len
)
5846 else if (s
[i
] == ')')
5856 ADVANCE_CHAR (s
, len
, i
);
5862 ADVANCE_CHAR (s
, len
, i
);
5866 i
= skip_single_quoted (s
, len
, ++i
);
5870 i
= skip_double_quoted ((char *)s
, len
, ++i
);
5875 return (count
== 0);
5878 /****************************************************************/
5880 /* Functions to perform parameter expansion on a string */
5882 /****************************************************************/
5884 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
5886 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5888 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
5890 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
5891 int want_substring
, want_indir
, want_patsub
;
5892 char *name
, *value
, *temp
, *temp1
;
5893 WORD_DESC
*tdesc
, *ret
;
5894 int t_index
, sindex
, c
, tflag
;
5897 value
= (char *)NULL
;
5898 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
5899 want_substring
= want_indir
= want_patsub
= 0;
5903 /* ${#var} doesn't have any of the other parameter expansions on it. */
5904 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
5905 name
= string_extract (string
, &t_index
, "}", EX_VARNAME
);
5907 name
= string_extract (string
, &t_index
, "#%:-=?+/}", EX_VARNAME
);
5912 /* If the name really consists of a special variable, then make sure
5913 that we have the entire name. We don't allow indirect references
5914 to special variables except `#', `?', `@' and `*'. */
5915 if ((sindex
== t_index
&&
5916 (string
[t_index
] == '-' ||
5917 string
[t_index
] == '?' ||
5918 string
[t_index
] == '#')) ||
5919 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
5920 (string
[t_index
] == '#' ||
5921 string
[t_index
] == '?' ||
5922 string
[t_index
] == '@' ||
5923 string
[t_index
] == '*')))
5927 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
5928 name
= (char *)xmalloc (3 + (strlen (temp1
)));
5929 *name
= string
[sindex
];
5930 if (string
[sindex
] == '!')
5932 /* indirect reference of $#, $?, $@, or $* */
5933 name
[1] = string
[sindex
+ 1];
5934 strcpy (name
+ 2, temp1
);
5937 strcpy (name
+ 1, temp1
);
5942 /* Find out what character ended the variable name. Then
5943 do the appropriate thing. */
5944 if (c
= string
[sindex
])
5947 /* If c is followed by one of the valid parameter expansion
5948 characters, move past it as normal. If not, assume that
5949 a substring specification is being given, and do not move
5951 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
5954 if (c
= string
[sindex
])
5957 else if (c
== ':' && string
[sindex
] != RBRACE
)
5959 else if (c
== '/' && string
[sindex
] != RBRACE
)
5962 /* Catch the valid and invalid brace expressions that made it through the
5964 /* ${#-} is a valid expansion and means to take the length of $-.
5965 Similarly for ${#?} and ${##}... */
5966 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
5967 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
5969 name
= (char *)xrealloc (name
, 3);
5972 c
= string
[sindex
++];
5975 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
5976 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
5977 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
5979 temp
= (char *)NULL
;
5980 goto bad_substitution
;
5983 /* Indirect expansion begins with a `!'. A valid indirect expansion is
5984 either a variable name, one of the positional parameters or a special
5985 variable that expands to one of the positional parameters. */
5986 want_indir
= *name
== '!' &&
5987 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
5988 || VALID_INDIR_PARAM (name
[1]));
5990 /* Determine the value of this variable. */
5992 /* Check for special variables, directly referenced. */
5993 if (SPECIAL_VAR (name
, want_indir
))
5996 /* Check for special expansion things, like the length of a parameter */
5997 if (*name
== '#' && name
[1])
5999 /* If we are not pointing at the character just after the
6000 closing brace, then we haven't gotten all of the name.
6001 Since it begins with a special character, this is a bad
6002 substitution. Also check NAME for validity before trying
6004 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6006 temp
= (char *)NULL
;
6007 goto bad_substitution
;
6010 number
= parameter_brace_expand_length (name
);
6015 return (&expand_wdesc_error
);
6018 ret
= alloc_word_desc ();
6019 ret
->word
= itos (number
);
6024 /* ${@} is identical to $@. */
6025 if (name
[0] == '@' && name
[1] == '\0')
6027 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6028 *quoted_dollar_atp
= 1;
6030 if (contains_dollar_at
)
6031 *contains_dollar_at
= 1;
6034 /* Process ${!PREFIX*} expansion. */
6035 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6036 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6037 legal_variable_starter ((unsigned char) name
[1]))
6042 temp1
= savestring (name
+ 1);
6043 number
= strlen (temp1
);
6044 temp1
[number
- 1] = '\0';
6045 x
= all_variables_matching_prefix (temp1
);
6046 xlist
= strvec_to_word_list (x
, 0, 0);
6047 if (string
[sindex
- 2] == '*')
6048 temp
= string_list_dollar_star (xlist
);
6051 temp
= string_list_dollar_at (xlist
, quoted
);
6052 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6053 *quoted_dollar_atp
= 1;
6054 if (contains_dollar_at
)
6055 *contains_dollar_at
= 1;
6062 ret
= alloc_word_desc ();
6067 #if defined (ARRAY_VARS)
6068 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6069 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6070 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6074 temp1
= savestring (name
+ 1);
6075 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6077 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6079 temp
= array_keys (temp1
, quoted
);
6082 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6083 *quoted_dollar_atp
= 1;
6084 if (contains_dollar_at
)
6085 *contains_dollar_at
= 1;
6091 ret
= alloc_word_desc ();
6098 #endif /* ARRAY_VARS */
6100 /* Make sure that NAME is valid before trying to go on. */
6101 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6102 var_is_special
) == 0)
6104 temp
= (char *)NULL
;
6105 goto bad_substitution
;
6109 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6111 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
6116 tflag
= tdesc
->flags
;
6117 dispose_word_desc (tdesc
);
6122 #if defined (ARRAY_VARS)
6123 if (valid_array_reference (name
))
6124 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6127 var_is_set
= temp
!= (char *)0;
6128 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6130 /* Get the rest of the stuff inside the braces. */
6131 if (c
&& c
!= RBRACE
)
6133 /* Extract the contents of the ${ ... } expansion
6134 according to the Posix.2 rules. */
6135 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6136 if (string
[sindex
] == RBRACE
)
6139 goto bad_substitution
;
6142 value
= (char *)NULL
;
6146 /* If this is a substring spec, process it and add the result. */
6149 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6154 if (temp1
== &expand_param_error
)
6155 return (&expand_wdesc_error
);
6156 else if (temp1
== &expand_param_fatal
)
6157 return (&expand_wdesc_fatal
);
6159 ret
= alloc_word_desc ();
6161 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6162 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6165 else if (want_patsub
)
6167 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6172 if (temp1
== &expand_param_error
)
6173 return (&expand_wdesc_error
);
6174 else if (temp1
== &expand_param_fatal
)
6175 return (&expand_wdesc_fatal
);
6177 ret
= alloc_word_desc ();
6182 /* Do the right thing based on which character ended the variable name. */
6188 report_error (_("%s: bad substitution"), string
? string
: "??");
6192 return &expand_wdesc_error
;
6195 if (var_is_set
== 0 && unbound_vars_is_error
)
6197 err_unboundvar (name
);
6201 last_command_exit_value
= EXECUTION_FAILURE
;
6202 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6206 case '#': /* ${param#[#]pattern} */
6207 case '%': /* ${param%[%]pattern} */
6208 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6213 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6223 if (var_is_set
&& var_is_null
== 0)
6225 /* If the operator is `+', we don't want the value of the named
6226 variable for anything, just the value of the right hand side. */
6230 /* XXX -- if we're double-quoted and the named variable is "$@",
6231 we want to turn off any special handling of "$@" --
6232 we're not using it, so whatever is on the rhs applies. */
6233 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6234 *quoted_dollar_atp
= 0;
6235 if (contains_dollar_at
)
6236 *contains_dollar_at
= 0;
6241 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6244 contains_dollar_at
);
6245 /* XXX - fix up later, esp. noting presence of
6246 W_HASQUOTEDNULL in ret->flags */
6250 temp
= (char *)NULL
;
6256 /* Otherwise do nothing; just use the value in TEMP. */
6258 else /* VAR not set or VAR is NULL. */
6261 temp
= (char *)NULL
;
6262 if (c
== '=' && var_is_special
)
6264 report_error (_("$%s: cannot assign in this way"), name
);
6267 return &expand_wdesc_error
;
6271 parameter_brace_expand_error (name
, value
);
6272 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6276 /* XXX -- if we're double-quoted and the named variable is "$@",
6277 we want to turn off any special handling of "$@" --
6278 we're not using it, so whatever is on the rhs applies. */
6279 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6280 *quoted_dollar_atp
= 0;
6281 if (contains_dollar_at
)
6282 *contains_dollar_at
= 0;
6284 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
6286 contains_dollar_at
);
6287 /* XXX - fix up later, esp. noting presence of
6288 W_HASQUOTEDNULL in tdesc->flags */
6299 ret
= alloc_word_desc ();
6306 /* Expand a single ${xxx} expansion. The braces are optional. When
6307 the braces are used, parameter_brace_expand() does the work,
6308 possibly calling param_expand recursively. */
6310 param_expand (string
, sindex
, quoted
, expanded_something
,
6311 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
6314 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
6315 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
6317 char *temp
, *temp1
, uerror
[3];
6318 int zindex
, t_index
, expok
;
6323 WORD_DESC
*tdesc
, *ret
;
6327 c
= string
[++zindex
];
6329 temp
= (char *)NULL
;
6330 ret
= tdesc
= (WORD_DESC
*)NULL
;
6333 /* Do simple cases first. Switch on what follows '$'. */
6347 temp1
= dollar_vars
[TODIGIT (c
)];
6348 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
6353 err_unboundvar (uerror
);
6354 last_command_exit_value
= EXECUTION_FAILURE
;
6355 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6358 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6359 ? quote_string (temp1
)
6360 : quote_escapes (temp1
);
6362 temp
= (char *)NULL
;
6366 /* $$ -- pid of the invoking shell. */
6368 temp
= itos (dollar_dollar_pid
);
6371 /* $# -- number of positional parameters. */
6373 temp
= itos (number_of_args ());
6376 /* $? -- return value of the last synchronous command. */
6378 temp
= itos (last_command_exit_value
);
6381 /* $- -- flags supplied to the shell on invocation or by `set'. */
6383 temp
= which_set_flags ();
6386 /* $! -- Pid of the last asynchronous command. */
6388 /* If no asynchronous pids have been created, expand to nothing.
6389 If `set -u' has been executed, and no async processes have
6390 been created, this is an expansion error. */
6391 if (last_asynchronous_pid
== NO_PID
)
6393 if (expanded_something
)
6394 *expanded_something
= 0;
6395 temp
= (char *)NULL
;
6396 if (unbound_vars_is_error
)
6401 err_unboundvar (uerror
);
6402 last_command_exit_value
= EXECUTION_FAILURE
;
6403 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6407 temp
= itos (last_asynchronous_pid
);
6410 /* The only difference between this and $@ is when the arg is quoted. */
6411 case '*': /* `$*' */
6412 list
= list_rest_of_args ();
6414 /* If there are no command-line arguments, this should just
6415 disappear if there are other characters in the expansion,
6416 even if it's quoted. */
6417 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
6418 temp
= (char *)NULL
;
6419 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6421 /* If we have "$*" we want to make a string of the positional
6422 parameters, separated by the first character of $IFS, and
6423 quote the whole string, including the separators. If IFS
6424 is unset, the parameters are separated by ' '; if $IFS is
6425 null, the parameters are concatenated. */
6426 temp
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (list
) : string_list (list
);
6427 temp1
= quote_string (temp
);
6429 tflag
|= W_HASQUOTEDNULL
;
6435 /* We check whether or not we're eventually going to split $* here,
6436 for example when IFS is empty and we are processing the rhs of
6437 an assignment statement. In that case, we don't separate the
6438 arguments at all. Otherwise, if the $* is not quoted it is
6441 # if defined (HANDLE_MULTIBYTE)
6442 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
6444 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
6446 temp
= string_list_dollar_star (list
);
6448 temp
= string_list_dollar_at (list
, quoted
);
6450 temp
= string_list_dollar_at (list
, quoted
);
6452 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
6453 *contains_dollar_at
= 1;
6456 dispose_words (list
);
6459 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
6460 means that we have to turn quoting off after we split into
6461 the individually quoted arguments so that the final split
6462 on the first character of $IFS is still done. */
6463 case '@': /* `$@' */
6464 list
= list_rest_of_args ();
6466 /* We want to flag the fact that we saw this. We can't turn
6467 off quoting entirely, because other characters in the
6468 string might need it (consider "\"$@\""), but we need some
6469 way to signal that the final split on the first character
6470 of $IFS should be done, even though QUOTED is 1. */
6471 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6472 *quoted_dollar_at_p
= 1;
6473 if (contains_dollar_at
)
6474 *contains_dollar_at
= 1;
6476 /* We want to separate the positional parameters with the first
6477 character of $IFS in case $IFS is something other than a space.
6478 We also want to make sure that splitting is done no matter what --
6479 according to POSIX.2, this expands to a list of the positional
6480 parameters no matter what IFS is set to. */
6481 temp
= string_list_dollar_at (list
, quoted
);
6483 dispose_words (list
);
6487 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
6489 contains_dollar_at
);
6491 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
6493 temp
= tdesc
? tdesc
->word
: (char *)0;
6496 /* Quoted nulls should be removed if there is anything else
6498 /* Note that we saw the quoted null so we can add one back at
6499 the end of this function if there are no other characters
6500 in the string, discard TEMP, and go on. The exception to
6501 this is when we have "${@}" and $1 is '', since $@ needs
6502 special handling. */
6503 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
6505 if (had_quoted_null_p
)
6506 *had_quoted_null_p
= 1;
6507 if (*quoted_dollar_at_p
== 0)
6510 tdesc
->word
= temp
= (char *)NULL
;
6518 /* Do command or arithmetic substitution. */
6520 /* We have to extract the contents of this paren substitution. */
6521 t_index
= zindex
+ 1;
6522 temp
= extract_command_subst (string
, &t_index
);
6525 /* For Posix.2-style `$(( ))' arithmetic substitution,
6526 extract the expression and pass it to the evaluator. */
6527 if (temp
&& *temp
== LPAREN
)
6531 temp2
= savestring (temp1
);
6532 t_index
= strlen (temp2
) - 1;
6534 if (temp2
[t_index
] != RPAREN
)
6540 /* Cut off ending `)' */
6541 temp2
[t_index
] = '\0';
6543 if (chk_arithsub (temp2
, t_index
) == 0)
6549 /* Expand variables found inside the expression. */
6550 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6554 /* No error messages. */
6555 this_command_name
= (char *)NULL
;
6556 number
= evalexp (temp1
, &expok
);
6561 if (interactive_shell
== 0 && posixly_correct
)
6563 last_command_exit_value
= EXECUTION_FAILURE
;
6564 return (&expand_wdesc_fatal
);
6567 return (&expand_wdesc_error
);
6569 temp
= itos (number
);
6574 if (pflags
& PF_NOCOMSUB
)
6575 /* we need zindex+1 because string[zindex] == RPAREN */
6576 temp1
= substring (string
, *sindex
, zindex
+1);
6578 temp1
= command_substitute (temp
, quoted
);
6583 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
6584 away in a future bash release. */
6586 /* Extract the contents of this arithmetic substitution. */
6587 t_index
= zindex
+ 1;
6588 temp
= extract_arithmetic_subst (string
, &t_index
);
6591 /* Do initial variable expansion. */
6592 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
6597 /* Find the variable in VARIABLE_LIST. */
6598 temp
= (char *)NULL
;
6600 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
6602 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
6604 /* If this isn't a variable name, then just output the `$'. */
6605 if (temp1
== 0 || *temp1
== '\0')
6608 temp
= (char *)xmalloc (2);
6611 if (expanded_something
)
6612 *expanded_something
= 0;
6616 /* If the variable exists, return its value cell. */
6617 var
= find_variable (temp1
);
6619 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
6621 #if defined (ARRAY_VARS)
6624 temp
= array_reference (array_cell (var
), 0);
6626 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6627 ? quote_string (temp
)
6628 : quote_escapes (temp
);
6629 else if (unbound_vars_is_error
)
6630 goto unbound_variable
;
6635 temp
= value_cell (var
);
6637 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6638 ? quote_string (temp
)
6639 : quote_escapes (temp
);
6647 temp
= (char *)NULL
;
6650 if (unbound_vars_is_error
)
6651 err_unboundvar (temp1
);
6659 last_command_exit_value
= EXECUTION_FAILURE
;
6660 return ((unbound_vars_is_error
&& interactive_shell
== 0)
6661 ? &expand_wdesc_fatal
6662 : &expand_wdesc_error
);
6673 ret
= alloc_word_desc ();
6674 ret
->flags
= tflag
; /* XXX */
6680 /* Make a word list which is the result of parameter and variable
6681 expansion, command substitution, arithmetic substitution, and
6682 quote removal of WORD. Return a pointer to a WORD_LIST which is
6683 the result of the expansion. If WORD contains a null word, the
6684 word list returned is also null.
6686 QUOTED contains flag values defined in shell.h.
6688 ISEXP is used to tell expand_word_internal that the word should be
6689 treated as the result of an expansion. This has implications for
6690 how IFS characters in the word are treated.
6692 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
6693 they point to an integer value which receives information about expansion.
6694 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
6695 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
6698 This only does word splitting in the case of $@ expansion. In that
6699 case, we split on ' '. */
6701 /* Values for the local variable quoted_state. */
6703 #define PARTIALLY_QUOTED 1
6704 #define WHOLLY_QUOTED 2
6707 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
6710 int *contains_dollar_at
;
6711 int *expanded_something
;
6716 /* The intermediate string that we build while expanding. */
6719 /* The current size of the above object. */
6722 /* Index into ISTRING. */
6725 /* Temporary string storage. */
6728 /* The text of WORD. */
6729 register char *string
;
6731 /* The size of STRING. */
6734 /* The index into STRING. */
6737 /* This gets 1 if we see a $@ while quoted. */
6738 int quoted_dollar_at
;
6740 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
6741 whether WORD contains no quoting characters, a partially quoted
6742 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
6746 int had_quoted_null
;
6750 int assignoff
; /* If assignment, offset of `=' */
6752 register unsigned char c
; /* Current character. */
6753 int t_index
; /* For calls to string_extract_xxx. */
6759 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
6760 istring
[istring_index
= 0] = '\0';
6761 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
6762 quoted_state
= UNQUOTED
;
6764 string
= word
->word
;
6766 goto finished_with_string
;
6767 /* Don't need the string length for the SADD... and COPY_ macros unless
6768 multibyte characters are possible. */
6769 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
6771 if (contains_dollar_at
)
6772 *contains_dollar_at
= 0;
6776 /* Begin the expansion. */
6782 /* Case on toplevel character. */
6786 goto finished_with_string
;
6790 #if HANDLE_MULTIBYTE
6791 if (MB_CUR_MAX
> 1 && string
[sindex
])
6793 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
6798 temp
= (char *)xmalloc (3);
6800 temp
[1] = c
= string
[sindex
];
6811 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
6817 #if defined (PROCESS_SUBSTITUTION)
6818 /* Process substitution. */
6822 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
6824 sindex
--; /* add_character: label increments sindex */
6828 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
6830 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
6833 /* If the process substitution specification is `<()', we want to
6834 open the pipe for writing in the child and produce output; if
6835 it is `>()', we want to open the pipe for reading in the child
6836 and consume input. */
6837 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
6841 goto dollar_add_string
;
6843 #endif /* PROCESS_SUBSTITUTION */
6846 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6847 which are not assignment statements are not expanded. If the
6848 shell isn't in posix mode, though, we perform tilde expansion
6849 on `likely candidate' unquoted assignment statements (flags
6850 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
6851 contains an unquoted :~ or =~. Something to think about: we
6852 now have a flag that says to perform tilde expansion on arguments
6853 to `assignment builtins' like declare and export that look like
6854 assignment statements. We now do tilde expansion on such words
6855 even in POSIX mode. */
6856 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
6858 /* If we're not in posix mode or forcing assignment-statement tilde
6859 expansion, note where the `=' appears in the word and prepare to
6860 do tilde expansion following the first `='. */
6861 if ((word
->flags
& W_ASSIGNMENT
) &&
6862 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6863 assignoff
== -1 && sindex
> 0)
6865 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
6866 word
->flags
|= W_ITILDE
;
6868 else if ((word
->flags
& W_ASSIGNMENT
) &&
6869 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
6870 string
[sindex
+1] == '~')
6871 word
->flags
|= W_ITILDE
;
6876 if (word
->flags
& W_NOTILDE
)
6879 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
6880 string
[sindex
+1] == '~')
6881 word
->flags
|= W_ITILDE
;
6885 /* If the word isn't supposed to be tilde expanded, or we're not
6886 at the start of a word or after an unquoted : or = in an
6887 assignment statement, we don't do tilde expansion. */
6888 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
6889 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
6890 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
6892 word
->flags
&= ~W_ITILDE
;
6896 if (word
->flags
& W_ASSIGNRHS
)
6898 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
6903 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
6905 word
->flags
&= ~W_ITILDE
;
6907 if (temp
&& *temp
&& t_index
> 0)
6909 temp1
= bash_tilde_expand (temp
, tflag
);
6910 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
6914 goto add_character
; /* tilde expansion failed */
6928 if (expanded_something
)
6929 *expanded_something
= 1;
6932 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
6933 &has_dollar_at
, "ed_dollar_at
,
6935 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
6937 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
6941 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
6942 : &expand_word_fatal
);
6944 if (contains_dollar_at
&& has_dollar_at
)
6945 *contains_dollar_at
= 1;
6947 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
6948 had_quoted_null
= 1;
6951 dispose_word_desc (tword
);
6956 case '`': /* Backquoted command substitution. */
6960 temp
= string_extract (string
, &sindex
, "`", EX_REQMATCH
);
6961 /* The test of sindex against t_index is to allow bare instances of
6962 ` to pass through, for backwards compatibility. */
6963 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
6965 if (sindex
- 1 == t_index
)
6970 report_error ("bad substitution: no closing \"`\" in %s", string
+t_index
);
6973 return ((temp
== &extract_string_error
) ? &expand_word_error
6974 : &expand_word_fatal
);
6977 if (expanded_something
)
6978 *expanded_something
= 1;
6980 if (word
->flags
& W_NOCOMSUB
)
6981 /* sindex + 1 because string[sindex] == '`' */
6982 temp1
= substring (string
, t_index
, sindex
+ 1);
6985 de_backslash (temp
);
6986 temp1
= command_substitute (temp
, quoted
);
6990 goto dollar_add_string
;
6994 if (string
[sindex
+ 1] == '\n')
7000 c
= string
[++sindex
];
7002 if (quoted
& Q_HERE_DOCUMENT
)
7004 else if (quoted
& Q_DOUBLE_QUOTES
)
7009 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7011 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7016 sindex
--; /* add_character: label increments sindex */
7021 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7026 /* BEFORE jumping here, we need to increment sindex if appropriate */
7027 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7028 DEFAULT_ARRAY_SIZE
);
7029 istring
[istring_index
++] = twochars
[0];
7030 istring
[istring_index
++] = twochars
[1];
7031 istring
[istring_index
] = '\0';
7037 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7039 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7044 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7046 /* If the quotes surrounded the entire string, then the
7047 whole word was quoted. */
7048 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7054 tword
= alloc_word_desc ();
7057 temp
= (char *)NULL
;
7060 /* Need to get W_HASQUOTEDNULL flag through this function. */
7061 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7063 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7067 /* expand_word_internal has already freed temp_word->word
7068 for us because of the way it prints error messages. */
7069 tword
->word
= (char *)NULL
;
7070 dispose_word (tword
);
7074 dispose_word (tword
);
7076 /* "$@" (a double-quoted dollar-at) expands into nothing,
7077 not even a NULL word, when there are no positional
7079 if (list
== 0 && has_dollar_at
)
7085 /* If we get "$@", we know we have expanded something, so we
7086 need to remember it for the final split on $IFS. This is
7087 a special case; it's the only case where a quoted string
7088 can expand into more than one word. It's going to come back
7089 from the above call to expand_word_internal as a list with
7090 a single word, in which all characters are quoted and
7091 separated by blanks. What we want to do is to turn it back
7092 into a list for the next piece of code. */
7094 dequote_list (list
);
7096 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7097 had_quoted_null
= 1;
7102 if (contains_dollar_at
)
7103 *contains_dollar_at
= 1;
7104 if (expanded_something
)
7105 *expanded_something
= 1;
7110 /* What we have is "". This is a minor optimization. */
7112 list
= (WORD_LIST
*)NULL
;
7115 /* The code above *might* return a list (consider the case of "$@",
7116 where it returns "$1", "$2", etc.). We can't throw away the
7117 rest of the list, and we have to make sure each word gets added
7118 as quoted. We test on tresult->next: if it is non-NULL, we
7119 quote the whole list, save it to a string with string_list, and
7120 add that string. We don't need to quote the results of this
7121 (and it would be wrong, since that would quote the separators
7122 as well), so we go directly to add_string. */
7127 /* Testing quoted_dollar_at makes sure that "$@" is
7128 split correctly when $IFS does not contain a space. */
7129 temp
= quoted_dollar_at
7130 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7131 : string_list (quote_list (list
));
7132 dispose_words (list
);
7137 temp
= savestring (list
->word
->word
);
7138 tflag
= list
->word
->flags
;
7139 dispose_words (list
);
7141 /* If the string is not a quoted null string, we want
7142 to remove any embedded unquoted CTLNUL characters.
7143 We do not want to turn quoted null strings back into
7144 the empty string, though. We do this because we
7145 want to remove any quoted nulls from expansions that
7146 contain other characters. For example, if we have
7147 x"$*"y or "x$*y" and there are no positional parameters,
7148 the $* should expand into nothing. */
7149 /* We use the W_HASQUOTEDNULL flag to differentiate the
7150 cases: a quoted null character as above and when
7151 CTLNUL is contained in the (non-null) expansion
7152 of some variable. We use the had_quoted_null flag to
7153 pass the value through this function to its caller. */
7154 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7155 remove_quoted_nulls (temp
); /* XXX */
7159 temp
= (char *)NULL
;
7161 /* We do not want to add quoted nulls to strings that are only
7162 partially quoted; we can throw them away. */
7163 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7171 temp
= quote_string (temp
);
7179 sindex
--; /* add_character: label increments sindex */
7187 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7189 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7194 temp
= string_extract_single_quoted (string
, &sindex
);
7196 /* If the entire STRING was surrounded by single quotes,
7197 then the string is wholly quoted. */
7198 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7202 /* If all we had was '', it is a null expansion. */
7206 temp
= (char *)NULL
;
7209 remove_quoted_escapes (temp
); /* ??? */
7211 /* We do not want to add quoted nulls to strings that are only
7212 partially quoted; such nulls are discarded. */
7213 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7216 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7220 sindex
--; /* add_character: label increments sindex */
7224 goto add_quoted_string
;
7229 /* This is the fix for " $@ " */
7230 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7232 if (string
[sindex
]) /* from old goto dollar_add_string */
7241 #if HANDLE_MULTIBYTE
7247 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7252 twochars
[0] = CTLESC
;
7259 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7262 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7263 DEFAULT_ARRAY_SIZE
);
7264 istring
[istring_index
++] = c
;
7265 istring
[istring_index
] = '\0';
7267 /* Next character. */
7272 finished_with_string
:
7273 /* OK, we're ready to return. If we have a quoted string, and
7274 quoted_dollar_at is not set, we do no splitting at all; otherwise
7275 we split on ' '. The routines that call this will handle what to
7276 do if nothing has been expanded. */
7278 /* Partially and wholly quoted strings which expand to the empty
7279 string are retained as an empty arguments. Unquoted strings
7280 which expand to the empty string are discarded. The single
7281 exception is the case of expanding "$@" when there are no
7282 positional parameters. In that case, we discard the expansion. */
7284 /* Because of how the code that handles "" and '' in partially
7285 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7286 if we saw quoting characters, but the expansion was empty.
7287 "" and '' are tossed away before we get to this point when
7288 processing partially quoted strings. This makes "" and $xxx""
7289 equivalent when xxx is unset. We also look to see whether we
7290 saw a quoted null from a ${} expansion and add one back if we
7293 /* If we expand to nothing and there were no single or double quotes
7294 in the word, we throw it away. Otherwise, we return a NULL word.
7295 The single exception is for $@ surrounded by double quotes when
7296 there are no positional parameters. In that case, we also throw
7299 if (*istring
== '\0')
7301 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7303 istring
[0] = CTLNUL
;
7305 tword
= make_bare_word (istring
);
7306 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7307 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7308 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7309 tword
->flags
|= W_QUOTED
;
7311 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7312 and a double-quoted "$@" appears anywhere in it, then the entire
7314 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
7315 list
= (WORD_LIST
*)NULL
;
7319 tword
= make_bare_word (istring
);
7320 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7321 tword
->flags
|= W_QUOTED
;
7322 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7326 list
= (WORD_LIST
*)NULL
;
7329 else if (word
->flags
& W_NOSPLIT
)
7331 tword
= make_bare_word (istring
);
7332 if (word
->flags
& W_ASSIGNMENT
)
7333 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
7334 if (word
->flags
& W_COMPASSIGN
)
7335 tword
->flags
|= W_COMPASSIGN
; /* XXX */
7336 if (word
->flags
& W_NOGLOB
)
7337 tword
->flags
|= W_NOGLOB
; /* XXX */
7338 if (word
->flags
& W_NOEXPAND
)
7339 tword
->flags
|= W_NOEXPAND
; /* XXX */
7340 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7341 tword
->flags
|= W_QUOTED
;
7342 if (had_quoted_null
)
7343 tword
->flags
|= W_HASQUOTEDNULL
;
7344 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7350 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
7352 /* If we have $@, we need to split the results no matter what. If
7353 IFS is unset or NULL, string_list_dollar_at has separated the
7354 positional parameters with a space, so we split on space (we have
7355 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7356 string_list_dollar_at has separated the positional parameters
7357 with the first character of $IFS, so we split on $IFS. */
7358 if (has_dollar_at
&& ifs_chars
)
7359 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
7362 tword
= make_bare_word (istring
);
7363 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
7364 tword
->flags
|= W_QUOTED
;
7365 if (word
->flags
& W_ASSIGNMENT
)
7366 tword
->flags
|= W_ASSIGNMENT
;
7367 if (word
->flags
& W_COMPASSIGN
)
7368 tword
->flags
|= W_COMPASSIGN
;
7369 if (word
->flags
& W_NOGLOB
)
7370 tword
->flags
|= W_NOGLOB
;
7371 if (word
->flags
& W_NOEXPAND
)
7372 tword
->flags
|= W_NOEXPAND
;
7373 if (had_quoted_null
)
7374 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7375 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7383 /* **************************************************************** */
7385 /* Functions for Quote Removal */
7387 /* **************************************************************** */
7389 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
7390 backslash quoting rules for within double quotes or a here document. */
7392 string_quote_removal (string
, quoted
)
7397 char *r
, *result_string
, *temp
, *send
;
7398 int sindex
, tindex
, dquote
;
7402 /* The result can be no longer than the original string. */
7403 slen
= strlen (string
);
7404 send
= string
+ slen
;
7406 r
= result_string
= (char *)xmalloc (slen
+ 1);
7408 for (dquote
= sindex
= 0; c
= string
[sindex
];)
7413 c
= string
[++sindex
];
7414 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
7419 SCOPY_CHAR_M (r
, string
, send
, sindex
);
7423 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
7429 tindex
= sindex
+ 1;
7430 temp
= string_extract_single_quoted (string
, &tindex
);
7441 dquote
= 1 - dquote
;
7447 return (result_string
);
7452 /* Perform quote removal on word WORD. This allocates and returns a new
7455 word_quote_removal (word
, quoted
)
7462 t
= string_quote_removal (word
->word
, quoted
);
7463 w
= alloc_word_desc ();
7464 w
->word
= t
? t
: savestring ("");
7468 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
7469 the members of the list are treated as if they are surrounded by
7470 double quotes. Return a new list, or NULL if LIST is NULL. */
7472 word_list_quote_removal (list
, quoted
)
7476 WORD_LIST
*result
, *t
, *tresult
, *e
;
7478 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7480 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
7482 result
= (WORD_LIST
*) list_append (result
, tresult
);
7485 result
= e
= tresult
;
7498 /*******************************************
7500 * Functions to perform word splitting *
7502 *******************************************/
7513 ifs_value
= v
? value_cell (v
) : " \t\n";
7515 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
7518 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
7519 handle multibyte chars in IFS */
7520 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
7521 for (t
= ifs_value
; t
&& *t
; t
++)
7527 #if defined (HANDLE_MULTIBYTE)
7530 ifs_firstc
[0] = '\0';
7536 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
7537 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
7538 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
7540 ifs_firstc
[0] = ifs_value
[0];
7541 ifs_firstc
[1] = '\0';
7545 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
7548 ifs_firstc
= ifs_value
? *ifs_value
: 0;
7558 /* This splits a single word into a WORD LIST on $IFS, but only if the word
7559 is not quoted. list_string () performs quote removal for us, even if we
7560 don't do any splitting. */
7562 word_split (w
, ifs_chars
)
7572 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
7573 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
7576 result
= (WORD_LIST
*)NULL
;
7581 /* Perform word splitting on LIST and return the RESULT. It is possible
7582 to return (WORD_LIST *)NULL. */
7584 word_list_split (list
)
7587 WORD_LIST
*result
, *t
, *tresult
, *e
;
7589 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
7591 tresult
= word_split (t
->word
, ifs_value
);
7593 result
= e
= tresult
;
7604 /**************************************************
7606 * Functions to expand an entire WORD_LIST *
7608 **************************************************/
7610 /* Do any word-expansion-specific cleanup and jump to top_level */
7612 exp_jump_to_top_level (v
)
7615 /* Cleanup code goes here. */
7616 expand_no_split_dollar_star
= 0; /* XXX */
7617 expanding_redir
= 0;
7619 jump_to_top_level (v
);
7622 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
7623 ELIST, and set ELIST to the new list. */
7624 #define PREPEND_LIST(nlist, elist) \
7625 do { nlist->next = elist; elist = nlist; } while (0)
7627 /* Separate out any initial variable assignments from TLIST. If set -k has
7628 been executed, remove all assignment statements from TLIST. Initial
7629 variable assignments and other environment assignments are placed
7630 on SUBST_ASSIGN_VARLIST. */
7632 separate_out_assignments (tlist
)
7635 register WORD_LIST
*vp
, *lp
;
7638 return ((WORD_LIST
*)NULL
);
7640 if (subst_assign_varlist
)
7641 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
7643 subst_assign_varlist
= (WORD_LIST
*)NULL
;
7646 /* Separate out variable assignments at the start of the command.
7647 Loop invariant: vp->next == lp
7649 lp = list of words left after assignment statements skipped
7650 tlist = original list of words
7652 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
7658 /* If lp != tlist, we have some initial assignment statements.
7659 We make SUBST_ASSIGN_VARLIST point to the list of assignment
7660 words and TLIST point to the remaining words. */
7663 subst_assign_varlist
= tlist
;
7664 /* ASSERT(vp->next == lp); */
7665 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
7666 tlist
= lp
; /* remainder of word list */
7669 /* vp == end of variable list */
7670 /* tlist == remainder of original word list without variable assignments */
7672 /* All the words in tlist were assignment statements */
7673 return ((WORD_LIST
*)NULL
);
7675 /* ASSERT(tlist != NULL); */
7676 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
7678 /* If the -k option is in effect, we need to go through the remaining
7679 words, separate out the assignment words, and place them on
7680 SUBST_ASSIGN_VARLIST. */
7681 if (place_keywords_in_env
)
7683 WORD_LIST
*tp
; /* tp == running pointer into tlist */
7688 /* Loop Invariant: tp->next == lp */
7689 /* Loop postcondition: tlist == word list without assignment statements */
7692 if (lp
->word
->flags
& W_ASSIGNMENT
)
7694 /* Found an assignment statement, add this word to end of
7695 subst_assign_varlist (vp). */
7696 if (!subst_assign_varlist
)
7697 subst_assign_varlist
= vp
= lp
;
7704 /* Remove the word pointed to by LP from TLIST. */
7705 tp
->next
= lp
->next
;
7706 /* ASSERT(vp == lp); */
7707 lp
->next
= (WORD_LIST
*)NULL
;
7720 #define WEXP_VARASSIGN 0x001
7721 #define WEXP_BRACEEXP 0x002
7722 #define WEXP_TILDEEXP 0x004
7723 #define WEXP_PARAMEXP 0x008
7724 #define WEXP_PATHEXP 0x010
7726 /* All of the expansions, including variable assignments at the start of
7728 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7730 /* All of the expansions except variable assignments at the start of
7732 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
7734 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
7735 expansion, command substitution, arithmetic expansion, word splitting, and
7737 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
7739 /* Take the list of words in LIST and do the various substitutions. Return
7740 a new list of words which is the expanded list, and without things like
7741 variable assignments. */
7747 return (expand_word_list_internal (list
, WEXP_ALL
));
7750 /* Same as expand_words (), but doesn't hack variable or environment
7753 expand_words_no_vars (list
)
7756 return (expand_word_list_internal (list
, WEXP_NOVARS
));
7760 expand_words_shellexp (list
)
7763 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
7767 glob_expand_word_list (tlist
, eflags
)
7771 char **glob_array
, *temp_string
;
7772 register int glob_index
;
7773 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
7776 output_list
= disposables
= (WORD_LIST
*)NULL
;
7777 glob_array
= (char **)NULL
;
7780 /* For each word, either globbing is attempted or the word is
7781 added to orig_list. If globbing succeeds, the results are
7782 added to orig_list and the word (tlist) is added to the list
7783 of disposable words. If globbing fails and failed glob
7784 expansions are left unchanged (the shell default), the
7785 original word is added to orig_list. If globbing fails and
7786 failed glob expansions are removed, the original word is
7787 added to the list of disposable words. orig_list ends up
7788 in reverse order and requires a call to REVERSE_LIST to
7789 be set right. After all words are examined, the disposable
7793 /* If the word isn't an assignment and contains an unquoted
7794 pattern matching character, then glob it. */
7795 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
7796 unquoted_glob_pattern_p (tlist
->word
->word
))
7798 glob_array
= shell_glob_filename (tlist
->word
->word
);
7800 /* Handle error cases.
7801 I don't think we should report errors like "No such file
7802 or directory". However, I would like to report errors
7803 like "Read failed". */
7805 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
7807 glob_array
= (char **)xmalloc (sizeof (char *));
7808 glob_array
[0] = (char *)NULL
;
7811 /* Dequote the current word in case we have to use it. */
7812 if (glob_array
[0] == NULL
)
7814 temp_string
= dequote_string (tlist
->word
->word
);
7815 free (tlist
->word
->word
);
7816 tlist
->word
->word
= temp_string
;
7819 /* Make the array into a word list. */
7820 glob_list
= (WORD_LIST
*)NULL
;
7821 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
7823 tword
= make_bare_word (glob_array
[glob_index
]);
7824 tword
->flags
|= W_GLOBEXP
; /* XXX */
7825 glob_list
= make_word_list (tword
, glob_list
);
7830 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
7831 PREPEND_LIST (tlist
, disposables
);
7833 else if (fail_glob_expansion
!= 0)
7835 report_error (_("no match: %s"), tlist
->word
->word
);
7836 jump_to_top_level (DISCARD
);
7838 else if (allow_null_glob_expansion
== 0)
7840 /* Failed glob expressions are left unchanged. */
7841 PREPEND_LIST (tlist
, output_list
);
7845 /* Failed glob expressions are removed. */
7846 PREPEND_LIST (tlist
, disposables
);
7851 /* Dequote the string. */
7852 temp_string
= dequote_string (tlist
->word
->word
);
7853 free (tlist
->word
->word
);
7854 tlist
->word
->word
= temp_string
;
7855 PREPEND_LIST (tlist
, output_list
);
7858 strvec_dispose (glob_array
);
7859 glob_array
= (char **)NULL
;
7865 dispose_words (disposables
);
7868 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7870 return (output_list
);
7873 #if defined (BRACE_EXPANSION)
7875 brace_expand_word_list (tlist
, eflags
)
7879 register char **expansions
;
7881 WORD_LIST
*disposables
, *output_list
, *next
;
7885 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
7889 /* Only do brace expansion if the word has a brace character. If
7890 not, just add the word list element to BRACES and continue. In
7891 the common case, at least when running shell scripts, this will
7892 degenerate to a bunch of calls to `xstrchr', and then what is
7893 basically a reversal of TLIST into BRACES, which is corrected
7894 by a call to REVERSE_LIST () on BRACES when the end of TLIST
7896 if (xstrchr (tlist
->word
->word
, LBRACE
))
7898 expansions
= brace_expand (tlist
->word
->word
);
7900 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
7902 w
= make_word (temp_string
);
7903 /* If brace expansion didn't change the word, preserve
7904 the flags. We may want to preserve the flags
7905 unconditionally someday -- XXX */
7906 if (STREQ (temp_string
, tlist
->word
->word
))
7907 w
->flags
= tlist
->word
->flags
;
7908 output_list
= make_word_list (w
, output_list
);
7909 free (expansions
[eindex
]);
7913 /* Add TLIST to the list of words to be freed after brace
7914 expansion has been performed. */
7915 PREPEND_LIST (tlist
, disposables
);
7918 PREPEND_LIST (tlist
, output_list
);
7922 dispose_words (disposables
);
7925 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
7927 return (output_list
);
7932 shell_expand_word_list (tlist
, eflags
)
7936 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
7937 int expanded_something
, has_dollar_at
;
7940 /* We do tilde expansion all the time. This is what 1003.2 says. */
7941 new_list
= (WORD_LIST
*)NULL
;
7942 for (orig_list
= tlist
; tlist
; tlist
= next
)
7944 temp_string
= tlist
->word
->word
;
7948 #if defined (ARRAY_VARS)
7949 /* If this is a compound array assignment to a builtin that accepts
7950 such assignments (e.g., `declare'), take the assignment and perform
7951 it separately, handling the semantics of declarations inside shell
7952 functions. This avoids the double-evaluation of such arguments,
7953 because `declare' does some evaluation of compound assignments on
7955 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
7959 t
= do_word_assignment (tlist
->word
);
7962 last_command_exit_value
= EXECUTION_FAILURE
;
7963 exp_jump_to_top_level (DISCARD
);
7966 /* Now transform the word as ksh93 appears to do and go on */
7967 t
= assignment (tlist
->word
->word
, 0);
7968 tlist
->word
->word
[t
] = '\0';
7969 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
);
7973 expanded_something
= 0;
7974 expanded
= expand_word_internal
7975 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
7977 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
7979 /* By convention, each time this error is returned,
7980 tlist->word->word has already been freed. */
7981 tlist
->word
->word
= (char *)NULL
;
7983 /* Dispose our copy of the original list. */
7984 dispose_words (orig_list
);
7985 /* Dispose the new list we're building. */
7986 dispose_words (new_list
);
7988 last_command_exit_value
= EXECUTION_FAILURE
;
7989 if (expanded
== &expand_word_error
)
7990 exp_jump_to_top_level (DISCARD
);
7992 exp_jump_to_top_level (FORCE_EOF
);
7995 /* Don't split words marked W_NOSPLIT. */
7996 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
7998 temp_list
= word_list_split (expanded
);
7999 dispose_words (expanded
);
8003 /* If no parameter expansion, command substitution, process
8004 substitution, or arithmetic substitution took place, then
8005 do not do word splitting. We still have to remove quoted
8006 null characters from the result. */
8007 word_list_remove_quoted_nulls (expanded
);
8008 temp_list
= expanded
;
8011 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8012 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8016 dispose_words (orig_list
);
8019 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8024 /* The workhorse for expand_words () and expand_words_no_vars ().
8025 First arg is LIST, a WORD_LIST of words.
8026 Second arg EFLAGS is a flags word controlling which expansions are
8029 This does all of the substitutions: brace expansion, tilde expansion,
8030 parameter expansion, command substitution, arithmetic expansion,
8031 process substitution, word splitting, and pathname expansion, according
8032 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8033 set, or for which no expansion is done, do not undergo word splitting.
8034 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8036 expand_word_list_internal (list
, eflags
)
8040 WORD_LIST
*new_list
, *temp_list
;
8044 return ((WORD_LIST
*)NULL
);
8046 garglist
= new_list
= copy_word_list (list
);
8047 if (eflags
& WEXP_VARASSIGN
)
8049 garglist
= new_list
= separate_out_assignments (new_list
);
8052 if (subst_assign_varlist
)
8054 /* All the words were variable assignments, so they are placed
8055 into the shell's environment. */
8056 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8058 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8059 tint
= do_word_assignment (temp_list
->word
);
8060 /* Variable assignment errors in non-interactive shells
8061 running in Posix.2 mode cause the shell to exit. */
8064 last_command_exit_value
= EXECUTION_FAILURE
;
8065 if (interactive_shell
== 0 && posixly_correct
)
8066 exp_jump_to_top_level (FORCE_EOF
);
8068 exp_jump_to_top_level (DISCARD
);
8071 dispose_words (subst_assign_varlist
);
8072 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8074 return ((WORD_LIST
*)NULL
);
8078 /* Begin expanding the words that remain. The expansions take place on
8079 things that aren't really variable assignments. */
8081 #if defined (BRACE_EXPANSION)
8082 /* Do brace expansion on this word if there are any brace characters
8084 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8085 new_list
= brace_expand_word_list (new_list
, eflags
);
8086 #endif /* BRACE_EXPANSION */
8088 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8089 variable substitution, command substitution, arithmetic expansion,
8090 and word splitting. */
8091 new_list
= shell_expand_word_list (new_list
, eflags
);
8093 /* Okay, we're almost done. Now let's just do some filename
8097 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8098 /* Glob expand the word list unless globbing has been disabled. */
8099 new_list
= glob_expand_word_list (new_list
, eflags
);
8101 /* Dequote the words, because we're not performing globbing. */
8102 new_list
= dequote_list (new_list
);
8105 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8107 sh_wassign_func_t
*assign_func
;
8109 /* If the remainder of the words expand to nothing, Posix.2 requires
8110 that the variable and environment assignments affect the shell's
8112 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8113 tempenv_assign_error
= 0;
8115 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8117 this_command_name
= (char *)NULL
;
8118 tint
= (*assign_func
) (temp_list
->word
);
8119 /* Variable assignment errors in non-interactive shells running
8120 in Posix.2 mode cause the shell to exit. */
8123 if (assign_func
== do_word_assignment
)
8125 last_command_exit_value
= EXECUTION_FAILURE
;
8126 if (interactive_shell
== 0 && posixly_correct
)
8127 exp_jump_to_top_level (FORCE_EOF
);
8129 exp_jump_to_top_level (DISCARD
);
8132 tempenv_assign_error
++;
8136 dispose_words (subst_assign_varlist
);
8137 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8141 tint
= list_length (new_list
) + 1;
8142 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8143 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8144 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8145 glob_argv_flags
[tint
] = '\0';