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-2009 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
47 #include "execute_cmd.h"
51 #include "mailcheck.h"
55 #include "builtins/getopt.h"
56 #include "builtins/common.h"
58 #include "builtins/builtext.h"
60 #include <tilde/tilde.h>
61 #include <glob/strmatch.h>
67 /* The size that strings change by. */
68 #define DEFAULT_INITIAL_ARRAY_SIZE 112
69 #define DEFAULT_ARRAY_SIZE 128
75 #define VT_ARRAYMEMBER 3
78 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
80 /* Flags for quoted_strchr */
81 #define ST_BACKSL 0x01
82 #define ST_CTLESC 0x02
83 #define ST_SQUOTE 0x04 /* unused yet */
84 #define ST_DQUOTE 0x08 /* unused yet */
86 /* Flags for the `pflags' argument to param_expand() */
87 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
88 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
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 /* Sentinel to tell when we are performing variable assignments preceding a
138 command name and putting them into the environment. Used to make sure
139 we use the temporary environment when looking up variable values. */
140 int assigning_in_environment
;
142 /* Used to hold a list of variable assignments preceding a command. Global
143 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
144 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
145 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
147 /* Extern functions and variables from different files. */
148 extern int last_command_exit_value
, last_command_exit_signal
;
149 extern int subshell_environment
;
150 extern int subshell_level
, parse_and_execute_level
;
151 extern int eof_encountered
;
152 extern int return_catch_flag
, return_catch_value
;
153 extern pid_t dollar_dollar_pid
;
154 extern int posixly_correct
;
155 extern char *this_command_name
;
156 extern struct fd_bitmap
*current_fds_to_close
;
157 extern int wordexp_only
;
158 extern int expanding_redir
;
159 extern int tempenv_assign_error
;
161 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
162 extern wchar_t *wcsdup
__P((const wchar_t *));
165 /* Non-zero means to allow unmatched globbed filenames to expand to
167 int allow_null_glob_expansion
;
169 /* Non-zero means to throw an error when globbing fails to match anything. */
170 int fail_glob_expansion
;
173 /* Variables to keep track of which words in an expanded word list (the
174 output of expand_word_list_internal) are the result of globbing
175 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
176 (CURRENTLY UNUSED). */
177 char *glob_argv_flags
;
178 static int glob_argv_flags_size
;
181 static WORD_LIST expand_word_error
, expand_word_fatal
;
182 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
183 static char expand_param_error
, expand_param_fatal
;
184 static char extract_string_error
, extract_string_fatal
;
186 /* Tell the expansion functions to not longjmp back to top_level on fatal
187 errors. Enabled when doing completion and prompt string expansion. */
188 static int no_longjmp_on_fatal_error
= 0;
190 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
191 $* on $IFS, primarily when doing assignment statements. */
192 static int expand_no_split_dollar_star
= 0;
194 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
195 without any leading variable assignments. */
196 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
198 static char *quoted_substring
__P((char *, int, int));
199 static int quoted_strlen
__P((char *));
200 static char *quoted_strchr
__P((char *, int, int));
202 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
203 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
204 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
205 static WORD_LIST
*expand_string_internal
__P((char *, int));
206 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
207 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
209 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
210 static char *make_quoted_char
__P((int));
211 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
213 static int unquoted_substring
__P((char *, char *));
214 static int unquoted_member
__P((int, char *));
216 #if defined (ARRAY_VARS)
217 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
219 static int do_assignment_internal
__P((const WORD_DESC
*, int));
221 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
222 static char *string_extract
__P((char *, int *, char *, int));
223 static char *string_extract_double_quoted
__P((char *, int *, int));
224 static inline char *string_extract_single_quoted
__P((char *, int *));
225 static inline int skip_single_quoted
__P((const char *, size_t, int));
226 static int skip_double_quoted
__P((char *, size_t, int));
227 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
228 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
229 static int skip_matched_pair
__P((const char *, int, int, int, int));
231 static char *pos_params
__P((char *, int, int, int));
233 static unsigned char *mb_getcharlens
__P((char *, int));
235 static char *remove_upattern
__P((char *, char *, int));
236 #if defined (HANDLE_MULTIBYTE)
237 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
239 static char *remove_pattern
__P((char *, char *, int));
241 static int match_pattern_char
__P((char *, char *));
242 static int match_upattern
__P((char *, char *, int, char **, char **));
243 #if defined (HANDLE_MULTIBYTE)
244 static int match_pattern_wchar
__P((wchar_t *, wchar_t *));
245 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
247 static int match_pattern
__P((char *, char *, int, char **, char **));
248 static int getpatspec
__P((int, char *));
249 static char *getpattern
__P((char *, int, int));
250 static char *variable_remove_pattern
__P((char *, char *, int, int));
251 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
252 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
254 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
256 static char *parameter_brace_remove_pattern
__P((char *, char *, char *, int, int));
258 static char *process_substitute
__P((char *, int));
260 static char *read_comsub
__P((int, int, int *));
263 static arrayind_t array_length_reference
__P((char *));
266 static int valid_brace_expansion_word
__P((char *, int));
267 static int chk_atstar
__P((char *, int, int *, int *));
268 static int chk_arithsub
__P((const char *, int));
270 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int));
271 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
272 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
273 static void parameter_brace_expand_error
__P((char *, char *));
275 static int valid_length_expression
__P((char *));
276 static intmax_t parameter_brace_expand_length
__P((char *));
278 static char *skiparith
__P((char *, int));
279 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
280 static int get_var_and_type
__P((char *, char *, int, SHELL_VAR
**, char **));
281 static char *mb_substring
__P((char *, int, int));
282 static char *parameter_brace_substring
__P((char *, char *, char *, int));
284 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
286 static char *parameter_brace_patsub
__P((char *, char *, char *, int));
288 static char *pos_params_casemod
__P((char *, char *, int, int));
289 static char *parameter_brace_casemod
__P((char *, char *, int, char *, int));
291 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int *, int *));
292 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
294 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
296 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
298 static void exp_jump_to_top_level
__P((int));
300 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
301 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
302 #ifdef BRACE_EXPANSION
303 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
305 #if defined (ARRAY_VARS)
306 static int make_internal_declare
__P((char *, char *));
308 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
309 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
311 /* **************************************************************** */
313 /* Utility Functions */
315 /* **************************************************************** */
319 dump_word_flags (flags
)
325 fprintf (stderr
, "%d -> ", f
);
326 if (f
& W_ASSIGNASSOC
)
329 fprintf (stderr
, "W_ASSIGNASSOC%s", f
? "|" : "");
334 fprintf (stderr
, "W_HASCTLESC%s", f
? "|" : "");
339 fprintf (stderr
, "W_NOPROCSUB%s", f
? "|" : "");
344 fprintf (stderr
, "W_DQUOTE%s", f
? "|" : "");
346 if (f
& W_HASQUOTEDNULL
)
348 f
&= ~W_HASQUOTEDNULL
;
349 fprintf (stderr
, "W_HASQUOTEDNULL%s", f
? "|" : "");
354 fprintf (stderr
, "W_ASSIGNARG%s", f
? "|" : "");
359 fprintf (stderr
, "W_ASSNBLTIN%s", f
? "|" : "");
361 if (f
& W_COMPASSIGN
)
364 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
369 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
374 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
379 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
384 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
389 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
391 if (f
& W_DOLLARSTAR
)
394 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
399 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
404 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
409 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
414 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
419 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
424 fprintf (stderr
, "W_GLOBEXP%s", f
? "|" : "");
426 if (f
& W_ASSIGNMENT
)
429 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
434 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
439 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
441 fprintf (stderr
, "\n");
446 #ifdef INCLUDE_UNUSED
448 quoted_substring (string
, start
, end
)
453 register char *result
, *s
, *r
;
457 /* Move to string[start], skipping quoted characters. */
458 for (s
= string
, l
= 0; *s
&& l
< start
; )
470 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
472 /* Copy LEN characters, including quote characters. */
474 for (l
= 0; l
< len
; s
++)
488 #ifdef INCLUDE_UNUSED
489 /* Return the length of S, skipping over quoted characters */
513 /* Find the first occurrence of character C in string S, obeying shell
514 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
515 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
516 escaped with CTLESC are skipped. */
518 quoted_strchr (s
, c
, flags
)
526 if (((flags
& ST_BACKSL
) && *p
== '\\')
527 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
531 return ((char *)NULL
);
537 return ((char *)NULL
);
540 /* Return 1 if CHARACTER appears in an unquoted portion of
541 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
543 unquoted_member (character
, string
)
551 slen
= strlen (string
);
553 while (c
= string
[sindex
])
561 ADVANCE_CHAR (string
, slen
, sindex
);
567 ADVANCE_CHAR (string
, slen
, sindex
);
571 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
575 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
582 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
584 unquoted_substring (substr
, string
)
585 char *substr
, *string
;
588 int sindex
, c
, sublen
;
591 if (substr
== 0 || *substr
== '\0')
594 slen
= strlen (string
);
595 sublen
= strlen (substr
);
596 for (sindex
= 0; c
= string
[sindex
]; )
598 if (STREQN (string
+ sindex
, substr
, sublen
))
607 ADVANCE_CHAR (string
, slen
, sindex
);
611 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
615 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
619 ADVANCE_CHAR (string
, slen
, sindex
);
626 /* Most of the substitutions must be done in parallel. In order
627 to avoid using tons of unclear goto's, I have some functions
628 for manipulating malloc'ed strings. They all take INDX, a
629 pointer to an integer which is the offset into the string
630 where manipulation is taking place. They also take SIZE, a
631 pointer to an integer which is the current length of the
632 character array for this string. */
634 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
635 of space allocated to TARGET. SOURCE can be NULL, in which
636 case nothing happens. Gets rid of SOURCE by freeing it.
637 Returns TARGET in case the location has changed. */
639 sub_append_string (source
, target
, indx
, size
)
640 char *source
, *target
;
647 srclen
= STRLEN (source
);
648 if (srclen
>= (int)(*size
- *indx
))
651 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
652 target
= (char *)xrealloc (target
, (*size
= n
));
655 FASTCOPY (source
, target
+ *indx
, srclen
);
657 target
[*indx
] = '\0';
666 /* Append the textual representation of NUMBER to TARGET.
667 INDX and SIZE are as in SUB_APPEND_STRING. */
669 sub_append_number (number
, target
, indx
, size
)
676 temp
= itos (number
);
677 return (sub_append_string (temp
, target
, indx
, size
));
681 /* Extract a substring from STRING, starting at SINDEX and ending with
682 one of the characters in CHARLIST. Don't make the ending character
683 part of the string. Leave SINDEX pointing at the ending character.
684 Understand about backslashes in the string. If (flags & SX_VARNAME)
685 is non-zero, and array variables have been compiled into the shell,
686 everything between a `[' and a corresponding `]' is skipped over.
687 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
688 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
689 contain a closing character from CHARLIST. */
691 string_extract (string
, sindex
, charlist
, flags
)
703 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
706 while (c
= string
[i
])
715 #if defined (ARRAY_VARS)
716 else if ((flags
& SX_VARNAME
) && c
== '[')
719 /* If this is an array subscript, skip over it and continue. */
720 ni
= skipsubscript (string
, i
, 0);
721 if (string
[ni
] == ']')
725 else if (MEMBER (c
, charlist
))
731 ADVANCE_CHAR (string
, slen
, i
);
734 /* If we had to have a matching delimiter and didn't find one, return an
735 error and let the caller deal with it. */
736 if ((flags
& SX_REQMATCH
) && found
== 0)
739 return (&extract_string_error
);
742 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
748 /* Extract the contents of STRING as if it is enclosed in double quotes.
749 SINDEX, when passed in, is the offset of the character immediately
750 following the opening double quote; on exit, SINDEX is left pointing after
751 the closing double quote. If STRIPDQ is non-zero, unquoted double
752 quotes are stripped and the string is terminated by a null byte.
753 Backslashes between the embedded double quotes are processed. If STRIPDQ
754 is zero, an unquoted `"' terminates the string. */
756 string_extract_double_quoted (string
, sindex
, stripdq
)
758 int *sindex
, stripdq
;
764 char *temp
, *ret
; /* The new string we return. */
765 int pass_next
, backquote
, si
; /* State variables for the machine. */
769 slen
= strlen (string
+ *sindex
) + *sindex
;
770 send
= string
+ slen
;
772 pass_next
= backquote
= dquote
= 0;
773 temp
= (char *)xmalloc (1 + slen
- *sindex
);
777 while (c
= string
[i
])
779 /* Process a character that was quoted by a backslash. */
784 ``The backslash shall retain its special meaning as an escape
785 character only when followed by one of the characters:
788 If STRIPDQ is zero, we handle the double quotes here and let
789 expand_word_internal handle the rest. If STRIPDQ is non-zero,
790 we have already been through one round of backslash stripping,
791 and want to strip these backslashes only if DQUOTE is non-zero,
792 indicating that we are inside an embedded double-quoted string. */
794 /* If we are in an embedded quoted string, then don't strip
795 backslashes before characters for which the backslash
796 retains its special meaning, but remove backslashes in
797 front of other characters. If we are not in an
798 embedded quoted string, don't strip backslashes at all.
799 This mess is necessary because the string was already
800 surrounded by double quotes (and sh has some really weird
802 The returned string will be run through expansion as if
803 it were double-quoted. */
804 if ((stripdq
== 0 && c
!= '"') ||
805 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
810 COPY_CHAR_I (temp
, j
, string
, send
, i
);
814 /* A backslash protects the next character. The code just above
815 handles preserving the backslash in front of any character but
824 /* Inside backquotes, ``the portion of the quoted string from the
825 initial backquote and the characters up to the next backquote
826 that is not preceded by a backslash, having escape characters
827 removed, defines that command''. */
845 /* Pass everything between `$(' and the matching `)' or a quoted
846 ${ ... } pair through according to the Posix.2 specification. */
847 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
852 if (string
[i
+ 1] == LPAREN
)
853 ret
= extract_command_subst (string
, &si
, 0);
855 ret
= extract_dollar_brace_string (string
, &si
, 1, 0);
858 temp
[j
++] = string
[i
+ 1];
860 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
862 if (ret
== 0 && no_longjmp_on_fatal_error
)
865 ret
= string
+ i
+ 2;
868 for (t
= 0; ret
[t
]; t
++, j
++)
870 temp
[j
] = string
[si
];
885 /* Add any character but a double quote to the quoted string we're
888 goto add_one_character
;
902 /* Point to after the closing quote. */
910 /* This should really be another option to string_extract_double_quoted. */
912 skip_double_quoted (string
, slen
, sind
)
919 int pass_next
, backquote
, si
;
922 pass_next
= backquote
= 0;
924 while (c
= string
[i
])
929 ADVANCE_CHAR (string
, slen
, i
);
942 ADVANCE_CHAR (string
, slen
, i
);
951 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
954 if (string
[i
+ 1] == LPAREN
)
955 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
957 ret
= extract_dollar_brace_string (string
, &si
, 1, SX_NOALLOC
);
964 ADVANCE_CHAR (string
, slen
, i
);
977 /* Extract the contents of STRING as if it is enclosed in single quotes.
978 SINDEX, when passed in, is the offset of the character immediately
979 following the opening single quote; on exit, SINDEX is left pointing after
980 the closing single quote. */
982 string_extract_single_quoted (string
, sindex
)
991 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
992 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
994 while (string
[i
] && string
[i
] != '\'')
995 ADVANCE_CHAR (string
, slen
, i
);
997 t
= substring (string
, *sindex
, i
);
1007 skip_single_quoted (string
, slen
, sind
)
1016 while (string
[c
] && string
[c
] != '\'')
1017 ADVANCE_CHAR (string
, slen
, c
);
1024 /* Just like string_extract, but doesn't hack backslashes or any of
1025 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1027 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1035 #if defined (HANDLE_MULTIBYTE)
1043 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1045 temp
= string_extract_single_quoted (string
, sindex
);
1046 --*sindex
; /* leave *sindex at separator character */
1052 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1053 this only if MB_CUR_MAX > 1. */
1054 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1056 #if defined (HANDLE_MULTIBYTE)
1057 clen
= strlen (charlist
);
1060 while (c
= string
[i
])
1062 #if defined (HANDLE_MULTIBYTE)
1065 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1070 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1071 through, to protect the CTLNULs from later calls to
1072 remove_quoted_nulls. */
1073 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1079 #if defined (HANDLE_MULTIBYTE)
1080 mblength
= MBLEN (string
+ i
, slen
- i
);
1084 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1085 if (MB_INVALIDCH (mblength
))
1087 if (MEMBER (c
, charlist
))
1095 len
= mbstowcs (wcharlist
, charlist
, 0);
1098 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1099 mbstowcs (wcharlist
, charlist
, len
+ 1);
1102 if (wcschr (wcharlist
, wc
))
1108 if (MEMBER (c
, charlist
))
1111 ADVANCE_CHAR (string
, slen
, i
);
1114 #if defined (HANDLE_MULTIBYTE)
1118 temp
= substring (string
, *sindex
, i
);
1124 /* Extract the $( construct in STRING, and return a new string.
1125 Start extracting at (SINDEX) as if we had just seen "$(".
1126 Make (SINDEX) get the position of the matching ")". )
1127 XFLAGS is additional flags to pass to other extraction functions, */
1129 extract_command_subst (string
, sindex
, xflags
)
1134 if (string
[*sindex
] == '(') /*)*/
1135 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1138 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1139 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1143 /* Extract the $[ construct in STRING, and return a new string. (])
1144 Start extracting at (SINDEX) as if we had just seen "$[".
1145 Make (SINDEX) get the position of the matching "]". */
1147 extract_arithmetic_subst (string
, sindex
)
1151 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1154 #if defined (PROCESS_SUBSTITUTION)
1155 /* Extract the <( or >( construct in STRING, and return a new string.
1156 Start extracting at (SINDEX) as if we had just seen "<(".
1157 Make (SINDEX) get the position of the matching ")". */ /*))*/
1159 extract_process_subst (string
, starter
, sindex
)
1164 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", 0));
1166 #endif /* PROCESS_SUBSTITUTION */
1168 #if defined (ARRAY_VARS)
1169 /* This can be fooled by unquoted right parens in the passed string. If
1170 each caller verifies that the last character in STRING is a right paren,
1171 we don't even need to call extract_delimited_string. */
1173 extract_array_assignment_list (string
, sindex
)
1180 slen
= strlen (string
); /* ( */
1181 if (string
[slen
- 1] == ')')
1183 ret
= substring (string
, *sindex
, slen
- 1);
1191 /* Extract and create a new string from the contents of STRING, a
1192 character string delimited with OPENER and CLOSER. SINDEX is
1193 the address of an int describing the current offset in STRING;
1194 it should point to just after the first OPENER found. On exit,
1195 SINDEX gets the position of the last character of the matching CLOSER.
1196 If OPENER is more than a single character, ALT_OPENER, if non-null,
1197 contains a character string that can also match CLOSER and thus
1198 needs to be skipped. */
1200 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1203 char *opener
, *alt_opener
, *closer
;
1209 int pass_character
, nesting_level
, in_comment
;
1210 int len_closer
, len_opener
, len_alt_opener
;
1213 slen
= strlen (string
+ *sindex
) + *sindex
;
1214 len_opener
= STRLEN (opener
);
1215 len_alt_opener
= STRLEN (alt_opener
);
1216 len_closer
= STRLEN (closer
);
1218 pass_character
= in_comment
= 0;
1223 while (nesting_level
)
1234 ADVANCE_CHAR (string
, slen
, i
);
1238 if (pass_character
) /* previous char was backslash */
1241 ADVANCE_CHAR (string
, slen
, i
);
1245 /* Not exactly right yet; should handle shell metacharacters and
1246 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1247 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1250 ADVANCE_CHAR (string
, slen
, i
);
1254 if (c
== CTLESC
|| c
== '\\')
1261 /* Process a nested OPENER. */
1262 if (STREQN (string
+ i
, opener
, len_opener
))
1264 si
= i
+ len_opener
;
1265 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1270 /* Process a nested ALT_OPENER */
1271 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1273 si
= i
+ len_alt_opener
;
1274 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1279 /* If the current substring terminates the delimited string, decrement
1280 the nesting level. */
1281 if (STREQN (string
+ i
, closer
, len_closer
))
1283 i
+= len_closer
- 1; /* move to last byte of the closer */
1285 if (nesting_level
== 0)
1289 /* Pass old-style command substitution through verbatim. */
1293 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1298 /* Pass single-quoted and double-quoted strings through verbatim. */
1299 if (c
== '\'' || c
== '"')
1302 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1303 : skip_double_quoted (string
, slen
, si
);
1307 /* move past this character, which was not special. */
1308 ADVANCE_CHAR (string
, slen
, i
);
1311 if (c
== 0 && nesting_level
)
1313 if (no_longjmp_on_fatal_error
== 0)
1315 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1316 last_command_exit_value
= EXECUTION_FAILURE
;
1317 exp_jump_to_top_level (DISCARD
);
1322 return (char *)NULL
;
1326 si
= i
- *sindex
- len_closer
+ 1;
1327 if (flags
& SX_NOALLOC
)
1328 result
= (char *)NULL
;
1331 result
= (char *)xmalloc (1 + si
);
1332 strncpy (result
, string
+ *sindex
, si
);
1340 /* Extract a parameter expansion expression within ${ and } from STRING.
1341 Obey the Posix.2 rules for finding the ending `}': count braces while
1342 skipping over enclosed quoted strings and command substitutions.
1343 SINDEX is the address of an int describing the current offset in STRING;
1344 it should point to just after the first `{' found. On exit, SINDEX
1345 gets the position of the matching `}'. QUOTED is non-zero if this
1346 occurs inside double quotes. */
1347 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1349 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1351 int *sindex
, quoted
, flags
;
1355 int pass_character
, nesting_level
, si
;
1361 slen
= strlen (string
+ *sindex
) + *sindex
;
1364 while (c
= string
[i
])
1369 ADVANCE_CHAR (string
, slen
, i
);
1373 /* CTLESCs and backslashes quote the next character. */
1374 if (c
== CTLESC
|| c
== '\\')
1381 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1391 if (nesting_level
== 0)
1397 /* Pass the contents of old-style command substitutions through
1402 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1407 /* Pass the contents of new-style command substitutions and
1408 arithmetic substitutions through verbatim. */
1409 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1412 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1417 /* Pass the contents of single-quoted and double-quoted strings
1418 through verbatim. */
1419 if (c
== '\'' || c
== '"')
1422 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1423 : skip_double_quoted (string
, slen
, si
);
1424 /* skip_XXX_quoted leaves index one past close quote */
1428 /* move past this character, which was not special. */
1429 ADVANCE_CHAR (string
, slen
, i
);
1432 if (c
== 0 && nesting_level
)
1434 if (no_longjmp_on_fatal_error
== 0)
1436 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1437 last_command_exit_value
= EXECUTION_FAILURE
;
1438 exp_jump_to_top_level (DISCARD
);
1443 return ((char *)NULL
);
1447 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1453 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1454 STRING, and returns a pointer to it. */
1456 de_backslash (string
)
1459 register size_t slen
;
1460 register int i
, j
, prev_i
;
1463 slen
= strlen (string
);
1466 /* Loop copying string[i] to string[j], i >= j. */
1469 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1470 string
[i
+ 1] == '$'))
1473 ADVANCE_CHAR (string
, slen
, i
);
1475 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1486 /* Replace instances of \! in a string with !. */
1488 unquote_bang (string
)
1492 register char *temp
;
1494 temp
= (char *)xmalloc (1 + strlen (string
));
1496 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1498 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1504 strcpy (string
, temp
);
1509 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1511 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1512 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1513 matched pairs of quotes or backquotes, or skip word expansions; it is
1514 intended to be used after expansion has been performed and during final
1515 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1517 skip_matched_pair (string
, start
, open
, close
, flags
)
1519 int start
, open
, close
, flags
;
1521 int i
, pass_next
, backq
, si
, c
, count
;
1526 slen
= strlen (string
+ start
) + start
;
1527 no_longjmp_on_fatal_error
= 1;
1529 i
= start
+ 1; /* skip over leading bracket */
1531 pass_next
= backq
= 0;
1532 ss
= (char *)string
;
1533 while (c
= string
[i
])
1540 ADVANCE_CHAR (string
, slen
, i
);
1553 ADVANCE_CHAR (string
, slen
, i
);
1556 else if ((flags
& 1) == 0 && c
== '`')
1562 else if ((flags
& 1) == 0 && c
== open
)
1568 else if (c
== close
)
1576 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1578 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1579 : skip_double_quoted (ss
, slen
, ++i
);
1580 /* no increment, the skip functions increment past the closing quote. */
1582 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1585 if (string
[si
] == '\0')
1588 if (string
[i
+1] == LPAREN
)
1589 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1591 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1593 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1599 ADVANCE_CHAR (string
, slen
, i
);
1605 #if defined (ARRAY_VARS)
1607 skipsubscript (string
, start
, flags
)
1611 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1615 /* Skip characters in STRING until we find a character in DELIMS, and return
1616 the index of that character. START is the index into string at which we
1617 begin. This is similar in spirit to strpbrk, but it returns an index into
1618 STRING and takes a starting index. This little piece of code knows quite
1619 a lot of shell syntax. It's very similar to skip_double_quoted and other
1620 functions of that ilk. */
1622 skip_to_delim (string
, start
, delims
, flags
)
1628 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
;
1633 slen
= strlen (string
+ start
) + start
;
1634 if (flags
& SD_NOJMP
)
1635 no_longjmp_on_fatal_error
= 1;
1636 invert
= (flags
& SD_INVERT
);
1639 pass_next
= backq
= 0;
1640 while (c
= string
[i
])
1642 /* If this is non-zero, we should not let quote characters be delimiters
1643 and the current character is a single or double quote. We should not
1644 test whether or not it's a delimiter until after we skip single- or
1645 double-quoted strings. */
1646 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1652 ADVANCE_CHAR (string
, slen
, i
);
1665 ADVANCE_CHAR (string
, slen
, i
);
1674 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1676 else if (c
== '\'' || c
== '"')
1678 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1679 : skip_double_quoted (string
, slen
, ++i
);
1680 /* no increment, the skip functions increment past the closing quote. */
1682 else if (c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1685 if (string
[si
] == '\0')
1688 if (string
[i
+1] == LPAREN
)
1689 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1691 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1693 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1698 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1701 ADVANCE_CHAR (string
, slen
, i
);
1707 #if defined (READLINE)
1708 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1709 an unclosed quoted string), or if the character at EINDEX is quoted
1710 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1711 single and double-quoted string parsing functions should not return an
1712 error if there are unclosed quotes or braces. The characters that this
1713 recognizes need to be the same as the contents of
1714 rl_completer_quote_characters. */
1717 char_is_quoted (string
, eindex
)
1721 int i
, pass_next
, c
;
1725 slen
= strlen (string
);
1726 no_longjmp_on_fatal_error
= 1;
1735 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1737 ADVANCE_CHAR (string
, slen
, i
);
1746 else if (c
== '\'' || c
== '"')
1748 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1749 : skip_double_quoted (string
, slen
, ++i
);
1752 /* no increment, the skip_xxx functions go one past end */
1755 ADVANCE_CHAR (string
, slen
, i
);
1762 unclosed_pair (string
, eindex
, openstr
)
1767 int i
, pass_next
, openc
, olen
;
1771 slen
= strlen (string
);
1772 olen
= strlen (openstr
);
1773 i
= pass_next
= openc
= 0;
1779 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1781 ADVANCE_CHAR (string
, slen
, i
);
1784 else if (string
[i
] == '\\')
1790 else if (STREQN (string
+ i
, openstr
, olen
))
1795 else if (string
[i
] == '\'' || string
[i
] == '"')
1797 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1798 : skip_double_quoted (string
, slen
, i
);
1803 ADVANCE_CHAR (string
, slen
, i
);
1808 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1809 individual words. If DELIMS is NULL, the current value of $IFS is used
1810 to split the string, and the function follows the shell field splitting
1811 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1812 gets the number of words in the returned list. CWP, if non-NULL, gets
1813 the index of the word containing SENTINEL. Non-whitespace chars in
1814 DELIMS delimit separate fields. */
1816 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1820 int sentinel
, flags
;
1823 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1824 char *token
, *d
, *d2
;
1825 WORD_LIST
*ret
, *tl
;
1827 if (string
== 0 || *string
== '\0')
1833 return ((WORD_LIST
*)NULL
);
1836 d
= (delims
== 0) ? ifs_value
: delims
;
1837 ifs_split
= delims
== 0;
1839 /* Make d2 the non-whitespace characters in delims */
1844 #if defined (HANDLE_MULTIBYTE)
1845 size_t mblength
= 1;
1849 slength
= strlen (delims
);
1850 d2
= (char *)xmalloc (slength
+ 1);
1854 #if defined (HANDLE_MULTIBYTE)
1855 mbstate_t state_bak
;
1857 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1858 if (MB_INVALIDCH (mblength
))
1860 else if (mblength
> 1)
1862 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1865 slength
-= mblength
;
1869 if (whitespace (delims
[i
]) == 0)
1870 d2
[ts
++] = delims
[i
];
1878 ret
= (WORD_LIST
*)NULL
;
1880 /* Remove sequences of whitespace characters at the start of the string, as
1881 long as those characters are delimiters. */
1882 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1884 if (string
[i
] == '\0')
1890 dflags
= flags
|SD_NOJMP
;
1893 te
= skip_to_delim (string
, ts
, d
, dflags
);
1895 /* If we have a non-whitespace delimiter character, use it to make a
1896 separate field. This is just about what $IFS splitting does and
1897 is closer to the behavior of the shell parser. */
1898 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
1901 /* If we're using IFS splitting, the non-whitespace delimiter char
1902 and any additional IFS whitespace delimits a field. */
1904 while (member (string
[te
], d
) && spctabnl (string
[te
]))
1907 while (member (string
[te
], d2
))
1911 token
= substring (string
, ts
, te
);
1913 ret
= add_string_to_list (token
, ret
);
1917 if (sentinel
>= ts
&& sentinel
<= te
)
1920 /* If the cursor is at whitespace just before word start, set the
1921 sentinel word to the current word. */
1922 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
1925 /* If the cursor is at whitespace between two words, make a new, empty
1926 word, add it before (well, after, since the list is in reverse order)
1927 the word we just added, and set the current word to that one. */
1928 if (cwp
&& cw
== -1 && sentinel
< ts
)
1930 tl
= make_word_list (make_word (""), ret
->next
);
1936 if (string
[te
] == 0)
1940 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
1949 /* Special case for SENTINEL at the end of STRING. If we haven't found
1950 the word containing SENTINEL yet, and the index we're looking for is at
1951 the end of STRING (or past the end of the previously-found token,
1952 possible if the end of the line is composed solely of IFS whitespace)
1953 add an additional null argument and set the current word pointer to that. */
1954 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
1956 if (whitespace (string
[sentinel
- 1]))
1959 ret
= add_string_to_list (token
, ret
);
1970 return (REVERSE_LIST (ret
, WORD_LIST
*));
1972 #endif /* READLINE */
1976 /* Extract the name of the variable to bind to from the assignment string. */
1978 assignment_name (string
)
1984 offset
= assignment (string
, 0);
1986 return (char *)NULL
;
1987 temp
= substring (string
, 0, offset
);
1992 /* **************************************************************** */
1994 /* Functions to convert strings to WORD_LISTs and vice versa */
1996 /* **************************************************************** */
1998 /* Return a single string of all the words in LIST. SEP is the separator
1999 to put between individual elements of LIST in the output string. */
2001 string_list_internal (list
, sep
)
2005 register WORD_LIST
*t
;
2007 int word_len
, sep_len
, result_size
;
2010 return ((char *)NULL
);
2012 /* Short-circuit quickly if we don't need to separate anything. */
2013 if (list
->next
== 0)
2014 return (savestring (list
->word
->word
));
2016 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2017 sep_len
= STRLEN (sep
);
2020 for (t
= list
; t
; t
= t
->next
)
2023 result_size
+= sep_len
;
2024 result_size
+= strlen (t
->word
->word
);
2027 r
= result
= (char *)xmalloc (result_size
+ 1);
2029 for (t
= list
; t
; t
= t
->next
)
2031 if (t
!= list
&& sep_len
)
2035 FASTCOPY (sep
, r
, sep_len
);
2042 word_len
= strlen (t
->word
->word
);
2043 FASTCOPY (t
->word
->word
, r
, word_len
);
2051 /* Return a single string of all the words present in LIST, separating
2052 each word with a space. */
2057 return (string_list_internal (list
, " "));
2060 /* An external interface that can be used by the rest of the shell to
2061 obtain a string containing the first character in $IFS. Handles all
2062 the multibyte complications. If LENP is non-null, it is set to the
2063 length of the returned string. */
2065 ifs_firstchar (lenp
)
2071 ret
= xmalloc (MB_LEN_MAX
+ 1);
2072 #if defined (HANDLE_MULTIBYTE)
2073 if (ifs_firstc_len
== 1)
2075 ret
[0] = ifs_firstc
[0];
2077 len
= ret
[0] ? 1 : 0;
2081 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2082 ret
[len
= ifs_firstc_len
] = '\0';
2085 ret
[0] = ifs_firstc
;
2087 len
= ret
[0] ? 0 : 1;
2096 /* Return a single string of all the words present in LIST, obeying the
2097 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2098 expansion [of $*] appears within a double quoted string, it expands
2099 to a single field with the value of each parameter separated by the
2100 first character of the IFS variable, or by a <space> if IFS is unset." */
2102 string_list_dollar_star (list
)
2106 #if defined (HANDLE_MULTIBYTE)
2107 # if defined (__GNUC__)
2108 char sep
[MB_CUR_MAX
+ 1];
2116 #if defined (HANDLE_MULTIBYTE)
2117 # if !defined (__GNUC__)
2118 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2119 # endif /* !__GNUC__ */
2120 if (ifs_firstc_len
== 1)
2122 sep
[0] = ifs_firstc
[0];
2127 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2128 sep
[ifs_firstc_len
] = '\0';
2131 sep
[0] = ifs_firstc
;
2135 ret
= string_list_internal (list
, sep
);
2136 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2142 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2143 is non-zero, the $@ appears within double quotes, and we should quote
2144 the list before converting it into a string. If IFS is unset, and the
2145 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2146 in the words in the list, because the default value of $IFS is
2147 <space><tab><newline>, IFS characters in the words in the list should
2148 also be split. If IFS is null, and the word is not quoted, we need
2149 to quote the words in the list to preserve the positional parameters
2152 string_list_dollar_at (list
, quoted
)
2157 #if defined (HANDLE_MULTIBYTE)
2158 # if defined (__GNUC__)
2159 char sep
[MB_CUR_MAX
+ 1];
2162 # endif /* !__GNUC__ */
2168 /* XXX this could just be ifs = ifs_value; */
2169 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2171 #if defined (HANDLE_MULTIBYTE)
2172 # if !defined (__GNUC__)
2173 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2174 # endif /* !__GNUC__ */
2177 if (ifs_firstc_len
== 1)
2179 sep
[0] = ifs_firstc
[0];
2184 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2185 sep
[ifs_firstc_len
] = '\0';
2194 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2198 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2199 it now that quote_escapes quotes spaces */
2201 tlist
= ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (ifs
&& *ifs
== 0))
2203 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2206 : list_quote_escapes (list
);
2208 ret
= string_list_internal (tlist
, sep
);
2209 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2215 /* Turn the positional paramters into a string, understanding quoting and
2216 the various subtleties of using the first character of $IFS as the
2217 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2218 string_list as appropriate. */
2220 string_list_pos_params (pchar
, list
, quoted
)
2228 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2230 tlist
= quote_list (list
);
2231 word_list_remove_quoted_nulls (tlist
);
2232 ret
= string_list_dollar_star (tlist
);
2234 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2236 tlist
= quote_list (list
);
2237 word_list_remove_quoted_nulls (tlist
);
2238 ret
= string_list (tlist
);
2240 else if (pchar
== '*')
2242 /* Even when unquoted, string_list_dollar_star does the right thing
2243 making sure that the first character of $IFS is used as the
2245 ret
= string_list_dollar_star (list
);
2247 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2248 /* We use string_list_dollar_at, but only if the string is quoted, since
2249 that quotes the escapes if it's not, which we don't want. We could
2250 use string_list (the old code did), but that doesn't do the right
2251 thing if the first character of $IFS is not a space. We use
2252 string_list_dollar_star if the string is unquoted so we make sure that
2253 the elements of $@ are separated by the first character of $IFS for
2255 ret
= string_list_dollar_at (list
, quoted
);
2256 else if (pchar
== '@')
2257 ret
= string_list_dollar_star (list
);
2259 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2264 /* Return the list of words present in STRING. Separate the string into
2265 words at any of the characters found in SEPARATORS. If QUOTED is
2266 non-zero then word in the list will have its quoted flag set, otherwise
2267 the quoted flag is left as make_word () deemed fit.
2269 This obeys the P1003.2 word splitting semantics. If `separators' is
2270 exactly <space><tab><newline>, then the splitting algorithm is that of
2271 the Bourne shell, which treats any sequence of characters from `separators'
2272 as a delimiter. If IFS is unset, which results in `separators' being set
2273 to "", no splitting occurs. If separators has some other value, the
2274 following rules are applied (`IFS white space' means zero or more
2275 occurrences of <space>, <tab>, or <newline>, as long as those characters
2276 are in `separators'):
2278 1) IFS white space is ignored at the start and the end of the
2280 2) Each occurrence of a character in `separators' that is not
2281 IFS white space, along with any adjacent occurrences of
2282 IFS white space delimits a field.
2283 3) Any nonzero-length sequence of IFS white space delimits a field.
2286 /* BEWARE! list_string strips null arguments. Don't call it twice and
2287 expect to have "" preserved! */
2289 /* This performs word splitting and quoted null character removal on
2292 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2293 : (c) == (separators)[0]) \
2297 list_string (string
, separators
, quoted
)
2298 register char *string
, *separators
;
2303 char *current_word
, *s
;
2304 int sindex
, sh_style_split
, whitesep
, xflags
;
2307 if (!string
|| !*string
)
2308 return ((WORD_LIST
*)NULL
);
2310 sh_style_split
= separators
&& separators
[0] == ' ' &&
2311 separators
[1] == '\t' &&
2312 separators
[2] == '\n' &&
2313 separators
[3] == '\0';
2314 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2316 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2317 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2321 /* Remove sequences of whitespace at the beginning of STRING, as
2322 long as those characters appear in IFS. Do not do this if
2323 STRING is quoted or if there are no separator characters. */
2324 if (!quoted
|| !separators
|| !*separators
)
2326 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2329 return ((WORD_LIST
*)NULL
);
2334 /* OK, now STRING points to a word that does not begin with white space.
2335 The splitting algorithm is:
2336 extract a word, stopping at a separator
2337 skip sequences of spc, tab, or nl as long as they are separators
2338 This obeys the field splitting rules in Posix.2. */
2339 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2340 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2342 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2343 unless multibyte chars are possible. */
2344 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2345 if (current_word
== 0)
2348 /* If we have a quoted empty string, add a quoted null argument. We
2349 want to preserve the quoted null character iff this is a quoted
2350 empty string; otherwise the quoted null characters are removed
2352 if (QUOTED_NULL (current_word
))
2354 t
= alloc_word_desc ();
2355 t
->word
= make_quoted_char ('\0');
2356 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2357 result
= make_word_list (t
, result
);
2359 else if (current_word
[0] != '\0')
2361 /* If we have something, then add it regardless. However,
2362 perform quoted null character removal on the current word. */
2363 remove_quoted_nulls (current_word
);
2364 result
= add_string_to_list (current_word
, result
);
2365 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2366 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2367 result
->word
->flags
|= W_QUOTED
;
2370 /* If we're not doing sequences of separators in the traditional
2371 Bourne shell style, then add a quoted null argument. */
2372 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2374 t
= alloc_word_desc ();
2375 t
->word
= make_quoted_char ('\0');
2376 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2377 result
= make_word_list (t
, result
);
2380 free (current_word
);
2382 /* Note whether or not the separator is IFS whitespace, used later. */
2383 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2385 /* Move past the current separator character. */
2389 ADVANCE_CHAR (string
, slen
, sindex
);
2392 /* Now skip sequences of space, tab, or newline characters if they are
2393 in the list of separators. */
2394 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2397 /* If the first separator was IFS whitespace and the current character
2398 is a non-whitespace IFS character, it should be part of the current
2399 field delimiter, not a separate delimiter that would result in an
2400 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2401 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2404 /* An IFS character that is not IFS white space, along with any
2405 adjacent IFS white space, shall delimit a field. (SUSv3) */
2406 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2410 return (REVERSE_LIST (result
, WORD_LIST
*));
2413 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2414 ENDPTR is set to the first character after the word. This is used by
2415 the `read' builtin. This is never called with SEPARATORS != $IFS;
2416 it should be simplified.
2418 XXX - this function is very similar to list_string; they should be
2421 get_word_from_string (stringp
, separators
, endptr
)
2422 char **stringp
, *separators
, **endptr
;
2426 int sindex
, sh_style_split
, whitesep
, xflags
;
2429 if (!stringp
|| !*stringp
|| !**stringp
)
2430 return ((char *)NULL
);
2432 sh_style_split
= separators
&& separators
[0] == ' ' &&
2433 separators
[1] == '\t' &&
2434 separators
[2] == '\n' &&
2435 separators
[3] == '\0';
2436 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2438 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2439 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2445 /* Remove sequences of whitespace at the beginning of STRING, as
2446 long as those characters appear in IFS. */
2447 if (sh_style_split
|| !separators
|| !*separators
)
2449 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2451 /* If the string is nothing but whitespace, update it and return. */
2457 return ((char *)NULL
);
2461 /* OK, S points to a word that does not begin with white space.
2462 Now extract a word, stopping at a separator, save a pointer to
2463 the first character after the word, then skip sequences of spc,
2464 tab, or nl as long as they are separators.
2466 This obeys the field splitting rules in Posix.2. */
2468 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2469 unless multibyte chars are possible. */
2470 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2471 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2473 /* Set ENDPTR to the first character after the end of the word. */
2475 *endptr
= s
+ sindex
;
2477 /* Note whether or not the separator is IFS whitespace, used later. */
2478 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2480 /* Move past the current separator character. */
2484 ADVANCE_CHAR (s
, slen
, sindex
);
2487 /* Now skip sequences of space, tab, or newline characters if they are
2488 in the list of separators. */
2489 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2492 /* If the first separator was IFS whitespace and the current character is
2493 a non-whitespace IFS character, it should be part of the current field
2494 delimiter, not a separate delimiter that would result in an empty field.
2495 Look at POSIX.2, 3.6.5, (3)(b). */
2496 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2499 /* An IFS character that is not IFS white space, along with any adjacent
2500 IFS white space, shall delimit a field. */
2501 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2505 /* Update STRING to point to the next field. */
2506 *stringp
= s
+ sindex
;
2507 return (current_word
);
2510 /* Remove IFS white space at the end of STRING. Start at the end
2511 of the string and walk backwards until the beginning of the string
2512 or we find a character that's not IFS white space and not CTLESC.
2513 Only let CTLESC escape a white space character if SAW_ESCAPE is
2516 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2517 char *string
, *separators
;
2522 s
= string
+ STRLEN (string
) - 1;
2523 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2524 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2532 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2533 backslashes, single and double quotes. */
2535 list_string_with_quotes (string
)
2541 int c
, i
, tokstart
, len
;
2543 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2545 if (s
== 0 || *s
== 0)
2546 return ((WORD_LIST
*)NULL
);
2550 list
= (WORD_LIST
*)NULL
;
2561 i
= skip_single_quoted (s
, s_len
, ++i
);
2563 i
= skip_double_quoted (s
, s_len
, ++i
);
2564 else if (c
== 0 || spctabnl (c
))
2566 /* We have found the end of a token. Make a word out of it and
2567 add it to the word list. */
2568 token
= substring (s
, tokstart
, i
);
2569 list
= add_string_to_list (token
, list
);
2571 while (spctabnl (s
[i
]))
2579 i
++; /* normal character */
2581 return (REVERSE_LIST (list
, WORD_LIST
*));
2585 /********************************************************/
2587 /* Functions to perform assignment statements */
2589 /********************************************************/
2591 #if defined (ARRAY_VARS)
2593 do_compound_assignment (name
, value
, flags
)
2598 int mklocal
, mkassoc
;
2601 mklocal
= flags
& ASS_MKLOCAL
;
2602 mkassoc
= flags
& ASS_MKASSOC
;
2604 if (mklocal
&& variable_context
)
2606 v
= find_variable (name
);
2607 list
= expand_compound_array_assignment (v
, value
, flags
);
2609 v
= make_local_assoc_variable (name
);
2610 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2611 v
= make_local_array_variable (name
);
2612 assign_compound_array_list (v
, list
, flags
);
2615 v
= assign_array_from_string (name
, value
, flags
);
2621 /* Given STRING, an assignment string, get the value of the right side
2622 of the `=', and bind it to the left side. If EXPAND is true, then
2623 perform parameter expansion, command substitution, and arithmetic
2624 expansion on the right-hand side. Perform tilde expansion in any
2625 case. Do not perform word splitting on the result of expansion. */
2627 do_assignment_internal (word
, expand
)
2628 const WORD_DESC
*word
;
2631 int offset
, tlen
, appendop
, assign_list
, aflags
, retval
;
2634 #if defined (ARRAY_VARS)
2640 if (word
== 0 || word
->word
== 0)
2643 appendop
= assign_list
= aflags
= 0;
2644 string
= word
->word
;
2645 offset
= assignment (string
, 0);
2646 name
= savestring (string
);
2647 value
= (char *)NULL
;
2649 if (name
[offset
] == '=')
2653 if (name
[offset
- 1] == '+')
2656 name
[offset
- 1] = '\0';
2659 name
[offset
] = 0; /* might need this set later */
2660 temp
= name
+ offset
+ 1;
2661 tlen
= STRLEN (temp
);
2663 #if defined (ARRAY_VARS)
2664 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2666 assign_list
= ni
= 1;
2667 value
= extract_array_assignment_list (temp
, &ni
);
2671 if (expand
&& temp
[0])
2672 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2674 value
= savestring (temp
);
2679 value
= (char *)xmalloc (1);
2683 if (echo_command_at_execute
)
2686 name
[offset
- 1] = '+';
2687 xtrace_print_assignment (name
, value
, assign_list
, 1);
2689 name
[offset
- 1] = '\0';
2692 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2695 aflags
|= ASS_APPEND
;
2697 #if defined (ARRAY_VARS)
2698 if (t
= mbschr (name
, '[')) /*]*/
2702 report_error (_("%s: cannot assign list to array member"), name
);
2705 entry
= assign_array_element (name
, value
, aflags
);
2709 else if (assign_list
)
2711 if (word
->flags
& W_ASSIGNARG
)
2712 aflags
|= ASS_MKLOCAL
;
2713 if (word
->flags
& W_ASSIGNASSOC
)
2714 aflags
|= ASS_MKASSOC
;
2715 entry
= do_compound_assignment (name
, value
, aflags
);
2718 #endif /* ARRAY_VARS */
2719 entry
= bind_variable (name
, value
, aflags
);
2721 stupidly_hack_special_variables (name
);
2724 /* Return 1 if the assignment seems to have been performed correctly. */
2725 if (entry
== 0 || readonly_p (entry
))
2726 retval
= 0; /* assignment failure */
2727 else if (noassign_p (entry
))
2729 last_command_exit_value
= EXECUTION_FAILURE
;
2730 retval
= 1; /* error status, but not assignment failure */
2735 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2736 VUNSETATTR (entry
, att_invisible
);
2738 ASSIGN_RETURN (retval
);
2741 VUNSETATTR (entry
, att_invisible
);
2743 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2747 /* Perform the assignment statement in STRING, and expand the
2748 right side by doing tilde, command and parameter expansion. */
2750 do_assignment (string
)
2755 td
.flags
= W_ASSIGNMENT
;
2758 return do_assignment_internal (&td
, 1);
2762 do_word_assignment (word
)
2765 return do_assignment_internal (word
, 1);
2768 /* Given STRING, an assignment string, get the value of the right side
2769 of the `=', and bind it to the left side. Do not perform any word
2770 expansions on the right hand side. */
2772 do_assignment_no_expand (string
)
2777 td
.flags
= W_ASSIGNMENT
;
2780 return (do_assignment_internal (&td
, 0));
2783 /***************************************************
2785 * Functions to manage the positional parameters *
2787 ***************************************************/
2789 /* Return the word list that corresponds to `$*'. */
2791 list_rest_of_args ()
2793 register WORD_LIST
*list
, *args
;
2796 /* Break out of the loop as soon as one of the dollar variables is null. */
2797 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2798 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2800 for (args
= rest_of_args
; args
; args
= args
->next
)
2801 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2803 return (REVERSE_LIST (list
, WORD_LIST
*));
2809 register WORD_LIST
*list
;
2812 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2814 for (list
= rest_of_args
; list
; list
= list
->next
)
2819 /* Return the value of a positional parameter. This handles values > 10. */
2821 get_dollar_var_value (ind
)
2828 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2829 else /* We want something like ${11} */
2832 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2834 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2839 /* Make a single large string out of the dollar digit variables,
2840 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2841 case of "$*" with respect to IFS. */
2843 string_rest_of_args (dollar_star
)
2846 register WORD_LIST
*list
;
2849 list
= list_rest_of_args ();
2850 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2851 dispose_words (list
);
2855 /* Return a string containing the positional parameters from START to
2856 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2857 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2858 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2859 no quoting chars are added. */
2861 pos_params (string
, start
, end
, quoted
)
2863 int start
, end
, quoted
;
2865 WORD_LIST
*save
, *params
, *h
, *t
;
2869 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2871 return ((char *)NULL
);
2873 save
= params
= list_rest_of_args ();
2875 return ((char *)NULL
);
2877 if (start
== 0) /* handle ${@:0[:x]} specially */
2879 t
= make_word_list (make_word (dollar_vars
[0]), params
);
2883 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
2884 params
= params
->next
;
2886 return ((char *)NULL
);
2887 for (h
= t
= params
; params
&& i
< end
; i
++)
2890 params
= params
->next
;
2893 t
->next
= (WORD_LIST
*)NULL
;
2895 ret
= string_list_pos_params (string
[0], h
, quoted
);
2900 dispose_words (save
);
2904 /******************************************************************/
2906 /* Functions to expand strings to strings or WORD_LISTs */
2908 /******************************************************************/
2910 #if defined (PROCESS_SUBSTITUTION)
2911 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2913 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2916 /* If there are any characters in STRING that require full expansion,
2917 then call FUNC to expand STRING; otherwise just perform quote
2918 removal if necessary. This returns a new string. */
2920 expand_string_if_necessary (string
, quoted
, func
)
2931 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2932 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
2936 if (EXP_CHAR (string
[i
]))
2938 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
2940 ADVANCE_CHAR (string
, slen
, i
);
2945 list
= (*func
) (string
, quoted
);
2948 ret
= string_list (list
);
2949 dispose_words (list
);
2954 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
2955 ret
= string_quote_removal (string
, quoted
);
2957 ret
= savestring (string
);
2962 static inline char *
2963 expand_string_to_string_internal (string
, quoted
, func
)
2971 if (string
== 0 || *string
== '\0')
2972 return ((char *)NULL
);
2974 list
= (*func
) (string
, quoted
);
2977 ret
= string_list (list
);
2978 dispose_words (list
);
2987 expand_string_to_string (string
, quoted
)
2991 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
2995 expand_string_unsplit_to_string (string
, quoted
)
2999 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3003 expand_assignment_string_to_string (string
, quoted
)
3007 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3011 expand_arith_string (string
, quoted
)
3015 return (expand_string_if_necessary (string
, quoted
, expand_string
));
3018 #if defined (COND_COMMAND)
3019 /* Just remove backslashes in STRING. Returns a new string. */
3021 remove_backslashes (string
)
3026 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3027 for (s
= string
; s
&& *s
; )
3039 /* This needs better error handling. */
3040 /* Expand W for use as an argument to a unary or binary operator in a
3041 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3042 to the != or == operator, and should be treated as a pattern. In
3043 this case, we quote the string specially for the globbing code. If
3044 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3045 be quoted appropriately for regcomp/regexec. The caller is responsible
3046 for removing the backslashes if the unquoted word is needed later. */
3048 cond_expand_word (w
, special
)
3056 if (w
->word
== 0 || w
->word
[0] == '\0')
3057 return ((char *)NULL
);
3059 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3065 r
= string_list (l
);
3069 qflags
= QGLOB_CVTNULL
;
3071 qflags
|= QGLOB_REGEXP
;
3072 p
= string_list (l
);
3073 r
= quote_string_for_globbing (p
, qflags
);
3085 /* Call expand_word_internal to expand W and handle error returns.
3086 A convenience function for functions that don't want to handle
3087 any errors or free any memory before aborting. */
3089 call_expand_word_internal (w
, q
, i
, c
, e
)
3095 result
= expand_word_internal (w
, q
, i
, c
, e
);
3096 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3098 /* By convention, each time this error is returned, w->word has
3099 already been freed (it sometimes may not be in the fatal case,
3100 but that doesn't result in a memory leak because we're going
3101 to exit in most cases). */
3102 w
->word
= (char *)NULL
;
3103 last_command_exit_value
= EXECUTION_FAILURE
;
3104 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3111 /* Perform parameter expansion, command substitution, and arithmetic
3112 expansion on STRING, as if it were a word. Leave the result quoted. */
3114 expand_string_internal (string
, quoted
)
3121 if (string
== 0 || *string
== 0)
3122 return ((WORD_LIST
*)NULL
);
3125 td
.word
= savestring (string
);
3127 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3133 /* Expand STRING by performing parameter expansion, command substitution,
3134 and arithmetic expansion. Dequote the resulting WORD_LIST before
3135 returning it, but do not perform word splitting. The call to
3136 remove_quoted_nulls () is in here because word splitting normally
3137 takes care of quote removal. */
3139 expand_string_unsplit (string
, quoted
)
3145 if (string
== 0 || *string
== '\0')
3146 return ((WORD_LIST
*)NULL
);
3148 expand_no_split_dollar_star
= 1;
3149 value
= expand_string_internal (string
, quoted
);
3150 expand_no_split_dollar_star
= 0;
3156 remove_quoted_nulls (value
->word
->word
);
3157 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3159 dequote_list (value
);
3164 /* Expand the rhs of an assignment statement */
3166 expand_string_assignment (string
, quoted
)
3173 if (string
== 0 || *string
== '\0')
3174 return ((WORD_LIST
*)NULL
);
3176 expand_no_split_dollar_star
= 1;
3178 td
.flags
= W_ASSIGNRHS
;
3179 td
.word
= savestring (string
);
3180 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3183 expand_no_split_dollar_star
= 0;
3189 remove_quoted_nulls (value
->word
->word
);
3190 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3192 dequote_list (value
);
3198 /* Expand one of the PS? prompt strings. This is a sort of combination of
3199 expand_string_unsplit and expand_string_internal, but returns the
3200 passed string when an error occurs. Might want to trap other calls
3201 to jump_to_top_level here so we don't endlessly loop. */
3203 expand_prompt_string (string
, quoted
, wflags
)
3211 if (string
== 0 || *string
== 0)
3212 return ((WORD_LIST
*)NULL
);
3215 td
.word
= savestring (string
);
3217 no_longjmp_on_fatal_error
= 1;
3218 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3219 no_longjmp_on_fatal_error
= 0;
3221 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3223 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3231 remove_quoted_nulls (value
->word
->word
);
3232 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3234 dequote_list (value
);
3239 /* Expand STRING just as if you were expanding a word, but do not dequote
3240 the resultant WORD_LIST. This is called only from within this file,
3241 and is used to correctly preserve quoted characters when expanding
3242 things like ${1+"$@"}. This does parameter expansion, command
3243 substitution, arithmetic expansion, and word splitting. */
3245 expand_string_leave_quoted (string
, quoted
)
3252 if (string
== 0 || *string
== '\0')
3253 return ((WORD_LIST
*)NULL
);
3255 tlist
= expand_string_internal (string
, quoted
);
3259 tresult
= word_list_split (tlist
);
3260 dispose_words (tlist
);
3263 return ((WORD_LIST
*)NULL
);
3266 /* This does not perform word splitting or dequote the WORD_LIST
3269 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3271 int quoted
, *dollar_at_p
, *has_dollar_at
;
3276 if (string
== 0 || *string
== '\0')
3277 return (WORD_LIST
*)NULL
;
3281 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3285 /* Expand STRING just as if you were expanding a word. This also returns
3286 a list of words. Note that filename globbing is *NOT* done for word
3287 or string expansion, just when the shell is expanding a command. This
3288 does parameter expansion, command substitution, arithmetic expansion,
3289 and word splitting. Dequote the resultant WORD_LIST before returning. */
3291 expand_string (string
, quoted
)
3297 if (string
== 0 || *string
== '\0')
3298 return ((WORD_LIST
*)NULL
);
3300 result
= expand_string_leave_quoted (string
, quoted
);
3301 return (result
? dequote_list (result
) : result
);
3304 /***************************************************
3306 * Functions to handle quoting chars *
3308 ***************************************************/
3312 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3313 The parser passes CTLNUL as CTLESC CTLNUL. */
3315 /* Quote escape characters in string s, but no other characters. This is
3316 used to protect CTLESC and CTLNUL in variable values from the rest of
3317 the word expansion process after the variable is expanded (word splitting
3318 and filename generation). If IFS is null, we quote spaces as well, just
3319 in case we split on spaces later (in the case of unquoted $@, we will
3320 eventually attempt to split the entire word on spaces). Corresponding
3321 code exists in dequote_escapes. Even if we don't end up splitting on
3322 spaces, quoting spaces is not a problem. This should never be called on
3323 a string that is quoted with single or double quotes or part of a here
3324 document (effectively double-quoted). */
3326 quote_escapes (string
)
3329 register char *s
, *t
;
3331 char *result
, *send
;
3332 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3335 slen
= strlen (string
);
3336 send
= string
+ slen
;
3338 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3340 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3341 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3343 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3348 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3350 COPY_CHAR_P (t
, s
, send
);
3357 list_quote_escapes (list
)
3360 register WORD_LIST
*w
;
3363 for (w
= list
; w
; w
= w
->next
)
3366 w
->word
->word
= quote_escapes (t
);
3372 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3374 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3375 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3376 data stream pass through properly.
3378 We need to remove doubled CTLESC characters inside quoted strings before
3379 quoting the entire string, so we do not double the number of CTLESC
3382 Also used by parts of the pattern substitution code. */
3384 dequote_escapes (string
)
3387 register char *s
, *t
, *s1
;
3389 char *result
, *send
;
3396 slen
= strlen (string
);
3397 send
= string
+ slen
;
3399 t
= result
= (char *)xmalloc (slen
+ 1);
3401 if (strchr (string
, CTLESC
) == 0)
3402 return (strcpy (result
, string
));
3404 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3409 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3415 COPY_CHAR_P (t
, s
, send
);
3421 /* Return a new string with the quoted representation of character C.
3422 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3423 set in any resultant WORD_DESC where this value is the word. */
3425 make_quoted_char (c
)
3430 temp
= (char *)xmalloc (3);
3445 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3446 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3447 this value is the word. */
3449 quote_string (string
)
3454 char *result
, *send
;
3458 result
= (char *)xmalloc (2);
3466 slen
= strlen (string
);
3467 send
= string
+ slen
;
3469 result
= (char *)xmalloc ((slen
* 2) + 1);
3471 for (t
= result
; string
< send
; )
3474 COPY_CHAR_P (t
, string
, send
);
3481 /* De-quote quoted characters in STRING. */
3483 dequote_string (string
)
3486 register char *s
, *t
;
3488 char *result
, *send
;
3491 slen
= strlen (string
);
3493 t
= result
= (char *)xmalloc (slen
+ 1);
3495 if (QUOTED_NULL (string
))
3501 /* If no character in the string can be quoted, don't bother examining
3502 each character. Just return a copy of the string passed to us. */
3503 if (strchr (string
, CTLESC
) == NULL
)
3504 return (strcpy (result
, string
));
3506 send
= string
+ slen
;
3516 COPY_CHAR_P (t
, s
, send
);
3523 /* Quote the entire WORD_LIST list. */
3528 register WORD_LIST
*w
;
3531 for (w
= list
; w
; w
= w
->next
)
3534 w
->word
->word
= quote_string (t
);
3536 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3537 w
->word
->flags
|= W_QUOTED
;
3543 /* De-quote quoted characters in each word in LIST. */
3549 register WORD_LIST
*tlist
;
3551 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3553 s
= dequote_string (tlist
->word
->word
);
3554 if (QUOTED_NULL (tlist
->word
->word
))
3555 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3556 free (tlist
->word
->word
);
3557 tlist
->word
->word
= s
;
3562 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3565 remove_quoted_escapes (string
)
3572 t
= dequote_escapes (string
);
3580 /* Perform quoted null character removal on STRING. We don't allow any
3581 quoted null characters in the middle or at the ends of strings because
3582 of how expand_word_internal works. remove_quoted_nulls () turns
3583 STRING into an empty string iff it only consists of a quoted null,
3584 and removes all unquoted CTLNUL characters. */
3586 remove_quoted_nulls (string
)
3589 register size_t slen
;
3590 register int i
, j
, prev_i
;
3593 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3594 return string
; /* XXX */
3596 slen
= strlen (string
);
3601 if (string
[i
] == CTLESC
)
3603 /* Old code had j++, but we cannot assume that i == j at this
3604 point -- what if a CTLNUL has already been removed from the
3605 string? We don't want to drop the CTLESC or recopy characters
3606 that we've already copied down. */
3607 i
++; string
[j
++] = CTLESC
;
3611 else if (string
[i
] == CTLNUL
)
3615 ADVANCE_CHAR (string
, slen
, i
);
3618 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3628 /* Perform quoted null character removal on each element of LIST.
3629 This modifies LIST. */
3631 word_list_remove_quoted_nulls (list
)
3634 register WORD_LIST
*t
;
3636 for (t
= list
; t
; t
= t
->next
)
3638 remove_quoted_nulls (t
->word
->word
);
3639 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3643 /* **************************************************************** */
3645 /* Functions for Matching and Removing Patterns */
3647 /* **************************************************************** */
3649 #if defined (HANDLE_MULTIBYTE)
3650 #if 0 /* Currently unused */
3651 static unsigned char *
3652 mb_getcharlens (string
, len
)
3656 int i
, offset
, last
;
3663 ret
= (unsigned char *)xmalloc (len
);
3664 memset (ret
, 0, len
);
3665 while (string
[last
])
3667 ADVANCE_CHAR (string
, len
, offset
);
3668 ret
[last
] = offset
- last
;
3676 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3677 can have one of 4 values:
3678 RP_LONG_LEFT remove longest matching portion at start of PARAM
3679 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3680 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3681 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3684 #define RP_LONG_LEFT 1
3685 #define RP_SHORT_LEFT 2
3686 #define RP_LONG_RIGHT 3
3687 #define RP_SHORT_RIGHT 4
3690 remove_upattern (param
, pattern
, op
)
3691 char *param
, *pattern
;
3696 register char *p
, *ret
, c
;
3698 len
= STRLEN (param
);
3703 case RP_LONG_LEFT
: /* remove longest match at start */
3704 for (p
= end
; p
>= param
; p
--)
3707 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3710 return (savestring (p
));
3717 case RP_SHORT_LEFT
: /* remove shortest match at start */
3718 for (p
= param
; p
<= end
; p
++)
3721 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3724 return (savestring (p
));
3730 case RP_LONG_RIGHT
: /* remove longest match at end */
3731 for (p
= param
; p
<= end
; p
++)
3733 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3736 ret
= savestring (param
);
3743 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3744 for (p
= end
; p
>= param
; p
--)
3746 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3749 ret
= savestring (param
);
3757 return (savestring (param
)); /* no match, return original string */
3760 #if defined (HANDLE_MULTIBYTE)
3762 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3773 case RP_LONG_LEFT
: /* remove longest match at start */
3774 for (n
= wstrlen
; n
>= 0; n
--)
3776 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3777 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3780 return (wcsdup (wparam
+ n
));
3786 case RP_SHORT_LEFT
: /* remove shortest match at start */
3787 for (n
= 0; n
<= wstrlen
; n
++)
3789 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3790 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3793 return (wcsdup (wparam
+ n
));
3799 case RP_LONG_RIGHT
: /* remove longest match at end */
3800 for (n
= 0; n
<= wstrlen
; n
++)
3802 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3804 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3805 ret
= wcsdup (wparam
);
3812 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3813 for (n
= wstrlen
; n
>= 0; n
--)
3815 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3817 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3818 ret
= wcsdup (wparam
);
3826 return (wcsdup (wparam
)); /* no match, return original string */
3828 #endif /* HANDLE_MULTIBYTE */
3831 remove_pattern (param
, pattern
, op
)
3832 char *param
, *pattern
;
3837 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3838 return (savestring (param
));
3840 #if defined (HANDLE_MULTIBYTE)
3843 wchar_t *ret
, *oret
;
3845 wchar_t *wparam
, *wpattern
;
3849 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3850 if (n
== (size_t)-1)
3851 return (remove_upattern (param
, pattern
, op
));
3852 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3853 if (n
== (size_t)-1)
3856 return (remove_upattern (param
, pattern
, op
));
3858 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3864 xret
= (char *)xmalloc (n
+ 1);
3865 memset (&ps
, '\0', sizeof (mbstate_t));
3866 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3867 xret
[n
] = '\0'; /* just to make sure */
3873 return (remove_upattern (param
, pattern
, op
));
3876 /* Return 1 of the first character of STRING could match the first
3877 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3879 match_pattern_char (pat
, string
)
3890 return (*string
== c
);
3892 return (*string
== *pat
);
3894 return (*pat
== LPAREN
? 1 : (*string
!= '\0'));
3900 return (*pat
== LPAREN
? 1 : (*string
== c
));
3902 return (*string
!= '\0');
3906 /* Match PAT anywhere in STRING and return the match boundaries.
3907 This returns 1 in case of a successful match, 0 otherwise. SP
3908 and EP are pointers into the string where the match begins and
3909 ends, respectively. MTYPE controls what kind of match is attempted.
3910 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3911 of the string, respectively. The longest match is returned. */
3913 match_upattern (string
, pat
, mtype
, sp
, ep
)
3919 register char *p
, *p1
, *npat
;
3922 /* If the pattern doesn't match anywhere in the string, go ahead and
3923 short-circuit right away. A minor optimization, saves a bunch of
3924 unnecessary calls to strmatch (up to N calls for a string of N
3925 characters) if the match is unsuccessful. To preserve the semantics
3926 of the substring matches below, we make sure that the pattern has
3927 `*' as first and last character, making a new pattern if necessary. */
3928 /* XXX - check this later if I ever implement `**' with special meaning,
3929 since this will potentially result in `**' at the beginning or end */
3931 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == '(' && extended_glob
) || pat
[len
- 1] != '*') /*)*/
3933 p
= npat
= (char *)xmalloc (len
+ 3);
3935 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == '(' && extended_glob
)) /*)*/
3939 if (p1
[-1] != '*' || p
[-2] == '\\')
3945 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
3948 if (c
== FNM_NOMATCH
)
3951 len
= STRLEN (string
);
3957 for (p
= string
; p
<= end
; p
++)
3959 if (match_pattern_char (pat
, p
))
3961 for (p1
= end
; p1
>= p
; p1
--)
3963 c
= *p1
; *p1
= '\0';
3964 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3979 if (match_pattern_char (pat
, string
) == 0)
3982 for (p
= end
; p
>= string
; p
--)
3985 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
3998 for (p
= string
; p
<= end
; p
++)
4000 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4015 #if defined (HANDLE_MULTIBYTE)
4016 /* Return 1 of the first character of WSTRING could match the first
4017 character of pattern WPAT. Wide character version. */
4019 match_pattern_wchar (wpat
, wstring
)
4020 wchar_t *wpat
, *wstring
;
4027 switch (wc
= *wpat
++)
4030 return (*wstring
== wc
);
4032 return (*wstring
== *wpat
);
4034 return (*wpat
== LPAREN
? 1 : (*wstring
!= L
'\0'));
4040 return (*wpat
== LPAREN
? 1 : (*wstring
== wc
));
4042 return (*wstring
!= L
'\0');
4046 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4047 This returns 1 in case of a successful match, 0 otherwise. Wide
4048 character version. */
4050 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4058 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4061 size_t n
, n1
; /* Apple's gcc seems to miscompile this badly */
4066 /* If the pattern doesn't match anywhere in the string, go ahead and
4067 short-circuit right away. A minor optimization, saves a bunch of
4068 unnecessary calls to strmatch (up to N calls for a string of N
4069 characters) if the match is unsuccessful. To preserve the semantics
4070 of the substring matches below, we make sure that the pattern has
4071 `*' as first and last character, making a new pattern if necessary. */
4072 /* XXX - check this later if I ever implement `**' with special meaning,
4073 since this will potentially result in `**' at the beginning or end */
4074 len
= wcslen (wpat
);
4075 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == L
'(' && extended_glob
) || wpat
[len
- 1] != L
'*') /*)*/
4077 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4079 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == '(' && extended_glob
)) /*)*/
4081 while (*wp1
!= L
'\0')
4083 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4089 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
4092 if (len
== FNM_NOMATCH
)
4098 for (n
= 0; n
<= wstrlen
; n
++)
4100 if (match_pattern_wchar (wpat
, wstring
+ n
))
4102 for (n1
= wstrlen
; n1
>= n
; n1
--)
4104 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4105 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4120 if (match_pattern_wchar (wpat
, wstring
) == 0)
4123 for (n
= wstrlen
; n
>= 0; n
--)
4125 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4126 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
4139 for (n
= 0; n
<= wstrlen
; n
++)
4141 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4144 *ep
= indices
[wstrlen
];
4154 #endif /* HANDLE_MULTIBYTE */
4157 match_pattern (string
, pat
, mtype
, sp
, ep
)
4162 #if defined (HANDLE_MULTIBYTE)
4165 wchar_t *wstring
, *wpat
;
4169 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4172 #if defined (HANDLE_MULTIBYTE)
4175 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4176 if (n
== (size_t)-1)
4177 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4178 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4179 if (n
== (size_t)-1)
4182 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4184 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4194 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4198 getpatspec (c
, value
)
4203 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4205 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4208 /* Posix.2 says that the WORD should be run through tilde expansion,
4209 parameter expansion, command substitution and arithmetic expansion.
4210 This leaves the result quoted, so quote_string_for_globbing () has
4211 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4212 it means that the entire expression was enclosed in double quotes.
4213 This means that quoting characters in the pattern do not make any
4214 special pattern characters quoted. For example, the `*' in the
4215 following retains its special meaning: "${foo#'*'}". */
4217 getpattern (value
, quoted
, expandpat
)
4219 int quoted
, expandpat
;
4226 /* There is a problem here: how to handle single or double quotes in the
4227 pattern string when the whole expression is between double quotes?
4228 POSIX.2 says that enclosing double quotes do not cause the pattern to
4229 be quoted, but does that leave us a problem with @ and array[@] and their
4230 expansions inside a pattern? */
4232 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4235 pat
= string_extract_double_quoted (tword
, &i
, 1);
4241 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4243 l
= *value
? expand_string_for_rhs (value
,
4244 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4245 (int *)NULL
, (int *)NULL
)
4247 pat
= string_list (l
);
4251 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4259 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4260 or ${name#[#]value}. */
4262 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4263 char *value
, *pattern
;
4264 int patspec
, quoted
;
4268 tword
= remove_pattern (value
, pattern
, patspec
);
4275 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4278 int patspec
, itype
, quoted
;
4284 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4286 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4287 w
= alloc_word_desc ();
4288 w
->word
= tword
? tword
: savestring ("");
4289 new = make_word_list (w
, new);
4292 l
= REVERSE_LIST (new, WORD_LIST
*);
4293 tword
= string_list_pos_params (itype
, l
, quoted
);
4300 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4303 int patspec
, quoted
;
4308 list
= list_rest_of_args ();
4310 return ((char *)NULL
);
4311 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4312 dispose_words (list
);
4316 #if defined (ARRAY_VARS)
4318 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4322 char *varname
; /* so we can figure out how it's indexed */
4332 /* compute itype from varname here */
4333 v
= array_variable_part (varname
, &ret
, 0);
4336 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4337 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4339 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4341 return ((char *)NULL
);
4342 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4343 dispose_words (list
);
4347 #endif /* ARRAY_VARS */
4350 parameter_brace_remove_pattern (varname
, value
, patstr
, rtype
, quoted
)
4351 char *varname
, *value
, *patstr
;
4354 int vtype
, patspec
, starsub
;
4355 char *temp1
, *val
, *pattern
;
4359 return ((char *)NULL
);
4361 this_command_name
= varname
;
4363 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
4365 return ((char *)NULL
);
4367 starsub
= vtype
& VT_STARSUB
;
4368 vtype
&= ~VT_STARSUB
;
4370 patspec
= getpatspec (rtype
, patstr
);
4371 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4374 /* Need to pass getpattern newly-allocated memory in case of expansion --
4375 the expansion code will free the passed string on an error. */
4376 temp1
= savestring (patstr
);
4377 pattern
= getpattern (temp1
, quoted
, 1);
4380 temp1
= (char *)NULL
; /* shut up gcc */
4384 case VT_ARRAYMEMBER
:
4385 temp1
= remove_pattern (val
, pattern
, patspec
);
4386 if (vtype
== VT_VARIABLE
)
4390 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4391 ? quote_string (temp1
)
4392 : quote_escapes (temp1
);
4397 #if defined (ARRAY_VARS)
4399 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4400 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4402 val
= quote_escapes (temp1
);
4409 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4410 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4412 val
= quote_escapes (temp1
);
4423 /*******************************************
4425 * Functions to expand WORD_DESCs *
4427 *******************************************/
4429 /* Expand WORD, performing word splitting on the result. This does
4430 parameter expansion, command substitution, arithmetic expansion,
4431 word splitting, and quote removal. */
4434 expand_word (word
, quoted
)
4438 WORD_LIST
*result
, *tresult
;
4440 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4441 result
= word_list_split (tresult
);
4442 dispose_words (tresult
);
4443 return (result
? dequote_list (result
) : result
);
4446 /* Expand WORD, but do not perform word splitting on the result. This
4447 does parameter expansion, command substitution, arithmetic expansion,
4448 and quote removal. */
4450 expand_word_unsplit (word
, quoted
)
4456 expand_no_split_dollar_star
= 1;
4457 #if defined (HANDLE_MULTIBYTE)
4458 if (ifs_firstc
[0] == 0)
4460 if (ifs_firstc
== 0)
4462 word
->flags
|= W_NOSPLIT
;
4463 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4464 expand_no_split_dollar_star
= 0;
4466 return (result
? dequote_list (result
) : result
);
4469 /* Perform shell expansions on WORD, but do not perform word splitting or
4470 quote removal on the result. Virtually identical to expand_word_unsplit;
4471 could be combined if implementations don't diverge. */
4473 expand_word_leave_quoted (word
, quoted
)
4479 expand_no_split_dollar_star
= 1;
4480 #if defined (HANDLE_MULTIBYTE)
4481 if (ifs_firstc
[0] == 0)
4483 if (ifs_firstc
== 0)
4485 word
->flags
|= W_NOSPLIT
;
4486 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4487 expand_no_split_dollar_star
= 0;
4492 #if defined (PROCESS_SUBSTITUTION)
4494 /*****************************************************************/
4496 /* Hacking Process Substitution */
4498 /*****************************************************************/
4500 #if !defined (HAVE_DEV_FD)
4501 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4502 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4503 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4504 list. NFIFO is a count of the number of FIFOs in the list. */
4505 #define FIFO_INCR 20
4512 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4514 static int fifo_list_size
;
4517 add_fifo_list (pathname
)
4520 if (nfifo
>= fifo_list_size
- 1)
4522 fifo_list_size
+= FIFO_INCR
;
4523 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4524 fifo_list_size
* sizeof (struct temp_fifo
));
4527 fifo_list
[nfifo
].file
= savestring (pathname
);
4539 for (i
= saved
= 0; i
< nfifo
; i
++)
4541 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4543 unlink (fifo_list
[i
].file
);
4544 free (fifo_list
[i
].file
);
4545 fifo_list
[i
].file
= (char *)NULL
;
4546 fifo_list
[i
].proc
= -1;
4552 /* If we didn't remove some of the FIFOs, compact the list. */
4555 for (i
= j
= 0; i
< nfifo
; i
++)
4556 if (fifo_list
[i
].file
)
4558 fifo_list
[j
].file
= fifo_list
[i
].file
;
4559 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4579 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4580 if (mkfifo (tname
, 0600) < 0)
4583 return ((char *)NULL
);
4586 add_fifo_list (tname
);
4590 #else /* HAVE_DEV_FD */
4592 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4593 has open to children. NFDS is a count of the number of bits currently
4594 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4596 static char *dev_fd_list
= (char *)NULL
;
4598 static int totfds
; /* The highest possible number of open files. */
4604 if (!dev_fd_list
|| fd
>= totfds
)
4609 totfds
= getdtablesize ();
4610 if (totfds
< 0 || totfds
> 256)
4615 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4616 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4619 dev_fd_list
[fd
] = 1;
4626 return 0; /* used for cleanup; not needed with /dev/fd */
4637 for (i
= 0; nfds
&& i
< totfds
; i
++)
4648 #if defined (NOTDEF)
4649 print_dev_fd_list ()
4653 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4656 for (i
= 0; i
< totfds
; i
++)
4659 fprintf (stderr
, " %d", i
);
4661 fprintf (stderr
, "\n");
4666 make_dev_fd_filename (fd
)
4669 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4671 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4673 strcpy (ret
, DEV_FD_PREFIX
);
4674 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4675 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4681 #endif /* HAVE_DEV_FD */
4683 /* Return a filename that will open a connection to the process defined by
4684 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4685 a filename in /dev/fd corresponding to a descriptor that is one of the
4686 ends of the pipe. If not defined, we use named pipes on systems that have
4687 them. Systems without /dev/fd and named pipes are out of luck.
4689 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4690 use the read end of the pipe and dup that file descriptor to fd 0 in
4691 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4692 writing or use the write end of the pipe in the child, and dup that
4693 file descriptor to fd 1 in the child. The parent does the opposite. */
4696 process_substitute (string
, open_for_read_in_child
)
4698 int open_for_read_in_child
;
4703 #if defined (HAVE_DEV_FD)
4704 int parent_pipe_fd
, child_pipe_fd
;
4706 #endif /* HAVE_DEV_FD */
4707 #if defined (JOB_CONTROL)
4708 pid_t old_pipeline_pgrp
;
4711 if (!string
|| !*string
|| wordexp_only
)
4712 return ((char *)NULL
);
4714 #if !defined (HAVE_DEV_FD)
4715 pathname
= make_named_pipe ();
4716 #else /* HAVE_DEV_FD */
4717 if (pipe (fildes
) < 0)
4719 sys_error (_("cannot make pipe for process substitution"));
4720 return ((char *)NULL
);
4722 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4723 the pipe in the parent, otherwise the read end. */
4724 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4725 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4726 /* Move the parent end of the pipe to some high file descriptor, to
4727 avoid clashes with FDs used by the script. */
4728 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4730 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4731 #endif /* HAVE_DEV_FD */
4735 sys_error (_("cannot make pipe for process substitution"));
4736 return ((char *)NULL
);
4739 old_pid
= last_made_pid
;
4741 #if defined (JOB_CONTROL)
4742 old_pipeline_pgrp
= pipeline_pgrp
;
4743 pipeline_pgrp
= shell_pgrp
;
4745 #endif /* JOB_CONTROL */
4747 pid
= make_child ((char *)NULL
, 1);
4750 reset_terminating_signals (); /* XXX */
4751 free_pushed_string_input ();
4752 /* Cancel traps, in trap.c. */
4753 restore_original_signals ();
4754 setup_async_signals ();
4755 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
4758 #if defined (JOB_CONTROL)
4759 set_sigchld_handler ();
4760 stop_making_children ();
4761 /* XXX - should we only do this in the parent? (as in command subst) */
4762 pipeline_pgrp
= old_pipeline_pgrp
;
4763 #endif /* JOB_CONTROL */
4767 sys_error (_("cannot make child for process substitution"));
4769 #if defined (HAVE_DEV_FD)
4770 close (parent_pipe_fd
);
4771 close (child_pipe_fd
);
4772 #endif /* HAVE_DEV_FD */
4773 return ((char *)NULL
);
4778 #if defined (JOB_CONTROL)
4779 restore_pipeline (1);
4782 #if !defined (HAVE_DEV_FD)
4783 fifo_list
[nfifo
-1].proc
= pid
;
4786 last_made_pid
= old_pid
;
4788 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4790 #endif /* JOB_CONTROL && PGRP_PIPE */
4792 #if defined (HAVE_DEV_FD)
4793 close (child_pipe_fd
);
4794 #endif /* HAVE_DEV_FD */
4799 set_sigint_handler ();
4801 #if defined (JOB_CONTROL)
4802 set_job_control (0);
4803 #endif /* JOB_CONTROL */
4805 #if !defined (HAVE_DEV_FD)
4806 /* Open the named pipe in the child. */
4807 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4810 /* Two separate strings for ease of translation. */
4811 if (open_for_read_in_child
)
4812 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4814 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4818 if (open_for_read_in_child
)
4820 if (sh_unset_nodelay_mode (fd
) < 0)
4822 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
4826 #else /* HAVE_DEV_FD */
4828 #endif /* HAVE_DEV_FD */
4830 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4832 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4833 open_for_read_in_child
? 0 : 1);
4837 if (fd
!= (open_for_read_in_child
? 0 : 1))
4840 /* Need to close any files that this process has open to pipes inherited
4842 if (current_fds_to_close
)
4844 close_fd_bitmap (current_fds_to_close
);
4845 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4848 #if defined (HAVE_DEV_FD)
4849 /* Make sure we close the parent's end of the pipe and clear the slot
4850 in the fd list so it is not closed later, if reallocated by, for
4851 instance, pipe(2). */
4852 close (parent_pipe_fd
);
4853 dev_fd_list
[parent_pipe_fd
] = 0;
4854 #endif /* HAVE_DEV_FD */
4856 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4858 #if !defined (HAVE_DEV_FD)
4859 /* Make sure we close the named pipe in the child before we exit. */
4860 close (open_for_read_in_child
? 0 : 1);
4861 #endif /* !HAVE_DEV_FD */
4866 #endif /* PROCESS_SUBSTITUTION */
4868 /***********************************/
4870 /* Command Substitution */
4872 /***********************************/
4875 read_comsub (fd
, quoted
, rflag
)
4879 char *istring
, buf
[128], *bufp
, *s
;
4880 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
4883 istring
= (char *)NULL
;
4884 istring_index
= istring_size
= bufn
= tflag
= 0;
4886 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
4887 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
4890 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4893 /* Read the output of the command through the pipe. This may need to be
4894 changed to understand multibyte characters in the future. */
4901 bufn
= zread (fd
, buf
, sizeof (buf
));
4911 internal_warning ("read_comsub: ignored null byte in input");
4916 /* Add the character to ISTRING, possibly after resizing it. */
4917 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4919 /* This is essentially quote_string inline */
4920 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
4921 istring
[istring_index
++] = CTLESC
;
4922 /* Escape CTLESC and CTLNUL in the output to protect those characters
4923 from the rest of the word expansions (word splitting and globbing.)
4924 This is essentially quote_escapes inline. */
4925 else if (skip_ctlesc
== 0 && c
== CTLESC
)
4927 tflag
|= W_HASCTLESC
;
4928 istring
[istring_index
++] = CTLESC
;
4930 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
4931 istring
[istring_index
++] = CTLESC
;
4933 istring
[istring_index
++] = c
;
4936 #if defined (__CYGWIN__)
4937 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4940 istring
[istring_index
- 1] = '\n';
4947 istring
[istring_index
] = '\0';
4949 /* If we read no output, just return now and save ourselves some
4951 if (istring_index
== 0)
4956 return (char *)NULL
;
4959 /* Strip trailing newlines from the output of the command. */
4960 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4962 while (istring_index
> 0)
4964 if (istring
[istring_index
- 1] == '\n')
4968 /* If the newline was quoted, remove the quoting char. */
4969 if (istring
[istring_index
- 1] == CTLESC
)
4975 istring
[istring_index
] = '\0';
4978 strip_trailing (istring
, istring_index
- 1, 1);
4985 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
4986 contained string possibly quoted. */
4988 command_substitute (string
, quoted
)
4992 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4994 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
4997 istring
= (char *)NULL
;
4999 /* Don't fork () if there is no need to. In the case of no command to
5000 run, just return NULL. */
5001 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5002 return ((WORD_DESC
*)NULL
);
5004 if (wordexp_only
&& read_but_dont_execute
)
5006 last_command_exit_value
= EX_WEXPCOMSUB
;
5007 jump_to_top_level (EXITPROG
);
5010 /* We're making the assumption here that the command substitution will
5011 eventually run a command from the file system. Since we'll run
5012 maybe_make_export_env in this subshell before executing that command,
5013 the parent shell and any other shells it starts will have to remake
5014 the environment. If we make it before we fork, other shells won't
5015 have to. Don't bother if we have any temporary variable assignments,
5016 though, because the export environment will be remade after this
5017 command completes anyway, but do it if all the words to be expanded
5018 are variable assignments. */
5019 if (subst_assign_varlist
== 0 || garglist
== 0)
5020 maybe_make_export_env (); /* XXX */
5022 /* Flags to pass to parse_and_execute() */
5023 pflags
= interactive
? SEVAL_RESETLINE
: 0;
5025 /* Pipe the output of executing STRING into the current shell. */
5026 if (pipe (fildes
) < 0)
5028 sys_error (_("cannot make pipe for command substitution"));
5032 old_pid
= last_made_pid
;
5033 #if defined (JOB_CONTROL)
5034 old_pipeline_pgrp
= pipeline_pgrp
;
5035 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5036 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5037 pipeline_pgrp
= shell_pgrp
;
5038 cleanup_the_pipeline ();
5039 #endif /* JOB_CONTROL */
5041 old_async_pid
= last_asynchronous_pid
;
5042 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5043 last_asynchronous_pid
= old_async_pid
;
5046 /* Reset the signal handlers in the child, but don't free the
5048 reset_signal_handlers ();
5050 #if defined (JOB_CONTROL)
5051 /* XXX DO THIS ONLY IN PARENT ? XXX */
5052 set_sigchld_handler ();
5053 stop_making_children ();
5055 pipeline_pgrp
= old_pipeline_pgrp
;
5057 stop_making_children ();
5058 #endif /* JOB_CONTROL */
5062 sys_error (_("cannot make child for command substitution"));
5068 return ((WORD_DESC
*)NULL
);
5073 set_sigint_handler (); /* XXX */
5075 free_pushed_string_input ();
5077 if (dup2 (fildes
[1], 1) < 0)
5079 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5080 exit (EXECUTION_FAILURE
);
5083 /* If standard output is closed in the parent shell
5084 (such as after `exec >&-'), file descriptor 1 will be
5085 the lowest available file descriptor, and end up in
5086 fildes[0]. This can happen for stdin and stderr as well,
5087 but stdout is more important -- it will cause no output
5088 to be generated from this command. */
5089 if ((fildes
[1] != fileno (stdin
)) &&
5090 (fildes
[1] != fileno (stdout
)) &&
5091 (fildes
[1] != fileno (stderr
)))
5094 if ((fildes
[0] != fileno (stdin
)) &&
5095 (fildes
[0] != fileno (stdout
)) &&
5096 (fildes
[0] != fileno (stderr
)))
5099 /* The currently executing shell is not interactive. */
5102 /* This is a subshell environment. */
5103 subshell_environment
|= SUBSHELL_COMSUB
;
5105 /* When not in POSIX mode, command substitution does not inherit
5107 if (posixly_correct
== 0)
5108 exit_immediately_on_error
= 0;
5110 remove_quoted_escapes (string
);
5112 startup_state
= 2; /* see if we can avoid a fork */
5113 /* Give command substitution a place to jump back to on failure,
5114 so we don't go back up to main (). */
5115 result
= setjmp (top_level
);
5117 /* If we're running a command substitution inside a shell function,
5118 trap `return' so we don't return from the function in the subshell
5119 and go off to never-never land. */
5120 if (result
== 0 && return_catch_flag
)
5121 function_value
= setjmp (return_catch
);
5125 if (result
== ERREXIT
)
5126 rc
= last_command_exit_value
;
5127 else if (result
== EXITPROG
)
5128 rc
= last_command_exit_value
;
5130 rc
= EXECUTION_FAILURE
;
5131 else if (function_value
)
5132 rc
= return_catch_value
;
5136 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5140 last_command_exit_value
= rc
;
5141 rc
= run_exit_trap ();
5142 #if defined (PROCESS_SUBSTITUTION)
5143 unlink_fifo_list ();
5149 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5151 #endif /* JOB_CONTROL && PGRP_PIPE */
5156 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5160 current_command_subst_pid
= pid
;
5161 last_command_exit_value
= wait_for (pid
);
5162 last_command_subst_pid
= pid
;
5163 last_made_pid
= old_pid
;
5165 #if defined (JOB_CONTROL)
5166 /* If last_command_exit_value > 128, then the substituted command
5167 was terminated by a signal. If that signal was SIGINT, then send
5168 SIGINT to ourselves. This will break out of loops, for instance. */
5169 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5170 kill (getpid (), SIGINT
);
5172 /* wait_for gives the terminal back to shell_pgrp. If some other
5173 process group should have it, give it away to that group here.
5174 pipeline_pgrp is non-zero only while we are constructing a
5175 pipline, so what we are concerned about is whether or not that
5176 pipeline was started in the background. A pipeline started in
5177 the background should never get the tty back here. */
5179 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
5181 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5183 give_terminal_to (pipeline_pgrp
, 0);
5184 #endif /* JOB_CONTROL */
5186 ret
= alloc_word_desc ();
5187 ret
->word
= istring
;
5194 /********************************************************
5196 * Utility functions for parameter expansion *
5198 ********************************************************/
5200 #if defined (ARRAY_VARS)
5203 array_length_reference (s
)
5213 var
= array_variable_part (s
, &t
, &len
);
5215 /* If unbound variables should generate an error, report one and return
5217 if ((var
== 0 || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5221 last_command_exit_value
= EXECUTION_FAILURE
;
5229 /* We support a couple of expansions for variables that are not arrays.
5230 We'll return the length of the value for v[0], and 1 for v[@] or
5231 v[*]. Return 0 for everything else. */
5233 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5235 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5238 return (assoc_num_elements (assoc_cell (var
)));
5239 else if (array_p (var
))
5240 return (array_num_elements (array
));
5248 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5250 if (akey
== 0 || *akey
== 0)
5252 err_badarraysub (t
);
5255 t
= assoc_reference (assoc_cell (var
), akey
);
5259 ind
= array_expand_index (t
, len
);
5262 err_badarraysub (t
);
5266 t
= array_reference (array
, ind
);
5268 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5271 len
= MB_STRLEN (t
);
5274 #endif /* ARRAY_VARS */
5277 valid_brace_expansion_word (name
, var_is_special
)
5281 if (DIGIT (*name
) && all_digits (name
))
5283 else if (var_is_special
)
5285 #if defined (ARRAY_VARS)
5286 else if (valid_array_reference (name
))
5288 #endif /* ARRAY_VARS */
5289 else if (legal_identifier (name
))
5296 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5299 int *quoted_dollar_atp
, *contains_dollar_at
;
5305 if (quoted_dollar_atp
)
5306 *quoted_dollar_atp
= 0;
5307 if (contains_dollar_at
)
5308 *contains_dollar_at
= 0;
5312 /* check for $@ and $* */
5313 if (name
[0] == '@' && name
[1] == 0)
5315 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5316 *quoted_dollar_atp
= 1;
5317 if (contains_dollar_at
)
5318 *contains_dollar_at
= 1;
5321 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5323 if (contains_dollar_at
)
5324 *contains_dollar_at
= 1;
5328 /* Now check for ${array[@]} and ${array[*]} */
5329 #if defined (ARRAY_VARS)
5330 else if (valid_array_reference (name
))
5332 temp1
= mbschr (name
, '[');
5333 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5335 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5336 *quoted_dollar_atp
= 1;
5337 if (contains_dollar_at
)
5338 *contains_dollar_at
= 1;
5341 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5342 which should result in separate words even when IFS is unset. */
5343 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5345 if (contains_dollar_at
)
5346 *contains_dollar_at
= 1;
5354 /* Parameter expand NAME, and return a new string which is the expansion,
5355 or NULL if there was no expansion.
5356 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5357 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5358 NAME was found inside of a double-quoted expression. */
5360 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
)
5362 int var_is_special
, quoted
, pflags
;
5374 /* Handle multiple digit arguments, as in ${11}. */
5375 if (legal_number (name
, &arg_index
))
5377 tt
= get_dollar_var_value (arg_index
);
5379 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5381 : quote_escapes (tt
);
5383 temp
= (char *)NULL
;
5386 else if (var_is_special
) /* ${@} */
5389 tt
= (char *)xmalloc (2 + strlen (name
));
5390 tt
[sindex
= 0] = '$';
5391 strcpy (tt
+ 1, name
);
5393 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5394 (int *)NULL
, (int *)NULL
, pflags
);
5397 #if defined (ARRAY_VARS)
5398 else if (valid_array_reference (name
))
5400 temp
= array_value (name
, quoted
, &atype
);
5401 if (atype
== 0 && temp
)
5402 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5403 ? quote_string (temp
)
5404 : quote_escapes (temp
);
5405 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5406 rflags
|= W_HASQUOTEDNULL
;
5409 else if (var
= find_variable (name
))
5411 if (var_isset (var
) && invisible_p (var
) == 0)
5413 #if defined (ARRAY_VARS)
5415 temp
= assoc_reference (assoc_cell (var
), "0");
5416 else if (array_p (var
))
5417 temp
= array_reference (array_cell (var
), 0);
5419 temp
= value_cell (var
);
5421 temp
= value_cell (var
);
5425 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5426 ? quote_string (temp
)
5427 : quote_escapes (temp
);
5430 temp
= (char *)NULL
;
5433 temp
= (char *)NULL
;
5437 ret
= alloc_word_desc ();
5439 ret
->flags
|= rflags
;
5444 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5445 value of the variable whose name is the value of NAME. */
5447 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5449 int var_is_special
, quoted
;
5450 int *quoted_dollar_atp
, *contains_dollar_at
;
5455 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
5457 /* Have to dequote here if necessary */
5460 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5461 ? dequote_string (t
)
5462 : dequote_escapes (t
);
5466 dispose_word_desc (w
);
5468 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5470 return (WORD_DESC
*)NULL
;
5472 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0);
5478 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5479 depending on the value of C, the separating character. C can be one of
5480 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5481 between double quotes. */
5483 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5485 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5489 char *t
, *t1
, *temp
;
5492 /* If the entire expression is between double quotes, we want to treat
5493 the value as a double-quoted string, with the exception that we strip
5494 embedded unescaped double quotes (for sh backwards compatibility). */
5495 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5498 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5503 w
= alloc_word_desc ();
5505 /* XXX was 0 not quoted */
5506 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5509 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5514 /* The expansion of TEMP returned something. We need to treat things
5515 slightly differently if HASDOL is non-zero. If we have "$@", the
5516 individual words have already been quoted. We need to turn them
5517 into a string with the words separated by the first character of
5518 $IFS without any additional quoting, so string_list_dollar_at won't
5519 do the right thing. We use string_list_dollar_star instead. */
5520 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5522 /* If l->next is not null, we know that TEMP contained "$@", since that
5523 is the only expansion that creates more than one word. */
5524 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5528 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5530 /* The brace expansion occurred between double quotes and there was
5531 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5532 it does not expand to anything. In this case, we want to return
5533 a quoted empty string. */
5534 temp
= make_quoted_char ('\0');
5535 w
->flags
|= W_HASQUOTEDNULL
;
5538 temp
= (char *)NULL
;
5540 if (c
== '-' || c
== '+')
5547 t
= temp
? savestring (temp
) : savestring ("");
5548 t1
= dequote_string (t
);
5550 #if defined (ARRAY_VARS)
5551 if (valid_array_reference (name
))
5552 assign_array_element (name
, t1
, 0);
5554 #endif /* ARRAY_VARS */
5555 bind_variable (name
, t1
, 0);
5562 /* Deal with the right hand side of a ${name:?value} expansion in the case
5563 that NAME is null or not set. If VALUE is non-null it is expanded and
5564 used as the error message to print, otherwise a standard message is
5567 parameter_brace_expand_error (name
, value
)
5573 if (value
&& *value
)
5575 l
= expand_string (value
, 0);
5576 temp
= string_list (l
);
5577 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5582 report_error (_("%s: parameter null or not set"), name
);
5584 /* Free the data we have allocated during this expansion, since we
5585 are about to longjmp out. */
5590 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5593 valid_length_expression (name
)
5596 return (name
[1] == '\0' || /* ${#} */
5597 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5598 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5599 #if defined (ARRAY_VARS)
5600 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5602 legal_identifier (name
+ 1)); /* ${#PS1} */
5605 #if defined (HANDLE_MULTIBYTE)
5611 mbstate_t mbs
, mbsbak
;
5614 memset (&mbs
, 0, sizeof (mbs
));
5616 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5618 if (MB_INVALIDCH(clen
))
5620 clen
= 1; /* assume single byte */
5633 /* Handle the parameter brace expansion that requires us to return the
5634 length of a parameter. */
5636 parameter_brace_expand_length (name
)
5640 intmax_t number
, arg_index
;
5642 #if defined (ARRAY_VARS)
5646 if (name
[1] == '\0') /* ${#} */
5647 number
= number_of_args ();
5648 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5649 number
= number_of_args ();
5650 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5652 /* Take the lengths of some of the shell's special parameters. */
5656 t
= which_set_flags ();
5659 t
= itos (last_command_exit_value
);
5662 t
= itos (dollar_dollar_pid
);
5665 if (last_asynchronous_pid
== NO_PID
)
5668 t
= itos (last_asynchronous_pid
);
5671 t
= itos (number_of_args ());
5674 number
= STRLEN (t
);
5677 #if defined (ARRAY_VARS)
5678 else if (valid_array_reference (name
+ 1))
5679 number
= array_length_reference (name
+ 1);
5680 #endif /* ARRAY_VARS */
5685 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5687 t
= get_dollar_var_value (arg_index
);
5688 number
= MB_STRLEN (t
);
5691 #if defined (ARRAY_VARS)
5692 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
5695 t
= assoc_reference (assoc_cell (var
), "0");
5697 t
= array_reference (array_cell (var
), 0);
5698 number
= MB_STRLEN (t
);
5703 newname
= savestring (name
);
5705 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5706 t
= list
? string_list (list
) : (char *)NULL
;
5709 dispose_words (list
);
5711 number
= MB_STRLEN (t
);
5719 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5720 so we do some ad-hoc parsing of an arithmetic expression to find
5721 the first DELIM, instead of using strchr(3). Two rules:
5722 1. If the substring contains a `(', read until closing `)'.
5723 2. If the substring contains a `?', read past one `:' for each `?'.
5727 skiparith (substr
, delim
)
5732 int skipcol
, pcount
, i
;
5735 sublen
= strlen (substr
);
5736 i
= skipcol
= pcount
= 0;
5739 /* Balance parens */
5740 if (substr
[i
] == LPAREN
)
5746 if (substr
[i
] == RPAREN
&& pcount
)
5754 ADVANCE_CHAR (substr
, sublen
, i
);
5758 /* Skip one `:' for each `?' */
5759 if (substr
[i
] == ':' && skipcol
)
5765 if (substr
[i
] == delim
)
5767 if (substr
[i
] == '?')
5773 ADVANCE_CHAR (substr
, sublen
, i
);
5776 return (substr
+ i
);
5779 /* Verify and limit the start and end of the desired substring. If
5780 VTYPE == 0, a regular shell variable is being used; if it is 1,
5781 then the positional parameters are being used; if it is 2, then
5782 VALUE is really a pointer to an array variable that should be used.
5783 Return value is 1 if both values were OK, 0 if there was a problem
5784 with an invalid expression, or -1 if the values were out of range. */
5786 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
5788 char *value
, *substr
;
5790 intmax_t *e1p
, *e2p
;
5792 char *t
, *temp1
, *temp2
;
5795 #if defined (ARRAY_VARS)
5800 /* duplicate behavior of strchr(3) */
5801 t
= skiparith (substr
, ':');
5802 if (*t
&& *t
== ':')
5807 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5808 *e1p
= evalexp (temp1
, &expok
);
5813 len
= -1; /* paranoia */
5817 case VT_ARRAYMEMBER
:
5818 len
= MB_STRLEN (value
);
5821 len
= number_of_args () + 1;
5823 len
++; /* add one arg if counting from $0 */
5825 #if defined (ARRAY_VARS)
5827 /* For arrays, the first value deals with array indices. Negative
5828 offsets count from one past the array's maximum index. Associative
5829 arrays treat the number of elements as the maximum index. */
5833 len
= assoc_num_elements (h
) + (*e1p
< 0);
5838 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5844 if (len
== -1) /* paranoia */
5847 if (*e1p
< 0) /* negative offsets count from end */
5850 if (*e1p
> len
|| *e1p
< 0)
5853 #if defined (ARRAY_VARS)
5854 /* For arrays, the second offset deals with the number of elements. */
5855 if (vtype
== VT_ARRAYVAR
)
5856 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
5862 temp2
= savestring (t
);
5863 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5866 *e2p
= evalexp (temp1
, &expok
);
5872 internal_error (_("%s: substring expression < 0"), t
);
5875 #if defined (ARRAY_VARS)
5876 /* In order to deal with sparse arrays, push the intelligence about how
5877 to deal with the number of elements desired down to the array-
5878 specific functions. */
5879 if (vtype
!= VT_ARRAYVAR
)
5882 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5893 /* Return the type of variable specified by VARNAME (simple variable,
5894 positional param, or array variable). Also return the value specified
5895 by VARNAME (value of a variable or a reference to an array element).
5896 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5897 characters in the value are quoted with CTLESC and takes appropriate
5898 steps. For convenience, *VALP is set to the dequoted VALUE. */
5900 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5901 char *varname
, *value
;
5908 #if defined (ARRAY_VARS)
5912 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5913 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5914 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5915 vtype
|= VT_STARSUB
;
5916 *varp
= (SHELL_VAR
*)NULL
;
5918 #if defined (ARRAY_VARS)
5919 if (valid_array_reference (varname
))
5921 v
= array_variable_part (varname
, &temp
, (int *)0);
5922 if (v
&& (array_p (v
) || assoc_p (v
)))
5924 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5926 /* Callers have to differentiate betwen indexed and associative */
5927 vtype
= VT_ARRAYVAR
;
5929 vtype
|= VT_STARSUB
;
5930 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
5934 vtype
= VT_ARRAYMEMBER
;
5935 *valp
= array_value (varname
, 1, (int *)NULL
);
5939 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5941 vtype
= VT_VARIABLE
;
5943 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5944 *valp
= dequote_string (value
);
5946 *valp
= dequote_escapes (value
);
5950 vtype
= VT_ARRAYMEMBER
;
5952 *valp
= array_value (varname
, 1, (int *)NULL
);
5955 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
5957 vtype
= VT_ARRAYMEMBER
;
5959 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
5964 if (value
&& vtype
== VT_VARIABLE
)
5966 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5967 *valp
= dequote_string (value
);
5969 *valp
= dequote_escapes (value
);
5978 /******************************************************/
5980 /* Functions to extract substrings of variable values */
5982 /******************************************************/
5984 #if defined (HANDLE_MULTIBYTE)
5985 /* Character-oriented rather than strictly byte-oriented substrings. S and
5986 E, rather being strict indices into STRING, indicate character (possibly
5987 multibyte character) positions that require calculation.
5988 Used by the ${param:offset[:length]} expansion. */
5990 mb_substring (string
, s
, e
)
5995 int start
, stop
, i
, slen
;
5999 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6000 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6003 while (string
[start
] && i
--)
6004 ADVANCE_CHAR (string
, slen
, start
);
6007 while (string
[stop
] && i
--)
6008 ADVANCE_CHAR (string
, slen
, stop
);
6009 tt
= substring (string
, start
, stop
);
6014 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6015 is `@', use the positional parameters; otherwise, use the value of
6016 VARNAME. If VARNAME is an array variable, use the array elements. */
6019 parameter_brace_substring (varname
, value
, substr
, quoted
)
6020 char *varname
, *value
, *substr
;
6024 int vtype
, r
, starsub
;
6025 char *temp
, *val
, *tt
, *oname
;
6029 return ((char *)NULL
);
6031 oname
= this_command_name
;
6032 this_command_name
= varname
;
6034 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6037 this_command_name
= oname
;
6038 return ((char *)NULL
);
6041 starsub
= vtype
& VT_STARSUB
;
6042 vtype
&= ~VT_STARSUB
;
6044 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6045 this_command_name
= oname
;
6047 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6052 case VT_ARRAYMEMBER
:
6053 #if defined (HANDLE_MULTIBYTE)
6055 tt
= mb_substring (val
, e1
, e2
);
6058 tt
= substring (val
, e1
, e2
);
6060 if (vtype
== VT_VARIABLE
)
6062 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6063 temp
= quote_string (tt
);
6065 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6069 tt
= pos_params (varname
, e1
, e2
, quoted
);
6070 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6072 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6078 #if defined (ARRAY_VARS)
6081 /* we convert to list and take first e2 elements starting at e1th
6082 element -- officially undefined for now */
6083 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6085 /* We want E2 to be the number of elements desired (arrays can be sparse,
6086 so verify_substring_values just returns the numbers specified and we
6087 rely on array_subrange to understand how to deal with them). */
6088 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6089 /* array_subrange now calls array_quote_escapes as appropriate, so the
6090 caller no longer needs to. */
6094 temp
= (char *)NULL
;
6100 /****************************************************************/
6102 /* Functions to perform pattern substitution on variable values */
6104 /****************************************************************/
6107 pat_subst (string
, pat
, rep
, mflags
)
6108 char *string
, *pat
, *rep
;
6111 char *ret
, *s
, *e
, *str
;
6112 int rsize
, rptr
, l
, replen
, mtype
;
6114 mtype
= mflags
& MATCH_TYPEMASK
;
6117 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6118 * with REP and return the result.
6119 * 2. A null pattern with mtype == MATCH_END means to append REP to
6120 * STRING and return the result.
6122 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
6124 replen
= STRLEN (rep
);
6125 l
= strlen (string
);
6126 ret
= (char *)xmalloc (replen
+ l
+ 2);
6128 strcpy (ret
, string
);
6129 else if (mtype
== MATCH_BEG
)
6132 strcpy (ret
+ replen
, string
);
6136 strcpy (ret
, string
);
6137 strcpy (ret
+ l
, rep
);
6142 ret
= (char *)xmalloc (rsize
= 64);
6145 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6147 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6150 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
6152 /* OK, now copy the leading unmatched portion of the string (from
6153 str to s) to ret starting at rptr (the current offset). Then copy
6154 the replacement string at ret + rptr + (s - str). Increment
6155 rptr (if necessary) and str and go on. */
6158 strncpy (ret
+ rptr
, str
, l
);
6163 strncpy (ret
+ rptr
, rep
, replen
);
6166 str
= e
; /* e == end of match */
6168 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6173 /* On a zero-length match, make sure we copy one character, since
6174 we increment one character to avoid infinite recursion. */
6175 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6176 ret
[rptr
++] = *str
++;
6177 e
++; /* avoid infinite recursion on zero-length match */
6181 /* Now copy the unmatched portion of the input string */
6184 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6185 strcpy (ret
+ rptr
, str
);
6193 /* Do pattern match and replacement on the positional parameters. */
6195 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6196 char *string
, *pat
, *rep
;
6199 WORD_LIST
*save
, *params
;
6204 save
= params
= list_rest_of_args ();
6206 return ((char *)NULL
);
6208 for ( ; params
; params
= params
->next
)
6210 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6211 w
= alloc_word_desc ();
6212 w
->word
= ret
? ret
: savestring ("");
6213 dispose_word (params
->word
);
6217 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6218 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6221 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
6222 ret
= string_list_dollar_star (quote_list (save
));
6223 else if ((mflags
& MATCH_STARSUB
) == MATCH_STARSUB
)
6224 ret
= string_list_dollar_star (save
);
6225 else if ((mflags
& MATCH_QUOTED
) == MATCH_QUOTED
)
6226 ret
= string_list_dollar_at (save
, qflags
);
6228 ret
= string_list_dollar_star (save
);
6230 ret
= string_list_pos_params (pchar
, save
, qflags
);
6233 dispose_words (save
);
6238 /* Perform pattern substitution on VALUE, which is the expansion of
6239 VARNAME. PATSUB is an expression supplying the pattern to match
6240 and the string to substitute. QUOTED is a flags word containing
6241 the type of quoting currently in effect. */
6243 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
6244 char *varname
, *value
, *patsub
;
6247 int vtype
, mflags
, starsub
, delim
;
6248 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6252 return ((char *)NULL
);
6254 this_command_name
= varname
;
6256 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6258 return ((char *)NULL
);
6260 starsub
= vtype
& VT_STARSUB
;
6261 vtype
&= ~VT_STARSUB
;
6264 if (patsub
&& *patsub
== '/')
6266 mflags
|= MATCH_GLOBREP
;
6270 /* Malloc this because expand_string_if_necessary or one of the expansion
6271 functions in its call chain may free it on a substitution error. */
6272 lpatsub
= savestring (patsub
);
6274 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6275 mflags
|= MATCH_QUOTED
;
6278 mflags
|= MATCH_STARSUB
;
6280 /* If the pattern starts with a `/', make sure we skip over it when looking
6281 for the replacement delimiter. */
6283 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
6288 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6289 if (lpatsub
[delim
] == '/')
6292 rep
= lpatsub
+ delim
+ 1;
6298 if (rep
&& *rep
== '\0')
6301 /* Perform the same expansions on the pattern as performed by the
6302 pattern removal expansions. */
6303 pat
= getpattern (lpatsub
, quoted
, 1);
6307 if ((mflags
& MATCH_QUOTED
) == 0)
6308 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6310 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6313 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6314 pattern. This is an extension. Make sure we don't anchor the pattern
6315 at the beginning or end of the string if we're doing global replacement,
6318 if (mflags
& MATCH_GLOBREP
)
6319 mflags
|= MATCH_ANY
;
6320 else if (pat
&& pat
[0] == '#')
6322 mflags
|= MATCH_BEG
;
6325 else if (pat
&& pat
[0] == '%')
6327 mflags
|= MATCH_END
;
6331 mflags
|= MATCH_ANY
;
6333 /* OK, we now want to substitute REP for PAT in VAL. If
6334 flags & MATCH_GLOBREP is non-zero, the substitution is done
6335 everywhere, otherwise only the first occurrence of PAT is
6336 replaced. The pattern matching code doesn't understand
6337 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6338 values passed in (VT_VARIABLE) so the pattern substitution
6339 code works right. We need to requote special chars after
6340 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6341 other cases if QUOTED == 0, since the posparams and arrays
6342 indexed by * or @ do special things when QUOTED != 0. */
6347 case VT_ARRAYMEMBER
:
6348 temp
= pat_subst (val
, p
, rep
, mflags
);
6349 if (vtype
== VT_VARIABLE
)
6353 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6359 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6360 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6362 tt
= quote_escapes (temp
);
6367 #if defined (ARRAY_VARS)
6369 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6370 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6371 /* Don't call quote_escapes anymore; array_patsub calls
6372 array_quote_escapes as appropriate before adding the
6373 space separators; ditto for assoc_patsub. */
6385 /****************************************************************/
6387 /* Functions to perform case modification on variable values */
6389 /****************************************************************/
6391 /* Do case modification on the positional parameters. */
6394 pos_params_modcase (string
, pat
, modop
, mflags
)
6399 WORD_LIST
*save
, *params
;
6404 save
= params
= list_rest_of_args ();
6406 return ((char *)NULL
);
6408 for ( ; params
; params
= params
->next
)
6410 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6411 w
= alloc_word_desc ();
6412 w
->word
= ret
? ret
: savestring ("");
6413 dispose_word (params
->word
);
6417 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6418 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6420 ret
= string_list_pos_params (pchar
, save
, qflags
);
6421 dispose_words (save
);
6426 /* Perform case modification on VALUE, which is the expansion of
6427 VARNAME. MODSPEC is an expression supplying the type of modification
6428 to perform. QUOTED is a flags word containing the type of quoting
6429 currently in effect. */
6431 parameter_brace_casemod (varname
, value
, modspec
, patspec
, quoted
)
6432 char *varname
, *value
;
6437 int vtype
, starsub
, modop
, mflags
, x
;
6438 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6442 return ((char *)NULL
);
6444 this_command_name
= varname
;
6446 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6448 return ((char *)NULL
);
6450 starsub
= vtype
& VT_STARSUB
;
6451 vtype
&= ~VT_STARSUB
;
6455 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6456 mflags
|= MATCH_QUOTED
;
6458 mflags
|= MATCH_STARSUB
;
6463 x
= p
&& p
[0] == modspec
;
6464 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6467 else if (modspec
== ',')
6469 x
= p
&& p
[0] == modspec
;
6470 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6473 else if (modspec
== '~')
6475 x
= p
&& p
[0] == modspec
;
6476 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6480 lpat
= p
? savestring (p
) : 0;
6481 /* Perform the same expansions on the pattern as performed by the
6482 pattern removal expansions. FOR LATER */
6483 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6485 /* OK, now we do the case modification. */
6489 case VT_ARRAYMEMBER
:
6490 temp
= sh_modcase (val
, pat
, modop
);
6491 if (vtype
== VT_VARIABLE
)
6495 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6502 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6503 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6505 tt
= quote_escapes (temp
);
6511 #if defined (ARRAY_VARS)
6513 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
6514 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
6515 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6516 as appropriate before adding the space separators; ditto for
6528 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6529 any occur, this must be a nested command substitution, so return 0.
6530 Otherwise, return 1. A valid arithmetic expression must always have a
6531 ( before a matching ), so any cases where there are more right parens
6532 means that this must not be an arithmetic expression, though the parser
6533 will not accept it without a balanced total number of parens. */
6535 chk_arithsub (s
, len
)
6547 else if (s
[i
] == ')')
6557 ADVANCE_CHAR (s
, len
, i
);
6563 ADVANCE_CHAR (s
, len
, i
);
6567 i
= skip_single_quoted (s
, len
, ++i
);
6571 i
= skip_double_quoted ((char *)s
, len
, ++i
);
6576 return (count
== 0);
6579 /****************************************************************/
6581 /* Functions to perform parameter expansion on a string */
6583 /****************************************************************/
6585 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6587 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
6589 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
6591 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
6592 int want_substring
, want_indir
, want_patsub
, want_casemod
;
6593 char *name
, *value
, *temp
, *temp1
;
6594 WORD_DESC
*tdesc
, *ret
;
6595 int t_index
, sindex
, c
, tflag
, modspec
;
6598 temp
= temp1
= value
= (char *)NULL
;
6599 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
6600 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
6604 /* ${#var} doesn't have any of the other parameter expansions on it. */
6605 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
6606 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
6608 #if defined (CASEMOD_EXPANSIONS)
6609 /* To enable case-toggling expansions using the `~' operator character
6610 change the 1 to 0. */
6611 # if defined (CASEMOD_CAPCASE)
6612 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
6614 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
6615 # endif /* CASEMOD_CAPCASE */
6617 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
6618 #endif /* CASEMOD_EXPANSIONS */
6623 /* If the name really consists of a special variable, then make sure
6624 that we have the entire name. We don't allow indirect references
6625 to special variables except `#', `?', `@' and `*'. */
6626 if ((sindex
== t_index
&&
6627 (string
[t_index
] == '-' ||
6628 string
[t_index
] == '?' ||
6629 string
[t_index
] == '#')) ||
6630 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
6631 (string
[t_index
] == '#' ||
6632 string
[t_index
] == '?' ||
6633 string
[t_index
] == '@' ||
6634 string
[t_index
] == '*')))
6638 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
6639 name
= (char *)xmalloc (3 + (strlen (temp1
)));
6640 *name
= string
[sindex
];
6641 if (string
[sindex
] == '!')
6643 /* indirect reference of $#, $?, $@, or $* */
6644 name
[1] = string
[sindex
+ 1];
6645 strcpy (name
+ 2, temp1
);
6648 strcpy (name
+ 1, temp1
);
6653 /* Find out what character ended the variable name. Then
6654 do the appropriate thing. */
6655 if (c
= string
[sindex
])
6658 /* If c is followed by one of the valid parameter expansion
6659 characters, move past it as normal. If not, assume that
6660 a substring specification is being given, and do not move
6662 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
6665 if (c
= string
[sindex
])
6668 else if (c
== ':' && string
[sindex
] != RBRACE
)
6670 else if (c
== '/' && string
[sindex
] != RBRACE
)
6672 #if defined (CASEMOD_EXPANSIONS)
6673 else if (c
== '^' || c
== ',' || c
== '~')
6680 /* Catch the valid and invalid brace expressions that made it through the
6682 /* ${#-} is a valid expansion and means to take the length of $-.
6683 Similarly for ${#?} and ${##}... */
6684 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6685 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
6687 name
= (char *)xrealloc (name
, 3);
6690 c
= string
[sindex
++];
6693 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6694 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6695 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
6697 temp
= (char *)NULL
;
6698 goto bad_substitution
;
6701 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6702 either a variable name, one of the positional parameters or a special
6703 variable that expands to one of the positional parameters. */
6704 want_indir
= *name
== '!' &&
6705 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
6706 || VALID_INDIR_PARAM (name
[1]));
6708 /* Determine the value of this variable. */
6710 /* Check for special variables, directly referenced. */
6711 if (SPECIAL_VAR (name
, want_indir
))
6714 /* Check for special expansion things, like the length of a parameter */
6715 if (*name
== '#' && name
[1])
6717 /* If we are not pointing at the character just after the
6718 closing brace, then we haven't gotten all of the name.
6719 Since it begins with a special character, this is a bad
6720 substitution. Also check NAME for validity before trying
6722 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6724 temp
= (char *)NULL
;
6725 goto bad_substitution
;
6728 number
= parameter_brace_expand_length (name
);
6733 return (&expand_wdesc_error
);
6736 ret
= alloc_word_desc ();
6737 ret
->word
= itos (number
);
6742 /* ${@} is identical to $@. */
6743 if (name
[0] == '@' && name
[1] == '\0')
6745 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6746 *quoted_dollar_atp
= 1;
6748 if (contains_dollar_at
)
6749 *contains_dollar_at
= 1;
6752 /* Process ${!PREFIX*} expansion. */
6753 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6754 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6755 legal_variable_starter ((unsigned char) name
[1]))
6760 temp1
= savestring (name
+ 1);
6761 number
= strlen (temp1
);
6762 temp1
[number
- 1] = '\0';
6763 x
= all_variables_matching_prefix (temp1
);
6764 xlist
= strvec_to_word_list (x
, 0, 0);
6765 if (string
[sindex
- 2] == '*')
6766 temp
= string_list_dollar_star (xlist
);
6769 temp
= string_list_dollar_at (xlist
, quoted
);
6770 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6771 *quoted_dollar_atp
= 1;
6772 if (contains_dollar_at
)
6773 *contains_dollar_at
= 1;
6776 dispose_words (xlist
);
6780 ret
= alloc_word_desc ();
6785 #if defined (ARRAY_VARS)
6786 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6787 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6788 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6792 temp1
= savestring (name
+ 1);
6793 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6795 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6797 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
6800 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6801 *quoted_dollar_atp
= 1;
6802 if (contains_dollar_at
)
6803 *contains_dollar_at
= 1;
6809 ret
= alloc_word_desc ();
6816 #endif /* ARRAY_VARS */
6818 /* Make sure that NAME is valid before trying to go on. */
6819 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6820 var_is_special
) == 0)
6822 temp
= (char *)NULL
;
6823 goto bad_substitution
;
6827 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6829 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
6834 tflag
= tdesc
->flags
;
6835 dispose_word_desc (tdesc
);
6840 #if defined (ARRAY_VARS)
6841 if (valid_array_reference (name
))
6842 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6845 var_is_set
= temp
!= (char *)0;
6846 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6848 /* Get the rest of the stuff inside the braces. */
6849 if (c
&& c
!= RBRACE
)
6851 /* Extract the contents of the ${ ... } expansion
6852 according to the Posix.2 rules. */
6853 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6854 if (string
[sindex
] == RBRACE
)
6857 goto bad_substitution
;
6860 value
= (char *)NULL
;
6864 /* If this is a substring spec, process it and add the result. */
6867 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6872 if (temp1
== &expand_param_error
)
6873 return (&expand_wdesc_error
);
6874 else if (temp1
== &expand_param_fatal
)
6875 return (&expand_wdesc_fatal
);
6877 ret
= alloc_word_desc ();
6879 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6880 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6883 else if (want_patsub
)
6885 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6890 if (temp1
== &expand_param_error
)
6891 return (&expand_wdesc_error
);
6892 else if (temp1
== &expand_param_fatal
)
6893 return (&expand_wdesc_fatal
);
6895 ret
= alloc_word_desc ();
6897 ret
= alloc_word_desc ();
6899 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6900 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6903 #if defined (CASEMOD_EXPANSIONS)
6904 else if (want_casemod
)
6906 temp1
= parameter_brace_casemod (name
, temp
, modspec
, value
, quoted
);
6911 if (temp1
== &expand_param_error
)
6912 return (&expand_wdesc_error
);
6913 else if (temp1
== &expand_param_fatal
)
6914 return (&expand_wdesc_fatal
);
6916 ret
= alloc_word_desc ();
6918 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6919 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6924 /* Do the right thing based on which character ended the variable name. */
6930 report_error (_("%s: bad substitution"), string
? string
: "??");
6934 return &expand_wdesc_error
;
6937 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
6939 last_command_exit_value
= EXECUTION_FAILURE
;
6940 err_unboundvar (name
);
6944 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6948 case '#': /* ${param#[#]pattern} */
6949 case '%': /* ${param%[%]pattern} */
6950 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6955 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6959 ret
= alloc_word_desc ();
6961 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6962 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6969 if (var_is_set
&& var_is_null
== 0)
6971 /* If the operator is `+', we don't want the value of the named
6972 variable for anything, just the value of the right hand side. */
6976 /* XXX -- if we're double-quoted and the named variable is "$@",
6977 we want to turn off any special handling of "$@" --
6978 we're not using it, so whatever is on the rhs applies. */
6979 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6980 *quoted_dollar_atp
= 0;
6981 if (contains_dollar_at
)
6982 *contains_dollar_at
= 0;
6987 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6990 contains_dollar_at
);
6991 /* XXX - fix up later, esp. noting presence of
6992 W_HASQUOTEDNULL in ret->flags */
6996 temp
= (char *)NULL
;
7002 /* Otherwise do nothing; just use the value in TEMP. */
7004 else /* VAR not set or VAR is NULL. */
7007 temp
= (char *)NULL
;
7008 if (c
== '=' && var_is_special
)
7010 report_error (_("$%s: cannot assign in this way"), name
);
7013 return &expand_wdesc_error
;
7017 parameter_brace_expand_error (name
, value
);
7018 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7022 /* XXX -- if we're double-quoted and the named variable is "$@",
7023 we want to turn off any special handling of "$@" --
7024 we're not using it, so whatever is on the rhs applies. */
7025 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7026 *quoted_dollar_atp
= 0;
7027 if (contains_dollar_at
)
7028 *contains_dollar_at
= 0;
7030 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
7032 contains_dollar_at
);
7033 /* XXX - fix up later, esp. noting presence of
7034 W_HASQUOTEDNULL in tdesc->flags */
7045 ret
= alloc_word_desc ();
7052 /* Expand a single ${xxx} expansion. The braces are optional. When
7053 the braces are used, parameter_brace_expand() does the work,
7054 possibly calling param_expand recursively. */
7056 param_expand (string
, sindex
, quoted
, expanded_something
,
7057 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
7060 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
7061 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
7063 char *temp
, *temp1
, uerror
[3];
7064 int zindex
, t_index
, expok
;
7069 WORD_DESC
*tdesc
, *ret
;
7073 c
= string
[++zindex
];
7075 temp
= (char *)NULL
;
7076 ret
= tdesc
= (WORD_DESC
*)NULL
;
7079 /* Do simple cases first. Switch on what follows '$'. */
7093 temp1
= dollar_vars
[TODIGIT (c
)];
7094 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
7099 last_command_exit_value
= EXECUTION_FAILURE
;
7100 err_unboundvar (uerror
);
7101 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7104 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7105 ? quote_string (temp1
)
7106 : quote_escapes (temp1
);
7108 temp
= (char *)NULL
;
7112 /* $$ -- pid of the invoking shell. */
7114 temp
= itos (dollar_dollar_pid
);
7117 /* $# -- number of positional parameters. */
7119 temp
= itos (number_of_args ());
7122 /* $? -- return value of the last synchronous command. */
7124 temp
= itos (last_command_exit_value
);
7127 /* $- -- flags supplied to the shell on invocation or by `set'. */
7129 temp
= which_set_flags ();
7132 /* $! -- Pid of the last asynchronous command. */
7134 /* If no asynchronous pids have been created, expand to nothing.
7135 If `set -u' has been executed, and no async processes have
7136 been created, this is an expansion error. */
7137 if (last_asynchronous_pid
== NO_PID
)
7139 if (expanded_something
)
7140 *expanded_something
= 0;
7141 temp
= (char *)NULL
;
7142 if (unbound_vars_is_error
)
7147 last_command_exit_value
= EXECUTION_FAILURE
;
7148 err_unboundvar (uerror
);
7149 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7153 temp
= itos (last_asynchronous_pid
);
7156 /* The only difference between this and $@ is when the arg is quoted. */
7157 case '*': /* `$*' */
7158 list
= list_rest_of_args ();
7161 /* According to austin-group posix proposal by Geoff Clare in
7162 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7164 "The shell shall write a message to standard error and
7165 immediately exit when it tries to expand an unset parameter
7166 other than the '@' and '*' special parameters."
7169 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7174 last_command_exit_value
= EXECUTION_FAILURE
;
7175 err_unboundvar (uerror
);
7176 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7180 /* If there are no command-line arguments, this should just
7181 disappear if there are other characters in the expansion,
7182 even if it's quoted. */
7183 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7184 temp
= (char *)NULL
;
7185 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7187 /* If we have "$*" we want to make a string of the positional
7188 parameters, separated by the first character of $IFS, and
7189 quote the whole string, including the separators. If IFS
7190 is unset, the parameters are separated by ' '; if $IFS is
7191 null, the parameters are concatenated. */
7192 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7193 temp1
= quote_string (temp
);
7195 tflag
|= W_HASQUOTEDNULL
;
7201 /* We check whether or not we're eventually going to split $* here,
7202 for example when IFS is empty and we are processing the rhs of
7203 an assignment statement. In that case, we don't separate the
7204 arguments at all. Otherwise, if the $* is not quoted it is
7207 # if defined (HANDLE_MULTIBYTE)
7208 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7210 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7212 temp
= string_list_dollar_star (list
);
7214 temp
= string_list_dollar_at (list
, quoted
);
7216 temp
= string_list_dollar_at (list
, quoted
);
7218 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7219 *contains_dollar_at
= 1;
7222 dispose_words (list
);
7225 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7226 means that we have to turn quoting off after we split into
7227 the individually quoted arguments so that the final split
7228 on the first character of $IFS is still done. */
7229 case '@': /* `$@' */
7230 list
= list_rest_of_args ();
7233 /* According to austin-group posix proposal by Geoff Clare in
7234 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7236 "The shell shall write a message to standard error and
7237 immediately exit when it tries to expand an unset parameter
7238 other than the '@' and '*' special parameters."
7241 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7246 last_command_exit_value
= EXECUTION_FAILURE
;
7247 err_unboundvar (uerror
);
7248 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7252 /* We want to flag the fact that we saw this. We can't turn
7253 off quoting entirely, because other characters in the
7254 string might need it (consider "\"$@\""), but we need some
7255 way to signal that the final split on the first character
7256 of $IFS should be done, even though QUOTED is 1. */
7257 /* XXX - should this test include Q_PATQUOTE? */
7258 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7259 *quoted_dollar_at_p
= 1;
7260 if (contains_dollar_at
)
7261 *contains_dollar_at
= 1;
7263 /* We want to separate the positional parameters with the first
7264 character of $IFS in case $IFS is something other than a space.
7265 We also want to make sure that splitting is done no matter what --
7266 according to POSIX.2, this expands to a list of the positional
7267 parameters no matter what IFS is set to. */
7268 temp
= string_list_dollar_at (list
, quoted
);
7270 dispose_words (list
);
7274 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
7276 contains_dollar_at
);
7278 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7280 temp
= tdesc
? tdesc
->word
: (char *)0;
7283 /* Quoted nulls should be removed if there is anything else
7285 /* Note that we saw the quoted null so we can add one back at
7286 the end of this function if there are no other characters
7287 in the string, discard TEMP, and go on. The exception to
7288 this is when we have "${@}" and $1 is '', since $@ needs
7289 special handling. */
7290 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7292 if (had_quoted_null_p
)
7293 *had_quoted_null_p
= 1;
7294 if (*quoted_dollar_at_p
== 0)
7297 tdesc
->word
= temp
= (char *)NULL
;
7305 /* Do command or arithmetic substitution. */
7307 /* We have to extract the contents of this paren substitution. */
7308 t_index
= zindex
+ 1;
7309 temp
= extract_command_subst (string
, &t_index
, 0);
7312 /* For Posix.2-style `$(( ))' arithmetic substitution,
7313 extract the expression and pass it to the evaluator. */
7314 if (temp
&& *temp
== LPAREN
)
7318 temp2
= savestring (temp1
);
7319 t_index
= strlen (temp2
) - 1;
7321 if (temp2
[t_index
] != RPAREN
)
7327 /* Cut off ending `)' */
7328 temp2
[t_index
] = '\0';
7330 if (chk_arithsub (temp2
, t_index
) == 0)
7336 /* Expand variables found inside the expression. */
7337 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7341 /* No error messages. */
7342 this_command_name
= (char *)NULL
;
7343 number
= evalexp (temp1
, &expok
);
7348 if (interactive_shell
== 0 && posixly_correct
)
7350 last_command_exit_value
= EXECUTION_FAILURE
;
7351 return (&expand_wdesc_fatal
);
7354 return (&expand_wdesc_error
);
7356 temp
= itos (number
);
7361 if (pflags
& PF_NOCOMSUB
)
7362 /* we need zindex+1 because string[zindex] == RPAREN */
7363 temp1
= substring (string
, *sindex
, zindex
+1);
7366 tdesc
= command_substitute (temp
, quoted
);
7367 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7369 dispose_word_desc (tdesc
);
7375 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7376 away in a future bash release. */
7378 /* Extract the contents of this arithmetic substitution. */
7379 t_index
= zindex
+ 1;
7380 temp
= extract_arithmetic_subst (string
, &t_index
);
7384 temp
= savestring (string
);
7385 if (expanded_something
)
7386 *expanded_something
= 0;
7390 /* Do initial variable expansion. */
7391 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7396 /* Find the variable in VARIABLE_LIST. */
7397 temp
= (char *)NULL
;
7399 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7401 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7403 /* If this isn't a variable name, then just output the `$'. */
7404 if (temp1
== 0 || *temp1
== '\0')
7407 temp
= (char *)xmalloc (2);
7410 if (expanded_something
)
7411 *expanded_something
= 0;
7415 /* If the variable exists, return its value cell. */
7416 var
= find_variable (temp1
);
7418 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7420 #if defined (ARRAY_VARS)
7421 if (assoc_p (var
) || array_p (var
))
7423 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7424 : assoc_reference (assoc_cell (var
), "0");
7426 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7427 ? quote_string (temp
)
7428 : quote_escapes (temp
);
7429 else if (unbound_vars_is_error
)
7430 goto unbound_variable
;
7435 temp
= value_cell (var
);
7437 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7438 ? quote_string (temp
)
7439 : quote_escapes (temp
);
7447 temp
= (char *)NULL
;
7450 if (unbound_vars_is_error
)
7452 last_command_exit_value
= EXECUTION_FAILURE
;
7453 err_unboundvar (temp1
);
7462 last_command_exit_value
= EXECUTION_FAILURE
;
7463 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7464 ? &expand_wdesc_fatal
7465 : &expand_wdesc_error
);
7476 ret
= alloc_word_desc ();
7477 ret
->flags
= tflag
; /* XXX */
7483 /* Make a word list which is the result of parameter and variable
7484 expansion, command substitution, arithmetic substitution, and
7485 quote removal of WORD. Return a pointer to a WORD_LIST which is
7486 the result of the expansion. If WORD contains a null word, the
7487 word list returned is also null.
7489 QUOTED contains flag values defined in shell.h.
7491 ISEXP is used to tell expand_word_internal that the word should be
7492 treated as the result of an expansion. This has implications for
7493 how IFS characters in the word are treated.
7495 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7496 they point to an integer value which receives information about expansion.
7497 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7498 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7501 This only does word splitting in the case of $@ expansion. In that
7502 case, we split on ' '. */
7504 /* Values for the local variable quoted_state. */
7506 #define PARTIALLY_QUOTED 1
7507 #define WHOLLY_QUOTED 2
7510 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7513 int *contains_dollar_at
;
7514 int *expanded_something
;
7519 /* The intermediate string that we build while expanding. */
7522 /* The current size of the above object. */
7525 /* Index into ISTRING. */
7528 /* Temporary string storage. */
7531 /* The text of WORD. */
7532 register char *string
;
7534 /* The size of STRING. */
7537 /* The index into STRING. */
7540 /* This gets 1 if we see a $@ while quoted. */
7541 int quoted_dollar_at
;
7543 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7544 whether WORD contains no quoting characters, a partially quoted
7545 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7549 int had_quoted_null
;
7553 int assignoff
; /* If assignment, offset of `=' */
7555 register unsigned char c
; /* Current character. */
7556 int t_index
; /* For calls to string_extract_xxx. */
7562 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
7563 istring
[istring_index
= 0] = '\0';
7564 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
7565 quoted_state
= UNQUOTED
;
7567 string
= word
->word
;
7569 goto finished_with_string
;
7570 /* Don't need the string length for the SADD... and COPY_ macros unless
7571 multibyte characters are possible. */
7572 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
7574 if (contains_dollar_at
)
7575 *contains_dollar_at
= 0;
7579 /* Begin the expansion. */
7585 /* Case on toplevel character. */
7589 goto finished_with_string
;
7593 #if HANDLE_MULTIBYTE
7594 if (MB_CUR_MAX
> 1 && string
[sindex
])
7596 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7601 temp
= (char *)xmalloc (3);
7603 temp
[1] = c
= string
[sindex
];
7614 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
7620 #if defined (PROCESS_SUBSTITUTION)
7621 /* Process substitution. */
7625 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
7627 sindex
--; /* add_character: label increments sindex */
7631 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
7633 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
7636 /* If the process substitution specification is `<()', we want to
7637 open the pipe for writing in the child and produce output; if
7638 it is `>()', we want to open the pipe for reading in the child
7639 and consume input. */
7640 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
7644 goto dollar_add_string
;
7646 #endif /* PROCESS_SUBSTITUTION */
7649 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7650 which are not assignment statements are not expanded. If the
7651 shell isn't in posix mode, though, we perform tilde expansion
7652 on `likely candidate' unquoted assignment statements (flags
7653 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7654 contains an unquoted :~ or =~. Something to think about: we
7655 now have a flag that says to perform tilde expansion on arguments
7656 to `assignment builtins' like declare and export that look like
7657 assignment statements. We now do tilde expansion on such words
7658 even in POSIX mode. */
7659 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
7661 if (isexp
== 0 && isifs (c
))
7662 goto add_ifs_character
;
7666 /* If we're not in posix mode or forcing assignment-statement tilde
7667 expansion, note where the `=' appears in the word and prepare to
7668 do tilde expansion following the first `='. */
7669 if ((word
->flags
& W_ASSIGNMENT
) &&
7670 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7671 assignoff
== -1 && sindex
> 0)
7673 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
7674 word
->flags
|= W_ITILDE
;
7676 else if ((word
->flags
& W_ASSIGNMENT
) &&
7677 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7678 string
[sindex
+1] == '~')
7679 word
->flags
|= W_ITILDE
;
7681 if (isexp
== 0 && isifs (c
))
7682 goto add_ifs_character
;
7687 if (word
->flags
& W_NOTILDE
)
7689 if (isexp
== 0 && isifs (c
))
7690 goto add_ifs_character
;
7695 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
7696 string
[sindex
+1] == '~')
7697 word
->flags
|= W_ITILDE
;
7699 if (isexp
== 0 && isifs (c
))
7700 goto add_ifs_character
;
7705 /* If the word isn't supposed to be tilde expanded, or we're not
7706 at the start of a word or after an unquoted : or = in an
7707 assignment statement, we don't do tilde expansion. */
7708 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
7709 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
7710 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7712 word
->flags
&= ~W_ITILDE
;
7713 if (isexp
== 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
7714 goto add_ifs_character
;
7719 if (word
->flags
& W_ASSIGNRHS
)
7721 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
7726 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
7728 word
->flags
&= ~W_ITILDE
;
7730 if (temp
&& *temp
&& t_index
> 0)
7732 temp1
= bash_tilde_expand (temp
, tflag
);
7733 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
7737 goto add_character
; /* tilde expansion failed */
7742 goto add_quoted_string
; /* XXX was add_string */
7751 if (expanded_something
)
7752 *expanded_something
= 1;
7755 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
7756 &has_dollar_at
, "ed_dollar_at
,
7758 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
7760 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
7764 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
7765 : &expand_word_fatal
);
7767 if (contains_dollar_at
&& has_dollar_at
)
7768 *contains_dollar_at
= 1;
7770 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
7771 had_quoted_null
= 1;
7774 dispose_word_desc (tword
);
7779 case '`': /* Backquoted command substitution. */
7783 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
7784 /* The test of sindex against t_index is to allow bare instances of
7785 ` to pass through, for backwards compatibility. */
7786 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
7788 if (sindex
- 1 == t_index
)
7793 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
7796 return ((temp
== &extract_string_error
) ? &expand_word_error
7797 : &expand_word_fatal
);
7800 if (expanded_something
)
7801 *expanded_something
= 1;
7803 if (word
->flags
& W_NOCOMSUB
)
7804 /* sindex + 1 because string[sindex] == '`' */
7805 temp1
= substring (string
, t_index
, sindex
+ 1);
7808 de_backslash (temp
);
7809 tword
= command_substitute (temp
, quoted
);
7810 temp1
= tword
? tword
->word
: (char *)NULL
;
7812 dispose_word_desc (tword
);
7816 goto dollar_add_string
;
7820 if (string
[sindex
+ 1] == '\n')
7826 c
= string
[++sindex
];
7828 if (quoted
& Q_HERE_DOCUMENT
)
7830 else if (quoted
& Q_DOUBLE_QUOTES
)
7835 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7837 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7842 sindex
--; /* add_character: label increments sindex */
7847 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7852 /* BEFORE jumping here, we need to increment sindex if appropriate */
7853 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7854 DEFAULT_ARRAY_SIZE
);
7855 istring
[istring_index
++] = twochars
[0];
7856 istring
[istring_index
++] = twochars
[1];
7857 istring
[istring_index
] = '\0';
7863 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7865 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7870 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7872 /* If the quotes surrounded the entire string, then the
7873 whole word was quoted. */
7874 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7880 tword
= alloc_word_desc ();
7883 temp
= (char *)NULL
;
7886 /* Need to get W_HASQUOTEDNULL flag through this function. */
7887 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7889 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7893 /* expand_word_internal has already freed temp_word->word
7894 for us because of the way it prints error messages. */
7895 tword
->word
= (char *)NULL
;
7896 dispose_word (tword
);
7900 dispose_word (tword
);
7902 /* "$@" (a double-quoted dollar-at) expands into nothing,
7903 not even a NULL word, when there are no positional
7905 if (list
== 0 && has_dollar_at
)
7911 /* If we get "$@", we know we have expanded something, so we
7912 need to remember it for the final split on $IFS. This is
7913 a special case; it's the only case where a quoted string
7914 can expand into more than one word. It's going to come back
7915 from the above call to expand_word_internal as a list with
7916 a single word, in which all characters are quoted and
7917 separated by blanks. What we want to do is to turn it back
7918 into a list for the next piece of code. */
7920 dequote_list (list
);
7922 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7923 had_quoted_null
= 1;
7928 if (contains_dollar_at
)
7929 *contains_dollar_at
= 1;
7930 if (expanded_something
)
7931 *expanded_something
= 1;
7936 /* What we have is "". This is a minor optimization. */
7938 list
= (WORD_LIST
*)NULL
;
7941 /* The code above *might* return a list (consider the case of "$@",
7942 where it returns "$1", "$2", etc.). We can't throw away the
7943 rest of the list, and we have to make sure each word gets added
7944 as quoted. We test on tresult->next: if it is non-NULL, we
7945 quote the whole list, save it to a string with string_list, and
7946 add that string. We don't need to quote the results of this
7947 (and it would be wrong, since that would quote the separators
7948 as well), so we go directly to add_string. */
7953 /* Testing quoted_dollar_at makes sure that "$@" is
7954 split correctly when $IFS does not contain a space. */
7955 temp
= quoted_dollar_at
7956 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7957 : string_list (quote_list (list
));
7958 dispose_words (list
);
7963 temp
= savestring (list
->word
->word
);
7964 tflag
= list
->word
->flags
;
7965 dispose_words (list
);
7967 /* If the string is not a quoted null string, we want
7968 to remove any embedded unquoted CTLNUL characters.
7969 We do not want to turn quoted null strings back into
7970 the empty string, though. We do this because we
7971 want to remove any quoted nulls from expansions that
7972 contain other characters. For example, if we have
7973 x"$*"y or "x$*y" and there are no positional parameters,
7974 the $* should expand into nothing. */
7975 /* We use the W_HASQUOTEDNULL flag to differentiate the
7976 cases: a quoted null character as above and when
7977 CTLNUL is contained in the (non-null) expansion
7978 of some variable. We use the had_quoted_null flag to
7979 pass the value through this function to its caller. */
7980 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7981 remove_quoted_nulls (temp
); /* XXX */
7985 temp
= (char *)NULL
;
7987 /* We do not want to add quoted nulls to strings that are only
7988 partially quoted; we can throw them away. */
7989 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7997 temp
= quote_string (temp
);
8005 sindex
--; /* add_character: label increments sindex */
8013 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
8015 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8020 temp
= string_extract_single_quoted (string
, &sindex
);
8022 /* If the entire STRING was surrounded by single quotes,
8023 then the string is wholly quoted. */
8024 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8028 /* If all we had was '', it is a null expansion. */
8032 temp
= (char *)NULL
;
8035 remove_quoted_escapes (temp
); /* ??? */
8037 /* We do not want to add quoted nulls to strings that are only
8038 partially quoted; such nulls are discarded. */
8039 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
8042 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8046 sindex
--; /* add_character: label increments sindex */
8050 goto add_quoted_string
;
8055 /* This is the fix for " $@ " */
8057 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
8059 if (string
[sindex
]) /* from old goto dollar_add_string */
8068 #if HANDLE_MULTIBYTE
8074 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8079 twochars
[0] = CTLESC
;
8086 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
8089 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
8090 DEFAULT_ARRAY_SIZE
);
8091 istring
[istring_index
++] = c
;
8092 istring
[istring_index
] = '\0';
8094 /* Next character. */
8099 finished_with_string
:
8100 /* OK, we're ready to return. If we have a quoted string, and
8101 quoted_dollar_at is not set, we do no splitting at all; otherwise
8102 we split on ' '. The routines that call this will handle what to
8103 do if nothing has been expanded. */
8105 /* Partially and wholly quoted strings which expand to the empty
8106 string are retained as an empty arguments. Unquoted strings
8107 which expand to the empty string are discarded. The single
8108 exception is the case of expanding "$@" when there are no
8109 positional parameters. In that case, we discard the expansion. */
8111 /* Because of how the code that handles "" and '' in partially
8112 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8113 if we saw quoting characters, but the expansion was empty.
8114 "" and '' are tossed away before we get to this point when
8115 processing partially quoted strings. This makes "" and $xxx""
8116 equivalent when xxx is unset. We also look to see whether we
8117 saw a quoted null from a ${} expansion and add one back if we
8120 /* If we expand to nothing and there were no single or double quotes
8121 in the word, we throw it away. Otherwise, we return a NULL word.
8122 The single exception is for $@ surrounded by double quotes when
8123 there are no positional parameters. In that case, we also throw
8126 if (*istring
== '\0')
8128 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
8130 istring
[0] = CTLNUL
;
8132 tword
= make_bare_word (istring
);
8133 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8134 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8135 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8136 tword
->flags
|= W_QUOTED
;
8138 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8139 and a double-quoted "$@" appears anywhere in it, then the entire
8141 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8142 list
= (WORD_LIST
*)NULL
;
8146 tword
= make_bare_word (istring
);
8147 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8148 tword
->flags
|= W_QUOTED
;
8149 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8153 list
= (WORD_LIST
*)NULL
;
8156 else if (word
->flags
& W_NOSPLIT
)
8158 tword
= make_bare_word (istring
);
8159 if (word
->flags
& W_ASSIGNMENT
)
8160 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8161 if (word
->flags
& W_COMPASSIGN
)
8162 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8163 if (word
->flags
& W_NOGLOB
)
8164 tword
->flags
|= W_NOGLOB
; /* XXX */
8165 if (word
->flags
& W_NOEXPAND
)
8166 tword
->flags
|= W_NOEXPAND
; /* XXX */
8167 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8168 tword
->flags
|= W_QUOTED
;
8169 if (had_quoted_null
)
8170 tword
->flags
|= W_HASQUOTEDNULL
;
8171 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8177 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8179 /* If we have $@, we need to split the results no matter what. If
8180 IFS is unset or NULL, string_list_dollar_at has separated the
8181 positional parameters with a space, so we split on space (we have
8182 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8183 string_list_dollar_at has separated the positional parameters
8184 with the first character of $IFS, so we split on $IFS. */
8185 if (has_dollar_at
&& ifs_chars
)
8186 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8189 tword
= make_bare_word (istring
);
8190 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8191 tword
->flags
|= W_QUOTED
;
8192 if (word
->flags
& W_ASSIGNMENT
)
8193 tword
->flags
|= W_ASSIGNMENT
;
8194 if (word
->flags
& W_COMPASSIGN
)
8195 tword
->flags
|= W_COMPASSIGN
;
8196 if (word
->flags
& W_NOGLOB
)
8197 tword
->flags
|= W_NOGLOB
;
8198 if (word
->flags
& W_NOEXPAND
)
8199 tword
->flags
|= W_NOEXPAND
;
8200 if (had_quoted_null
)
8201 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8202 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8210 /* **************************************************************** */
8212 /* Functions for Quote Removal */
8214 /* **************************************************************** */
8216 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8217 backslash quoting rules for within double quotes or a here document. */
8219 string_quote_removal (string
, quoted
)
8224 char *r
, *result_string
, *temp
, *send
;
8225 int sindex
, tindex
, dquote
;
8229 /* The result can be no longer than the original string. */
8230 slen
= strlen (string
);
8231 send
= string
+ slen
;
8233 r
= result_string
= (char *)xmalloc (slen
+ 1);
8235 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8240 c
= string
[++sindex
];
8246 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8251 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8255 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8261 tindex
= sindex
+ 1;
8262 temp
= string_extract_single_quoted (string
, &tindex
);
8273 dquote
= 1 - dquote
;
8279 return (result_string
);
8284 /* Perform quote removal on word WORD. This allocates and returns a new
8287 word_quote_removal (word
, quoted
)
8294 t
= string_quote_removal (word
->word
, quoted
);
8295 w
= alloc_word_desc ();
8296 w
->word
= t
? t
: savestring ("");
8300 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8301 the members of the list are treated as if they are surrounded by
8302 double quotes. Return a new list, or NULL if LIST is NULL. */
8304 word_list_quote_removal (list
, quoted
)
8308 WORD_LIST
*result
, *t
, *tresult
, *e
;
8310 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8312 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8314 result
= (WORD_LIST
*) list_append (result
, tresult
);
8317 result
= e
= tresult
;
8330 /*******************************************
8332 * Functions to perform word splitting *
8334 *******************************************/
8344 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8346 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8347 handle multibyte chars in IFS */
8348 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8349 for (t
= ifs_value
; t
&& *t
; t
++)
8355 #if defined (HANDLE_MULTIBYTE)
8358 ifs_firstc
[0] = '\0';
8364 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8365 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8366 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8368 ifs_firstc
[0] = ifs_value
[0];
8369 ifs_firstc
[1] = '\0';
8373 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8376 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8386 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8387 is not quoted. list_string () performs quote removal for us, even if we
8388 don't do any splitting. */
8390 word_split (w
, ifs_chars
)
8400 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8401 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8404 result
= (WORD_LIST
*)NULL
;
8409 /* Perform word splitting on LIST and return the RESULT. It is possible
8410 to return (WORD_LIST *)NULL. */
8412 word_list_split (list
)
8415 WORD_LIST
*result
, *t
, *tresult
, *e
;
8417 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8419 tresult
= word_split (t
->word
, ifs_value
);
8421 result
= e
= tresult
;
8432 /**************************************************
8434 * Functions to expand an entire WORD_LIST *
8436 **************************************************/
8438 /* Do any word-expansion-specific cleanup and jump to top_level */
8440 exp_jump_to_top_level (v
)
8443 set_pipestatus_from_exit (last_command_exit_value
);
8445 /* Cleanup code goes here. */
8446 expand_no_split_dollar_star
= 0; /* XXX */
8447 expanding_redir
= 0;
8448 assigning_in_environment
= 0;
8450 if (parse_and_execute_level
== 0)
8451 top_level_cleanup (); /* from sig.c */
8453 jump_to_top_level (v
);
8456 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8457 ELIST, and set ELIST to the new list. */
8458 #define PREPEND_LIST(nlist, elist) \
8459 do { nlist->next = elist; elist = nlist; } while (0)
8461 /* Separate out any initial variable assignments from TLIST. If set -k has
8462 been executed, remove all assignment statements from TLIST. Initial
8463 variable assignments and other environment assignments are placed
8464 on SUBST_ASSIGN_VARLIST. */
8466 separate_out_assignments (tlist
)
8469 register WORD_LIST
*vp
, *lp
;
8472 return ((WORD_LIST
*)NULL
);
8474 if (subst_assign_varlist
)
8475 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8477 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8480 /* Separate out variable assignments at the start of the command.
8481 Loop invariant: vp->next == lp
8483 lp = list of words left after assignment statements skipped
8484 tlist = original list of words
8486 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8492 /* If lp != tlist, we have some initial assignment statements.
8493 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8494 words and TLIST point to the remaining words. */
8497 subst_assign_varlist
= tlist
;
8498 /* ASSERT(vp->next == lp); */
8499 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8500 tlist
= lp
; /* remainder of word list */
8503 /* vp == end of variable list */
8504 /* tlist == remainder of original word list without variable assignments */
8506 /* All the words in tlist were assignment statements */
8507 return ((WORD_LIST
*)NULL
);
8509 /* ASSERT(tlist != NULL); */
8510 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8512 /* If the -k option is in effect, we need to go through the remaining
8513 words, separate out the assignment words, and place them on
8514 SUBST_ASSIGN_VARLIST. */
8515 if (place_keywords_in_env
)
8517 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8522 /* Loop Invariant: tp->next == lp */
8523 /* Loop postcondition: tlist == word list without assignment statements */
8526 if (lp
->word
->flags
& W_ASSIGNMENT
)
8528 /* Found an assignment statement, add this word to end of
8529 subst_assign_varlist (vp). */
8530 if (!subst_assign_varlist
)
8531 subst_assign_varlist
= vp
= lp
;
8538 /* Remove the word pointed to by LP from TLIST. */
8539 tp
->next
= lp
->next
;
8540 /* ASSERT(vp == lp); */
8541 lp
->next
= (WORD_LIST
*)NULL
;
8554 #define WEXP_VARASSIGN 0x001
8555 #define WEXP_BRACEEXP 0x002
8556 #define WEXP_TILDEEXP 0x004
8557 #define WEXP_PARAMEXP 0x008
8558 #define WEXP_PATHEXP 0x010
8560 /* All of the expansions, including variable assignments at the start of
8562 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8564 /* All of the expansions except variable assignments at the start of
8566 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8568 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8569 expansion, command substitution, arithmetic expansion, word splitting, and
8571 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8573 /* Take the list of words in LIST and do the various substitutions. Return
8574 a new list of words which is the expanded list, and without things like
8575 variable assignments. */
8581 return (expand_word_list_internal (list
, WEXP_ALL
));
8584 /* Same as expand_words (), but doesn't hack variable or environment
8587 expand_words_no_vars (list
)
8590 return (expand_word_list_internal (list
, WEXP_NOVARS
));
8594 expand_words_shellexp (list
)
8597 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
8601 glob_expand_word_list (tlist
, eflags
)
8605 char **glob_array
, *temp_string
;
8606 register int glob_index
;
8607 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
8610 output_list
= disposables
= (WORD_LIST
*)NULL
;
8611 glob_array
= (char **)NULL
;
8614 /* For each word, either globbing is attempted or the word is
8615 added to orig_list. If globbing succeeds, the results are
8616 added to orig_list and the word (tlist) is added to the list
8617 of disposable words. If globbing fails and failed glob
8618 expansions are left unchanged (the shell default), the
8619 original word is added to orig_list. If globbing fails and
8620 failed glob expansions are removed, the original word is
8621 added to the list of disposable words. orig_list ends up
8622 in reverse order and requires a call to REVERSE_LIST to
8623 be set right. After all words are examined, the disposable
8627 /* If the word isn't an assignment and contains an unquoted
8628 pattern matching character, then glob it. */
8629 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
8630 unquoted_glob_pattern_p (tlist
->word
->word
))
8632 glob_array
= shell_glob_filename (tlist
->word
->word
);
8634 /* Handle error cases.
8635 I don't think we should report errors like "No such file
8636 or directory". However, I would like to report errors
8637 like "Read failed". */
8639 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
8641 glob_array
= (char **)xmalloc (sizeof (char *));
8642 glob_array
[0] = (char *)NULL
;
8645 /* Dequote the current word in case we have to use it. */
8646 if (glob_array
[0] == NULL
)
8648 temp_string
= dequote_string (tlist
->word
->word
);
8649 free (tlist
->word
->word
);
8650 tlist
->word
->word
= temp_string
;
8653 /* Make the array into a word list. */
8654 glob_list
= (WORD_LIST
*)NULL
;
8655 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
8657 tword
= make_bare_word (glob_array
[glob_index
]);
8658 tword
->flags
|= W_GLOBEXP
; /* XXX */
8659 glob_list
= make_word_list (tword
, glob_list
);
8664 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
8665 PREPEND_LIST (tlist
, disposables
);
8667 else if (fail_glob_expansion
!= 0)
8669 report_error (_("no match: %s"), tlist
->word
->word
);
8670 exp_jump_to_top_level (DISCARD
);
8672 else if (allow_null_glob_expansion
== 0)
8674 /* Failed glob expressions are left unchanged. */
8675 PREPEND_LIST (tlist
, output_list
);
8679 /* Failed glob expressions are removed. */
8680 PREPEND_LIST (tlist
, disposables
);
8685 /* Dequote the string. */
8686 temp_string
= dequote_string (tlist
->word
->word
);
8687 free (tlist
->word
->word
);
8688 tlist
->word
->word
= temp_string
;
8689 PREPEND_LIST (tlist
, output_list
);
8692 strvec_dispose (glob_array
);
8693 glob_array
= (char **)NULL
;
8699 dispose_words (disposables
);
8702 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8704 return (output_list
);
8707 #if defined (BRACE_EXPANSION)
8709 brace_expand_word_list (tlist
, eflags
)
8713 register char **expansions
;
8715 WORD_LIST
*disposables
, *output_list
, *next
;
8719 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
8723 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8725 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
8726 PREPEND_LIST (tlist
, output_list
);
8730 /* Only do brace expansion if the word has a brace character. If
8731 not, just add the word list element to BRACES and continue. In
8732 the common case, at least when running shell scripts, this will
8733 degenerate to a bunch of calls to `mbschr', and then what is
8734 basically a reversal of TLIST into BRACES, which is corrected
8735 by a call to REVERSE_LIST () on BRACES when the end of TLIST
8737 if (mbschr (tlist
->word
->word
, LBRACE
))
8739 expansions
= brace_expand (tlist
->word
->word
);
8741 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
8743 w
= make_word (temp_string
);
8744 /* If brace expansion didn't change the word, preserve
8745 the flags. We may want to preserve the flags
8746 unconditionally someday -- XXX */
8747 if (STREQ (temp_string
, tlist
->word
->word
))
8748 w
->flags
= tlist
->word
->flags
;
8749 output_list
= make_word_list (w
, output_list
);
8750 free (expansions
[eindex
]);
8754 /* Add TLIST to the list of words to be freed after brace
8755 expansion has been performed. */
8756 PREPEND_LIST (tlist
, disposables
);
8759 PREPEND_LIST (tlist
, output_list
);
8763 dispose_words (disposables
);
8766 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8768 return (output_list
);
8772 #if defined (ARRAY_VARS)
8773 /* Take WORD, a compound associative array assignment, and internally run
8774 'declare -A w', where W is the variable name portion of WORD. */
8776 make_internal_declare (word
, option
)
8784 w
= make_word (word
);
8786 t
= assignment (w
->word
, 0);
8789 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
8790 wl
= make_word_list (make_word (option
), wl
);
8792 return (declare_builtin (wl
));
8797 shell_expand_word_list (tlist
, eflags
)
8801 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
8802 int expanded_something
, has_dollar_at
;
8805 /* We do tilde expansion all the time. This is what 1003.2 says. */
8806 new_list
= (WORD_LIST
*)NULL
;
8807 for (orig_list
= tlist
; tlist
; tlist
= next
)
8809 temp_string
= tlist
->word
->word
;
8813 #if defined (ARRAY_VARS)
8814 /* If this is a compound array assignment to a builtin that accepts
8815 such assignments (e.g., `declare'), take the assignment and perform
8816 it separately, handling the semantics of declarations inside shell
8817 functions. This avoids the double-evaluation of such arguments,
8818 because `declare' does some evaluation of compound assignments on
8820 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8824 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
8825 make_internal_declare (tlist
->word
->word
, "-A");
8827 t
= do_word_assignment (tlist
->word
);
8830 last_command_exit_value
= EXECUTION_FAILURE
;
8831 exp_jump_to_top_level (DISCARD
);
8834 /* Now transform the word as ksh93 appears to do and go on */
8835 t
= assignment (tlist
->word
->word
, 0);
8836 tlist
->word
->word
[t
] = '\0';
8837 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
8841 expanded_something
= 0;
8842 expanded
= expand_word_internal
8843 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
8845 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
8847 /* By convention, each time this error is returned,
8848 tlist->word->word has already been freed. */
8849 tlist
->word
->word
= (char *)NULL
;
8851 /* Dispose our copy of the original list. */
8852 dispose_words (orig_list
);
8853 /* Dispose the new list we're building. */
8854 dispose_words (new_list
);
8856 last_command_exit_value
= EXECUTION_FAILURE
;
8857 if (expanded
== &expand_word_error
)
8858 exp_jump_to_top_level (DISCARD
);
8860 exp_jump_to_top_level (FORCE_EOF
);
8863 /* Don't split words marked W_NOSPLIT. */
8864 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
8866 temp_list
= word_list_split (expanded
);
8867 dispose_words (expanded
);
8871 /* If no parameter expansion, command substitution, process
8872 substitution, or arithmetic substitution took place, then
8873 do not do word splitting. We still have to remove quoted
8874 null characters from the result. */
8875 word_list_remove_quoted_nulls (expanded
);
8876 temp_list
= expanded
;
8879 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8880 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8884 dispose_words (orig_list
);
8887 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8892 /* The workhorse for expand_words () and expand_words_no_vars ().
8893 First arg is LIST, a WORD_LIST of words.
8894 Second arg EFLAGS is a flags word controlling which expansions are
8897 This does all of the substitutions: brace expansion, tilde expansion,
8898 parameter expansion, command substitution, arithmetic expansion,
8899 process substitution, word splitting, and pathname expansion, according
8900 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8901 set, or for which no expansion is done, do not undergo word splitting.
8902 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8904 expand_word_list_internal (list
, eflags
)
8908 WORD_LIST
*new_list
, *temp_list
;
8912 return ((WORD_LIST
*)NULL
);
8914 garglist
= new_list
= copy_word_list (list
);
8915 if (eflags
& WEXP_VARASSIGN
)
8917 garglist
= new_list
= separate_out_assignments (new_list
);
8920 if (subst_assign_varlist
)
8922 /* All the words were variable assignments, so they are placed
8923 into the shell's environment. */
8924 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8926 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8927 tint
= do_word_assignment (temp_list
->word
);
8928 /* Variable assignment errors in non-interactive shells
8929 running in Posix.2 mode cause the shell to exit. */
8932 last_command_exit_value
= EXECUTION_FAILURE
;
8933 if (interactive_shell
== 0 && posixly_correct
)
8934 exp_jump_to_top_level (FORCE_EOF
);
8936 exp_jump_to_top_level (DISCARD
);
8939 dispose_words (subst_assign_varlist
);
8940 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8942 return ((WORD_LIST
*)NULL
);
8946 /* Begin expanding the words that remain. The expansions take place on
8947 things that aren't really variable assignments. */
8949 #if defined (BRACE_EXPANSION)
8950 /* Do brace expansion on this word if there are any brace characters
8952 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8953 new_list
= brace_expand_word_list (new_list
, eflags
);
8954 #endif /* BRACE_EXPANSION */
8956 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8957 variable substitution, command substitution, arithmetic expansion,
8958 and word splitting. */
8959 new_list
= shell_expand_word_list (new_list
, eflags
);
8961 /* Okay, we're almost done. Now let's just do some filename
8965 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8966 /* Glob expand the word list unless globbing has been disabled. */
8967 new_list
= glob_expand_word_list (new_list
, eflags
);
8969 /* Dequote the words, because we're not performing globbing. */
8970 new_list
= dequote_list (new_list
);
8973 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8975 sh_wassign_func_t
*assign_func
;
8977 /* If the remainder of the words expand to nothing, Posix.2 requires
8978 that the variable and environment assignments affect the shell's
8980 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8981 tempenv_assign_error
= 0;
8983 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8985 this_command_name
= (char *)NULL
;
8986 assigning_in_environment
= (assign_func
== assign_in_env
);
8987 tint
= (*assign_func
) (temp_list
->word
);
8988 assigning_in_environment
= 0;
8989 /* Variable assignment errors in non-interactive shells running
8990 in Posix.2 mode cause the shell to exit. */
8993 if (assign_func
== do_word_assignment
)
8995 last_command_exit_value
= EXECUTION_FAILURE
;
8996 if (interactive_shell
== 0 && posixly_correct
)
8997 exp_jump_to_top_level (FORCE_EOF
);
8999 exp_jump_to_top_level (DISCARD
);
9002 tempenv_assign_error
++;
9006 dispose_words (subst_assign_varlist
);
9007 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9011 tint
= list_length (new_list
) + 1;
9012 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
9013 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
9014 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
9015 glob_argv_flags
[tint
] = '\0';