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-2013 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
48 #include "execute_cmd.h"
52 #include "mailcheck.h"
57 #include "builtins/getopt.h"
58 #include "builtins/common.h"
60 #include "builtins/builtext.h"
62 #include <tilde/tilde.h>
63 #include <glob/strmatch.h>
69 /* The size that strings change by. */
70 #define DEFAULT_INITIAL_ARRAY_SIZE 112
71 #define DEFAULT_ARRAY_SIZE 128
77 #define VT_ARRAYMEMBER 3
80 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
82 /* Flags for quoted_strchr */
83 #define ST_BACKSL 0x01
84 #define ST_CTLESC 0x02
85 #define ST_SQUOTE 0x04 /* unused yet */
86 #define ST_DQUOTE 0x08 /* unused yet */
88 /* Flags for the `pflags' argument to param_expand() */
89 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
91 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
92 #define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */
94 /* These defs make it easier to use the editor. */
100 #if defined (HANDLE_MULTIBYTE)
105 /* Evaluates to 1 if C is one of the shell's special parameters whose length
106 can be taken, but is also one of the special expansion characters. */
107 #define VALID_SPECIAL_LENGTH_PARAM(c) \
108 ((c) == '-' || (c) == '?' || (c) == '#')
110 /* Evaluates to 1 if C is one of the shell's special parameters for which an
111 indirect variable reference may be made. */
112 #define VALID_INDIR_PARAM(c) \
113 ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
115 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
116 in ${parameter[:]OPword}. */
117 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
119 /* Evaluates to 1 if this is one of the shell's special variables. */
120 #define SPECIAL_VAR(name, wi) \
121 ((DIGIT (*name) && all_digits (name)) || \
122 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
123 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
125 /* An expansion function that takes a string and a quoted flag and returns
126 a WORD_LIST *. Used as the type of the third argument to
127 expand_string_if_necessary(). */
128 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
130 /* Process ID of the last command executed within command substitution. */
131 pid_t last_command_subst_pid
= NO_PID
;
132 pid_t current_command_subst_pid
= NO_PID
;
134 /* Variables used to keep track of the characters in IFS. */
137 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
138 int ifs_is_set
, ifs_is_null
;
140 #if defined (HANDLE_MULTIBYTE)
141 unsigned char ifs_firstc
[MB_LEN_MAX
];
142 size_t ifs_firstc_len
;
144 unsigned char ifs_firstc
;
147 /* Sentinel to tell when we are performing variable assignments preceding a
148 command name and putting them into the environment. Used to make sure
149 we use the temporary environment when looking up variable values. */
150 int assigning_in_environment
;
152 /* Used to hold a list of variable assignments preceding a command. Global
153 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
154 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
155 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
157 /* Extern functions and variables from different files. */
158 extern int last_command_exit_value
, last_command_exit_signal
;
159 extern int subshell_environment
, line_number
;
160 extern int subshell_level
, parse_and_execute_level
, sourcelevel
;
161 extern int eof_encountered
;
162 extern int return_catch_flag
, return_catch_value
;
163 extern pid_t dollar_dollar_pid
;
164 extern int posixly_correct
;
165 extern char *this_command_name
;
166 extern struct fd_bitmap
*current_fds_to_close
;
167 extern int wordexp_only
;
168 extern int expanding_redir
;
169 extern int tempenv_assign_error
;
170 extern int builtin_ignoring_errexit
;
172 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
173 extern wchar_t *wcsdup
__P((const wchar_t *));
176 /* Non-zero means to allow unmatched globbed filenames to expand to
178 int allow_null_glob_expansion
;
180 /* Non-zero means to throw an error when globbing fails to match anything. */
181 int fail_glob_expansion
;
184 /* Variables to keep track of which words in an expanded word list (the
185 output of expand_word_list_internal) are the result of globbing
186 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
187 (CURRENTLY UNUSED). */
188 char *glob_argv_flags
;
189 static int glob_argv_flags_size
;
192 static WORD_LIST expand_word_error
, expand_word_fatal
;
193 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
194 static char expand_param_error
, expand_param_fatal
;
195 static char extract_string_error
, extract_string_fatal
;
197 /* Tell the expansion functions to not longjmp back to top_level on fatal
198 errors. Enabled when doing completion and prompt string expansion. */
199 static int no_longjmp_on_fatal_error
= 0;
201 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
202 $* on $IFS, primarily when doing assignment statements. */
203 static int expand_no_split_dollar_star
= 0;
205 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
206 without any leading variable assignments. */
207 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
209 static char *quoted_substring
__P((char *, int, int));
210 static int quoted_strlen
__P((char *));
211 static char *quoted_strchr
__P((char *, int, int));
213 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
214 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
215 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
216 static WORD_LIST
*expand_string_internal
__P((char *, int));
217 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
218 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
220 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
221 static char *make_quoted_char
__P((int));
222 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
224 static int unquoted_substring
__P((char *, char *));
225 static int unquoted_member
__P((int, char *));
227 #if defined (ARRAY_VARS)
228 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
230 static int do_assignment_internal
__P((const WORD_DESC
*, int));
232 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
233 static char *string_extract
__P((char *, int *, char *, int));
234 static char *string_extract_double_quoted
__P((char *, int *, int));
235 static inline char *string_extract_single_quoted
__P((char *, int *));
236 static inline int skip_single_quoted
__P((const char *, size_t, int));
237 static int skip_double_quoted
__P((char *, size_t, int));
238 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
239 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
240 static int skip_matched_pair
__P((const char *, int, int, int, int));
242 static char *pos_params
__P((char *, int, int, int));
244 static unsigned char *mb_getcharlens
__P((char *, int));
246 static char *remove_upattern
__P((char *, char *, int));
247 #if defined (HANDLE_MULTIBYTE)
248 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
250 static char *remove_pattern
__P((char *, char *, int));
252 static int match_upattern
__P((char *, char *, int, char **, char **));
253 #if defined (HANDLE_MULTIBYTE)
254 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
256 static int match_pattern
__P((char *, char *, int, char **, char **));
257 static int getpatspec
__P((int, char *));
258 static char *getpattern
__P((char *, int, int));
259 static char *variable_remove_pattern
__P((char *, char *, int, int));
260 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
261 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
263 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
265 static char *parameter_brace_remove_pattern
__P((char *, char *, int, char *, int, int, int));
267 static char *process_substitute
__P((char *, int));
269 static char *read_comsub
__P((int, int, int *));
272 static arrayind_t array_length_reference
__P((char *));
275 static int valid_brace_expansion_word
__P((char *, int));
276 static int chk_atstar
__P((char *, int, int *, int *));
277 static int chk_arithsub
__P((const char *, int));
279 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int, arrayind_t
*));
280 static char *parameter_brace_find_indir
__P((char *, int, int, int));
281 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
282 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
283 static void parameter_brace_expand_error
__P((char *, char *));
285 static int valid_length_expression
__P((char *));
286 static intmax_t parameter_brace_expand_length
__P((char *));
288 static char *skiparith
__P((char *, int));
289 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
290 static int get_var_and_type
__P((char *, char *, arrayind_t
, int, int, SHELL_VAR
**, char **));
291 static char *mb_substring
__P((char *, int, int));
292 static char *parameter_brace_substring
__P((char *, char *, int, char *, int, int));
294 static int shouldexp_replacement
__P((char *));
296 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
298 static char *parameter_brace_patsub
__P((char *, char *, int, char *, int, int));
300 static char *pos_params_casemod
__P((char *, char *, int, int));
301 static char *parameter_brace_casemod
__P((char *, char *, int, int, char *, int, int));
303 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int, int *, int *));
304 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
306 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
308 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
310 static void exp_jump_to_top_level
__P((int));
312 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
313 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
314 #ifdef BRACE_EXPANSION
315 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
317 #if defined (ARRAY_VARS)
318 static int make_internal_declare
__P((char *, char *));
320 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
321 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
323 /* **************************************************************** */
325 /* Utility Functions */
327 /* **************************************************************** */
331 dump_word_flags (flags
)
337 fprintf (stderr
, "%d -> ", f
);
338 if (f
& W_ASSIGNASSOC
)
341 fprintf (stderr
, "W_ASSIGNASSOC%s", f
? "|" : "");
343 if (f
& W_ASSIGNARRAY
)
346 fprintf (stderr
, "W_ASSIGNARRAY%s", f
? "|" : "");
351 fprintf (stderr
, "W_HASCTLESC%s", f
? "|" : "");
356 fprintf (stderr
, "W_NOPROCSUB%s", f
? "|" : "");
361 fprintf (stderr
, "W_DQUOTE%s", f
? "|" : "");
363 if (f
& W_HASQUOTEDNULL
)
365 f
&= ~W_HASQUOTEDNULL
;
366 fprintf (stderr
, "W_HASQUOTEDNULL%s", f
? "|" : "");
371 fprintf (stderr
, "W_ASSIGNARG%s", f
? "|" : "");
376 fprintf (stderr
, "W_ASSNBLTIN%s", f
? "|" : "");
378 if (f
& W_ASSNGLOBAL
)
381 fprintf (stderr
, "W_ASSNGLOBAL%s", f
? "|" : "");
386 fprintf (stderr
, "W_ASSIGNINT%s", f
? "|" : "");
388 if (f
& W_COMPASSIGN
)
391 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
396 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
401 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
406 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
411 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
416 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
418 if (f
& W_DOLLARSTAR
)
421 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
426 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
431 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
436 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
441 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
446 fprintf (stderr
, "W_NOBRACE%s", f
? "|" : "");
451 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
453 if (f
& W_SPLITSPACE
)
456 fprintf (stderr
, "W_SPLITSPACE%s", f
? "|" : "");
458 if (f
& W_ASSIGNMENT
)
461 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
466 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
471 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
473 fprintf (stderr
, "\n");
478 #ifdef INCLUDE_UNUSED
480 quoted_substring (string
, start
, end
)
485 register char *result
, *s
, *r
;
489 /* Move to string[start], skipping quoted characters. */
490 for (s
= string
, l
= 0; *s
&& l
< start
; )
502 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
504 /* Copy LEN characters, including quote characters. */
506 for (l
= 0; l
< len
; s
++)
520 #ifdef INCLUDE_UNUSED
521 /* Return the length of S, skipping over quoted characters */
545 /* Find the first occurrence of character C in string S, obeying shell
546 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
547 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
548 escaped with CTLESC are skipped. */
550 quoted_strchr (s
, c
, flags
)
558 if (((flags
& ST_BACKSL
) && *p
== '\\')
559 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
563 return ((char *)NULL
);
569 return ((char *)NULL
);
572 /* Return 1 if CHARACTER appears in an unquoted portion of
573 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
575 unquoted_member (character
, string
)
583 slen
= strlen (string
);
585 while (c
= string
[sindex
])
593 ADVANCE_CHAR (string
, slen
, sindex
);
599 ADVANCE_CHAR (string
, slen
, sindex
);
603 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
607 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
614 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
616 unquoted_substring (substr
, string
)
617 char *substr
, *string
;
620 int sindex
, c
, sublen
;
623 if (substr
== 0 || *substr
== '\0')
626 slen
= strlen (string
);
627 sublen
= strlen (substr
);
628 for (sindex
= 0; c
= string
[sindex
]; )
630 if (STREQN (string
+ sindex
, substr
, sublen
))
638 ADVANCE_CHAR (string
, slen
, sindex
);
642 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
646 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
650 ADVANCE_CHAR (string
, slen
, sindex
);
657 /* Most of the substitutions must be done in parallel. In order
658 to avoid using tons of unclear goto's, I have some functions
659 for manipulating malloc'ed strings. They all take INDX, a
660 pointer to an integer which is the offset into the string
661 where manipulation is taking place. They also take SIZE, a
662 pointer to an integer which is the current length of the
663 character array for this string. */
665 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
666 of space allocated to TARGET. SOURCE can be NULL, in which
667 case nothing happens. Gets rid of SOURCE by freeing it.
668 Returns TARGET in case the location has changed. */
670 sub_append_string (source
, target
, indx
, size
)
671 char *source
, *target
;
678 srclen
= STRLEN (source
);
679 if (srclen
>= (int)(*size
- *indx
))
682 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
683 target
= (char *)xrealloc (target
, (*size
= n
));
686 FASTCOPY (source
, target
+ *indx
, srclen
);
688 target
[*indx
] = '\0';
697 /* Append the textual representation of NUMBER to TARGET.
698 INDX and SIZE are as in SUB_APPEND_STRING. */
700 sub_append_number (number
, target
, indx
, size
)
707 temp
= itos (number
);
708 return (sub_append_string (temp
, target
, indx
, size
));
712 /* Extract a substring from STRING, starting at SINDEX and ending with
713 one of the characters in CHARLIST. Don't make the ending character
714 part of the string. Leave SINDEX pointing at the ending character.
715 Understand about backslashes in the string. If (flags & SX_VARNAME)
716 is non-zero, and array variables have been compiled into the shell,
717 everything between a `[' and a corresponding `]' is skipped over.
718 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
719 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
720 contain a closing character from CHARLIST. */
722 string_extract (string
, sindex
, charlist
, flags
)
734 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
737 while (c
= string
[i
])
746 #if defined (ARRAY_VARS)
747 else if ((flags
& SX_VARNAME
) && c
== '[')
750 /* If this is an array subscript, skip over it and continue. */
751 ni
= skipsubscript (string
, i
, 0);
752 if (string
[ni
] == ']')
756 else if (MEMBER (c
, charlist
))
762 ADVANCE_CHAR (string
, slen
, i
);
765 /* If we had to have a matching delimiter and didn't find one, return an
766 error and let the caller deal with it. */
767 if ((flags
& SX_REQMATCH
) && found
== 0)
770 return (&extract_string_error
);
773 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
779 /* Extract the contents of STRING as if it is enclosed in double quotes.
780 SINDEX, when passed in, is the offset of the character immediately
781 following the opening double quote; on exit, SINDEX is left pointing after
782 the closing double quote. If STRIPDQ is non-zero, unquoted double
783 quotes are stripped and the string is terminated by a null byte.
784 Backslashes between the embedded double quotes are processed. If STRIPDQ
785 is zero, an unquoted `"' terminates the string. */
787 string_extract_double_quoted (string
, sindex
, stripdq
)
789 int *sindex
, stripdq
;
795 char *temp
, *ret
; /* The new string we return. */
796 int pass_next
, backquote
, si
; /* State variables for the machine. */
800 slen
= strlen (string
+ *sindex
) + *sindex
;
801 send
= string
+ slen
;
803 pass_next
= backquote
= dquote
= 0;
804 temp
= (char *)xmalloc (1 + slen
- *sindex
);
808 while (c
= string
[i
])
810 /* Process a character that was quoted by a backslash. */
813 /* XXX - take another look at this in light of Interp 221 */
816 ``The backslash shall retain its special meaning as an escape
817 character only when followed by one of the characters:
820 If STRIPDQ is zero, we handle the double quotes here and let
821 expand_word_internal handle the rest. If STRIPDQ is non-zero,
822 we have already been through one round of backslash stripping,
823 and want to strip these backslashes only if DQUOTE is non-zero,
824 indicating that we are inside an embedded double-quoted string. */
826 /* If we are in an embedded quoted string, then don't strip
827 backslashes before characters for which the backslash
828 retains its special meaning, but remove backslashes in
829 front of other characters. If we are not in an
830 embedded quoted string, don't strip backslashes at all.
831 This mess is necessary because the string was already
832 surrounded by double quotes (and sh has some really weird
834 The returned string will be run through expansion as if
835 it were double-quoted. */
836 if ((stripdq
== 0 && c
!= '"') ||
837 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
842 COPY_CHAR_I (temp
, j
, string
, send
, i
);
846 /* A backslash protects the next character. The code just above
847 handles preserving the backslash in front of any character but
856 /* Inside backquotes, ``the portion of the quoted string from the
857 initial backquote and the characters up to the next backquote
858 that is not preceded by a backslash, having escape characters
859 removed, defines that command''. */
877 /* Pass everything between `$(' and the matching `)' or a quoted
878 ${ ... } pair through according to the Posix.2 specification. */
879 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
884 if (string
[i
+ 1] == LPAREN
)
885 ret
= extract_command_subst (string
, &si
, 0);
887 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, 0);
890 temp
[j
++] = string
[i
+ 1];
892 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
894 if (ret
== 0 && no_longjmp_on_fatal_error
)
897 ret
= string
+ i
+ 2;
900 for (t
= 0; ret
[t
]; t
++, j
++)
902 temp
[j
] = string
[si
];
917 /* Add any character but a double quote to the quoted string we're
920 goto add_one_character
;
934 /* Point to after the closing quote. */
942 /* This should really be another option to string_extract_double_quoted. */
944 skip_double_quoted (string
, slen
, sind
)
951 int pass_next
, backquote
, si
;
954 pass_next
= backquote
= 0;
956 while (c
= string
[i
])
961 ADVANCE_CHAR (string
, slen
, i
);
974 ADVANCE_CHAR (string
, slen
, i
);
983 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
986 if (string
[i
+ 1] == LPAREN
)
987 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
989 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, SX_NOALLOC
);
996 ADVANCE_CHAR (string
, slen
, i
);
1009 /* Extract the contents of STRING as if it is enclosed in single quotes.
1010 SINDEX, when passed in, is the offset of the character immediately
1011 following the opening single quote; on exit, SINDEX is left pointing after
1012 the closing single quote. */
1013 static inline char *
1014 string_extract_single_quoted (string
, sindex
)
1023 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1024 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
1026 while (string
[i
] && string
[i
] != '\'')
1027 ADVANCE_CHAR (string
, slen
, i
);
1029 t
= substring (string
, *sindex
, i
);
1039 skip_single_quoted (string
, slen
, sind
)
1048 while (string
[c
] && string
[c
] != '\'')
1049 ADVANCE_CHAR (string
, slen
, c
);
1056 /* Just like string_extract, but doesn't hack backslashes or any of
1057 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1059 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1067 #if defined (HANDLE_MULTIBYTE)
1075 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1077 temp
= string_extract_single_quoted (string
, sindex
);
1078 --*sindex
; /* leave *sindex at separator character */
1084 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1085 this only if MB_CUR_MAX > 1. */
1086 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1088 #if defined (HANDLE_MULTIBYTE)
1089 clen
= strlen (charlist
);
1092 while (c
= string
[i
])
1094 #if defined (HANDLE_MULTIBYTE)
1097 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1102 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1103 through, to protect the CTLNULs from later calls to
1104 remove_quoted_nulls. */
1105 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1111 #if defined (HANDLE_MULTIBYTE)
1112 mblength
= MBLEN (string
+ i
, slen
- i
);
1116 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1117 if (MB_INVALIDCH (mblength
))
1119 if (MEMBER (c
, charlist
))
1127 len
= mbstowcs (wcharlist
, charlist
, 0);
1130 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1131 mbstowcs (wcharlist
, charlist
, len
+ 1);
1134 if (wcschr (wcharlist
, wc
))
1140 if (MEMBER (c
, charlist
))
1143 ADVANCE_CHAR (string
, slen
, i
);
1146 #if defined (HANDLE_MULTIBYTE)
1150 temp
= substring (string
, *sindex
, i
);
1156 /* Extract the $( construct in STRING, and return a new string.
1157 Start extracting at (SINDEX) as if we had just seen "$(".
1158 Make (SINDEX) get the position of the matching ")". )
1159 XFLAGS is additional flags to pass to other extraction functions. */
1161 extract_command_subst (string
, sindex
, xflags
)
1166 if (string
[*sindex
] == LPAREN
)
1167 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1170 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1171 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1175 /* Extract the $[ construct in STRING, and return a new string. (])
1176 Start extracting at (SINDEX) as if we had just seen "$[".
1177 Make (SINDEX) get the position of the matching "]". */
1179 extract_arithmetic_subst (string
, sindex
)
1183 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1186 #if defined (PROCESS_SUBSTITUTION)
1187 /* Extract the <( or >( construct in STRING, and return a new string.
1188 Start extracting at (SINDEX) as if we had just seen "<(".
1189 Make (SINDEX) get the position of the matching ")". */ /*))*/
1191 extract_process_subst (string
, starter
, sindex
)
1196 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", SX_COMMAND
));
1198 #endif /* PROCESS_SUBSTITUTION */
1200 #if defined (ARRAY_VARS)
1201 /* This can be fooled by unquoted right parens in the passed string. If
1202 each caller verifies that the last character in STRING is a right paren,
1203 we don't even need to call extract_delimited_string. */
1205 extract_array_assignment_list (string
, sindex
)
1212 slen
= strlen (string
); /* ( */
1213 if (string
[slen
- 1] == ')')
1215 ret
= substring (string
, *sindex
, slen
- 1);
1223 /* Extract and create a new string from the contents of STRING, a
1224 character string delimited with OPENER and CLOSER. SINDEX is
1225 the address of an int describing the current offset in STRING;
1226 it should point to just after the first OPENER found. On exit,
1227 SINDEX gets the position of the last character of the matching CLOSER.
1228 If OPENER is more than a single character, ALT_OPENER, if non-null,
1229 contains a character string that can also match CLOSER and thus
1230 needs to be skipped. */
1232 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1235 char *opener
, *alt_opener
, *closer
;
1241 int pass_character
, nesting_level
, in_comment
;
1242 int len_closer
, len_opener
, len_alt_opener
;
1245 slen
= strlen (string
+ *sindex
) + *sindex
;
1246 len_opener
= STRLEN (opener
);
1247 len_alt_opener
= STRLEN (alt_opener
);
1248 len_closer
= STRLEN (closer
);
1250 pass_character
= in_comment
= 0;
1255 while (nesting_level
)
1266 ADVANCE_CHAR (string
, slen
, i
);
1270 if (pass_character
) /* previous char was backslash */
1273 ADVANCE_CHAR (string
, slen
, i
);
1277 /* Not exactly right yet; should handle shell metacharacters and
1278 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1279 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1282 ADVANCE_CHAR (string
, slen
, i
);
1286 if (c
== CTLESC
|| c
== '\\')
1293 /* Process a nested command substitution, but only if we're parsing an
1294 arithmetic substitution. */
1295 if ((flags
& SX_COMMAND
) && string
[i
] == '$' && string
[i
+1] == LPAREN
)
1298 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1303 /* Process a nested OPENER. */
1304 if (STREQN (string
+ i
, opener
, len_opener
))
1306 si
= i
+ len_opener
;
1307 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1312 /* Process a nested ALT_OPENER */
1313 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1315 si
= i
+ len_alt_opener
;
1316 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1321 /* If the current substring terminates the delimited string, decrement
1322 the nesting level. */
1323 if (STREQN (string
+ i
, closer
, len_closer
))
1325 i
+= len_closer
- 1; /* move to last byte of the closer */
1327 if (nesting_level
== 0)
1331 /* Pass old-style command substitution through verbatim. */
1335 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1340 /* Pass single-quoted and double-quoted strings through verbatim. */
1341 if (c
== '\'' || c
== '"')
1344 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1345 : skip_double_quoted (string
, slen
, si
);
1349 /* move past this character, which was not special. */
1350 ADVANCE_CHAR (string
, slen
, i
);
1353 if (c
== 0 && nesting_level
)
1355 if (no_longjmp_on_fatal_error
== 0)
1357 last_command_exit_value
= EXECUTION_FAILURE
;
1358 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1359 exp_jump_to_top_level (DISCARD
);
1364 return (char *)NULL
;
1368 si
= i
- *sindex
- len_closer
+ 1;
1369 if (flags
& SX_NOALLOC
)
1370 result
= (char *)NULL
;
1373 result
= (char *)xmalloc (1 + si
);
1374 strncpy (result
, string
+ *sindex
, si
);
1382 /* Extract a parameter expansion expression within ${ and } from STRING.
1383 Obey the Posix.2 rules for finding the ending `}': count braces while
1384 skipping over enclosed quoted strings and command substitutions.
1385 SINDEX is the address of an int describing the current offset in STRING;
1386 it should point to just after the first `{' found. On exit, SINDEX
1387 gets the position of the matching `}'. QUOTED is non-zero if this
1388 occurs inside double quotes. */
1389 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1391 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1393 int *sindex
, quoted
, flags
;
1397 int pass_character
, nesting_level
, si
, dolbrace_state
;
1403 slen
= strlen (string
+ *sindex
) + *sindex
;
1405 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1406 parse_matched_pair(). The different initial value is to handle the
1407 case where this function is called to parse the word in
1408 ${param op word} (SX_WORD). */
1409 dolbrace_state
= (flags
& SX_WORD
) ? DOLBRACE_WORD
: DOLBRACE_PARAM
;
1410 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && (flags
& SX_POSIXEXP
))
1411 dolbrace_state
= DOLBRACE_QUOTE
;
1414 while (c
= string
[i
])
1419 ADVANCE_CHAR (string
, slen
, i
);
1423 /* CTLESCs and backslashes quote the next character. */
1424 if (c
== CTLESC
|| c
== '\\')
1431 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1441 if (nesting_level
== 0)
1447 /* Pass the contents of old-style command substitutions through
1452 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1457 /* Pass the contents of new-style command substitutions and
1458 arithmetic substitutions through verbatim. */
1459 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1462 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1467 /* Pass the contents of double-quoted strings through verbatim. */
1471 i
= skip_double_quoted (string
, slen
, si
);
1472 /* skip_XXX_quoted leaves index one past close quote */
1478 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1479 if (posixly_correct
&& shell_compatibility_level
> 42 && dolbrace_state
!= DOLBRACE_QUOTE
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1480 ADVANCE_CHAR (string
, slen
, i
);
1484 i
= skip_single_quoted (string
, slen
, si
);
1490 /* move past this character, which was not special. */
1491 ADVANCE_CHAR (string
, slen
, i
);
1493 /* This logic must agree with parse.y:parse_matched_pair, since they
1494 share the same defines. */
1495 if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '%' && (i
- *sindex
) > 1)
1496 dolbrace_state
= DOLBRACE_QUOTE
;
1497 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '#' && (i
- *sindex
) > 1)
1498 dolbrace_state
= DOLBRACE_QUOTE
;
1499 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '/' && (i
- *sindex
) > 1)
1500 dolbrace_state
= DOLBRACE_QUOTE2
; /* XXX */
1501 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '^' && (i
- *sindex
) > 1)
1502 dolbrace_state
= DOLBRACE_QUOTE
;
1503 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== ',' && (i
- *sindex
) > 1)
1504 dolbrace_state
= DOLBRACE_QUOTE
;
1505 else if (dolbrace_state
== DOLBRACE_PARAM
&& strchr ("#%^,~:-=?+/", c
) != 0)
1506 dolbrace_state
= DOLBRACE_OP
;
1507 else if (dolbrace_state
== DOLBRACE_OP
&& strchr ("#%^,~:-=?+/", c
) == 0)
1508 dolbrace_state
= DOLBRACE_WORD
;
1511 if (c
== 0 && nesting_level
)
1513 if (no_longjmp_on_fatal_error
== 0)
1515 last_command_exit_value
= EXECUTION_FAILURE
;
1516 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1517 exp_jump_to_top_level (DISCARD
);
1522 return ((char *)NULL
);
1526 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1532 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1533 STRING, and returns a pointer to it. */
1535 de_backslash (string
)
1538 register size_t slen
;
1539 register int i
, j
, prev_i
;
1542 slen
= strlen (string
);
1545 /* Loop copying string[i] to string[j], i >= j. */
1548 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1549 string
[i
+ 1] == '$'))
1552 ADVANCE_CHAR (string
, slen
, i
);
1554 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1565 /* Replace instances of \! in a string with !. */
1567 unquote_bang (string
)
1571 register char *temp
;
1573 temp
= (char *)xmalloc (1 + strlen (string
));
1575 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1577 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1583 strcpy (string
, temp
);
1588 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1590 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1591 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1592 matched pairs of quotes or backquotes, or skip word expansions; it is
1593 intended to be used after expansion has been performed and during final
1594 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1596 skip_matched_pair (string
, start
, open
, close
, flags
)
1598 int start
, open
, close
, flags
;
1600 int i
, pass_next
, backq
, si
, c
, count
;
1605 slen
= strlen (string
+ start
) + start
;
1606 no_longjmp_on_fatal_error
= 1;
1608 i
= start
+ 1; /* skip over leading bracket */
1610 pass_next
= backq
= 0;
1611 ss
= (char *)string
;
1612 while (c
= string
[i
])
1619 ADVANCE_CHAR (string
, slen
, i
);
1632 ADVANCE_CHAR (string
, slen
, i
);
1635 else if ((flags
& 1) == 0 && c
== '`')
1641 else if ((flags
& 1) == 0 && c
== open
)
1647 else if (c
== close
)
1655 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1657 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1658 : skip_double_quoted (ss
, slen
, ++i
);
1659 /* no increment, the skip functions increment past the closing quote. */
1661 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1664 if (string
[si
] == '\0')
1667 if (string
[i
+1] == LPAREN
)
1668 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1670 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1672 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1678 ADVANCE_CHAR (string
, slen
, i
);
1684 #if defined (ARRAY_VARS)
1686 skipsubscript (string
, start
, flags
)
1690 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1694 /* Skip characters in STRING until we find a character in DELIMS, and return
1695 the index of that character. START is the index into string at which we
1696 begin. This is similar in spirit to strpbrk, but it returns an index into
1697 STRING and takes a starting index. This little piece of code knows quite
1698 a lot of shell syntax. It's very similar to skip_double_quoted and other
1699 functions of that ilk. */
1701 skip_to_delim (string
, start
, delims
, flags
)
1707 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
, skipcmd
;
1709 char *temp
, open
[3];
1712 slen
= strlen (string
+ start
) + start
;
1713 if (flags
& SD_NOJMP
)
1714 no_longjmp_on_fatal_error
= 1;
1715 invert
= (flags
& SD_INVERT
);
1716 skipcmd
= (flags
& SD_NOSKIPCMD
) == 0;
1719 pass_next
= backq
= 0;
1720 while (c
= string
[i
])
1722 /* If this is non-zero, we should not let quote characters be delimiters
1723 and the current character is a single or double quote. We should not
1724 test whether or not it's a delimiter until after we skip single- or
1725 double-quoted strings. */
1726 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1732 ADVANCE_CHAR (string
, slen
, i
);
1745 ADVANCE_CHAR (string
, slen
, i
);
1754 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1756 else if (c
== '\'' || c
== '"')
1758 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1759 : skip_double_quoted (string
, slen
, ++i
);
1760 /* no increment, the skip functions increment past the closing quote. */
1762 else if (c
== '$' && ((skipcmd
&& string
[i
+1] == LPAREN
) || string
[i
+1] == LBRACE
))
1765 if (string
[si
] == '\0')
1768 if (string
[i
+1] == LPAREN
)
1769 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1771 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1773 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1778 #if defined (PROCESS_SUBSTITUTION)
1779 else if (skipcmd
&& (c
== '<' || c
== '>') && string
[i
+1] == LPAREN
)
1782 if (string
[si
] == '\0')
1784 temp
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &si
);
1785 free (temp
); /* no SX_ALLOC here */
1787 if (string
[i
] == '\0')
1792 #endif /* PROCESS_SUBSTITUTION */
1793 #if defined (EXTENDED_GLOB)
1794 else if ((flags
& SD_EXTGLOB
) && extended_glob
&& string
[i
+1] == LPAREN
&& member (c
, "?*+!@"))
1797 if (string
[si
] == '\0')
1803 temp
= extract_delimited_string (string
, &si
, open
, "(", ")", SX_NOALLOC
); /* ) */
1806 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1812 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1815 ADVANCE_CHAR (string
, slen
, i
);
1821 #if defined (READLINE)
1822 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1823 an unclosed quoted string), or if the character at EINDEX is quoted
1824 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1825 single and double-quoted string parsing functions should not return an
1826 error if there are unclosed quotes or braces. The characters that this
1827 recognizes need to be the same as the contents of
1828 rl_completer_quote_characters. */
1831 char_is_quoted (string
, eindex
)
1835 int i
, pass_next
, c
;
1839 slen
= strlen (string
);
1840 no_longjmp_on_fatal_error
= 1;
1849 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1851 ADVANCE_CHAR (string
, slen
, i
);
1860 else if (c
== '\'' || c
== '"')
1862 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1863 : skip_double_quoted (string
, slen
, ++i
);
1866 /* no increment, the skip_xxx functions go one past end */
1869 ADVANCE_CHAR (string
, slen
, i
);
1876 unclosed_pair (string
, eindex
, openstr
)
1881 int i
, pass_next
, openc
, olen
;
1885 slen
= strlen (string
);
1886 olen
= strlen (openstr
);
1887 i
= pass_next
= openc
= 0;
1893 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1895 ADVANCE_CHAR (string
, slen
, i
);
1898 else if (string
[i
] == '\\')
1904 else if (STREQN (string
+ i
, openstr
, olen
))
1909 else if (string
[i
] == '\'' || string
[i
] == '"')
1911 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1912 : skip_double_quoted (string
, slen
, i
);
1917 ADVANCE_CHAR (string
, slen
, i
);
1922 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1923 individual words. If DELIMS is NULL, the current value of $IFS is used
1924 to split the string, and the function follows the shell field splitting
1925 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1926 gets the number of words in the returned list. CWP, if non-NULL, gets
1927 the index of the word containing SENTINEL. Non-whitespace chars in
1928 DELIMS delimit separate fields. */
1930 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1934 int sentinel
, flags
;
1937 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1938 char *token
, *d
, *d2
;
1939 WORD_LIST
*ret
, *tl
;
1941 if (string
== 0 || *string
== '\0')
1947 return ((WORD_LIST
*)NULL
);
1950 d
= (delims
== 0) ? ifs_value
: delims
;
1951 ifs_split
= delims
== 0;
1953 /* Make d2 the non-whitespace characters in delims */
1958 #if defined (HANDLE_MULTIBYTE)
1959 size_t mblength
= 1;
1963 slength
= strlen (delims
);
1964 d2
= (char *)xmalloc (slength
+ 1);
1968 #if defined (HANDLE_MULTIBYTE)
1969 mbstate_t state_bak
;
1971 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1972 if (MB_INVALIDCH (mblength
))
1974 else if (mblength
> 1)
1976 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1979 slength
-= mblength
;
1983 if (whitespace (delims
[i
]) == 0)
1984 d2
[ts
++] = delims
[i
];
1992 ret
= (WORD_LIST
*)NULL
;
1994 /* Remove sequences of whitespace characters at the start of the string, as
1995 long as those characters are delimiters. */
1996 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1998 if (string
[i
] == '\0')
2004 dflags
= flags
|SD_NOJMP
;
2007 te
= skip_to_delim (string
, ts
, d
, dflags
);
2009 /* If we have a non-whitespace delimiter character, use it to make a
2010 separate field. This is just about what $IFS splitting does and
2011 is closer to the behavior of the shell parser. */
2012 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
2015 /* If we're using IFS splitting, the non-whitespace delimiter char
2016 and any additional IFS whitespace delimits a field. */
2018 while (member (string
[te
], d
) && spctabnl (string
[te
]))
2021 while (member (string
[te
], d2
))
2025 token
= substring (string
, ts
, te
);
2027 ret
= add_string_to_list (token
, ret
);
2031 if (sentinel
>= ts
&& sentinel
<= te
)
2034 /* If the cursor is at whitespace just before word start, set the
2035 sentinel word to the current word. */
2036 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
2039 /* If the cursor is at whitespace between two words, make a new, empty
2040 word, add it before (well, after, since the list is in reverse order)
2041 the word we just added, and set the current word to that one. */
2042 if (cwp
&& cw
== -1 && sentinel
< ts
)
2044 tl
= make_word_list (make_word (""), ret
->next
);
2050 if (string
[te
] == 0)
2054 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
2063 /* Special case for SENTINEL at the end of STRING. If we haven't found
2064 the word containing SENTINEL yet, and the index we're looking for is at
2065 the end of STRING (or past the end of the previously-found token,
2066 possible if the end of the line is composed solely of IFS whitespace)
2067 add an additional null argument and set the current word pointer to that. */
2068 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
2070 if (whitespace (string
[sentinel
- 1]))
2073 ret
= add_string_to_list (token
, ret
);
2086 return (REVERSE_LIST (ret
, WORD_LIST
*));
2088 #endif /* READLINE */
2092 /* Extract the name of the variable to bind to from the assignment string. */
2094 assignment_name (string
)
2100 offset
= assignment (string
, 0);
2102 return (char *)NULL
;
2103 temp
= substring (string
, 0, offset
);
2108 /* **************************************************************** */
2110 /* Functions to convert strings to WORD_LISTs and vice versa */
2112 /* **************************************************************** */
2114 /* Return a single string of all the words in LIST. SEP is the separator
2115 to put between individual elements of LIST in the output string. */
2117 string_list_internal (list
, sep
)
2121 register WORD_LIST
*t
;
2123 int word_len
, sep_len
, result_size
;
2126 return ((char *)NULL
);
2128 /* Short-circuit quickly if we don't need to separate anything. */
2129 if (list
->next
== 0)
2130 return (savestring (list
->word
->word
));
2132 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2133 sep_len
= STRLEN (sep
);
2136 for (t
= list
; t
; t
= t
->next
)
2139 result_size
+= sep_len
;
2140 result_size
+= strlen (t
->word
->word
);
2143 r
= result
= (char *)xmalloc (result_size
+ 1);
2145 for (t
= list
; t
; t
= t
->next
)
2147 if (t
!= list
&& sep_len
)
2151 FASTCOPY (sep
, r
, sep_len
);
2158 word_len
= strlen (t
->word
->word
);
2159 FASTCOPY (t
->word
->word
, r
, word_len
);
2167 /* Return a single string of all the words present in LIST, separating
2168 each word with a space. */
2173 return (string_list_internal (list
, " "));
2176 /* An external interface that can be used by the rest of the shell to
2177 obtain a string containing the first character in $IFS. Handles all
2178 the multibyte complications. If LENP is non-null, it is set to the
2179 length of the returned string. */
2181 ifs_firstchar (lenp
)
2187 ret
= xmalloc (MB_LEN_MAX
+ 1);
2188 #if defined (HANDLE_MULTIBYTE)
2189 if (ifs_firstc_len
== 1)
2191 ret
[0] = ifs_firstc
[0];
2193 len
= ret
[0] ? 1 : 0;
2197 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2198 ret
[len
= ifs_firstc_len
] = '\0';
2201 ret
[0] = ifs_firstc
;
2203 len
= ret
[0] ? 0 : 1;
2212 /* Return a single string of all the words present in LIST, obeying the
2213 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2214 expansion [of $*] appears within a double quoted string, it expands
2215 to a single field with the value of each parameter separated by the
2216 first character of the IFS variable, or by a <space> if IFS is unset." */
2218 string_list_dollar_star (list
)
2222 #if defined (HANDLE_MULTIBYTE)
2223 # if defined (__GNUC__)
2224 char sep
[MB_CUR_MAX
+ 1];
2232 #if defined (HANDLE_MULTIBYTE)
2233 # if !defined (__GNUC__)
2234 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2235 # endif /* !__GNUC__ */
2236 if (ifs_firstc_len
== 1)
2238 sep
[0] = ifs_firstc
[0];
2243 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2244 sep
[ifs_firstc_len
] = '\0';
2247 sep
[0] = ifs_firstc
;
2251 ret
= string_list_internal (list
, sep
);
2252 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2258 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2259 is non-zero, the $@ appears within double quotes, and we should quote
2260 the list before converting it into a string. If IFS is unset, and the
2261 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2262 in the words in the list, because the default value of $IFS is
2263 <space><tab><newline>, IFS characters in the words in the list should
2264 also be split. If IFS is null, and the word is not quoted, we need
2265 to quote the words in the list to preserve the positional parameters
2268 string_list_dollar_at (list
, quoted
)
2273 #if defined (HANDLE_MULTIBYTE)
2274 # if defined (__GNUC__)
2275 char sep
[MB_CUR_MAX
+ 1];
2278 # endif /* !__GNUC__ */
2284 /* XXX this could just be ifs = ifs_value; */
2285 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2287 #if defined (HANDLE_MULTIBYTE)
2288 # if !defined (__GNUC__)
2289 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2290 # endif /* !__GNUC__ */
2293 if (ifs_firstc_len
== 1)
2295 sep
[0] = ifs_firstc
[0];
2300 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2301 sep
[ifs_firstc_len
] = '\0';
2310 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2314 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2315 it now that quote_escapes quotes spaces */
2316 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2318 : list_quote_escapes (list
);
2320 ret
= string_list_internal (tlist
, sep
);
2321 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2327 /* Turn the positional parameters into a string, understanding quoting and
2328 the various subtleties of using the first character of $IFS as the
2329 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2330 string_list as appropriate. */
2332 string_list_pos_params (pchar
, list
, quoted
)
2340 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2342 tlist
= quote_list (list
);
2343 word_list_remove_quoted_nulls (tlist
);
2344 ret
= string_list_dollar_star (tlist
);
2346 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2348 tlist
= quote_list (list
);
2349 word_list_remove_quoted_nulls (tlist
);
2350 ret
= string_list (tlist
);
2352 else if (pchar
== '*')
2354 /* Even when unquoted, string_list_dollar_star does the right thing
2355 making sure that the first character of $IFS is used as the
2357 ret
= string_list_dollar_star (list
);
2359 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2360 /* We use string_list_dollar_at, but only if the string is quoted, since
2361 that quotes the escapes if it's not, which we don't want. We could
2362 use string_list (the old code did), but that doesn't do the right
2363 thing if the first character of $IFS is not a space. We use
2364 string_list_dollar_star if the string is unquoted so we make sure that
2365 the elements of $@ are separated by the first character of $IFS for
2367 ret
= string_list_dollar_at (list
, quoted
);
2368 else if (pchar
== '@')
2369 ret
= string_list_dollar_star (list
);
2371 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2376 /* Return the list of words present in STRING. Separate the string into
2377 words at any of the characters found in SEPARATORS. If QUOTED is
2378 non-zero then word in the list will have its quoted flag set, otherwise
2379 the quoted flag is left as make_word () deemed fit.
2381 This obeys the P1003.2 word splitting semantics. If `separators' is
2382 exactly <space><tab><newline>, then the splitting algorithm is that of
2383 the Bourne shell, which treats any sequence of characters from `separators'
2384 as a delimiter. If IFS is unset, which results in `separators' being set
2385 to "", no splitting occurs. If separators has some other value, the
2386 following rules are applied (`IFS white space' means zero or more
2387 occurrences of <space>, <tab>, or <newline>, as long as those characters
2388 are in `separators'):
2390 1) IFS white space is ignored at the start and the end of the
2392 2) Each occurrence of a character in `separators' that is not
2393 IFS white space, along with any adjacent occurrences of
2394 IFS white space delimits a field.
2395 3) Any nonzero-length sequence of IFS white space delimits a field.
2398 /* BEWARE! list_string strips null arguments. Don't call it twice and
2399 expect to have "" preserved! */
2401 /* This performs word splitting and quoted null character removal on
2404 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2405 : (c) == (separators)[0]) \
2409 list_string (string
, separators
, quoted
)
2410 register char *string
, *separators
;
2415 char *current_word
, *s
;
2416 int sindex
, sh_style_split
, whitesep
, xflags
;
2419 if (!string
|| !*string
)
2420 return ((WORD_LIST
*)NULL
);
2422 sh_style_split
= separators
&& separators
[0] == ' ' &&
2423 separators
[1] == '\t' &&
2424 separators
[2] == '\n' &&
2425 separators
[3] == '\0';
2426 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2428 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2429 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2433 /* Remove sequences of whitespace at the beginning of STRING, as
2434 long as those characters appear in IFS. Do not do this if
2435 STRING is quoted or if there are no separator characters. */
2436 if (!quoted
|| !separators
|| !*separators
)
2438 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2441 return ((WORD_LIST
*)NULL
);
2446 /* OK, now STRING points to a word that does not begin with white space.
2447 The splitting algorithm is:
2448 extract a word, stopping at a separator
2449 skip sequences of spc, tab, or nl as long as they are separators
2450 This obeys the field splitting rules in Posix.2. */
2451 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2452 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2454 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2455 unless multibyte chars are possible. */
2456 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2457 if (current_word
== 0)
2460 /* If we have a quoted empty string, add a quoted null argument. We
2461 want to preserve the quoted null character iff this is a quoted
2462 empty string; otherwise the quoted null characters are removed
2464 if (QUOTED_NULL (current_word
))
2466 t
= alloc_word_desc ();
2467 t
->word
= make_quoted_char ('\0');
2468 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2469 result
= make_word_list (t
, result
);
2471 else if (current_word
[0] != '\0')
2473 /* If we have something, then add it regardless. However,
2474 perform quoted null character removal on the current word. */
2475 remove_quoted_nulls (current_word
);
2476 result
= add_string_to_list (current_word
, result
);
2477 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2478 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2479 result
->word
->flags
|= W_QUOTED
;
2482 /* If we're not doing sequences of separators in the traditional
2483 Bourne shell style, then add a quoted null argument. */
2484 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2486 t
= alloc_word_desc ();
2487 t
->word
= make_quoted_char ('\0');
2488 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2489 result
= make_word_list (t
, result
);
2492 free (current_word
);
2494 /* Note whether or not the separator is IFS whitespace, used later. */
2495 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2497 /* Move past the current separator character. */
2501 ADVANCE_CHAR (string
, slen
, sindex
);
2504 /* Now skip sequences of space, tab, or newline characters if they are
2505 in the list of separators. */
2506 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2509 /* If the first separator was IFS whitespace and the current character
2510 is a non-whitespace IFS character, it should be part of the current
2511 field delimiter, not a separate delimiter that would result in an
2512 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2513 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2516 /* An IFS character that is not IFS white space, along with any
2517 adjacent IFS white space, shall delimit a field. (SUSv3) */
2518 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2522 return (REVERSE_LIST (result
, WORD_LIST
*));
2525 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2526 ENDPTR is set to the first character after the word. This is used by
2527 the `read' builtin. This is never called with SEPARATORS != $IFS;
2528 it should be simplified.
2530 XXX - this function is very similar to list_string; they should be
2533 get_word_from_string (stringp
, separators
, endptr
)
2534 char **stringp
, *separators
, **endptr
;
2538 int sindex
, sh_style_split
, whitesep
, xflags
;
2541 if (!stringp
|| !*stringp
|| !**stringp
)
2542 return ((char *)NULL
);
2544 sh_style_split
= separators
&& separators
[0] == ' ' &&
2545 separators
[1] == '\t' &&
2546 separators
[2] == '\n' &&
2547 separators
[3] == '\0';
2548 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2550 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2551 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2557 /* Remove sequences of whitespace at the beginning of STRING, as
2558 long as those characters appear in IFS. */
2559 if (sh_style_split
|| !separators
|| !*separators
)
2561 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2563 /* If the string is nothing but whitespace, update it and return. */
2569 return ((char *)NULL
);
2573 /* OK, S points to a word that does not begin with white space.
2574 Now extract a word, stopping at a separator, save a pointer to
2575 the first character after the word, then skip sequences of spc,
2576 tab, or nl as long as they are separators.
2578 This obeys the field splitting rules in Posix.2. */
2580 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2581 unless multibyte chars are possible. */
2582 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2583 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2585 /* Set ENDPTR to the first character after the end of the word. */
2587 *endptr
= s
+ sindex
;
2589 /* Note whether or not the separator is IFS whitespace, used later. */
2590 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2592 /* Move past the current separator character. */
2596 ADVANCE_CHAR (s
, slen
, sindex
);
2599 /* Now skip sequences of space, tab, or newline characters if they are
2600 in the list of separators. */
2601 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2604 /* If the first separator was IFS whitespace and the current character is
2605 a non-whitespace IFS character, it should be part of the current field
2606 delimiter, not a separate delimiter that would result in an empty field.
2607 Look at POSIX.2, 3.6.5, (3)(b). */
2608 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2611 /* An IFS character that is not IFS white space, along with any adjacent
2612 IFS white space, shall delimit a field. */
2613 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2617 /* Update STRING to point to the next field. */
2618 *stringp
= s
+ sindex
;
2619 return (current_word
);
2622 /* Remove IFS white space at the end of STRING. Start at the end
2623 of the string and walk backwards until the beginning of the string
2624 or we find a character that's not IFS white space and not CTLESC.
2625 Only let CTLESC escape a white space character if SAW_ESCAPE is
2628 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2629 char *string
, *separators
;
2634 s
= string
+ STRLEN (string
) - 1;
2635 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2636 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2644 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2645 backslashes, single and double quotes. */
2647 list_string_with_quotes (string
)
2653 int c
, i
, tokstart
, len
;
2655 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2657 if (s
== 0 || *s
== 0)
2658 return ((WORD_LIST
*)NULL
);
2662 list
= (WORD_LIST
*)NULL
;
2673 i
= skip_single_quoted (s
, s_len
, ++i
);
2675 i
= skip_double_quoted (s
, s_len
, ++i
);
2676 else if (c
== 0 || spctabnl (c
))
2678 /* We have found the end of a token. Make a word out of it and
2679 add it to the word list. */
2680 token
= substring (s
, tokstart
, i
);
2681 list
= add_string_to_list (token
, list
);
2683 while (spctabnl (s
[i
]))
2691 i
++; /* normal character */
2693 return (REVERSE_LIST (list
, WORD_LIST
*));
2697 /********************************************************/
2699 /* Functions to perform assignment statements */
2701 /********************************************************/
2703 #if defined (ARRAY_VARS)
2705 do_compound_assignment (name
, value
, flags
)
2710 int mklocal
, mkassoc
, mkglobal
;
2713 mklocal
= flags
& ASS_MKLOCAL
;
2714 mkassoc
= flags
& ASS_MKASSOC
;
2715 mkglobal
= flags
& ASS_MKGLOBAL
;
2717 if (mklocal
&& variable_context
)
2719 v
= find_variable (name
);
2720 list
= expand_compound_array_assignment (v
, value
, flags
);
2722 v
= make_local_assoc_variable (name
);
2723 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2724 v
= make_local_array_variable (name
, 0);
2726 assign_compound_array_list (v
, list
, flags
);
2728 /* In a function but forcing assignment in global context */
2729 else if (mkglobal
&& variable_context
)
2731 v
= find_global_variable (name
);
2732 list
= expand_compound_array_assignment (v
, value
, flags
);
2733 if (v
== 0 && mkassoc
)
2734 v
= make_new_assoc_variable (name
);
2735 else if (v
&& mkassoc
&& assoc_p (v
) == 0)
2736 v
= convert_var_to_assoc (v
);
2738 v
= make_new_array_variable (name
);
2739 else if (v
&& mkassoc
== 0 && array_p (v
) == 0)
2740 v
= convert_var_to_array (v
);
2742 assign_compound_array_list (v
, list
, flags
);
2745 v
= assign_array_from_string (name
, value
, flags
);
2751 /* Given STRING, an assignment string, get the value of the right side
2752 of the `=', and bind it to the left side. If EXPAND is true, then
2753 perform parameter expansion, command substitution, and arithmetic
2754 expansion on the right-hand side. Perform tilde expansion in any
2755 case. Do not perform word splitting on the result of expansion. */
2757 do_assignment_internal (word
, expand
)
2758 const WORD_DESC
*word
;
2761 int offset
, appendop
, assign_list
, aflags
, retval
;
2762 char *name
, *value
, *temp
;
2764 #if defined (ARRAY_VARS)
2770 if (word
== 0 || word
->word
== 0)
2773 appendop
= assign_list
= aflags
= 0;
2774 string
= word
->word
;
2775 offset
= assignment (string
, 0);
2776 name
= savestring (string
);
2777 value
= (char *)NULL
;
2779 if (name
[offset
] == '=')
2781 if (name
[offset
- 1] == '+')
2784 name
[offset
- 1] = '\0';
2787 name
[offset
] = 0; /* might need this set later */
2788 temp
= name
+ offset
+ 1;
2790 #if defined (ARRAY_VARS)
2791 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2793 assign_list
= ni
= 1;
2794 value
= extract_array_assignment_list (temp
, &ni
);
2798 if (expand
&& temp
[0])
2799 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2801 value
= savestring (temp
);
2806 value
= (char *)xmalloc (1);
2810 if (echo_command_at_execute
)
2813 name
[offset
- 1] = '+';
2814 xtrace_print_assignment (name
, value
, assign_list
, 1);
2816 name
[offset
- 1] = '\0';
2819 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2822 aflags
|= ASS_APPEND
;
2824 #if defined (ARRAY_VARS)
2825 if (t
= mbschr (name
, '[')) /*]*/
2829 report_error (_("%s: cannot assign list to array member"), name
);
2832 entry
= assign_array_element (name
, value
, aflags
);
2836 else if (assign_list
)
2838 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
) == 0)
2839 aflags
|= ASS_MKLOCAL
;
2840 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
))
2841 aflags
|= ASS_MKGLOBAL
;
2842 if (word
->flags
& W_ASSIGNASSOC
)
2843 aflags
|= ASS_MKASSOC
;
2844 entry
= do_compound_assignment (name
, value
, aflags
);
2847 #endif /* ARRAY_VARS */
2848 entry
= bind_variable (name
, value
, aflags
);
2850 stupidly_hack_special_variables (name
);
2852 /* Return 1 if the assignment seems to have been performed correctly. */
2853 if (entry
== 0 || readonly_p (entry
))
2854 retval
= 0; /* assignment failure */
2855 else if (noassign_p (entry
))
2857 last_command_exit_value
= EXECUTION_FAILURE
;
2858 retval
= 1; /* error status, but not assignment failure */
2863 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2864 VUNSETATTR (entry
, att_invisible
);
2866 ASSIGN_RETURN (retval
);
2869 /* Perform the assignment statement in STRING, and expand the
2870 right side by doing tilde, command and parameter expansion. */
2872 do_assignment (string
)
2877 td
.flags
= W_ASSIGNMENT
;
2880 return do_assignment_internal (&td
, 1);
2884 do_word_assignment (word
, flags
)
2888 return do_assignment_internal (word
, 1);
2891 /* Given STRING, an assignment string, get the value of the right side
2892 of the `=', and bind it to the left side. Do not perform any word
2893 expansions on the right hand side. */
2895 do_assignment_no_expand (string
)
2900 td
.flags
= W_ASSIGNMENT
;
2903 return (do_assignment_internal (&td
, 0));
2906 /***************************************************
2908 * Functions to manage the positional parameters *
2910 ***************************************************/
2912 /* Return the word list that corresponds to `$*'. */
2914 list_rest_of_args ()
2916 register WORD_LIST
*list
, *args
;
2919 /* Break out of the loop as soon as one of the dollar variables is null. */
2920 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2921 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2923 for (args
= rest_of_args
; args
; args
= args
->next
)
2924 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2926 return (REVERSE_LIST (list
, WORD_LIST
*));
2932 register WORD_LIST
*list
;
2935 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2937 for (list
= rest_of_args
; list
; list
= list
->next
)
2942 /* Return the value of a positional parameter. This handles values > 10. */
2944 get_dollar_var_value (ind
)
2951 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2952 else /* We want something like ${11} */
2955 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2957 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2962 /* Make a single large string out of the dollar digit variables,
2963 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2964 case of "$*" with respect to IFS. */
2966 string_rest_of_args (dollar_star
)
2969 register WORD_LIST
*list
;
2972 list
= list_rest_of_args ();
2973 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2974 dispose_words (list
);
2978 /* Return a string containing the positional parameters from START to
2979 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2980 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2981 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2982 no quoting chars are added. */
2984 pos_params (string
, start
, end
, quoted
)
2986 int start
, end
, quoted
;
2988 WORD_LIST
*save
, *params
, *h
, *t
;
2992 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2994 return ((char *)NULL
);
2996 save
= params
= list_rest_of_args ();
2998 return ((char *)NULL
);
3000 if (start
== 0) /* handle ${@:0[:x]} specially */
3002 t
= make_word_list (make_word (dollar_vars
[0]), params
);
3006 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
3007 params
= params
->next
;
3009 return ((char *)NULL
);
3010 for (h
= t
= params
; params
&& i
< end
; i
++)
3013 params
= params
->next
;
3016 t
->next
= (WORD_LIST
*)NULL
;
3018 ret
= string_list_pos_params (string
[0], h
, quoted
);
3023 dispose_words (save
);
3027 /******************************************************************/
3029 /* Functions to expand strings to strings or WORD_LISTs */
3031 /******************************************************************/
3033 #if defined (PROCESS_SUBSTITUTION)
3034 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3036 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3039 /* If there are any characters in STRING that require full expansion,
3040 then call FUNC to expand STRING; otherwise just perform quote
3041 removal if necessary. This returns a new string. */
3043 expand_string_if_necessary (string
, quoted
, func
)
3054 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3055 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3059 if (EXP_CHAR (string
[i
]))
3061 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3063 ADVANCE_CHAR (string
, slen
, i
);
3068 list
= (*func
) (string
, quoted
);
3071 ret
= string_list (list
);
3072 dispose_words (list
);
3077 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3078 ret
= string_quote_removal (string
, quoted
);
3080 ret
= savestring (string
);
3085 static inline char *
3086 expand_string_to_string_internal (string
, quoted
, func
)
3094 if (string
== 0 || *string
== '\0')
3095 return ((char *)NULL
);
3097 list
= (*func
) (string
, quoted
);
3100 ret
= string_list (list
);
3101 dispose_words (list
);
3110 expand_string_to_string (string
, quoted
)
3114 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
3118 expand_string_unsplit_to_string (string
, quoted
)
3122 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3126 expand_assignment_string_to_string (string
, quoted
)
3130 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3134 expand_arith_string (string
, quoted
)
3139 WORD_LIST
*list
, *tlist
;
3145 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3146 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3150 if (EXP_CHAR (string
[i
]))
3152 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3154 ADVANCE_CHAR (string
, slen
, i
);
3159 /* This is expanded version of expand_string_internal as it's called by
3160 expand_string_leave_quoted */
3161 td
.flags
= W_NOPROCSUB
; /* don't want process substitution */
3162 td
.word
= savestring (string
);
3163 list
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3164 /* This takes care of the calls from expand_string_leave_quoted and
3168 tlist
= word_list_split (list
);
3169 dispose_words (list
);
3172 dequote_list (list
);
3174 /* This comes from expand_string_if_necessary */
3177 ret
= string_list (list
);
3178 dispose_words (list
);
3184 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3185 ret
= string_quote_removal (string
, quoted
);
3187 ret
= savestring (string
);
3192 #if defined (COND_COMMAND)
3193 /* Just remove backslashes in STRING. Returns a new string. */
3195 remove_backslashes (string
)
3200 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3201 for (s
= string
; s
&& *s
; )
3213 /* This needs better error handling. */
3214 /* Expand W for use as an argument to a unary or binary operator in a
3215 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3216 to the != or == operator, and should be treated as a pattern. In
3217 this case, we quote the string specially for the globbing code. If
3218 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3219 be quoted appropriately for regcomp/regexec. The caller is responsible
3220 for removing the backslashes if the unquoted word is needed later. */
3222 cond_expand_word (w
, special
)
3230 if (w
->word
== 0 || w
->word
[0] == '\0')
3231 return ((char *)NULL
);
3233 w
->flags
|= W_NOSPLIT2
;
3234 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3240 r
= string_list (l
);
3244 qflags
= QGLOB_CVTNULL
;
3246 qflags
|= QGLOB_REGEXP
;
3247 p
= string_list (l
);
3248 r
= quote_string_for_globbing (p
, qflags
);
3260 /* Call expand_word_internal to expand W and handle error returns.
3261 A convenience function for functions that don't want to handle
3262 any errors or free any memory before aborting. */
3264 call_expand_word_internal (w
, q
, i
, c
, e
)
3270 result
= expand_word_internal (w
, q
, i
, c
, e
);
3271 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3273 /* By convention, each time this error is returned, w->word has
3274 already been freed (it sometimes may not be in the fatal case,
3275 but that doesn't result in a memory leak because we're going
3276 to exit in most cases). */
3277 w
->word
= (char *)NULL
;
3278 last_command_exit_value
= EXECUTION_FAILURE
;
3279 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3287 /* Perform parameter expansion, command substitution, and arithmetic
3288 expansion on STRING, as if it were a word. Leave the result quoted.
3289 Since this does not perform word splitting, it leaves quoted nulls
3292 expand_string_internal (string
, quoted
)
3299 if (string
== 0 || *string
== 0)
3300 return ((WORD_LIST
*)NULL
);
3303 td
.word
= savestring (string
);
3305 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3311 /* Expand STRING by performing parameter expansion, command substitution,
3312 and arithmetic expansion. Dequote the resulting WORD_LIST before
3313 returning it, but do not perform word splitting. The call to
3314 remove_quoted_nulls () is in here because word splitting normally
3315 takes care of quote removal. */
3317 expand_string_unsplit (string
, quoted
)
3323 if (string
== 0 || *string
== '\0')
3324 return ((WORD_LIST
*)NULL
);
3326 expand_no_split_dollar_star
= 1;
3327 value
= expand_string_internal (string
, quoted
);
3328 expand_no_split_dollar_star
= 0;
3334 remove_quoted_nulls (value
->word
->word
);
3335 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3337 dequote_list (value
);
3342 /* Expand the rhs of an assignment statement */
3344 expand_string_assignment (string
, quoted
)
3351 if (string
== 0 || *string
== '\0')
3352 return ((WORD_LIST
*)NULL
);
3354 expand_no_split_dollar_star
= 1;
3356 td
.flags
= W_ASSIGNRHS
;
3357 td
.word
= savestring (string
);
3358 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3361 expand_no_split_dollar_star
= 0;
3367 remove_quoted_nulls (value
->word
->word
);
3368 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3370 dequote_list (value
);
3376 /* Expand one of the PS? prompt strings. This is a sort of combination of
3377 expand_string_unsplit and expand_string_internal, but returns the
3378 passed string when an error occurs. Might want to trap other calls
3379 to jump_to_top_level here so we don't endlessly loop. */
3381 expand_prompt_string (string
, quoted
, wflags
)
3389 if (string
== 0 || *string
== 0)
3390 return ((WORD_LIST
*)NULL
);
3393 td
.word
= savestring (string
);
3395 no_longjmp_on_fatal_error
= 1;
3396 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3397 no_longjmp_on_fatal_error
= 0;
3399 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3401 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3409 remove_quoted_nulls (value
->word
->word
);
3410 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3412 dequote_list (value
);
3417 /* Expand STRING just as if you were expanding a word, but do not dequote
3418 the resultant WORD_LIST. This is called only from within this file,
3419 and is used to correctly preserve quoted characters when expanding
3420 things like ${1+"$@"}. This does parameter expansion, command
3421 substitution, arithmetic expansion, and word splitting. */
3423 expand_string_leave_quoted (string
, quoted
)
3430 if (string
== 0 || *string
== '\0')
3431 return ((WORD_LIST
*)NULL
);
3433 tlist
= expand_string_internal (string
, quoted
);
3437 tresult
= word_list_split (tlist
);
3438 dispose_words (tlist
);
3441 return ((WORD_LIST
*)NULL
);
3444 /* This does not perform word splitting or dequote the WORD_LIST
3447 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3449 int quoted
, *dollar_at_p
, *has_dollar_at
;
3454 if (string
== 0 || *string
== '\0')
3455 return (WORD_LIST
*)NULL
;
3457 td
.flags
= W_NOSPLIT2
; /* no splitting, remove "" and '' */
3459 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3463 /* Expand STRING just as if you were expanding a word. This also returns
3464 a list of words. Note that filename globbing is *NOT* done for word
3465 or string expansion, just when the shell is expanding a command. This
3466 does parameter expansion, command substitution, arithmetic expansion,
3467 and word splitting. Dequote the resultant WORD_LIST before returning. */
3469 expand_string (string
, quoted
)
3475 if (string
== 0 || *string
== '\0')
3476 return ((WORD_LIST
*)NULL
);
3478 result
= expand_string_leave_quoted (string
, quoted
);
3479 return (result
? dequote_list (result
) : result
);
3482 /***************************************************
3484 * Functions to handle quoting chars *
3486 ***************************************************/
3490 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3491 The parser passes CTLNUL as CTLESC CTLNUL. */
3493 /* Quote escape characters in string s, but no other characters. This is
3494 used to protect CTLESC and CTLNUL in variable values from the rest of
3495 the word expansion process after the variable is expanded (word splitting
3496 and filename generation). If IFS is null, we quote spaces as well, just
3497 in case we split on spaces later (in the case of unquoted $@, we will
3498 eventually attempt to split the entire word on spaces). Corresponding
3499 code exists in dequote_escapes. Even if we don't end up splitting on
3500 spaces, quoting spaces is not a problem. This should never be called on
3501 a string that is quoted with single or double quotes or part of a here
3502 document (effectively double-quoted). */
3504 quote_escapes (string
)
3507 register char *s
, *t
;
3509 char *result
, *send
;
3510 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3513 slen
= strlen (string
);
3514 send
= string
+ slen
;
3516 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3518 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3519 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3521 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3526 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3528 COPY_CHAR_P (t
, s
, send
);
3535 list_quote_escapes (list
)
3538 register WORD_LIST
*w
;
3541 for (w
= list
; w
; w
= w
->next
)
3544 w
->word
->word
= quote_escapes (t
);
3550 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3552 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3553 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3554 data stream pass through properly.
3556 We need to remove doubled CTLESC characters inside quoted strings before
3557 quoting the entire string, so we do not double the number of CTLESC
3560 Also used by parts of the pattern substitution code. */
3562 dequote_escapes (string
)
3565 register char *s
, *t
, *s1
;
3567 char *result
, *send
;
3574 slen
= strlen (string
);
3575 send
= string
+ slen
;
3577 t
= result
= (char *)xmalloc (slen
+ 1);
3579 if (strchr (string
, CTLESC
) == 0)
3580 return (strcpy (result
, string
));
3582 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3587 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3593 COPY_CHAR_P (t
, s
, send
);
3599 /* Return a new string with the quoted representation of character C.
3600 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3601 set in any resultant WORD_DESC where this value is the word. */
3603 make_quoted_char (c
)
3608 temp
= (char *)xmalloc (3);
3623 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3624 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3625 this value is the word. */
3627 quote_string (string
)
3632 char *result
, *send
;
3636 result
= (char *)xmalloc (2);
3644 slen
= strlen (string
);
3645 send
= string
+ slen
;
3647 result
= (char *)xmalloc ((slen
* 2) + 1);
3649 for (t
= result
; string
< send
; )
3652 COPY_CHAR_P (t
, string
, send
);
3659 /* De-quote quoted characters in STRING. */
3661 dequote_string (string
)
3664 register char *s
, *t
;
3666 char *result
, *send
;
3669 slen
= strlen (string
);
3671 t
= result
= (char *)xmalloc (slen
+ 1);
3673 if (QUOTED_NULL (string
))
3679 /* If no character in the string can be quoted, don't bother examining
3680 each character. Just return a copy of the string passed to us. */
3681 if (strchr (string
, CTLESC
) == NULL
)
3682 return (strcpy (result
, string
));
3684 send
= string
+ slen
;
3694 COPY_CHAR_P (t
, s
, send
);
3701 /* Quote the entire WORD_LIST list. */
3706 register WORD_LIST
*w
;
3709 for (w
= list
; w
; w
= w
->next
)
3712 w
->word
->word
= quote_string (t
);
3714 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3715 w
->word
->flags
|= W_QUOTED
;
3721 /* De-quote quoted characters in each word in LIST. */
3727 register WORD_LIST
*tlist
;
3729 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3731 s
= dequote_string (tlist
->word
->word
);
3732 if (QUOTED_NULL (tlist
->word
->word
))
3733 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3734 free (tlist
->word
->word
);
3735 tlist
->word
->word
= s
;
3740 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3743 remove_quoted_escapes (string
)
3750 t
= dequote_escapes (string
);
3758 /* Perform quoted null character removal on STRING. We don't allow any
3759 quoted null characters in the middle or at the ends of strings because
3760 of how expand_word_internal works. remove_quoted_nulls () turns
3761 STRING into an empty string iff it only consists of a quoted null,
3762 and removes all unquoted CTLNUL characters. */
3764 remove_quoted_nulls (string
)
3767 register size_t slen
;
3768 register int i
, j
, prev_i
;
3771 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3772 return string
; /* XXX */
3774 slen
= strlen (string
);
3779 if (string
[i
] == CTLESC
)
3781 /* Old code had j++, but we cannot assume that i == j at this
3782 point -- what if a CTLNUL has already been removed from the
3783 string? We don't want to drop the CTLESC or recopy characters
3784 that we've already copied down. */
3785 i
++; string
[j
++] = CTLESC
;
3789 else if (string
[i
] == CTLNUL
)
3796 ADVANCE_CHAR (string
, slen
, i
);
3799 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3809 /* Perform quoted null character removal on each element of LIST.
3810 This modifies LIST. */
3812 word_list_remove_quoted_nulls (list
)
3815 register WORD_LIST
*t
;
3817 for (t
= list
; t
; t
= t
->next
)
3819 remove_quoted_nulls (t
->word
->word
);
3820 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3824 /* **************************************************************** */
3826 /* Functions for Matching and Removing Patterns */
3828 /* **************************************************************** */
3830 #if defined (HANDLE_MULTIBYTE)
3831 #if 0 /* Currently unused */
3832 static unsigned char *
3833 mb_getcharlens (string
, len
)
3837 int i
, offset
, last
;
3844 ret
= (unsigned char *)xmalloc (len
);
3845 memset (ret
, 0, len
);
3846 while (string
[last
])
3848 ADVANCE_CHAR (string
, len
, offset
);
3849 ret
[last
] = offset
- last
;
3857 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3858 can have one of 4 values:
3859 RP_LONG_LEFT remove longest matching portion at start of PARAM
3860 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3861 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3862 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3865 #define RP_LONG_LEFT 1
3866 #define RP_SHORT_LEFT 2
3867 #define RP_LONG_RIGHT 3
3868 #define RP_SHORT_RIGHT 4
3870 /* Returns its first argument if nothing matched; new memory otherwise */
3872 remove_upattern (param
, pattern
, op
)
3873 char *param
, *pattern
;
3878 register char *p
, *ret
, c
;
3880 len
= STRLEN (param
);
3885 case RP_LONG_LEFT
: /* remove longest match at start */
3886 for (p
= end
; p
>= param
; p
--)
3889 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3892 return (savestring (p
));
3899 case RP_SHORT_LEFT
: /* remove shortest match at start */
3900 for (p
= param
; p
<= end
; p
++)
3903 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3906 return (savestring (p
));
3912 case RP_LONG_RIGHT
: /* remove longest match at end */
3913 for (p
= param
; p
<= end
; p
++)
3915 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3918 ret
= savestring (param
);
3925 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3926 for (p
= end
; p
>= param
; p
--)
3928 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3931 ret
= savestring (param
);
3939 return (param
); /* no match, return original string */
3942 #if defined (HANDLE_MULTIBYTE)
3943 /* Returns its first argument if nothing matched; new memory otherwise */
3945 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3956 case RP_LONG_LEFT
: /* remove longest match at start */
3957 for (n
= wstrlen
; n
>= 0; n
--)
3959 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3960 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3963 return (wcsdup (wparam
+ n
));
3969 case RP_SHORT_LEFT
: /* remove shortest match at start */
3970 for (n
= 0; n
<= wstrlen
; n
++)
3972 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3973 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3976 return (wcsdup (wparam
+ n
));
3982 case RP_LONG_RIGHT
: /* remove longest match at end */
3983 for (n
= 0; n
<= wstrlen
; n
++)
3985 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3987 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3988 ret
= wcsdup (wparam
);
3995 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3996 for (n
= wstrlen
; n
>= 0; n
--)
3998 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
4000 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
4001 ret
= wcsdup (wparam
);
4009 return (wparam
); /* no match, return original string */
4011 #endif /* HANDLE_MULTIBYTE */
4014 remove_pattern (param
, pattern
, op
)
4015 char *param
, *pattern
;
4022 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
4023 return (savestring (param
));
4025 #if defined (HANDLE_MULTIBYTE)
4028 wchar_t *ret
, *oret
;
4030 wchar_t *wparam
, *wpattern
;
4033 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
4034 if (n
== (size_t)-1)
4036 xret
= remove_upattern (param
, pattern
, op
);
4037 return ((xret
== param
) ? savestring (param
) : xret
);
4039 n
= xdupmbstowcs (&wparam
, NULL
, param
);
4041 if (n
== (size_t)-1)
4044 xret
= remove_upattern (param
, pattern
, op
);
4045 return ((xret
== param
) ? savestring (param
) : xret
);
4047 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
4048 /* Don't bother to convert wparam back to multibyte string if nothing
4049 matched; just return copy of original string */
4054 return (savestring (param
));
4061 xret
= (char *)xmalloc (n
+ 1);
4062 memset (&ps
, '\0', sizeof (mbstate_t));
4063 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
4064 xret
[n
] = '\0'; /* just to make sure */
4071 xret
= remove_upattern (param
, pattern
, op
);
4072 return ((xret
== param
) ? savestring (param
) : xret
);
4076 /* Match PAT anywhere in STRING and return the match boundaries.
4077 This returns 1 in case of a successful match, 0 otherwise. SP
4078 and EP are pointers into the string where the match begins and
4079 ends, respectively. MTYPE controls what kind of match is attempted.
4080 MATCH_BEG and MATCH_END anchor the match at the beginning and end
4081 of the string, respectively. The longest match is returned. */
4083 match_upattern (string
, pat
, mtype
, sp
, ep
)
4089 register char *p
, *p1
, *npat
;
4093 /* If the pattern doesn't match anywhere in the string, go ahead and
4094 short-circuit right away. A minor optimization, saves a bunch of
4095 unnecessary calls to strmatch (up to N calls for a string of N
4096 characters) if the match is unsuccessful. To preserve the semantics
4097 of the substring matches below, we make sure that the pattern has
4098 `*' as first and last character, making a new pattern if necessary. */
4099 /* XXX - check this later if I ever implement `**' with special meaning,
4100 since this will potentially result in `**' at the beginning or end */
4102 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == LPAREN
&& extended_glob
) || pat
[len
- 1] != '*')
4104 p
= npat
= (char *)xmalloc (len
+ 3);
4106 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == LPAREN
&& extended_glob
))
4110 if (p1
[-1] != '*' || p
[-2] == '\\')
4116 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
4119 if (c
== FNM_NOMATCH
)
4122 len
= STRLEN (string
);
4125 mlen
= umatchlen (pat
, len
);
4130 for (p
= string
; p
<= end
; p
++)
4132 if (match_pattern_char (pat
, p
))
4134 p1
= (mlen
== -1) ? end
: p
+ mlen
;
4135 /* p1 - p = length of portion of string to be considered
4136 p = current position in string
4137 mlen = number of characters consumed by match (-1 for entire string)
4139 we want to break immediately if the potential match len
4140 is greater than the number of characters remaining in the
4145 for ( ; p1
>= p
; p1
--)
4147 c
= *p1
; *p1
= '\0';
4148 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4157 /* If MLEN != -1, we have a fixed length pattern. */
4168 if (match_pattern_char (pat
, string
) == 0)
4171 for (p
= (mlen
== -1) ? end
: string
+ mlen
; p
>= string
; p
--)
4174 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
4182 /* If MLEN != -1, we have a fixed length pattern. */
4190 for (p
= end
- ((mlen
== -1) ? len
: mlen
); p
<= end
; p
++)
4192 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4198 /* If MLEN != -1, we have a fixed length pattern. */
4209 #if defined (HANDLE_MULTIBYTE)
4210 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4211 This returns 1 in case of a successful match, 0 otherwise. Wide
4212 character version. */
4214 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4222 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4225 int n
, n1
, n2
, simple
;
4227 simple
= (wpat
[0] != L
'\\' && wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'[');
4228 #if defined (EXTENDED_GLOB)
4230 simple
&= (wpat
[1] != L
'(' || (wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'+' && wpat
[0] != L
'!' && wpat
[0] != L
'@')); /*)*/
4233 /* If the pattern doesn't match anywhere in the string, go ahead and
4234 short-circuit right away. A minor optimization, saves a bunch of
4235 unnecessary calls to strmatch (up to N calls for a string of N
4236 characters) if the match is unsuccessful. To preserve the semantics
4237 of the substring matches below, we make sure that the pattern has
4238 `*' as first and last character, making a new pattern if necessary. */
4239 len
= wcslen (wpat
);
4240 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == WLPAREN
&& extended_glob
) || wpat
[len
- 1] != L
'*')
4242 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4244 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == WLPAREN
&& extended_glob
))
4246 while (*wp1
!= L
'\0')
4248 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4254 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
4257 if (len
== FNM_NOMATCH
)
4260 mlen
= wmatchlen (wpat
, wstrlen
);
4262 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4266 for (n
= 0; n
<= wstrlen
; n
++)
4268 n2
= simple
? (*wpat
== wstring
[n
]) : match_pattern_wchar (wpat
, wstring
+ n
);
4271 n1
= (mlen
== -1) ? wstrlen
: n
+ mlen
;
4275 for ( ; n1
>= n
; n1
--)
4277 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4278 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4286 /* If MLEN != -1, we have a fixed length pattern. */
4296 if (match_pattern_wchar (wpat
, wstring
) == 0)
4299 for (n
= (mlen
== -1) ? wstrlen
: mlen
; n
>= 0; n
--)
4301 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4302 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
4310 /* If MLEN != -1, we have a fixed length pattern. */
4318 for (n
= wstrlen
- ((mlen
== -1) ? wstrlen
: mlen
); n
<= wstrlen
; n
++)
4320 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4323 *ep
= indices
[wstrlen
];
4326 /* If MLEN != -1, we have a fixed length pattern. */
4336 #endif /* HANDLE_MULTIBYTE */
4339 match_pattern (string
, pat
, mtype
, sp
, ep
)
4344 #if defined (HANDLE_MULTIBYTE)
4347 wchar_t *wstring
, *wpat
;
4349 size_t slen
, plen
, mslen
, mplen
;
4352 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4355 #if defined (HANDLE_MULTIBYTE)
4358 if (mbsmbchar (string
) == 0 && mbsmbchar (pat
) == 0)
4359 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4361 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4362 if (n
== (size_t)-1)
4363 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4364 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4365 if (n
== (size_t)-1)
4368 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4370 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4380 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4384 getpatspec (c
, value
)
4389 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4391 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4394 /* Posix.2 says that the WORD should be run through tilde expansion,
4395 parameter expansion, command substitution and arithmetic expansion.
4396 This leaves the result quoted, so quote_string_for_globbing () has
4397 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4398 it means that the entire expression was enclosed in double quotes.
4399 This means that quoting characters in the pattern do not make any
4400 special pattern characters quoted. For example, the `*' in the
4401 following retains its special meaning: "${foo#'*'}". */
4403 getpattern (value
, quoted
, expandpat
)
4405 int quoted
, expandpat
;
4412 /* There is a problem here: how to handle single or double quotes in the
4413 pattern string when the whole expression is between double quotes?
4414 POSIX.2 says that enclosing double quotes do not cause the pattern to
4415 be quoted, but does that leave us a problem with @ and array[@] and their
4416 expansions inside a pattern? */
4418 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4421 pat
= string_extract_double_quoted (tword
, &i
, 1);
4427 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4429 l
= *value
? expand_string_for_rhs (value
,
4430 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4431 (int *)NULL
, (int *)NULL
)
4433 pat
= string_list (l
);
4437 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4445 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4446 or ${name#[#]value}. */
4448 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4449 char *value
, *pattern
;
4450 int patspec
, quoted
;
4454 tword
= remove_pattern (value
, pattern
, patspec
);
4461 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4464 int patspec
, itype
, quoted
;
4470 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4472 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4473 w
= alloc_word_desc ();
4474 w
->word
= tword
? tword
: savestring ("");
4475 new = make_word_list (w
, new);
4478 l
= REVERSE_LIST (new, WORD_LIST
*);
4479 tword
= string_list_pos_params (itype
, l
, quoted
);
4486 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4489 int patspec
, quoted
;
4494 list
= list_rest_of_args ();
4496 return ((char *)NULL
);
4497 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4498 dispose_words (list
);
4502 #if defined (ARRAY_VARS)
4504 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4508 char *varname
; /* so we can figure out how it's indexed */
4518 /* compute itype from varname here */
4519 v
= array_variable_part (varname
, &ret
, 0);
4522 if (v
&& invisible_p (var
))
4523 return ((char *)NULL
);
4527 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4528 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4530 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4532 return ((char *)NULL
);
4533 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4534 dispose_words (list
);
4538 #endif /* ARRAY_VARS */
4541 parameter_brace_remove_pattern (varname
, value
, ind
, patstr
, rtype
, quoted
, flags
)
4542 char *varname
, *value
;
4545 int rtype
, quoted
, flags
;
4547 int vtype
, patspec
, starsub
;
4548 char *temp1
, *val
, *pattern
;
4552 return ((char *)NULL
);
4554 this_command_name
= varname
;
4556 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4558 return ((char *)NULL
);
4560 starsub
= vtype
& VT_STARSUB
;
4561 vtype
&= ~VT_STARSUB
;
4563 patspec
= getpatspec (rtype
, patstr
);
4564 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4567 /* Need to pass getpattern newly-allocated memory in case of expansion --
4568 the expansion code will free the passed string on an error. */
4569 temp1
= savestring (patstr
);
4570 pattern
= getpattern (temp1
, quoted
, 1);
4573 temp1
= (char *)NULL
; /* shut up gcc */
4577 case VT_ARRAYMEMBER
:
4578 temp1
= remove_pattern (val
, pattern
, patspec
);
4579 if (vtype
== VT_VARIABLE
)
4583 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4584 ? quote_string (temp1
)
4585 : quote_escapes (temp1
);
4590 #if defined (ARRAY_VARS)
4592 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4593 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4595 val
= quote_escapes (temp1
);
4602 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4603 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4605 val
= quote_escapes (temp1
);
4616 /*******************************************
4618 * Functions to expand WORD_DESCs *
4620 *******************************************/
4622 /* Expand WORD, performing word splitting on the result. This does
4623 parameter expansion, command substitution, arithmetic expansion,
4624 word splitting, and quote removal. */
4627 expand_word (word
, quoted
)
4631 WORD_LIST
*result
, *tresult
;
4633 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4634 result
= word_list_split (tresult
);
4635 dispose_words (tresult
);
4636 return (result
? dequote_list (result
) : result
);
4639 /* Expand WORD, but do not perform word splitting on the result. This
4640 does parameter expansion, command substitution, arithmetic expansion,
4641 and quote removal. */
4643 expand_word_unsplit (word
, quoted
)
4649 expand_no_split_dollar_star
= 1;
4650 #if defined (HANDLE_MULTIBYTE)
4651 if (ifs_firstc
[0] == 0)
4653 if (ifs_firstc
== 0)
4655 word
->flags
|= W_NOSPLIT
;
4656 word
->flags
|= W_NOSPLIT2
;
4657 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4658 expand_no_split_dollar_star
= 0;
4660 return (result
? dequote_list (result
) : result
);
4663 /* Perform shell expansions on WORD, but do not perform word splitting or
4664 quote removal on the result. Virtually identical to expand_word_unsplit;
4665 could be combined if implementations don't diverge. */
4667 expand_word_leave_quoted (word
, quoted
)
4673 expand_no_split_dollar_star
= 1;
4674 #if defined (HANDLE_MULTIBYTE)
4675 if (ifs_firstc
[0] == 0)
4677 if (ifs_firstc
== 0)
4679 word
->flags
|= W_NOSPLIT
;
4680 word
->flags
|= W_NOSPLIT2
;
4681 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4682 expand_no_split_dollar_star
= 0;
4687 #if defined (PROCESS_SUBSTITUTION)
4689 /*****************************************************************/
4691 /* Hacking Process Substitution */
4693 /*****************************************************************/
4695 #if !defined (HAVE_DEV_FD)
4696 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4697 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4698 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4699 list. NFIFO is a count of the number of FIFOs in the list. */
4700 #define FIFO_INCR 20
4707 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4709 static int fifo_list_size
;
4712 copy_fifo_list (sizep
)
4717 return (char *)NULL
;
4721 add_fifo_list (pathname
)
4724 if (nfifo
>= fifo_list_size
- 1)
4726 fifo_list_size
+= FIFO_INCR
;
4727 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4728 fifo_list_size
* sizeof (struct temp_fifo
));
4731 fifo_list
[nfifo
].file
= savestring (pathname
);
4739 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4741 unlink (fifo_list
[i
].file
);
4742 free (fifo_list
[i
].file
);
4743 fifo_list
[i
].file
= (char *)NULL
;
4744 fifo_list
[i
].proc
= -1;
4756 for (i
= saved
= 0; i
< nfifo
; i
++)
4758 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4760 unlink (fifo_list
[i
].file
);
4761 free (fifo_list
[i
].file
);
4762 fifo_list
[i
].file
= (char *)NULL
;
4763 fifo_list
[i
].proc
= -1;
4769 /* If we didn't remove some of the FIFOs, compact the list. */
4772 for (i
= j
= 0; i
< nfifo
; i
++)
4773 if (fifo_list
[i
].file
)
4775 fifo_list
[j
].file
= fifo_list
[i
].file
;
4776 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4785 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4786 from some point in the past, and close all open FIFOs in fifo_list
4787 that are not marked as active in LIST. If LIST is NULL, close
4788 everything in fifo_list. LSIZE is the number of elements in LIST, in
4789 case it's larger than fifo_list_size (size of fifo_list). */
4791 close_new_fifos (list
, lsize
)
4799 unlink_fifo_list ();
4803 for (i
= 0; i
< lsize
; i
++)
4804 if (list
[i
] == 0 && i
< fifo_list_size
&& fifo_list
[i
].proc
!= -1)
4807 for (i
= lsize
; i
< fifo_list_size
; i
++)
4828 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4829 if (mkfifo (tname
, 0600) < 0)
4832 return ((char *)NULL
);
4835 add_fifo_list (tname
);
4839 #else /* HAVE_DEV_FD */
4841 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4842 has open to children. NFDS is a count of the number of bits currently
4843 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4845 static char *dev_fd_list
= (char *)NULL
;
4847 static int totfds
; /* The highest possible number of open files. */
4850 copy_fifo_list (sizep
)
4855 if (nfds
== 0 || totfds
== 0)
4859 return (char *)NULL
;
4864 ret
= (char *)xmalloc (totfds
);
4865 return (memcpy (ret
, dev_fd_list
, totfds
));
4872 if (dev_fd_list
== 0 || fd
>= totfds
)
4877 totfds
= getdtablesize ();
4878 if (totfds
< 0 || totfds
> 256)
4883 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4884 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4887 dev_fd_list
[fd
] = 1;
4894 return 0; /* used for cleanup; not needed with /dev/fd */
4907 if (dev_fd_list
[fd
])
4910 dev_fd_list
[fd
] = 0;
4923 for (i
= 0; nfds
&& i
< totfds
; i
++)
4929 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4930 the past, and close all open fds in dev_fd_list that are not marked
4931 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4932 LSIZE is the number of elements in LIST, in case it's larger than
4933 totfds (size of dev_fd_list). */
4935 close_new_fifos (list
, lsize
)
4943 unlink_fifo_list ();
4947 for (i
= 0; i
< lsize
; i
++)
4948 if (list
[i
] == 0 && i
< totfds
&& dev_fd_list
[i
])
4951 for (i
= lsize
; i
< totfds
; i
++)
4955 #if defined (NOTDEF)
4956 print_dev_fd_list ()
4960 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4963 for (i
= 0; i
< totfds
; i
++)
4966 fprintf (stderr
, " %d", i
);
4968 fprintf (stderr
, "\n");
4973 make_dev_fd_filename (fd
)
4976 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4978 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4980 strcpy (ret
, DEV_FD_PREFIX
);
4981 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4982 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4988 #endif /* HAVE_DEV_FD */
4990 /* Return a filename that will open a connection to the process defined by
4991 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4992 a filename in /dev/fd corresponding to a descriptor that is one of the
4993 ends of the pipe. If not defined, we use named pipes on systems that have
4994 them. Systems without /dev/fd and named pipes are out of luck.
4996 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4997 use the read end of the pipe and dup that file descriptor to fd 0 in
4998 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4999 writing or use the write end of the pipe in the child, and dup that
5000 file descriptor to fd 1 in the child. The parent does the opposite. */
5003 process_substitute (string
, open_for_read_in_child
)
5005 int open_for_read_in_child
;
5010 #if defined (HAVE_DEV_FD)
5011 int parent_pipe_fd
, child_pipe_fd
;
5013 #endif /* HAVE_DEV_FD */
5014 #if defined (JOB_CONTROL)
5015 pid_t old_pipeline_pgrp
;
5018 if (!string
|| !*string
|| wordexp_only
)
5019 return ((char *)NULL
);
5021 #if !defined (HAVE_DEV_FD)
5022 pathname
= make_named_pipe ();
5023 #else /* HAVE_DEV_FD */
5024 if (pipe (fildes
) < 0)
5026 sys_error (_("cannot make pipe for process substitution"));
5027 return ((char *)NULL
);
5029 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
5030 the pipe in the parent, otherwise the read end. */
5031 parent_pipe_fd
= fildes
[open_for_read_in_child
];
5032 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
5033 /* Move the parent end of the pipe to some high file descriptor, to
5034 avoid clashes with FDs used by the script. */
5035 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
5037 pathname
= make_dev_fd_filename (parent_pipe_fd
);
5038 #endif /* HAVE_DEV_FD */
5042 sys_error (_("cannot make pipe for process substitution"));
5043 return ((char *)NULL
);
5046 old_pid
= last_made_pid
;
5048 #if defined (JOB_CONTROL)
5049 old_pipeline_pgrp
= pipeline_pgrp
;
5050 pipeline_pgrp
= shell_pgrp
;
5052 #endif /* JOB_CONTROL */
5054 pid
= make_child ((char *)NULL
, 1);
5057 reset_terminating_signals (); /* XXX */
5058 free_pushed_string_input ();
5059 /* Cancel traps, in trap.c. */
5060 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5061 setup_async_signals ();
5062 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
5065 #if defined (JOB_CONTROL)
5066 set_sigchld_handler ();
5067 stop_making_children ();
5068 /* XXX - should we only do this in the parent? (as in command subst) */
5069 pipeline_pgrp
= old_pipeline_pgrp
;
5070 #endif /* JOB_CONTROL */
5074 sys_error (_("cannot make child for process substitution"));
5076 #if defined (HAVE_DEV_FD)
5077 close (parent_pipe_fd
);
5078 close (child_pipe_fd
);
5079 #endif /* HAVE_DEV_FD */
5080 return ((char *)NULL
);
5085 #if defined (JOB_CONTROL)
5086 restore_pipeline (1);
5089 #if !defined (HAVE_DEV_FD)
5090 fifo_list
[nfifo
-1].proc
= pid
;
5093 last_made_pid
= old_pid
;
5095 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5097 #endif /* JOB_CONTROL && PGRP_PIPE */
5099 #if defined (HAVE_DEV_FD)
5100 close (child_pipe_fd
);
5101 #endif /* HAVE_DEV_FD */
5106 set_sigint_handler ();
5108 #if defined (JOB_CONTROL)
5109 set_job_control (0);
5110 #endif /* JOB_CONTROL */
5112 #if !defined (HAVE_DEV_FD)
5113 /* Open the named pipe in the child. */
5114 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
: O_WRONLY
);
5117 /* Two separate strings for ease of translation. */
5118 if (open_for_read_in_child
)
5119 sys_error (_("cannot open named pipe %s for reading"), pathname
);
5121 sys_error (_("cannot open named pipe %s for writing"), pathname
);
5125 if (open_for_read_in_child
)
5127 if (sh_unset_nodelay_mode (fd
) < 0)
5129 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
5133 #else /* HAVE_DEV_FD */
5135 #endif /* HAVE_DEV_FD */
5137 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
5139 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
5140 open_for_read_in_child
? 0 : 1);
5144 if (fd
!= (open_for_read_in_child
? 0 : 1))
5147 /* Need to close any files that this process has open to pipes inherited
5149 if (current_fds_to_close
)
5151 close_fd_bitmap (current_fds_to_close
);
5152 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
5155 #if defined (HAVE_DEV_FD)
5156 /* Make sure we close the parent's end of the pipe and clear the slot
5157 in the fd list so it is not closed later, if reallocated by, for
5158 instance, pipe(2). */
5159 close (parent_pipe_fd
);
5160 dev_fd_list
[parent_pipe_fd
] = 0;
5161 #endif /* HAVE_DEV_FD */
5163 /* subshells shouldn't have this flag, which controls using the temporary
5164 environment for variable lookups. */
5165 expanding_redir
= 0;
5167 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
5169 #if !defined (HAVE_DEV_FD)
5170 /* Make sure we close the named pipe in the child before we exit. */
5171 close (open_for_read_in_child
? 0 : 1);
5172 #endif /* !HAVE_DEV_FD */
5174 last_command_exit_value
= result
;
5175 result
= run_exit_trap ();
5179 #endif /* PROCESS_SUBSTITUTION */
5181 /***********************************/
5183 /* Command Substitution */
5185 /***********************************/
5188 read_comsub (fd
, quoted
, rflag
)
5192 char *istring
, buf
[128], *bufp
, *s
;
5193 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
5196 istring
= (char *)NULL
;
5197 istring_index
= istring_size
= bufn
= tflag
= 0;
5199 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
5200 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
5202 /* Read the output of the command through the pipe. This may need to be
5203 changed to understand multibyte characters in the future. */
5210 bufn
= zread (fd
, buf
, sizeof (buf
));
5220 internal_warning ("read_comsub: ignored null byte in input");
5225 /* Add the character to ISTRING, possibly after resizing it. */
5226 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
5228 /* This is essentially quote_string inline */
5229 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
5230 istring
[istring_index
++] = CTLESC
;
5231 /* Escape CTLESC and CTLNUL in the output to protect those characters
5232 from the rest of the word expansions (word splitting and globbing.)
5233 This is essentially quote_escapes inline. */
5234 else if (skip_ctlesc
== 0 && c
== CTLESC
)
5236 tflag
|= W_HASCTLESC
;
5237 istring
[istring_index
++] = CTLESC
;
5239 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
5240 istring
[istring_index
++] = CTLESC
;
5242 istring
[istring_index
++] = c
;
5245 #if defined (__CYGWIN__)
5246 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
5249 istring
[istring_index
- 1] = '\n';
5256 istring
[istring_index
] = '\0';
5258 /* If we read no output, just return now and save ourselves some
5260 if (istring_index
== 0)
5265 return (char *)NULL
;
5268 /* Strip trailing newlines from the output of the command. */
5269 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5271 while (istring_index
> 0)
5273 if (istring
[istring_index
- 1] == '\n')
5277 /* If the newline was quoted, remove the quoting char. */
5278 if (istring
[istring_index
- 1] == CTLESC
)
5284 istring
[istring_index
] = '\0';
5287 strip_trailing (istring
, istring_index
- 1, 1);
5294 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5295 contained string possibly quoted. */
5297 command_substitute (string
, quoted
)
5301 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
5303 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
5306 istring
= (char *)NULL
;
5308 /* Don't fork () if there is no need to. In the case of no command to
5309 run, just return NULL. */
5310 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5311 return ((WORD_DESC
*)NULL
);
5313 if (wordexp_only
&& read_but_dont_execute
)
5315 last_command_exit_value
= EX_WEXPCOMSUB
;
5316 jump_to_top_level (EXITPROG
);
5319 /* We're making the assumption here that the command substitution will
5320 eventually run a command from the file system. Since we'll run
5321 maybe_make_export_env in this subshell before executing that command,
5322 the parent shell and any other shells it starts will have to remake
5323 the environment. If we make it before we fork, other shells won't
5324 have to. Don't bother if we have any temporary variable assignments,
5325 though, because the export environment will be remade after this
5326 command completes anyway, but do it if all the words to be expanded
5327 are variable assignments. */
5328 if (subst_assign_varlist
== 0 || garglist
== 0)
5329 maybe_make_export_env (); /* XXX */
5331 /* Flags to pass to parse_and_execute() */
5332 pflags
= (interactive
&& sourcelevel
== 0) ? SEVAL_RESETLINE
: 0;
5334 /* Pipe the output of executing STRING into the current shell. */
5335 if (pipe (fildes
) < 0)
5337 sys_error (_("cannot make pipe for command substitution"));
5341 old_pid
= last_made_pid
;
5342 #if defined (JOB_CONTROL)
5343 old_pipeline_pgrp
= pipeline_pgrp
;
5344 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5345 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5346 pipeline_pgrp
= shell_pgrp
;
5347 cleanup_the_pipeline ();
5348 #endif /* JOB_CONTROL */
5350 old_async_pid
= last_asynchronous_pid
;
5351 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5352 last_asynchronous_pid
= old_async_pid
;
5356 /* Reset the signal handlers in the child, but don't free the
5357 trap strings. Set a flag noting that we have to free the
5358 trap strings if we run trap to change a signal disposition. */
5359 reset_signal_handlers ();
5360 subshell_environment
|= SUBSHELL_RESETTRAP
;
5363 #if defined (JOB_CONTROL)
5364 /* XXX DO THIS ONLY IN PARENT ? XXX */
5365 set_sigchld_handler ();
5366 stop_making_children ();
5368 pipeline_pgrp
= old_pipeline_pgrp
;
5370 stop_making_children ();
5371 #endif /* JOB_CONTROL */
5375 sys_error (_("cannot make child for command substitution"));
5378 last_made_pid
= old_pid
;
5383 return ((WORD_DESC
*)NULL
);
5388 set_sigint_handler (); /* XXX */
5390 free_pushed_string_input ();
5392 if (dup2 (fildes
[1], 1) < 0)
5394 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5395 exit (EXECUTION_FAILURE
);
5398 /* If standard output is closed in the parent shell
5399 (such as after `exec >&-'), file descriptor 1 will be
5400 the lowest available file descriptor, and end up in
5401 fildes[0]. This can happen for stdin and stderr as well,
5402 but stdout is more important -- it will cause no output
5403 to be generated from this command. */
5404 if ((fildes
[1] != fileno (stdin
)) &&
5405 (fildes
[1] != fileno (stdout
)) &&
5406 (fildes
[1] != fileno (stderr
)))
5409 if ((fildes
[0] != fileno (stdin
)) &&
5410 (fildes
[0] != fileno (stdout
)) &&
5411 (fildes
[0] != fileno (stderr
)))
5415 /* Let stdio know the fd may have changed from text to binary mode, and
5416 make sure to preserve stdout line buffering. */
5417 freopen (NULL
, "w", stdout
);
5418 sh_setlinebuf (stdout
);
5419 #endif /* __CYGWIN__ */
5421 /* The currently executing shell is not interactive. */
5424 /* This is a subshell environment. */
5425 subshell_environment
|= SUBSHELL_COMSUB
;
5427 /* When not in POSIX mode, command substitution does not inherit
5429 if (posixly_correct
== 0)
5431 builtin_ignoring_errexit
= 0;
5432 change_flag ('e', FLAG_OFF
);
5436 remove_quoted_escapes (string
);
5438 startup_state
= 2; /* see if we can avoid a fork */
5439 /* Give command substitution a place to jump back to on failure,
5440 so we don't go back up to main (). */
5441 result
= setjmp_nosigs (top_level
);
5443 /* If we're running a command substitution inside a shell function,
5444 trap `return' so we don't return from the function in the subshell
5445 and go off to never-never land. */
5446 if (result
== 0 && return_catch_flag
)
5447 function_value
= setjmp_nosigs (return_catch
);
5451 if (result
== ERREXIT
)
5452 rc
= last_command_exit_value
;
5453 else if (result
== EXITPROG
)
5454 rc
= last_command_exit_value
;
5456 rc
= EXECUTION_FAILURE
;
5457 else if (function_value
)
5458 rc
= return_catch_value
;
5462 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5466 last_command_exit_value
= rc
;
5467 rc
= run_exit_trap ();
5468 #if defined (PROCESS_SUBSTITUTION)
5469 unlink_fifo_list ();
5475 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5477 #endif /* JOB_CONTROL && PGRP_PIPE */
5482 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5486 current_command_subst_pid
= pid
;
5487 last_command_exit_value
= wait_for (pid
);
5488 last_command_subst_pid
= pid
;
5489 last_made_pid
= old_pid
;
5491 #if defined (JOB_CONTROL)
5492 /* If last_command_exit_value > 128, then the substituted command
5493 was terminated by a signal. If that signal was SIGINT, then send
5494 SIGINT to ourselves. This will break out of loops, for instance. */
5495 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5496 kill (getpid (), SIGINT
);
5498 /* wait_for gives the terminal back to shell_pgrp. If some other
5499 process group should have it, give it away to that group here.
5500 pipeline_pgrp is non-zero only while we are constructing a
5501 pipeline, so what we are concerned about is whether or not that
5502 pipeline was started in the background. A pipeline started in
5503 the background should never get the tty back here. */
5504 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5505 give_terminal_to (pipeline_pgrp
, 0);
5506 #endif /* JOB_CONTROL */
5508 ret
= alloc_word_desc ();
5509 ret
->word
= istring
;
5516 /********************************************************
5518 * Utility functions for parameter expansion *
5520 ********************************************************/
5522 #if defined (ARRAY_VARS)
5525 array_length_reference (s
)
5536 var
= array_variable_part (s
, &t
, &len
);
5538 /* If unbound variables should generate an error, report one and return
5540 if ((var
== 0 || invisible_p (var
) || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5544 last_command_exit_value
= EXECUTION_FAILURE
;
5549 else if (var
== 0 || invisible_p (var
))
5552 /* We support a couple of expansions for variables that are not arrays.
5553 We'll return the length of the value for v[0], and 1 for v[@] or
5554 v[*]. Return 0 for everything else. */
5556 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5557 h
= assoc_p (var
) ? assoc_cell (var
) : (HASH_TABLE
*)NULL
;
5559 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5562 return (h
? assoc_num_elements (h
) : 0);
5563 else if (array_p (var
))
5564 return (array
? array_num_elements (array
) : 0);
5566 return (var_isset (var
) ? 1 : 0);
5572 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5574 if (akey
== 0 || *akey
== 0)
5576 err_badarraysub (t
);
5580 t
= assoc_reference (assoc_cell (var
), akey
);
5585 ind
= array_expand_index (var
, t
, len
);
5586 /* negative subscripts to indexed arrays count back from end */
5587 if (var
&& array_p (var
) && ind
< 0)
5588 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
5591 err_badarraysub (t
);
5595 t
= array_reference (array
, ind
);
5597 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5600 len
= MB_STRLEN (t
);
5603 #endif /* ARRAY_VARS */
5606 valid_brace_expansion_word (name
, var_is_special
)
5610 if (DIGIT (*name
) && all_digits (name
))
5612 else if (var_is_special
)
5614 #if defined (ARRAY_VARS)
5615 else if (valid_array_reference (name
))
5617 #endif /* ARRAY_VARS */
5618 else if (legal_identifier (name
))
5625 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5628 int *quoted_dollar_atp
, *contains_dollar_at
;
5634 if (quoted_dollar_atp
)
5635 *quoted_dollar_atp
= 0;
5636 if (contains_dollar_at
)
5637 *contains_dollar_at
= 0;
5641 /* check for $@ and $* */
5642 if (name
[0] == '@' && name
[1] == 0)
5644 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5645 *quoted_dollar_atp
= 1;
5646 if (contains_dollar_at
)
5647 *contains_dollar_at
= 1;
5650 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5652 if (contains_dollar_at
)
5653 *contains_dollar_at
= 1;
5657 /* Now check for ${array[@]} and ${array[*]} */
5658 #if defined (ARRAY_VARS)
5659 else if (valid_array_reference (name
))
5661 temp1
= mbschr (name
, '[');
5662 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5664 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5665 *quoted_dollar_atp
= 1;
5666 if (contains_dollar_at
)
5667 *contains_dollar_at
= 1;
5670 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5671 which should result in separate words even when IFS is unset. */
5672 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5674 if (contains_dollar_at
)
5675 *contains_dollar_at
= 1;
5683 /* Parameter expand NAME, and return a new string which is the expansion,
5684 or NULL if there was no expansion.
5685 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5686 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5687 NAME was found inside of a double-quoted expression. */
5689 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
, indp
)
5691 int var_is_special
, quoted
, pflags
;
5708 /* Handle multiple digit arguments, as in ${11}. */
5709 if (legal_number (name
, &arg_index
))
5711 tt
= get_dollar_var_value (arg_index
);
5713 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5715 : quote_escapes (tt
);
5717 temp
= (char *)NULL
;
5720 else if (var_is_special
) /* ${@} */
5723 tt
= (char *)xmalloc (2 + strlen (name
));
5724 tt
[sindex
= 0] = '$';
5725 strcpy (tt
+ 1, name
);
5727 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5728 (int *)NULL
, (int *)NULL
, pflags
);
5731 #if defined (ARRAY_VARS)
5732 else if (valid_array_reference (name
))
5735 /* XXX - does this leak if name[@] or name[*]? */
5736 if (pflags
& PF_ASSIGNRHS
)
5738 temp
= array_variable_name (name
, &tt
, (int *)0);
5739 if (ALL_ELEMENT_SUB (tt
[0]) && tt
[1] == ']')
5740 temp
= array_value (name
, quoted
|Q_DOUBLE_QUOTES
, 0, &atype
, &ind
);
5742 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5745 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5746 if (atype
== 0 && temp
)
5748 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5749 ? quote_string (temp
)
5750 : quote_escapes (temp
);
5751 rflags
|= W_ARRAYIND
;
5755 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5756 rflags
|= W_HASQUOTEDNULL
;
5759 else if (var
= find_variable (name
))
5761 if (var_isset (var
) && invisible_p (var
) == 0)
5763 #if defined (ARRAY_VARS)
5765 temp
= assoc_reference (assoc_cell (var
), "0");
5766 else if (array_p (var
))
5767 temp
= array_reference (array_cell (var
), 0);
5769 temp
= value_cell (var
);
5771 temp
= value_cell (var
);
5775 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5776 ? quote_string (temp
)
5777 : quote_escapes (temp
);
5780 temp
= (char *)NULL
;
5782 else if (var
= find_variable_last_nameref (name
))
5784 temp
= nameref_cell (var
);
5785 #if defined (ARRAY_VARS)
5786 /* Handle expanding nameref whose value is x[n] */
5787 if (temp
&& *temp
&& valid_array_reference (temp
))
5790 goto expand_arrayref
;
5794 /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */
5795 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
5797 last_command_exit_value
= EXECUTION_FAILURE
;
5798 report_error (_("%s: invalid variable name for name reference"), temp
);
5799 temp
= &expand_param_error
;
5802 temp
= (char *)NULL
;
5805 temp
= (char *)NULL
;
5809 ret
= alloc_word_desc ();
5811 ret
->flags
|= rflags
;
5817 parameter_brace_find_indir (name
, var_is_special
, quoted
, find_nameref
)
5819 int var_is_special
, quoted
, find_nameref
;
5825 if (find_nameref
&& var_is_special
== 0 && (v
= find_variable_last_nameref (name
)) &&
5826 nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
5827 return (savestring (t
));
5829 /* If var_is_special == 0, and name is not an array reference, this does
5830 more expansion than necessary. It should really look up the variable's
5831 value and not try to expand it. */
5832 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
, 0);
5834 /* Have to dequote here if necessary */
5837 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5838 ? dequote_string (t
)
5839 : dequote_escapes (t
);
5843 dispose_word_desc (w
);
5848 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5849 value of the variable whose name is the value of NAME. */
5851 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5853 int var_is_special
, quoted
;
5854 int *quoted_dollar_atp
, *contains_dollar_at
;
5860 /* See if it's a nameref first, behave in ksh93-compatible fashion.
5861 There is at least one incompatibility: given ${!foo[0]} where foo=bar,
5862 bash performs an indirect lookup on foo[0] and expands the result;
5863 ksh93 expands bar[0]. We could do that here -- there are enough usable
5864 primitives to do that -- but do not at this point. */
5865 if (var_is_special
== 0 && (v
= find_variable_last_nameref (name
)))
5867 if (nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
5869 w
= alloc_word_desc ();
5870 w
->word
= savestring (t
);
5876 t
= parameter_brace_find_indir (name
, var_is_special
, quoted
, 0);
5878 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5880 return (WORD_DESC
*)NULL
;
5882 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0, 0);
5888 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5889 depending on the value of C, the separating character. C can be one of
5890 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5891 between double quotes. */
5893 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5895 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5899 char *t
, *t1
, *temp
;
5902 /* If the entire expression is between double quotes, we want to treat
5903 the value as a double-quoted string, with the exception that we strip
5904 embedded unescaped double quotes (for sh backwards compatibility). */
5905 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5908 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5913 w
= alloc_word_desc ();
5915 /* XXX was 0 not quoted */
5916 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5919 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5924 /* The expansion of TEMP returned something. We need to treat things
5925 slightly differently if HASDOL is non-zero. If we have "$@", the
5926 individual words have already been quoted. We need to turn them
5927 into a string with the words separated by the first character of
5928 $IFS without any additional quoting, so string_list_dollar_at won't
5929 do the right thing. We use string_list_dollar_star instead. */
5930 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5932 /* If l->next is not null, we know that TEMP contained "$@", since that
5933 is the only expansion that creates more than one word. */
5934 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5936 /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
5937 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
5938 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
5939 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5940 (which is more paranoia than anything else), we need to return the
5941 quoted null string and set the flags to indicate it. */
5942 if (l
->next
== 0 && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
) && QUOTED_NULL (l
->word
->word
) && (l
->word
->flags
& W_HASQUOTEDNULL
))
5944 w
->flags
|= W_HASQUOTEDNULL
;
5948 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5950 /* The brace expansion occurred between double quotes and there was
5951 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5952 it does not expand to anything. In this case, we want to return
5953 a quoted empty string. */
5954 temp
= make_quoted_char ('\0');
5955 w
->flags
|= W_HASQUOTEDNULL
;
5958 temp
= (char *)NULL
;
5960 if (c
== '-' || c
== '+')
5967 t
= temp
? savestring (temp
) : savestring ("");
5968 t1
= dequote_string (t
);
5970 #if defined (ARRAY_VARS)
5971 if (valid_array_reference (name
))
5972 assign_array_element (name
, t1
, 0);
5974 #endif /* ARRAY_VARS */
5975 bind_variable (name
, t1
, 0);
5977 if (STREQ (name
, "IFS") == 0)
5979 stupidly_hack_special_variables (name
);
5981 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5988 /* Deal with the right hand side of a ${name:?value} expansion in the case
5989 that NAME is null or not set. If VALUE is non-null it is expanded and
5990 used as the error message to print, otherwise a standard message is
5993 parameter_brace_expand_error (name
, value
)
5999 last_command_exit_value
= EXECUTION_FAILURE
; /* ensure it's non-zero */
6000 if (value
&& *value
)
6002 l
= expand_string (value
, 0);
6003 temp
= string_list (l
);
6004 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
6009 report_error (_("%s: parameter null or not set"), name
);
6011 /* Free the data we have allocated during this expansion, since we
6012 are about to longjmp out. */
6017 /* Return 1 if NAME is something for which parameter_brace_expand_length is
6020 valid_length_expression (name
)
6023 return (name
[1] == '\0' || /* ${#} */
6024 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
6025 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
6026 #if defined (ARRAY_VARS)
6027 valid_array_reference (name
+ 1) || /* ${#a[7]} */
6029 legal_identifier (name
+ 1)); /* ${#PS1} */
6032 /* Handle the parameter brace expansion that requires us to return the
6033 length of a parameter. */
6035 parameter_brace_expand_length (name
)
6039 intmax_t number
, arg_index
;
6041 #if defined (ARRAY_VARS)
6045 if (name
[1] == '\0') /* ${#} */
6046 number
= number_of_args ();
6047 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
6048 number
= number_of_args ();
6049 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
6051 /* Take the lengths of some of the shell's special parameters. */
6055 t
= which_set_flags ();
6058 t
= itos (last_command_exit_value
);
6061 t
= itos (dollar_dollar_pid
);
6064 if (last_asynchronous_pid
== NO_PID
)
6065 t
= (char *)NULL
; /* XXX - error if set -u set? */
6067 t
= itos (last_asynchronous_pid
);
6070 t
= itos (number_of_args ());
6073 number
= STRLEN (t
);
6076 #if defined (ARRAY_VARS)
6077 else if (valid_array_reference (name
+ 1))
6078 number
= array_length_reference (name
+ 1);
6079 #endif /* ARRAY_VARS */
6084 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
6086 t
= get_dollar_var_value (arg_index
);
6087 if (t
== 0 && unbound_vars_is_error
)
6089 number
= MB_STRLEN (t
);
6092 #if defined (ARRAY_VARS)
6093 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
6096 t
= assoc_reference (assoc_cell (var
), "0");
6098 t
= array_reference (array_cell (var
), 0);
6099 if (t
== 0 && unbound_vars_is_error
)
6101 number
= MB_STRLEN (t
);
6106 newname
= savestring (name
);
6108 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
6109 t
= list
? string_list (list
) : (char *)NULL
;
6112 dispose_words (list
);
6114 number
= t
? MB_STRLEN (t
) : 0;
6122 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
6123 so we do some ad-hoc parsing of an arithmetic expression to find
6124 the first DELIM, instead of using strchr(3). Two rules:
6125 1. If the substring contains a `(', read until closing `)'.
6126 2. If the substring contains a `?', read past one `:' for each `?'.
6130 skiparith (substr
, delim
)
6135 int skipcol
, pcount
, i
;
6138 sublen
= strlen (substr
);
6139 i
= skipcol
= pcount
= 0;
6142 /* Balance parens */
6143 if (substr
[i
] == LPAREN
)
6149 if (substr
[i
] == RPAREN
&& pcount
)
6157 ADVANCE_CHAR (substr
, sublen
, i
);
6161 /* Skip one `:' for each `?' */
6162 if (substr
[i
] == ':' && skipcol
)
6168 if (substr
[i
] == delim
)
6170 if (substr
[i
] == '?')
6176 ADVANCE_CHAR (substr
, sublen
, i
);
6179 return (substr
+ i
);
6182 /* Verify and limit the start and end of the desired substring. If
6183 VTYPE == 0, a regular shell variable is being used; if it is 1,
6184 then the positional parameters are being used; if it is 2, then
6185 VALUE is really a pointer to an array variable that should be used.
6186 Return value is 1 if both values were OK, 0 if there was a problem
6187 with an invalid expression, or -1 if the values were out of range. */
6189 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
6191 char *value
, *substr
;
6193 intmax_t *e1p
, *e2p
;
6195 char *t
, *temp1
, *temp2
;
6198 #if defined (ARRAY_VARS)
6203 /* duplicate behavior of strchr(3) */
6204 t
= skiparith (substr
, ':');
6205 if (*t
&& *t
== ':')
6210 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
6211 *e1p
= evalexp (temp1
, &expok
);
6216 len
= -1; /* paranoia */
6220 case VT_ARRAYMEMBER
:
6221 len
= MB_STRLEN (value
);
6224 len
= number_of_args () + 1;
6226 len
++; /* add one arg if counting from $0 */
6228 #if defined (ARRAY_VARS)
6230 /* For arrays, the first value deals with array indices. Negative
6231 offsets count from one past the array's maximum index. Associative
6232 arrays treat the number of elements as the maximum index. */
6236 len
= assoc_num_elements (h
) + (*e1p
< 0);
6241 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
6247 if (len
== -1) /* paranoia */
6250 if (*e1p
< 0) /* negative offsets count from end */
6253 if (*e1p
> len
|| *e1p
< 0)
6256 #if defined (ARRAY_VARS)
6257 /* For arrays, the second offset deals with the number of elements. */
6258 if (vtype
== VT_ARRAYVAR
)
6259 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
6265 temp2
= savestring (t
);
6266 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6269 *e2p
= evalexp (temp1
, &expok
);
6274 if ((vtype
== VT_ARRAYVAR
|| vtype
== VT_POSPARMS
) && *e2p
< 0)
6276 /* bash-4.3: allow positional parameter length < 0 to count backwards
6277 from end of positional parameters */
6278 if (vtype
== VT_ARRAYVAR
&& *e2p
< 0)
6281 internal_error (_("%s: substring expression < 0"), t
);
6284 #if defined (ARRAY_VARS)
6285 /* In order to deal with sparse arrays, push the intelligence about how
6286 to deal with the number of elements desired down to the array-
6287 specific functions. */
6288 if (vtype
!= VT_ARRAYVAR
)
6294 if (*e2p
< 0 || *e2p
< *e1p
)
6296 internal_error (_("%s: substring expression < 0"), t
);
6301 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
6312 /* Return the type of variable specified by VARNAME (simple variable,
6313 positional param, or array variable). Also return the value specified
6314 by VARNAME (value of a variable or a reference to an array element).
6315 QUOTED is the standard description of quoting state, using Q_* defines.
6316 FLAGS is currently a set of flags to pass to array_value. If IND is
6317 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6318 passed to array_value so the array index is not computed again.
6319 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6320 characters in the value are quoted with CTLESC and takes appropriate
6321 steps. For convenience, *VALP is set to the dequoted VALUE. */
6323 get_var_and_type (varname
, value
, ind
, quoted
, flags
, varp
, valp
)
6324 char *varname
, *value
;
6330 int vtype
, want_indir
;
6333 #if defined (ARRAY_VARS)
6338 want_indir
= *varname
== '!' &&
6339 (legal_variable_starter ((unsigned char)varname
[1]) || DIGIT (varname
[1])
6340 || VALID_INDIR_PARAM (varname
[1]));
6342 vname
= parameter_brace_find_indir (varname
+1, SPECIAL_VAR (varname
, 1), quoted
, 1);
6346 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6347 vtype
= (vname
[0] == '@' || vname
[0] == '*') && vname
[1] == '\0';
6348 if (vtype
== VT_POSPARMS
&& vname
[0] == '*')
6349 vtype
|= VT_STARSUB
;
6350 *varp
= (SHELL_VAR
*)NULL
;
6352 #if defined (ARRAY_VARS)
6353 if (valid_array_reference (vname
))
6355 v
= array_variable_part (vname
, &temp
, (int *)0);
6356 /* If we want to signal array_value to use an already-computed index,
6357 set LIND to that index */
6358 lind
= (ind
!= INTMAX_MIN
&& (flags
& AV_USEIND
)) ? ind
: 0;
6359 if (v
&& invisible_p (v
))
6361 vtype
= VT_ARRAYMEMBER
;
6362 *varp
= (SHELL_VAR
*)NULL
;
6363 *valp
= (char *)NULL
;
6365 if (v
&& (array_p (v
) || assoc_p (v
)))
6367 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
6369 /* Callers have to differentiate between indexed and associative */
6370 vtype
= VT_ARRAYVAR
;
6372 vtype
|= VT_STARSUB
;
6373 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
6377 vtype
= VT_ARRAYMEMBER
;
6378 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6382 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
6384 vtype
= VT_VARIABLE
;
6386 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6387 *valp
= dequote_string (value
);
6389 *valp
= dequote_escapes (value
);
6393 vtype
= VT_ARRAYMEMBER
;
6395 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6398 else if ((v
= find_variable (vname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
6400 vtype
= VT_ARRAYMEMBER
;
6402 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
6407 if (value
&& vtype
== VT_VARIABLE
)
6409 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6410 *valp
= dequote_string (value
);
6412 *valp
= dequote_escapes (value
);
6424 /******************************************************/
6426 /* Functions to extract substrings of variable values */
6428 /******************************************************/
6430 #if defined (HANDLE_MULTIBYTE)
6431 /* Character-oriented rather than strictly byte-oriented substrings. S and
6432 E, rather being strict indices into STRING, indicate character (possibly
6433 multibyte character) positions that require calculation.
6434 Used by the ${param:offset[:length]} expansion. */
6436 mb_substring (string
, s
, e
)
6441 int start
, stop
, i
, slen
;
6445 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6446 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6449 while (string
[start
] && i
--)
6450 ADVANCE_CHAR (string
, slen
, start
);
6453 while (string
[stop
] && i
--)
6454 ADVANCE_CHAR (string
, slen
, stop
);
6455 tt
= substring (string
, start
, stop
);
6460 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6461 is `@', use the positional parameters; otherwise, use the value of
6462 VARNAME. If VARNAME is an array variable, use the array elements. */
6465 parameter_brace_substring (varname
, value
, ind
, substr
, quoted
, flags
)
6466 char *varname
, *value
;
6472 int vtype
, r
, starsub
;
6473 char *temp
, *val
, *tt
, *oname
;
6477 return ((char *)NULL
);
6479 oname
= this_command_name
;
6480 this_command_name
= varname
;
6482 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6485 this_command_name
= oname
;
6486 return ((char *)NULL
);
6489 starsub
= vtype
& VT_STARSUB
;
6490 vtype
&= ~VT_STARSUB
;
6492 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6493 this_command_name
= oname
;
6496 if (vtype
== VT_VARIABLE
)
6498 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6504 case VT_ARRAYMEMBER
:
6505 #if defined (HANDLE_MULTIBYTE)
6507 tt
= mb_substring (val
, e1
, e2
);
6510 tt
= substring (val
, e1
, e2
);
6512 if (vtype
== VT_VARIABLE
)
6514 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6515 temp
= quote_string (tt
);
6517 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6521 tt
= pos_params (varname
, e1
, e2
, quoted
);
6522 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6524 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6530 #if defined (ARRAY_VARS)
6533 /* we convert to list and take first e2 elements starting at e1th
6534 element -- officially undefined for now */
6535 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6537 /* We want E2 to be the number of elements desired (arrays can be sparse,
6538 so verify_substring_values just returns the numbers specified and we
6539 rely on array_subrange to understand how to deal with them). */
6540 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6541 /* array_subrange now calls array_quote_escapes as appropriate, so the
6542 caller no longer needs to. */
6546 temp
= (char *)NULL
;
6552 /****************************************************************/
6554 /* Functions to perform pattern substitution on variable values */
6556 /****************************************************************/
6559 shouldexp_replacement (s
)
6564 for (p
= s
; p
&& *p
; p
++)
6575 pat_subst (string
, pat
, rep
, mflags
)
6576 char *string
, *pat
, *rep
;
6579 char *ret
, *s
, *e
, *str
, *rstr
, *mstr
;
6580 int rsize
, rptr
, l
, replen
, mtype
, rxpand
, rslen
, mlen
;
6583 return (savestring (""));
6585 mtype
= mflags
& MATCH_TYPEMASK
;
6587 #if 0 /* bash-4.2 ? */
6588 rxpand
= (rep
&& *rep
) ? shouldexp_replacement (rep
) : 0;
6594 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6595 * with REP and return the result.
6596 * 2. A null pattern with mtype == MATCH_END means to append REP to
6597 * STRING and return the result.
6598 * These don't understand or process `&' in the replacement string.
6600 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
6602 replen
= STRLEN (rep
);
6603 l
= STRLEN (string
);
6604 ret
= (char *)xmalloc (replen
+ l
+ 2);
6606 strcpy (ret
, string
);
6607 else if (mtype
== MATCH_BEG
)
6610 strcpy (ret
+ replen
, string
);
6614 strcpy (ret
, string
);
6615 strcpy (ret
+ l
, rep
);
6620 ret
= (char *)xmalloc (rsize
= 64);
6623 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6625 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6633 mstr
= xmalloc (mlen
+ 1);
6634 for (x
= 0; x
< mlen
; x
++)
6637 rstr
= strcreplace (rep
, '&', mstr
, 0);
6638 rslen
= strlen (rstr
);
6646 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ rslen
), rsize
, 64);
6648 /* OK, now copy the leading unmatched portion of the string (from
6649 str to s) to ret starting at rptr (the current offset). Then copy
6650 the replacement string at ret + rptr + (s - str). Increment
6651 rptr (if necessary) and str and go on. */
6654 strncpy (ret
+ rptr
, str
, l
);
6659 strncpy (ret
+ rptr
, rstr
, rslen
);
6662 str
= e
; /* e == end of match */
6667 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6672 /* On a zero-length match, make sure we copy one character, since
6673 we increment one character to avoid infinite recursion. */
6674 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6675 ret
[rptr
++] = *str
++;
6676 e
++; /* avoid infinite recursion on zero-length match */
6680 /* Now copy the unmatched portion of the input string */
6683 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6684 strcpy (ret
+ rptr
, str
);
6692 /* Do pattern match and replacement on the positional parameters. */
6694 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6695 char *string
, *pat
, *rep
;
6698 WORD_LIST
*save
, *params
;
6703 save
= params
= list_rest_of_args ();
6705 return ((char *)NULL
);
6707 for ( ; params
; params
= params
->next
)
6709 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6710 w
= alloc_word_desc ();
6711 w
->word
= ret
? ret
: savestring ("");
6712 dispose_word (params
->word
);
6716 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6717 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6719 ret
= string_list_pos_params (pchar
, save
, qflags
);
6721 dispose_words (save
);
6726 /* Perform pattern substitution on VALUE, which is the expansion of
6727 VARNAME. PATSUB is an expression supplying the pattern to match
6728 and the string to substitute. QUOTED is a flags word containing
6729 the type of quoting currently in effect. */
6731 parameter_brace_patsub (varname
, value
, ind
, patsub
, quoted
, flags
)
6732 char *varname
, *value
;
6737 int vtype
, mflags
, starsub
, delim
;
6738 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6742 return ((char *)NULL
);
6744 this_command_name
= varname
;
6746 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6748 return ((char *)NULL
);
6750 starsub
= vtype
& VT_STARSUB
;
6751 vtype
&= ~VT_STARSUB
;
6754 /* PATSUB is never NULL when this is called. */
6757 mflags
|= MATCH_GLOBREP
;
6761 /* Malloc this because expand_string_if_necessary or one of the expansion
6762 functions in its call chain may free it on a substitution error. */
6763 lpatsub
= savestring (patsub
);
6765 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6766 mflags
|= MATCH_QUOTED
;
6769 mflags
|= MATCH_STARSUB
;
6771 /* If the pattern starts with a `/', make sure we skip over it when looking
6772 for the replacement delimiter. */
6773 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6774 if (lpatsub
[delim
] == '/')
6777 rep
= lpatsub
+ delim
+ 1;
6782 if (rep
&& *rep
== '\0')
6785 /* Perform the same expansions on the pattern as performed by the
6786 pattern removal expansions. */
6787 pat
= getpattern (lpatsub
, quoted
, 1);
6791 /* We want to perform quote removal on the expanded replacement even if
6792 the entire expansion is double-quoted because the parser and string
6793 extraction functions treated quotes in the replacement string as
6794 special. THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */
6795 if (shell_compatibility_level
> 42)
6796 rep
= expand_string_if_necessary (rep
, quoted
& ~(Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
), expand_string_unsplit
);
6797 /* This is the bash-4.2 code. */
6798 else if ((mflags
& MATCH_QUOTED
) == 0)
6799 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6801 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6804 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6805 pattern. This is an extension. Make sure we don't anchor the pattern
6806 at the beginning or end of the string if we're doing global replacement,
6809 if (mflags
& MATCH_GLOBREP
)
6810 mflags
|= MATCH_ANY
;
6811 else if (pat
&& pat
[0] == '#')
6813 mflags
|= MATCH_BEG
;
6816 else if (pat
&& pat
[0] == '%')
6818 mflags
|= MATCH_END
;
6822 mflags
|= MATCH_ANY
;
6824 /* OK, we now want to substitute REP for PAT in VAL. If
6825 flags & MATCH_GLOBREP is non-zero, the substitution is done
6826 everywhere, otherwise only the first occurrence of PAT is
6827 replaced. The pattern matching code doesn't understand
6828 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6829 values passed in (VT_VARIABLE) so the pattern substitution
6830 code works right. We need to requote special chars after
6831 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6832 other cases if QUOTED == 0, since the posparams and arrays
6833 indexed by * or @ do special things when QUOTED != 0. */
6838 case VT_ARRAYMEMBER
:
6839 temp
= pat_subst (val
, p
, rep
, mflags
);
6840 if (vtype
== VT_VARIABLE
)
6844 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6850 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6851 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6853 tt
= quote_escapes (temp
);
6858 #if defined (ARRAY_VARS)
6860 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6861 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6862 /* Don't call quote_escapes anymore; array_patsub calls
6863 array_quote_escapes as appropriate before adding the
6864 space separators; ditto for assoc_patsub. */
6876 /****************************************************************/
6878 /* Functions to perform case modification on variable values */
6880 /****************************************************************/
6882 /* Do case modification on the positional parameters. */
6885 pos_params_modcase (string
, pat
, modop
, mflags
)
6890 WORD_LIST
*save
, *params
;
6895 save
= params
= list_rest_of_args ();
6897 return ((char *)NULL
);
6899 for ( ; params
; params
= params
->next
)
6901 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6902 w
= alloc_word_desc ();
6903 w
->word
= ret
? ret
: savestring ("");
6904 dispose_word (params
->word
);
6908 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6909 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6911 ret
= string_list_pos_params (pchar
, save
, qflags
);
6912 dispose_words (save
);
6917 /* Perform case modification on VALUE, which is the expansion of
6918 VARNAME. MODSPEC is an expression supplying the type of modification
6919 to perform. QUOTED is a flags word containing the type of quoting
6920 currently in effect. */
6922 parameter_brace_casemod (varname
, value
, ind
, modspec
, patspec
, quoted
, flags
)
6923 char *varname
, *value
;
6928 int vtype
, starsub
, modop
, mflags
, x
;
6929 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6933 return ((char *)NULL
);
6935 this_command_name
= varname
;
6937 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6939 return ((char *)NULL
);
6941 starsub
= vtype
& VT_STARSUB
;
6942 vtype
&= ~VT_STARSUB
;
6946 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6947 mflags
|= MATCH_QUOTED
;
6949 mflags
|= MATCH_STARSUB
;
6954 x
= p
&& p
[0] == modspec
;
6955 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6958 else if (modspec
== ',')
6960 x
= p
&& p
[0] == modspec
;
6961 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6964 else if (modspec
== '~')
6966 x
= p
&& p
[0] == modspec
;
6967 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6971 lpat
= p
? savestring (p
) : 0;
6972 /* Perform the same expansions on the pattern as performed by the
6973 pattern removal expansions. FOR LATER */
6974 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6976 /* OK, now we do the case modification. */
6980 case VT_ARRAYMEMBER
:
6981 temp
= sh_modcase (val
, pat
, modop
);
6982 if (vtype
== VT_VARIABLE
)
6986 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6993 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6994 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6996 tt
= quote_escapes (temp
);
7002 #if defined (ARRAY_VARS)
7004 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
7005 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
7006 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
7007 as appropriate before adding the space separators; ditto for
7019 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
7020 any occur, this must be a nested command substitution, so return 0.
7021 Otherwise, return 1. A valid arithmetic expression must always have a
7022 ( before a matching ), so any cases where there are more right parens
7023 means that this must not be an arithmetic expression, though the parser
7024 will not accept it without a balanced total number of parens. */
7026 chk_arithsub (s
, len
)
7038 else if (s
[i
] == RPAREN
)
7048 ADVANCE_CHAR (s
, len
, i
);
7054 ADVANCE_CHAR (s
, len
, i
);
7058 i
= skip_single_quoted (s
, len
, ++i
);
7062 i
= skip_double_quoted ((char *)s
, len
, ++i
);
7067 return (count
== 0);
7070 /****************************************************************/
7072 /* Functions to perform parameter expansion on a string */
7074 /****************************************************************/
7076 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
7078 parameter_brace_expand (string
, indexp
, quoted
, pflags
, quoted_dollar_atp
, contains_dollar_at
)
7080 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
, pflags
;
7082 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
7083 int want_substring
, want_indir
, want_patsub
, want_casemod
;
7084 char *name
, *value
, *temp
, *temp1
;
7085 WORD_DESC
*tdesc
, *ret
;
7086 int t_index
, sindex
, c
, tflag
, modspec
;
7090 temp
= temp1
= value
= (char *)NULL
;
7091 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
7092 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
7096 /* ${#var} doesn't have any of the other parameter expansions on it. */
7097 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
7098 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
7100 #if defined (CASEMOD_EXPANSIONS)
7101 /* To enable case-toggling expansions using the `~' operator character
7102 change the 1 to 0. */
7103 # if defined (CASEMOD_CAPCASE)
7104 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
7106 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
7107 # endif /* CASEMOD_CAPCASE */
7109 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
7110 #endif /* CASEMOD_EXPANSIONS */
7117 /* If the name really consists of a special variable, then make sure
7118 that we have the entire name. We don't allow indirect references
7119 to special variables except `#', `?', `@' and `*'. */
7120 if ((sindex
== t_index
&& VALID_SPECIAL_LENGTH_PARAM (string
[t_index
])) ||
7121 (sindex
== t_index
- 1 && string
[sindex
] == '!' && VALID_INDIR_PARAM (string
[t_index
])))
7124 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
7125 name
= (char *)xrealloc (name
, 3 + (strlen (temp1
)));
7126 *name
= string
[sindex
];
7127 if (string
[sindex
] == '!')
7129 /* indirect reference of $#, $?, $@, or $* */
7130 name
[1] = string
[sindex
+ 1];
7131 strcpy (name
+ 2, temp1
);
7134 strcpy (name
+ 1, temp1
);
7139 /* Find out what character ended the variable name. Then
7140 do the appropriate thing. */
7141 if (c
= string
[sindex
])
7144 /* If c is followed by one of the valid parameter expansion
7145 characters, move past it as normal. If not, assume that
7146 a substring specification is being given, and do not move
7148 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
7151 if (c
= string
[sindex
])
7154 else if (c
== ':' && string
[sindex
] != RBRACE
)
7156 else if (c
== '/' /* && string[sindex] != RBRACE */) /* XXX */
7158 #if defined (CASEMOD_EXPANSIONS)
7159 else if (c
== '^' || c
== ',' || c
== '~')
7166 /* Catch the valid and invalid brace expressions that made it through the
7168 /* ${#-} is a valid expansion and means to take the length of $-.
7169 Similarly for ${#?} and ${##}... */
7170 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7171 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
7173 name
= (char *)xrealloc (name
, 3);
7176 c
= string
[sindex
++];
7179 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7180 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7181 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
7183 temp
= (char *)NULL
;
7184 goto bad_substitution
;
7187 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7188 either a variable name, one of the positional parameters or a special
7189 variable that expands to one of the positional parameters. */
7190 want_indir
= *name
== '!' &&
7191 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
7192 || VALID_INDIR_PARAM (name
[1]));
7194 /* Determine the value of this variable. */
7196 /* Check for special variables, directly referenced. */
7197 if (SPECIAL_VAR (name
, want_indir
))
7200 /* Check for special expansion things, like the length of a parameter */
7201 if (*name
== '#' && name
[1])
7203 /* If we are not pointing at the character just after the
7204 closing brace, then we haven't gotten all of the name.
7205 Since it begins with a special character, this is a bad
7206 substitution. Also check NAME for validity before trying
7208 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
7210 temp
= (char *)NULL
;
7211 goto bad_substitution
;
7214 number
= parameter_brace_expand_length (name
);
7215 if (number
== INTMAX_MIN
&& unbound_vars_is_error
)
7217 last_command_exit_value
= EXECUTION_FAILURE
;
7218 err_unboundvar (name
+1);
7220 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7226 return (&expand_wdesc_error
);
7229 ret
= alloc_word_desc ();
7230 ret
->word
= itos (number
);
7235 /* ${@} is identical to $@. */
7236 if (name
[0] == '@' && name
[1] == '\0')
7238 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7239 *quoted_dollar_atp
= 1;
7241 if (contains_dollar_at
)
7242 *contains_dollar_at
= 1;
7244 tflag
|= W_DOLLARAT
;
7247 /* Process ${!PREFIX*} expansion. */
7248 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7249 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
7250 legal_variable_starter ((unsigned char) name
[1]))
7255 temp1
= savestring (name
+ 1);
7256 number
= strlen (temp1
);
7257 temp1
[number
- 1] = '\0';
7258 x
= all_variables_matching_prefix (temp1
);
7259 xlist
= strvec_to_word_list (x
, 0, 0);
7260 if (string
[sindex
- 2] == '*')
7261 temp
= string_list_dollar_star (xlist
);
7264 temp
= string_list_dollar_at (xlist
, quoted
);
7265 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7266 *quoted_dollar_atp
= 1;
7267 if (contains_dollar_at
)
7268 *contains_dollar_at
= 1;
7270 tflag
|= W_DOLLARAT
;
7273 dispose_words (xlist
);
7279 ret
= alloc_word_desc ();
7281 ret
->flags
= tflag
; /* XXX */
7285 #if defined (ARRAY_VARS)
7286 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7287 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7288 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
7292 temp1
= savestring (name
+ 1);
7293 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
7295 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
7297 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
7300 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7301 *quoted_dollar_atp
= 1;
7302 if (contains_dollar_at
)
7303 *contains_dollar_at
= 1;
7305 tflag
|= W_DOLLARAT
;
7311 ret
= alloc_word_desc ();
7313 ret
->flags
= tflag
; /* XXX */
7319 #endif /* ARRAY_VARS */
7321 /* Make sure that NAME is valid before trying to go on. */
7322 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
7323 var_is_special
) == 0)
7325 temp
= (char *)NULL
;
7326 goto bad_substitution
;
7330 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7332 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
|(pflags
&(PF_NOSPLIT2
|PF_ASSIGNRHS
)), &ind
);
7337 tflag
= tdesc
->flags
;
7338 dispose_word_desc (tdesc
);
7343 if (temp
== &expand_param_error
|| temp
== &expand_param_fatal
)
7347 return (temp
== &expand_param_error
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7350 #if defined (ARRAY_VARS)
7351 if (valid_array_reference (name
))
7352 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7355 var_is_set
= temp
!= (char *)0;
7356 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
7357 /* XXX - this may not need to be restricted to special variables */
7359 var_is_null
|= var_is_set
&& var_is_special
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
);
7361 /* Get the rest of the stuff inside the braces. */
7362 if (c
&& c
!= RBRACE
)
7364 /* Extract the contents of the ${ ... } expansion
7365 according to the Posix.2 rules. */
7366 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, (c
== '%' || c
== '#' || c
=='/' || c
== '^' || c
== ',' || c
==':') ? SX_POSIXEXP
|SX_WORD
: SX_WORD
);
7367 if (string
[sindex
] == RBRACE
)
7370 goto bad_substitution
;
7373 value
= (char *)NULL
;
7377 /* All the cases where an expansion can possibly generate an unbound
7379 if (want_substring
|| want_patsub
|| want_casemod
|| c
== '#' || c
== '%' || c
== RBRACE
)
7381 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
7383 last_command_exit_value
= EXECUTION_FAILURE
;
7384 err_unboundvar (name
);
7388 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7392 /* If this is a substring spec, process it and add the result. */
7395 temp1
= parameter_brace_substring (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7400 if (temp1
== &expand_param_error
)
7401 return (&expand_wdesc_error
);
7402 else if (temp1
== &expand_param_fatal
)
7403 return (&expand_wdesc_fatal
);
7405 ret
= alloc_word_desc ();
7407 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7408 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7411 else if (want_patsub
)
7413 temp1
= parameter_brace_patsub (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7418 if (temp1
== &expand_param_error
)
7419 return (&expand_wdesc_error
);
7420 else if (temp1
== &expand_param_fatal
)
7421 return (&expand_wdesc_fatal
);
7423 ret
= alloc_word_desc ();
7425 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7426 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7429 #if defined (CASEMOD_EXPANSIONS)
7430 else if (want_casemod
)
7432 temp1
= parameter_brace_casemod (name
, temp
, ind
, modspec
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7437 if (temp1
== &expand_param_error
)
7438 return (&expand_wdesc_error
);
7439 else if (temp1
== &expand_param_fatal
)
7440 return (&expand_wdesc_fatal
);
7442 ret
= alloc_word_desc ();
7444 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7445 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7450 /* Do the right thing based on which character ended the variable name. */
7456 last_command_exit_value
= EXECUTION_FAILURE
;
7457 report_error (_("%s: bad substitution"), string
? string
: "??");
7461 return &expand_wdesc_error
;
7466 case '#': /* ${param#[#]pattern} */
7467 case '%': /* ${param%[%]pattern} */
7468 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
7473 temp1
= parameter_brace_remove_pattern (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7478 ret
= alloc_word_desc ();
7480 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7481 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7488 if (var_is_set
&& var_is_null
== 0)
7490 /* If the operator is `+', we don't want the value of the named
7491 variable for anything, just the value of the right hand side. */
7494 /* XXX -- if we're double-quoted and the named variable is "$@",
7495 we want to turn off any special handling of "$@" --
7496 we're not using it, so whatever is on the rhs applies. */
7497 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7498 *quoted_dollar_atp
= 0;
7499 if (contains_dollar_at
)
7500 *contains_dollar_at
= 0;
7505 /* From Posix discussion on austin-group list. Issue 221
7506 requires that backslashes escaping `}' inside
7507 double-quoted ${...} be removed. */
7508 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7509 quoted
|= Q_DOLBRACE
;
7510 ret
= parameter_brace_expand_rhs (name
, value
, c
,
7513 contains_dollar_at
);
7514 /* XXX - fix up later, esp. noting presence of
7515 W_HASQUOTEDNULL in ret->flags */
7519 temp
= (char *)NULL
;
7525 /* Otherwise do nothing; just use the value in TEMP. */
7527 else /* VAR not set or VAR is NULL. */
7530 temp
= (char *)NULL
;
7531 if (c
== '=' && var_is_special
)
7533 last_command_exit_value
= EXECUTION_FAILURE
;
7534 report_error (_("$%s: cannot assign in this way"), name
);
7537 return &expand_wdesc_error
;
7541 parameter_brace_expand_error (name
, value
);
7542 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7546 /* XXX -- if we're double-quoted and the named variable is "$@",
7547 we want to turn off any special handling of "$@" --
7548 we're not using it, so whatever is on the rhs applies. */
7549 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7550 *quoted_dollar_atp
= 0;
7551 if (contains_dollar_at
)
7552 *contains_dollar_at
= 0;
7554 /* From Posix discussion on austin-group list. Issue 221 requires
7555 that backslashes escaping `}' inside double-quoted ${...} be
7557 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7558 quoted
|= Q_DOLBRACE
;
7559 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
7561 contains_dollar_at
);
7562 /* XXX - fix up later, esp. noting presence of
7563 W_HASQUOTEDNULL in tdesc->flags */
7574 ret
= alloc_word_desc ();
7581 /* Expand a single ${xxx} expansion. The braces are optional. When
7582 the braces are used, parameter_brace_expand() does the work,
7583 possibly calling param_expand recursively. */
7585 param_expand (string
, sindex
, quoted
, expanded_something
,
7586 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
7589 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
7590 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
7592 char *temp
, *temp1
, uerror
[3];
7593 int zindex
, t_index
, expok
;
7598 WORD_DESC
*tdesc
, *ret
;
7602 c
= string
[++zindex
];
7604 temp
= (char *)NULL
;
7605 ret
= tdesc
= (WORD_DESC
*)NULL
;
7608 /* Do simple cases first. Switch on what follows '$'. */
7622 temp1
= dollar_vars
[TODIGIT (c
)];
7623 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
7628 last_command_exit_value
= EXECUTION_FAILURE
;
7629 err_unboundvar (uerror
);
7630 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7633 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7634 ? quote_string (temp1
)
7635 : quote_escapes (temp1
);
7637 temp
= (char *)NULL
;
7641 /* $$ -- pid of the invoking shell. */
7643 temp
= itos (dollar_dollar_pid
);
7646 /* $# -- number of positional parameters. */
7648 temp
= itos (number_of_args ());
7651 /* $? -- return value of the last synchronous command. */
7653 temp
= itos (last_command_exit_value
);
7656 /* $- -- flags supplied to the shell on invocation or by `set'. */
7658 temp
= which_set_flags ();
7661 /* $! -- Pid of the last asynchronous command. */
7663 /* If no asynchronous pids have been created, expand to nothing.
7664 If `set -u' has been executed, and no async processes have
7665 been created, this is an expansion error. */
7666 if (last_asynchronous_pid
== NO_PID
)
7668 if (expanded_something
)
7669 *expanded_something
= 0;
7670 temp
= (char *)NULL
;
7671 if (unbound_vars_is_error
)
7676 last_command_exit_value
= EXECUTION_FAILURE
;
7677 err_unboundvar (uerror
);
7678 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7682 temp
= itos (last_asynchronous_pid
);
7685 /* The only difference between this and $@ is when the arg is quoted. */
7686 case '*': /* `$*' */
7687 list
= list_rest_of_args ();
7690 /* According to austin-group posix proposal by Geoff Clare in
7691 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7693 "The shell shall write a message to standard error and
7694 immediately exit when it tries to expand an unset parameter
7695 other than the '@' and '*' special parameters."
7698 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7703 last_command_exit_value
= EXECUTION_FAILURE
;
7704 err_unboundvar (uerror
);
7705 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7709 /* If there are no command-line arguments, this should just
7710 disappear if there are other characters in the expansion,
7711 even if it's quoted. */
7712 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7713 temp
= (char *)NULL
;
7714 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7716 /* If we have "$*" we want to make a string of the positional
7717 parameters, separated by the first character of $IFS, and
7718 quote the whole string, including the separators. If IFS
7719 is unset, the parameters are separated by ' '; if $IFS is
7720 null, the parameters are concatenated. */
7721 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7724 temp1
= quote_string (temp
);
7726 tflag
|= W_HASQUOTEDNULL
;
7733 /* We check whether or not we're eventually going to split $* here,
7734 for example when IFS is empty and we are processing the rhs of
7735 an assignment statement. In that case, we don't separate the
7736 arguments at all. Otherwise, if the $* is not quoted it is
7738 # if defined (HANDLE_MULTIBYTE)
7739 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7741 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7743 temp
= string_list_dollar_star (list
);
7746 temp
= string_list_dollar_at (list
, quoted
);
7747 if (quoted
== 0 && (ifs_is_set
== 0 || ifs_is_null
))
7748 tflag
|= W_SPLITSPACE
;
7751 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7752 *contains_dollar_at
= 1;
7755 dispose_words (list
);
7758 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7759 means that we have to turn quoting off after we split into
7760 the individually quoted arguments so that the final split
7761 on the first character of $IFS is still done. */
7762 case '@': /* `$@' */
7763 list
= list_rest_of_args ();
7766 /* According to austin-group posix proposal by Geoff Clare in
7767 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7769 "The shell shall write a message to standard error and
7770 immediately exit when it tries to expand an unset parameter
7771 other than the '@' and '*' special parameters."
7774 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7779 last_command_exit_value
= EXECUTION_FAILURE
;
7780 err_unboundvar (uerror
);
7781 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7785 /* We want to flag the fact that we saw this. We can't turn
7786 off quoting entirely, because other characters in the
7787 string might need it (consider "\"$@\""), but we need some
7788 way to signal that the final split on the first character
7789 of $IFS should be done, even though QUOTED is 1. */
7790 /* XXX - should this test include Q_PATQUOTE? */
7791 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7792 *quoted_dollar_at_p
= 1;
7793 if (contains_dollar_at
)
7794 *contains_dollar_at
= 1;
7796 /* We want to separate the positional parameters with the first
7797 character of $IFS in case $IFS is something other than a space.
7798 We also want to make sure that splitting is done no matter what --
7799 according to POSIX.2, this expands to a list of the positional
7800 parameters no matter what IFS is set to. */
7801 temp
= string_list_dollar_at (list
, (pflags
& PF_ASSIGNRHS
) ? (quoted
|Q_DOUBLE_QUOTES
) : quoted
);
7803 tflag
|= W_DOLLARAT
;
7804 dispose_words (list
);
7808 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
, pflags
,
7810 contains_dollar_at
);
7812 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7814 temp
= tdesc
? tdesc
->word
: (char *)0;
7817 /* Quoted nulls should be removed if there is anything else
7819 /* Note that we saw the quoted null so we can add one back at
7820 the end of this function if there are no other characters
7821 in the string, discard TEMP, and go on. The exception to
7822 this is when we have "${@}" and $1 is '', since $@ needs
7823 special handling. */
7824 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7826 if (had_quoted_null_p
)
7827 *had_quoted_null_p
= 1;
7828 if (*quoted_dollar_at_p
== 0)
7831 tdesc
->word
= temp
= (char *)NULL
;
7839 /* Do command or arithmetic substitution. */
7841 /* We have to extract the contents of this paren substitution. */
7842 t_index
= zindex
+ 1;
7843 temp
= extract_command_subst (string
, &t_index
, 0);
7846 /* For Posix.2-style `$(( ))' arithmetic substitution,
7847 extract the expression and pass it to the evaluator. */
7848 if (temp
&& *temp
== LPAREN
)
7852 temp2
= savestring (temp1
);
7853 t_index
= strlen (temp2
) - 1;
7855 if (temp2
[t_index
] != RPAREN
)
7861 /* Cut off ending `)' */
7862 temp2
[t_index
] = '\0';
7864 if (chk_arithsub (temp2
, t_index
) == 0)
7868 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7873 /* Expand variables found inside the expression. */
7874 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7878 /* No error messages. */
7879 this_command_name
= (char *)NULL
;
7880 number
= evalexp (temp1
, &expok
);
7885 if (interactive_shell
== 0 && posixly_correct
)
7887 last_command_exit_value
= EXECUTION_FAILURE
;
7888 return (&expand_wdesc_fatal
);
7891 return (&expand_wdesc_error
);
7893 temp
= itos (number
);
7898 if (pflags
& PF_NOCOMSUB
)
7899 /* we need zindex+1 because string[zindex] == RPAREN */
7900 temp1
= substring (string
, *sindex
, zindex
+1);
7903 tdesc
= command_substitute (temp
, quoted
);
7904 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7906 dispose_word_desc (tdesc
);
7912 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7913 away in a future bash release. */
7915 /* Extract the contents of this arithmetic substitution. */
7916 t_index
= zindex
+ 1;
7917 temp
= extract_arithmetic_subst (string
, &t_index
);
7921 temp
= savestring (string
);
7922 if (expanded_something
)
7923 *expanded_something
= 0;
7927 /* Do initial variable expansion. */
7928 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7933 /* Find the variable in VARIABLE_LIST. */
7934 temp
= (char *)NULL
;
7936 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7938 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7940 /* If this isn't a variable name, then just output the `$'. */
7941 if (temp1
== 0 || *temp1
== '\0')
7944 temp
= (char *)xmalloc (2);
7947 if (expanded_something
)
7948 *expanded_something
= 0;
7952 /* If the variable exists, return its value cell. */
7953 var
= find_variable (temp1
);
7955 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7957 #if defined (ARRAY_VARS)
7958 if (assoc_p (var
) || array_p (var
))
7960 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7961 : assoc_reference (assoc_cell (var
), "0");
7963 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7964 ? quote_string (temp
)
7965 : quote_escapes (temp
);
7966 else if (unbound_vars_is_error
)
7967 goto unbound_variable
;
7972 temp
= value_cell (var
);
7974 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7975 ? quote_string (temp
)
7976 : quote_escapes (temp
);
7983 else if (var
= find_variable_last_nameref (temp1
))
7985 temp
= nameref_cell (var
);
7986 #if defined (ARRAY_VARS)
7987 if (temp
&& *temp
&& valid_array_reference (temp
))
7989 tdesc
= parameter_brace_expand_word (temp
, SPECIAL_VAR (temp
, 0), quoted
, pflags
, (arrayind_t
*)NULL
);
7990 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7997 /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */
7998 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
8000 last_command_exit_value
= EXECUTION_FAILURE
;
8001 report_error (_("%s: invalid variable name for name reference"), temp
);
8002 return (&expand_wdesc_error
); /* XXX */
8005 temp
= (char *)NULL
;
8008 temp
= (char *)NULL
;
8011 if (unbound_vars_is_error
)
8013 last_command_exit_value
= EXECUTION_FAILURE
;
8014 err_unboundvar (temp1
);
8023 last_command_exit_value
= EXECUTION_FAILURE
;
8024 return ((unbound_vars_is_error
&& interactive_shell
== 0)
8025 ? &expand_wdesc_fatal
8026 : &expand_wdesc_error
);
8037 ret
= alloc_word_desc ();
8038 ret
->flags
= tflag
; /* XXX */
8044 /* Make a word list which is the result of parameter and variable
8045 expansion, command substitution, arithmetic substitution, and
8046 quote removal of WORD. Return a pointer to a WORD_LIST which is
8047 the result of the expansion. If WORD contains a null word, the
8048 word list returned is also null.
8050 QUOTED contains flag values defined in shell.h.
8052 ISEXP is used to tell expand_word_internal that the word should be
8053 treated as the result of an expansion. This has implications for
8054 how IFS characters in the word are treated.
8056 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
8057 they point to an integer value which receives information about expansion.
8058 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
8059 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
8062 This only does word splitting in the case of $@ expansion. In that
8063 case, we split on ' '. */
8065 /* Values for the local variable quoted_state. */
8067 #define PARTIALLY_QUOTED 1
8068 #define WHOLLY_QUOTED 2
8071 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
8074 int *contains_dollar_at
;
8075 int *expanded_something
;
8080 /* The intermediate string that we build while expanding. */
8083 /* The current size of the above object. */
8086 /* Index into ISTRING. */
8089 /* Temporary string storage. */
8092 /* The text of WORD. */
8093 register char *string
;
8095 /* The size of STRING. */
8098 /* The index into STRING. */
8101 /* This gets 1 if we see a $@ while quoted. */
8102 int quoted_dollar_at
;
8104 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
8105 whether WORD contains no quoting characters, a partially quoted
8106 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
8110 int had_quoted_null
;
8111 int has_dollar_at
, temp_has_dollar_at
;
8112 int split_on_spaces
;
8114 int pflags
; /* flags passed to param_expand */
8116 int assignoff
; /* If assignment, offset of `=' */
8118 register unsigned char c
; /* Current character. */
8119 int t_index
; /* For calls to string_extract_xxx. */
8125 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
8126 istring
[istring_index
= 0] = '\0';
8127 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
8128 split_on_spaces
= 0;
8129 quoted_state
= UNQUOTED
;
8131 string
= word
->word
;
8133 goto finished_with_string
;
8134 /* Don't need the string length for the SADD... and COPY_ macros unless
8135 multibyte characters are possible. */
8136 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
8138 if (contains_dollar_at
)
8139 *contains_dollar_at
= 0;
8143 /* Begin the expansion. */
8149 /* Case on top-level character. */
8153 goto finished_with_string
;
8157 #if HANDLE_MULTIBYTE
8158 if (MB_CUR_MAX
> 1 && string
[sindex
])
8160 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8165 temp
= (char *)xmalloc (3);
8167 temp
[1] = c
= string
[sindex
];
8178 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
8184 #if defined (PROCESS_SUBSTITUTION)
8185 /* Process substitution. */
8189 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
8191 sindex
--; /* add_character: label increments sindex */
8195 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
8197 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
8200 /* If the process substitution specification is `<()', we want to
8201 open the pipe for writing in the child and produce output; if
8202 it is `>()', we want to open the pipe for reading in the child
8203 and consume input. */
8204 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
8208 goto dollar_add_string
;
8210 #endif /* PROCESS_SUBSTITUTION */
8213 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8214 which are not assignment statements are not expanded. If the
8215 shell isn't in posix mode, though, we perform tilde expansion
8216 on `likely candidate' unquoted assignment statements (flags
8217 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8218 contains an unquoted :~ or =~. Something to think about: we
8219 now have a flag that says to perform tilde expansion on arguments
8220 to `assignment builtins' like declare and export that look like
8221 assignment statements. We now do tilde expansion on such words
8222 even in POSIX mode. */
8223 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
8225 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8226 goto add_ifs_character
;
8230 /* If we're not in posix mode or forcing assignment-statement tilde
8231 expansion, note where the `=' appears in the word and prepare to
8232 do tilde expansion following the first `='. */
8233 if ((word
->flags
& W_ASSIGNMENT
) &&
8234 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8235 assignoff
== -1 && sindex
> 0)
8237 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
8238 word
->flags
|= W_ITILDE
;
8240 else if ((word
->flags
& W_ASSIGNMENT
) &&
8241 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8242 string
[sindex
+1] == '~')
8243 word
->flags
|= W_ITILDE
;
8245 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8246 goto add_ifs_character
;
8251 if (word
->flags
& W_NOTILDE
)
8253 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8254 goto add_ifs_character
;
8259 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
8260 string
[sindex
+1] == '~')
8261 word
->flags
|= W_ITILDE
;
8263 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8264 goto add_ifs_character
;
8269 /* If the word isn't supposed to be tilde expanded, or we're not
8270 at the start of a word or after an unquoted : or = in an
8271 assignment statement, we don't do tilde expansion. */
8272 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
8273 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
8274 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8276 word
->flags
&= ~W_ITILDE
;
8277 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
8278 goto add_ifs_character
;
8283 if (word
->flags
& W_ASSIGNRHS
)
8285 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
8290 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
8292 word
->flags
&= ~W_ITILDE
;
8294 if (temp
&& *temp
&& t_index
> 0)
8296 temp1
= bash_tilde_expand (temp
, tflag
);
8297 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
8301 goto add_character
; /* tilde expansion failed */
8306 goto add_quoted_string
; /* XXX was add_string */
8315 if (expanded_something
)
8316 *expanded_something
= 1;
8318 temp_has_dollar_at
= 0;
8319 pflags
= (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0;
8320 if (word
->flags
& W_NOSPLIT2
)
8321 pflags
|= PF_NOSPLIT2
;
8322 if (word
->flags
& W_ASSIGNRHS
)
8323 pflags
|= PF_ASSIGNRHS
;
8324 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
8325 &temp_has_dollar_at
, "ed_dollar_at
,
8326 &had_quoted_null
, pflags
);
8327 has_dollar_at
+= temp_has_dollar_at
;
8328 split_on_spaces
+= (tword
->flags
& W_SPLITSPACE
);
8330 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
8334 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
8335 : &expand_word_fatal
);
8337 if (contains_dollar_at
&& has_dollar_at
)
8338 *contains_dollar_at
= 1;
8340 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
8341 had_quoted_null
= 1;
8343 temp
= tword
? tword
->word
: (char *)NULL
;
8344 dispose_word_desc (tword
);
8346 /* Kill quoted nulls; we will add them back at the end of
8347 expand_word_internal if nothing else in the string */
8348 if (had_quoted_null
&& temp
&& QUOTED_NULL (temp
))
8351 temp
= (char *)NULL
;
8357 case '`': /* Backquoted command substitution. */
8361 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
8362 /* The test of sindex against t_index is to allow bare instances of
8363 ` to pass through, for backwards compatibility. */
8364 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
8366 if (sindex
- 1 == t_index
)
8371 last_command_exit_value
= EXECUTION_FAILURE
;
8372 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
8375 return ((temp
== &extract_string_error
) ? &expand_word_error
8376 : &expand_word_fatal
);
8379 if (expanded_something
)
8380 *expanded_something
= 1;
8382 if (word
->flags
& W_NOCOMSUB
)
8383 /* sindex + 1 because string[sindex] == '`' */
8384 temp1
= substring (string
, t_index
, sindex
+ 1);
8387 de_backslash (temp
);
8388 tword
= command_substitute (temp
, quoted
);
8389 temp1
= tword
? tword
->word
: (char *)NULL
;
8391 dispose_word_desc (tword
);
8395 goto dollar_add_string
;
8399 if (string
[sindex
+ 1] == '\n')
8405 c
= string
[++sindex
];
8407 if (quoted
& Q_HERE_DOCUMENT
)
8409 else if (quoted
& Q_DOUBLE_QUOTES
)
8414 /* From Posix discussion on austin-group list: Backslash escaping
8415 a } in ${...} is removed. Issue 0000221 */
8416 if ((quoted
& Q_DOLBRACE
) && c
== RBRACE
)
8418 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8420 /* This is the fix for " $@\ " */
8421 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0) && isexp
== 0 && isifs (c
))
8423 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8424 DEFAULT_ARRAY_SIZE
);
8425 istring
[istring_index
++] = CTLESC
;
8426 istring
[istring_index
++] = '\\';
8427 istring
[istring_index
] = '\0';
8429 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8431 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
8433 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
8438 sindex
--; /* add_character: label increments sindex */
8443 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8448 /* BEFORE jumping here, we need to increment sindex if appropriate */
8449 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8450 DEFAULT_ARRAY_SIZE
);
8451 istring
[istring_index
++] = twochars
[0];
8452 istring
[istring_index
++] = twochars
[1];
8453 istring
[istring_index
] = '\0';
8458 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8462 temp
= string_extract_double_quoted (string
, &sindex
, 0);
8464 /* If the quotes surrounded the entire string, then the
8465 whole word was quoted. */
8466 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8472 tword
= alloc_word_desc ();
8475 temp
= (char *)NULL
;
8477 temp_has_dollar_at
= 0; /* XXX */
8478 /* Need to get W_HASQUOTEDNULL flag through this function. */
8479 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &temp_has_dollar_at
, (int *)NULL
);
8480 has_dollar_at
+= temp_has_dollar_at
;
8482 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
8486 /* expand_word_internal has already freed temp_word->word
8487 for us because of the way it prints error messages. */
8488 tword
->word
= (char *)NULL
;
8489 dispose_word (tword
);
8493 dispose_word (tword
);
8495 /* "$@" (a double-quoted dollar-at) expands into nothing,
8496 not even a NULL word, when there are no positional
8498 if (list
== 0 && has_dollar_at
)
8504 /* If we get "$@", we know we have expanded something, so we
8505 need to remember it for the final split on $IFS. This is
8506 a special case; it's the only case where a quoted string
8507 can expand into more than one word. It's going to come back
8508 from the above call to expand_word_internal as a list with
8509 a single word, in which all characters are quoted and
8510 separated by blanks. What we want to do is to turn it back
8511 into a list for the next piece of code. */
8513 dequote_list (list
);
8515 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
8516 had_quoted_null
= 1; /* XXX */
8521 if (contains_dollar_at
)
8522 *contains_dollar_at
= 1;
8523 if (expanded_something
)
8524 *expanded_something
= 1;
8529 /* What we have is "". This is a minor optimization. */
8531 list
= (WORD_LIST
*)NULL
;
8534 /* The code above *might* return a list (consider the case of "$@",
8535 where it returns "$1", "$2", etc.). We can't throw away the
8536 rest of the list, and we have to make sure each word gets added
8537 as quoted. We test on tresult->next: if it is non-NULL, we
8538 quote the whole list, save it to a string with string_list, and
8539 add that string. We don't need to quote the results of this
8540 (and it would be wrong, since that would quote the separators
8541 as well), so we go directly to add_string. */
8546 /* Testing quoted_dollar_at makes sure that "$@" is
8547 split correctly when $IFS does not contain a space. */
8548 temp
= quoted_dollar_at
8549 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
8550 : string_list (quote_list (list
));
8551 dispose_words (list
);
8556 temp
= savestring (list
->word
->word
);
8557 tflag
= list
->word
->flags
;
8558 dispose_words (list
);
8560 /* If the string is not a quoted null string, we want
8561 to remove any embedded unquoted CTLNUL characters.
8562 We do not want to turn quoted null strings back into
8563 the empty string, though. We do this because we
8564 want to remove any quoted nulls from expansions that
8565 contain other characters. For example, if we have
8566 x"$*"y or "x$*y" and there are no positional parameters,
8567 the $* should expand into nothing. */
8568 /* We use the W_HASQUOTEDNULL flag to differentiate the
8569 cases: a quoted null character as above and when
8570 CTLNUL is contained in the (non-null) expansion
8571 of some variable. We use the had_quoted_null flag to
8572 pass the value through this function to its caller. */
8573 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
8574 remove_quoted_nulls (temp
); /* XXX */
8578 temp
= (char *)NULL
;
8580 /* We do not want to add quoted nulls to strings that are only
8581 partially quoted; we can throw them away. The exception to
8582 this is when we are going to be performing word splitting,
8583 since we have to preserve a null argument if the next character
8584 will cause word splitting. */
8585 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
&& (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)))
8593 temp
= quote_string (temp
);
8601 sindex
--; /* add_character: label increments sindex */
8608 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8612 temp
= string_extract_single_quoted (string
, &sindex
);
8614 /* If the entire STRING was surrounded by single quotes,
8615 then the string is wholly quoted. */
8616 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8620 /* If all we had was '', it is a null expansion. */
8624 temp
= (char *)NULL
;
8627 remove_quoted_escapes (temp
); /* ??? */
8629 /* We do not want to add quoted nulls to strings that are only
8630 partially quoted; such nulls are discarded. */
8631 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
8634 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8638 sindex
--; /* add_character: label increments sindex */
8642 goto add_quoted_string
;
8647 /* This is the fix for " $@ " */
8649 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
8651 if (string
[sindex
]) /* from old goto dollar_add_string */
8660 #if HANDLE_MULTIBYTE
8666 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8671 twochars
[0] = CTLESC
;
8678 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
8681 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
8682 DEFAULT_ARRAY_SIZE
);
8683 istring
[istring_index
++] = c
;
8684 istring
[istring_index
] = '\0';
8686 /* Next character. */
8691 finished_with_string
:
8692 /* OK, we're ready to return. If we have a quoted string, and
8693 quoted_dollar_at is not set, we do no splitting at all; otherwise
8694 we split on ' '. The routines that call this will handle what to
8695 do if nothing has been expanded. */
8697 /* Partially and wholly quoted strings which expand to the empty
8698 string are retained as an empty arguments. Unquoted strings
8699 which expand to the empty string are discarded. The single
8700 exception is the case of expanding "$@" when there are no
8701 positional parameters. In that case, we discard the expansion. */
8703 /* Because of how the code that handles "" and '' in partially
8704 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8705 if we saw quoting characters, but the expansion was empty.
8706 "" and '' are tossed away before we get to this point when
8707 processing partially quoted strings. This makes "" and $xxx""
8708 equivalent when xxx is unset. We also look to see whether we
8709 saw a quoted null from a ${} expansion and add one back if we
8712 /* If we expand to nothing and there were no single or double quotes
8713 in the word, we throw it away. Otherwise, we return a NULL word.
8714 The single exception is for $@ surrounded by double quotes when
8715 there are no positional parameters. In that case, we also throw
8718 if (*istring
== '\0')
8720 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
8722 istring
[0] = CTLNUL
;
8724 tword
= make_bare_word (istring
);
8725 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8726 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8727 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8728 tword
->flags
|= W_QUOTED
;
8730 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8731 and a double-quoted "$@" appears anywhere in it, then the entire
8733 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8734 list
= (WORD_LIST
*)NULL
;
8738 tword
= make_bare_word (istring
);
8739 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8740 tword
->flags
|= W_QUOTED
;
8741 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8745 list
= (WORD_LIST
*)NULL
;
8748 else if (word
->flags
& W_NOSPLIT
)
8750 tword
= make_bare_word (istring
);
8751 if (word
->flags
& W_ASSIGNMENT
)
8752 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8753 if (word
->flags
& W_COMPASSIGN
)
8754 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8755 if (word
->flags
& W_NOGLOB
)
8756 tword
->flags
|= W_NOGLOB
; /* XXX */
8757 if (word
->flags
& W_NOBRACE
)
8758 tword
->flags
|= W_NOBRACE
; /* XXX */
8759 if (word
->flags
& W_NOEXPAND
)
8760 tword
->flags
|= W_NOEXPAND
; /* XXX */
8761 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8762 tword
->flags
|= W_QUOTED
;
8763 if (had_quoted_null
&& QUOTED_NULL (istring
))
8764 tword
->flags
|= W_HASQUOTEDNULL
;
8765 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8771 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8773 /* If we have $@, we need to split the results no matter what. If
8774 IFS is unset or NULL, string_list_dollar_at has separated the
8775 positional parameters with a space, so we split on space (we have
8776 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8777 string_list_dollar_at has separated the positional parameters
8778 with the first character of $IFS, so we split on $IFS. If
8779 SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
8780 unset or null, and we want to make sure that we split on spaces
8781 regardless of what else has happened to IFS since the expansion. */
8782 if (split_on_spaces
)
8783 list
= list_string (istring
, " ", 1); /* XXX quoted == 1? */
8784 else if (has_dollar_at
&& ifs_chars
)
8785 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8788 tword
= make_bare_word (istring
);
8789 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8790 tword
->flags
|= W_QUOTED
;
8791 if (word
->flags
& W_ASSIGNMENT
)
8792 tword
->flags
|= W_ASSIGNMENT
;
8793 if (word
->flags
& W_COMPASSIGN
)
8794 tword
->flags
|= W_COMPASSIGN
;
8795 if (word
->flags
& W_NOGLOB
)
8796 tword
->flags
|= W_NOGLOB
;
8797 if (word
->flags
& W_NOBRACE
)
8798 tword
->flags
|= W_NOBRACE
;
8799 if (word
->flags
& W_NOEXPAND
)
8800 tword
->flags
|= W_NOEXPAND
;
8801 if (had_quoted_null
&& QUOTED_NULL (istring
))
8802 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8803 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8811 /* **************************************************************** */
8813 /* Functions for Quote Removal */
8815 /* **************************************************************** */
8817 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8818 backslash quoting rules for within double quotes or a here document. */
8820 string_quote_removal (string
, quoted
)
8825 char *r
, *result_string
, *temp
, *send
;
8826 int sindex
, tindex
, dquote
;
8830 /* The result can be no longer than the original string. */
8831 slen
= strlen (string
);
8832 send
= string
+ slen
;
8834 r
= result_string
= (char *)xmalloc (slen
+ 1);
8836 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8841 c
= string
[++sindex
];
8847 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8852 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8856 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8862 tindex
= sindex
+ 1;
8863 temp
= string_extract_single_quoted (string
, &tindex
);
8874 dquote
= 1 - dquote
;
8880 return (result_string
);
8885 /* Perform quote removal on word WORD. This allocates and returns a new
8888 word_quote_removal (word
, quoted
)
8895 t
= string_quote_removal (word
->word
, quoted
);
8896 w
= alloc_word_desc ();
8897 w
->word
= t
? t
: savestring ("");
8901 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8902 the members of the list are treated as if they are surrounded by
8903 double quotes. Return a new list, or NULL if LIST is NULL. */
8905 word_list_quote_removal (list
, quoted
)
8909 WORD_LIST
*result
, *t
, *tresult
, *e
;
8911 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8913 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8915 result
= (WORD_LIST
*) list_append (result
, tresult
);
8918 result
= e
= tresult
;
8931 /*******************************************
8933 * Functions to perform word splitting *
8935 *******************************************/
8945 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8947 ifs_is_set
= ifs_var
!= 0;
8948 ifs_is_null
= ifs_is_set
&& (*ifs_value
== 0);
8950 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8951 handle multibyte chars in IFS */
8952 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8953 for (t
= ifs_value
; t
&& *t
; t
++)
8959 #if defined (HANDLE_MULTIBYTE)
8962 ifs_firstc
[0] = '\0';
8968 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8969 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8970 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8972 ifs_firstc
[0] = ifs_value
[0];
8973 ifs_firstc
[1] = '\0';
8977 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8980 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8990 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8991 is not quoted. list_string () performs quote removal for us, even if we
8992 don't do any splitting. */
8994 word_split (w
, ifs_chars
)
9004 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
9005 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
9008 result
= (WORD_LIST
*)NULL
;
9013 /* Perform word splitting on LIST and return the RESULT. It is possible
9014 to return (WORD_LIST *)NULL. */
9016 word_list_split (list
)
9019 WORD_LIST
*result
, *t
, *tresult
, *e
;
9021 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
9023 tresult
= word_split (t
->word
, ifs_value
);
9025 result
= e
= tresult
;
9036 /**************************************************
9038 * Functions to expand an entire WORD_LIST *
9040 **************************************************/
9042 /* Do any word-expansion-specific cleanup and jump to top_level */
9044 exp_jump_to_top_level (v
)
9047 set_pipestatus_from_exit (last_command_exit_value
);
9049 /* Cleanup code goes here. */
9050 expand_no_split_dollar_star
= 0; /* XXX */
9051 expanding_redir
= 0;
9052 assigning_in_environment
= 0;
9054 if (parse_and_execute_level
== 0)
9055 top_level_cleanup (); /* from sig.c */
9057 jump_to_top_level (v
);
9060 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
9061 ELIST, and set ELIST to the new list. */
9062 #define PREPEND_LIST(nlist, elist) \
9063 do { nlist->next = elist; elist = nlist; } while (0)
9065 /* Separate out any initial variable assignments from TLIST. If set -k has
9066 been executed, remove all assignment statements from TLIST. Initial
9067 variable assignments and other environment assignments are placed
9068 on SUBST_ASSIGN_VARLIST. */
9070 separate_out_assignments (tlist
)
9073 register WORD_LIST
*vp
, *lp
;
9076 return ((WORD_LIST
*)NULL
);
9078 if (subst_assign_varlist
)
9079 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
9081 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9084 /* Separate out variable assignments at the start of the command.
9085 Loop invariant: vp->next == lp
9087 lp = list of words left after assignment statements skipped
9088 tlist = original list of words
9090 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
9096 /* If lp != tlist, we have some initial assignment statements.
9097 We make SUBST_ASSIGN_VARLIST point to the list of assignment
9098 words and TLIST point to the remaining words. */
9101 subst_assign_varlist
= tlist
;
9102 /* ASSERT(vp->next == lp); */
9103 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
9104 tlist
= lp
; /* remainder of word list */
9107 /* vp == end of variable list */
9108 /* tlist == remainder of original word list without variable assignments */
9110 /* All the words in tlist were assignment statements */
9111 return ((WORD_LIST
*)NULL
);
9113 /* ASSERT(tlist != NULL); */
9114 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
9116 /* If the -k option is in effect, we need to go through the remaining
9117 words, separate out the assignment words, and place them on
9118 SUBST_ASSIGN_VARLIST. */
9119 if (place_keywords_in_env
)
9121 WORD_LIST
*tp
; /* tp == running pointer into tlist */
9126 /* Loop Invariant: tp->next == lp */
9127 /* Loop postcondition: tlist == word list without assignment statements */
9130 if (lp
->word
->flags
& W_ASSIGNMENT
)
9132 /* Found an assignment statement, add this word to end of
9133 subst_assign_varlist (vp). */
9134 if (!subst_assign_varlist
)
9135 subst_assign_varlist
= vp
= lp
;
9142 /* Remove the word pointed to by LP from TLIST. */
9143 tp
->next
= lp
->next
;
9144 /* ASSERT(vp == lp); */
9145 lp
->next
= (WORD_LIST
*)NULL
;
9158 #define WEXP_VARASSIGN 0x001
9159 #define WEXP_BRACEEXP 0x002
9160 #define WEXP_TILDEEXP 0x004
9161 #define WEXP_PARAMEXP 0x008
9162 #define WEXP_PATHEXP 0x010
9164 /* All of the expansions, including variable assignments at the start of
9166 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9168 /* All of the expansions except variable assignments at the start of
9170 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9172 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
9173 expansion, command substitution, arithmetic expansion, word splitting, and
9175 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
9177 /* Take the list of words in LIST and do the various substitutions. Return
9178 a new list of words which is the expanded list, and without things like
9179 variable assignments. */
9185 return (expand_word_list_internal (list
, WEXP_ALL
));
9188 /* Same as expand_words (), but doesn't hack variable or environment
9191 expand_words_no_vars (list
)
9194 return (expand_word_list_internal (list
, WEXP_NOVARS
));
9198 expand_words_shellexp (list
)
9201 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
9205 glob_expand_word_list (tlist
, eflags
)
9209 char **glob_array
, *temp_string
;
9210 register int glob_index
;
9211 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
9214 output_list
= disposables
= (WORD_LIST
*)NULL
;
9215 glob_array
= (char **)NULL
;
9218 /* For each word, either globbing is attempted or the word is
9219 added to orig_list. If globbing succeeds, the results are
9220 added to orig_list and the word (tlist) is added to the list
9221 of disposable words. If globbing fails and failed glob
9222 expansions are left unchanged (the shell default), the
9223 original word is added to orig_list. If globbing fails and
9224 failed glob expansions are removed, the original word is
9225 added to the list of disposable words. orig_list ends up
9226 in reverse order and requires a call to REVERSE_LIST to
9227 be set right. After all words are examined, the disposable
9231 /* If the word isn't an assignment and contains an unquoted
9232 pattern matching character, then glob it. */
9233 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
9234 unquoted_glob_pattern_p (tlist
->word
->word
))
9236 glob_array
= shell_glob_filename (tlist
->word
->word
);
9238 /* Handle error cases.
9239 I don't think we should report errors like "No such file
9240 or directory". However, I would like to report errors
9241 like "Read failed". */
9243 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
9245 glob_array
= (char **)xmalloc (sizeof (char *));
9246 glob_array
[0] = (char *)NULL
;
9249 /* Dequote the current word in case we have to use it. */
9250 if (glob_array
[0] == NULL
)
9252 temp_string
= dequote_string (tlist
->word
->word
);
9253 free (tlist
->word
->word
);
9254 tlist
->word
->word
= temp_string
;
9257 /* Make the array into a word list. */
9258 glob_list
= (WORD_LIST
*)NULL
;
9259 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
9261 tword
= make_bare_word (glob_array
[glob_index
]);
9262 glob_list
= make_word_list (tword
, glob_list
);
9267 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
9268 PREPEND_LIST (tlist
, disposables
);
9270 else if (fail_glob_expansion
!= 0)
9272 last_command_exit_value
= EXECUTION_FAILURE
;
9273 report_error (_("no match: %s"), tlist
->word
->word
);
9274 exp_jump_to_top_level (DISCARD
);
9276 else if (allow_null_glob_expansion
== 0)
9278 /* Failed glob expressions are left unchanged. */
9279 PREPEND_LIST (tlist
, output_list
);
9283 /* Failed glob expressions are removed. */
9284 PREPEND_LIST (tlist
, disposables
);
9289 /* Dequote the string. */
9290 temp_string
= dequote_string (tlist
->word
->word
);
9291 free (tlist
->word
->word
);
9292 tlist
->word
->word
= temp_string
;
9293 PREPEND_LIST (tlist
, output_list
);
9296 strvec_dispose (glob_array
);
9297 glob_array
= (char **)NULL
;
9303 dispose_words (disposables
);
9306 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9308 return (output_list
);
9311 #if defined (BRACE_EXPANSION)
9313 brace_expand_word_list (tlist
, eflags
)
9317 register char **expansions
;
9319 WORD_LIST
*disposables
, *output_list
, *next
;
9323 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
9327 if (tlist
->word
->flags
& W_NOBRACE
)
9329 /*itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);*/
9330 PREPEND_LIST (tlist
, output_list
);
9334 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9336 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9337 PREPEND_LIST (tlist
, output_list
);
9341 /* Only do brace expansion if the word has a brace character. If
9342 not, just add the word list element to BRACES and continue. In
9343 the common case, at least when running shell scripts, this will
9344 degenerate to a bunch of calls to `mbschr', and then what is
9345 basically a reversal of TLIST into BRACES, which is corrected
9346 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9348 if (mbschr (tlist
->word
->word
, LBRACE
))
9350 expansions
= brace_expand (tlist
->word
->word
);
9352 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
9354 w
= alloc_word_desc ();
9355 w
->word
= temp_string
;
9357 /* If brace expansion didn't change the word, preserve
9358 the flags. We may want to preserve the flags
9359 unconditionally someday -- XXX */
9360 if (STREQ (temp_string
, tlist
->word
->word
))
9361 w
->flags
= tlist
->word
->flags
;
9363 w
= make_word_flags (w
, temp_string
);
9365 output_list
= make_word_list (w
, output_list
);
9369 /* Add TLIST to the list of words to be freed after brace
9370 expansion has been performed. */
9371 PREPEND_LIST (tlist
, disposables
);
9374 PREPEND_LIST (tlist
, output_list
);
9378 dispose_words (disposables
);
9381 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9383 return (output_list
);
9387 #if defined (ARRAY_VARS)
9388 /* Take WORD, a compound associative array assignment, and internally run
9389 'declare -A w', where W is the variable name portion of WORD. */
9391 make_internal_declare (word
, option
)
9399 w
= make_word (word
);
9401 t
= assignment (w
->word
, 0);
9404 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
9405 wl
= make_word_list (make_word (option
), wl
);
9407 return (declare_builtin (wl
));
9412 shell_expand_word_list (tlist
, eflags
)
9416 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
9417 int expanded_something
, has_dollar_at
;
9420 /* We do tilde expansion all the time. This is what 1003.2 says. */
9421 new_list
= (WORD_LIST
*)NULL
;
9422 for (orig_list
= tlist
; tlist
; tlist
= next
)
9424 temp_string
= tlist
->word
->word
;
9428 #if defined (ARRAY_VARS)
9429 /* If this is a compound array assignment to a builtin that accepts
9430 such assignments (e.g., `declare'), take the assignment and perform
9431 it separately, handling the semantics of declarations inside shell
9432 functions. This avoids the double-evaluation of such arguments,
9433 because `declare' does some evaluation of compound assignments on
9435 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9441 if (tlist
->word
->flags
& (W_ASSIGNASSOC
|W_ASSNGLOBAL
|W_ASSIGNARRAY
))
9444 if ((tlist
->word
->flags
& (W_ASSIGNASSOC
|W_ASSNGLOBAL
)) == (W_ASSIGNASSOC
|W_ASSNGLOBAL
))
9449 else if (tlist
->word
->flags
& W_ASSIGNASSOC
)
9451 else if ((tlist
->word
->flags
& (W_ASSIGNARRAY
|W_ASSNGLOBAL
)) == (W_ASSIGNARRAY
|W_ASSNGLOBAL
))
9456 else if (tlist
->word
->flags
& W_ASSIGNARRAY
)
9458 else if (tlist
->word
->flags
& W_ASSNGLOBAL
)
9462 /* If we have special handling note the integer attribute */
9463 if (opti
> 0 && (tlist
->word
->flags
& W_ASSIGNINT
))
9469 make_internal_declare (tlist
->word
->word
, opts
);
9471 t
= do_word_assignment (tlist
->word
, 0);
9474 last_command_exit_value
= EXECUTION_FAILURE
;
9475 exp_jump_to_top_level (DISCARD
);
9478 /* Now transform the word as ksh93 appears to do and go on */
9479 t
= assignment (tlist
->word
->word
, 0);
9480 tlist
->word
->word
[t
] = '\0';
9481 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
|W_ASSIGNARRAY
);
9485 expanded_something
= 0;
9486 expanded
= expand_word_internal
9487 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
9489 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
9491 /* By convention, each time this error is returned,
9492 tlist->word->word has already been freed. */
9493 tlist
->word
->word
= (char *)NULL
;
9495 /* Dispose our copy of the original list. */
9496 dispose_words (orig_list
);
9497 /* Dispose the new list we're building. */
9498 dispose_words (new_list
);
9500 last_command_exit_value
= EXECUTION_FAILURE
;
9501 if (expanded
== &expand_word_error
)
9502 exp_jump_to_top_level (DISCARD
);
9504 exp_jump_to_top_level (FORCE_EOF
);
9507 /* Don't split words marked W_NOSPLIT. */
9508 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
9510 temp_list
= word_list_split (expanded
);
9511 dispose_words (expanded
);
9515 /* If no parameter expansion, command substitution, process
9516 substitution, or arithmetic substitution took place, then
9517 do not do word splitting. We still have to remove quoted
9518 null characters from the result. */
9519 word_list_remove_quoted_nulls (expanded
);
9520 temp_list
= expanded
;
9523 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
9524 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
9528 dispose_words (orig_list
);
9531 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
9536 /* The workhorse for expand_words () and expand_words_no_vars ().
9537 First arg is LIST, a WORD_LIST of words.
9538 Second arg EFLAGS is a flags word controlling which expansions are
9541 This does all of the substitutions: brace expansion, tilde expansion,
9542 parameter expansion, command substitution, arithmetic expansion,
9543 process substitution, word splitting, and pathname expansion, according
9544 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9545 set, or for which no expansion is done, do not undergo word splitting.
9546 Words with the W_NOGLOB bit set do not undergo pathname expansion; words
9547 with W_NOBRACE set do not undergo brace expansion (see
9548 brace_expand_word_list above). */
9550 expand_word_list_internal (list
, eflags
)
9554 WORD_LIST
*new_list
, *temp_list
;
9557 tempenv_assign_error
= 0;
9559 return ((WORD_LIST
*)NULL
);
9561 garglist
= new_list
= copy_word_list (list
);
9562 if (eflags
& WEXP_VARASSIGN
)
9564 garglist
= new_list
= separate_out_assignments (new_list
);
9567 if (subst_assign_varlist
)
9569 /* All the words were variable assignments, so they are placed
9570 into the shell's environment. */
9571 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9573 this_command_name
= (char *)NULL
; /* no arithmetic errors */
9574 tint
= do_word_assignment (temp_list
->word
, 0);
9575 /* Variable assignment errors in non-interactive shells
9576 running in Posix.2 mode cause the shell to exit. */
9579 last_command_exit_value
= EXECUTION_FAILURE
;
9580 if (interactive_shell
== 0 && posixly_correct
)
9581 exp_jump_to_top_level (FORCE_EOF
);
9583 exp_jump_to_top_level (DISCARD
);
9586 dispose_words (subst_assign_varlist
);
9587 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9589 return ((WORD_LIST
*)NULL
);
9593 /* Begin expanding the words that remain. The expansions take place on
9594 things that aren't really variable assignments. */
9596 #if defined (BRACE_EXPANSION)
9597 /* Do brace expansion on this word if there are any brace characters
9599 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
9600 new_list
= brace_expand_word_list (new_list
, eflags
);
9601 #endif /* BRACE_EXPANSION */
9603 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9604 variable substitution, command substitution, arithmetic expansion,
9605 and word splitting. */
9606 new_list
= shell_expand_word_list (new_list
, eflags
);
9608 /* Okay, we're almost done. Now let's just do some filename
9612 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
9613 /* Glob expand the word list unless globbing has been disabled. */
9614 new_list
= glob_expand_word_list (new_list
, eflags
);
9616 /* Dequote the words, because we're not performing globbing. */
9617 new_list
= dequote_list (new_list
);
9620 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
9622 sh_wassign_func_t
*assign_func
;
9623 int is_special_builtin
, is_builtin_or_func
;
9625 /* If the remainder of the words expand to nothing, Posix.2 requires
9626 that the variable and environment assignments affect the shell's
9628 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
9629 tempenv_assign_error
= 0;
9631 is_builtin_or_func
= (new_list
&& new_list
->word
&& (find_shell_builtin (new_list
->word
->word
) || find_function (new_list
->word
->word
)));
9632 /* Posix says that special builtins exit if a variable assignment error
9633 occurs in an assignment preceding it. */
9634 is_special_builtin
= (posixly_correct
&& new_list
&& new_list
->word
&& find_special_builtin (new_list
->word
->word
));
9636 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9638 this_command_name
= (char *)NULL
;
9639 assigning_in_environment
= (assign_func
== assign_in_env
);
9640 tint
= (*assign_func
) (temp_list
->word
, is_builtin_or_func
);
9641 assigning_in_environment
= 0;
9642 /* Variable assignment errors in non-interactive shells running
9643 in Posix.2 mode cause the shell to exit. */
9646 if (assign_func
== do_word_assignment
)
9648 last_command_exit_value
= EXECUTION_FAILURE
;
9649 if (interactive_shell
== 0 && posixly_correct
&& is_special_builtin
)
9650 exp_jump_to_top_level (FORCE_EOF
);
9652 exp_jump_to_top_level (DISCARD
);
9655 tempenv_assign_error
++;
9659 dispose_words (subst_assign_varlist
);
9660 subst_assign_varlist
= (WORD_LIST
*)NULL
;