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
? "|" : "");
383 if (f
& W_COMPASSIGN
)
386 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
391 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
396 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
401 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
406 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
411 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
413 if (f
& W_DOLLARSTAR
)
416 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
421 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
426 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
431 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
436 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
441 fprintf (stderr
, "W_NOBRACE%s", f
? "|" : "");
446 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
448 if (f
& W_SPLITSPACE
)
451 fprintf (stderr
, "W_SPLITSPACE%s", f
? "|" : "");
453 if (f
& W_ASSIGNMENT
)
456 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
461 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
466 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
468 fprintf (stderr
, "\n");
473 #ifdef INCLUDE_UNUSED
475 quoted_substring (string
, start
, end
)
480 register char *result
, *s
, *r
;
484 /* Move to string[start], skipping quoted characters. */
485 for (s
= string
, l
= 0; *s
&& l
< start
; )
497 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
499 /* Copy LEN characters, including quote characters. */
501 for (l
= 0; l
< len
; s
++)
515 #ifdef INCLUDE_UNUSED
516 /* Return the length of S, skipping over quoted characters */
540 /* Find the first occurrence of character C in string S, obeying shell
541 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
542 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
543 escaped with CTLESC are skipped. */
545 quoted_strchr (s
, c
, flags
)
553 if (((flags
& ST_BACKSL
) && *p
== '\\')
554 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
558 return ((char *)NULL
);
564 return ((char *)NULL
);
567 /* Return 1 if CHARACTER appears in an unquoted portion of
568 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
570 unquoted_member (character
, string
)
578 slen
= strlen (string
);
580 while (c
= string
[sindex
])
588 ADVANCE_CHAR (string
, slen
, sindex
);
594 ADVANCE_CHAR (string
, slen
, sindex
);
598 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
602 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
609 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
611 unquoted_substring (substr
, string
)
612 char *substr
, *string
;
615 int sindex
, c
, sublen
;
618 if (substr
== 0 || *substr
== '\0')
621 slen
= strlen (string
);
622 sublen
= strlen (substr
);
623 for (sindex
= 0; c
= string
[sindex
]; )
625 if (STREQN (string
+ sindex
, substr
, sublen
))
633 ADVANCE_CHAR (string
, slen
, sindex
);
637 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
641 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
645 ADVANCE_CHAR (string
, slen
, sindex
);
652 /* Most of the substitutions must be done in parallel. In order
653 to avoid using tons of unclear goto's, I have some functions
654 for manipulating malloc'ed strings. They all take INDX, a
655 pointer to an integer which is the offset into the string
656 where manipulation is taking place. They also take SIZE, a
657 pointer to an integer which is the current length of the
658 character array for this string. */
660 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
661 of space allocated to TARGET. SOURCE can be NULL, in which
662 case nothing happens. Gets rid of SOURCE by freeing it.
663 Returns TARGET in case the location has changed. */
665 sub_append_string (source
, target
, indx
, size
)
666 char *source
, *target
;
673 srclen
= STRLEN (source
);
674 if (srclen
>= (int)(*size
- *indx
))
677 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
678 target
= (char *)xrealloc (target
, (*size
= n
));
681 FASTCOPY (source
, target
+ *indx
, srclen
);
683 target
[*indx
] = '\0';
692 /* Append the textual representation of NUMBER to TARGET.
693 INDX and SIZE are as in SUB_APPEND_STRING. */
695 sub_append_number (number
, target
, indx
, size
)
702 temp
= itos (number
);
703 return (sub_append_string (temp
, target
, indx
, size
));
707 /* Extract a substring from STRING, starting at SINDEX and ending with
708 one of the characters in CHARLIST. Don't make the ending character
709 part of the string. Leave SINDEX pointing at the ending character.
710 Understand about backslashes in the string. If (flags & SX_VARNAME)
711 is non-zero, and array variables have been compiled into the shell,
712 everything between a `[' and a corresponding `]' is skipped over.
713 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
714 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
715 contain a closing character from CHARLIST. */
717 string_extract (string
, sindex
, charlist
, flags
)
729 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
732 while (c
= string
[i
])
741 #if defined (ARRAY_VARS)
742 else if ((flags
& SX_VARNAME
) && c
== '[')
745 /* If this is an array subscript, skip over it and continue. */
746 ni
= skipsubscript (string
, i
, 0);
747 if (string
[ni
] == ']')
751 else if (MEMBER (c
, charlist
))
757 ADVANCE_CHAR (string
, slen
, i
);
760 /* If we had to have a matching delimiter and didn't find one, return an
761 error and let the caller deal with it. */
762 if ((flags
& SX_REQMATCH
) && found
== 0)
765 return (&extract_string_error
);
768 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
774 /* Extract the contents of STRING as if it is enclosed in double quotes.
775 SINDEX, when passed in, is the offset of the character immediately
776 following the opening double quote; on exit, SINDEX is left pointing after
777 the closing double quote. If STRIPDQ is non-zero, unquoted double
778 quotes are stripped and the string is terminated by a null byte.
779 Backslashes between the embedded double quotes are processed. If STRIPDQ
780 is zero, an unquoted `"' terminates the string. */
782 string_extract_double_quoted (string
, sindex
, stripdq
)
784 int *sindex
, stripdq
;
790 char *temp
, *ret
; /* The new string we return. */
791 int pass_next
, backquote
, si
; /* State variables for the machine. */
795 slen
= strlen (string
+ *sindex
) + *sindex
;
796 send
= string
+ slen
;
798 pass_next
= backquote
= dquote
= 0;
799 temp
= (char *)xmalloc (1 + slen
- *sindex
);
803 while (c
= string
[i
])
805 /* Process a character that was quoted by a backslash. */
808 /* XXX - take another look at this in light of Interp 221 */
811 ``The backslash shall retain its special meaning as an escape
812 character only when followed by one of the characters:
815 If STRIPDQ is zero, we handle the double quotes here and let
816 expand_word_internal handle the rest. If STRIPDQ is non-zero,
817 we have already been through one round of backslash stripping,
818 and want to strip these backslashes only if DQUOTE is non-zero,
819 indicating that we are inside an embedded double-quoted string. */
821 /* If we are in an embedded quoted string, then don't strip
822 backslashes before characters for which the backslash
823 retains its special meaning, but remove backslashes in
824 front of other characters. If we are not in an
825 embedded quoted string, don't strip backslashes at all.
826 This mess is necessary because the string was already
827 surrounded by double quotes (and sh has some really weird
829 The returned string will be run through expansion as if
830 it were double-quoted. */
831 if ((stripdq
== 0 && c
!= '"') ||
832 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
837 COPY_CHAR_I (temp
, j
, string
, send
, i
);
841 /* A backslash protects the next character. The code just above
842 handles preserving the backslash in front of any character but
851 /* Inside backquotes, ``the portion of the quoted string from the
852 initial backquote and the characters up to the next backquote
853 that is not preceded by a backslash, having escape characters
854 removed, defines that command''. */
872 /* Pass everything between `$(' and the matching `)' or a quoted
873 ${ ... } pair through according to the Posix.2 specification. */
874 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
879 if (string
[i
+ 1] == LPAREN
)
880 ret
= extract_command_subst (string
, &si
, 0);
882 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, 0);
885 temp
[j
++] = string
[i
+ 1];
887 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
889 if (ret
== 0 && no_longjmp_on_fatal_error
)
892 ret
= string
+ i
+ 2;
895 for (t
= 0; ret
[t
]; t
++, j
++)
897 temp
[j
] = string
[si
];
912 /* Add any character but a double quote to the quoted string we're
915 goto add_one_character
;
929 /* Point to after the closing quote. */
937 /* This should really be another option to string_extract_double_quoted. */
939 skip_double_quoted (string
, slen
, sind
)
946 int pass_next
, backquote
, si
;
949 pass_next
= backquote
= 0;
951 while (c
= string
[i
])
956 ADVANCE_CHAR (string
, slen
, i
);
969 ADVANCE_CHAR (string
, slen
, i
);
978 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
981 if (string
[i
+ 1] == LPAREN
)
982 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
984 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, SX_NOALLOC
);
991 ADVANCE_CHAR (string
, slen
, i
);
1004 /* Extract the contents of STRING as if it is enclosed in single quotes.
1005 SINDEX, when passed in, is the offset of the character immediately
1006 following the opening single quote; on exit, SINDEX is left pointing after
1007 the closing single quote. */
1008 static inline char *
1009 string_extract_single_quoted (string
, sindex
)
1018 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1019 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
1021 while (string
[i
] && string
[i
] != '\'')
1022 ADVANCE_CHAR (string
, slen
, i
);
1024 t
= substring (string
, *sindex
, i
);
1034 skip_single_quoted (string
, slen
, sind
)
1043 while (string
[c
] && string
[c
] != '\'')
1044 ADVANCE_CHAR (string
, slen
, c
);
1051 /* Just like string_extract, but doesn't hack backslashes or any of
1052 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1054 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1062 #if defined (HANDLE_MULTIBYTE)
1070 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1072 temp
= string_extract_single_quoted (string
, sindex
);
1073 --*sindex
; /* leave *sindex at separator character */
1079 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1080 this only if MB_CUR_MAX > 1. */
1081 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1083 #if defined (HANDLE_MULTIBYTE)
1084 clen
= strlen (charlist
);
1087 while (c
= string
[i
])
1089 #if defined (HANDLE_MULTIBYTE)
1092 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1097 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1098 through, to protect the CTLNULs from later calls to
1099 remove_quoted_nulls. */
1100 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1106 #if defined (HANDLE_MULTIBYTE)
1107 mblength
= MBLEN (string
+ i
, slen
- i
);
1111 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1112 if (MB_INVALIDCH (mblength
))
1114 if (MEMBER (c
, charlist
))
1122 len
= mbstowcs (wcharlist
, charlist
, 0);
1125 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1126 mbstowcs (wcharlist
, charlist
, len
+ 1);
1129 if (wcschr (wcharlist
, wc
))
1135 if (MEMBER (c
, charlist
))
1138 ADVANCE_CHAR (string
, slen
, i
);
1141 #if defined (HANDLE_MULTIBYTE)
1145 temp
= substring (string
, *sindex
, i
);
1151 /* Extract the $( construct in STRING, and return a new string.
1152 Start extracting at (SINDEX) as if we had just seen "$(".
1153 Make (SINDEX) get the position of the matching ")". )
1154 XFLAGS is additional flags to pass to other extraction functions. */
1156 extract_command_subst (string
, sindex
, xflags
)
1161 if (string
[*sindex
] == LPAREN
)
1162 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1165 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1166 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1170 /* Extract the $[ construct in STRING, and return a new string. (])
1171 Start extracting at (SINDEX) as if we had just seen "$[".
1172 Make (SINDEX) get the position of the matching "]". */
1174 extract_arithmetic_subst (string
, sindex
)
1178 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1181 #if defined (PROCESS_SUBSTITUTION)
1182 /* Extract the <( or >( construct in STRING, and return a new string.
1183 Start extracting at (SINDEX) as if we had just seen "<(".
1184 Make (SINDEX) get the position of the matching ")". */ /*))*/
1186 extract_process_subst (string
, starter
, sindex
)
1191 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", SX_COMMAND
));
1193 #endif /* PROCESS_SUBSTITUTION */
1195 #if defined (ARRAY_VARS)
1196 /* This can be fooled by unquoted right parens in the passed string. If
1197 each caller verifies that the last character in STRING is a right paren,
1198 we don't even need to call extract_delimited_string. */
1200 extract_array_assignment_list (string
, sindex
)
1207 slen
= strlen (string
); /* ( */
1208 if (string
[slen
- 1] == ')')
1210 ret
= substring (string
, *sindex
, slen
- 1);
1218 /* Extract and create a new string from the contents of STRING, a
1219 character string delimited with OPENER and CLOSER. SINDEX is
1220 the address of an int describing the current offset in STRING;
1221 it should point to just after the first OPENER found. On exit,
1222 SINDEX gets the position of the last character of the matching CLOSER.
1223 If OPENER is more than a single character, ALT_OPENER, if non-null,
1224 contains a character string that can also match CLOSER and thus
1225 needs to be skipped. */
1227 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1230 char *opener
, *alt_opener
, *closer
;
1236 int pass_character
, nesting_level
, in_comment
;
1237 int len_closer
, len_opener
, len_alt_opener
;
1240 slen
= strlen (string
+ *sindex
) + *sindex
;
1241 len_opener
= STRLEN (opener
);
1242 len_alt_opener
= STRLEN (alt_opener
);
1243 len_closer
= STRLEN (closer
);
1245 pass_character
= in_comment
= 0;
1250 while (nesting_level
)
1261 ADVANCE_CHAR (string
, slen
, i
);
1265 if (pass_character
) /* previous char was backslash */
1268 ADVANCE_CHAR (string
, slen
, i
);
1272 /* Not exactly right yet; should handle shell metacharacters and
1273 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1274 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1277 ADVANCE_CHAR (string
, slen
, i
);
1281 if (c
== CTLESC
|| c
== '\\')
1288 /* Process a nested command substitution, but only if we're parsing an
1289 arithmetic substitution. */
1290 if ((flags
& SX_COMMAND
) && string
[i
] == '$' && string
[i
+1] == LPAREN
)
1293 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1298 /* Process a nested OPENER. */
1299 if (STREQN (string
+ i
, opener
, len_opener
))
1301 si
= i
+ len_opener
;
1302 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1307 /* Process a nested ALT_OPENER */
1308 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1310 si
= i
+ len_alt_opener
;
1311 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1316 /* If the current substring terminates the delimited string, decrement
1317 the nesting level. */
1318 if (STREQN (string
+ i
, closer
, len_closer
))
1320 i
+= len_closer
- 1; /* move to last byte of the closer */
1322 if (nesting_level
== 0)
1326 /* Pass old-style command substitution through verbatim. */
1330 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1335 /* Pass single-quoted and double-quoted strings through verbatim. */
1336 if (c
== '\'' || c
== '"')
1339 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1340 : skip_double_quoted (string
, slen
, si
);
1344 /* move past this character, which was not special. */
1345 ADVANCE_CHAR (string
, slen
, i
);
1348 if (c
== 0 && nesting_level
)
1350 if (no_longjmp_on_fatal_error
== 0)
1352 last_command_exit_value
= EXECUTION_FAILURE
;
1353 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1354 exp_jump_to_top_level (DISCARD
);
1359 return (char *)NULL
;
1363 si
= i
- *sindex
- len_closer
+ 1;
1364 if (flags
& SX_NOALLOC
)
1365 result
= (char *)NULL
;
1368 result
= (char *)xmalloc (1 + si
);
1369 strncpy (result
, string
+ *sindex
, si
);
1377 /* Extract a parameter expansion expression within ${ and } from STRING.
1378 Obey the Posix.2 rules for finding the ending `}': count braces while
1379 skipping over enclosed quoted strings and command substitutions.
1380 SINDEX is the address of an int describing the current offset in STRING;
1381 it should point to just after the first `{' found. On exit, SINDEX
1382 gets the position of the matching `}'. QUOTED is non-zero if this
1383 occurs inside double quotes. */
1384 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1386 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1388 int *sindex
, quoted
, flags
;
1392 int pass_character
, nesting_level
, si
, dolbrace_state
;
1398 slen
= strlen (string
+ *sindex
) + *sindex
;
1400 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1401 parse_matched_pair(). The different initial value is to handle the
1402 case where this function is called to parse the word in
1403 ${param op word} (SX_WORD). */
1404 dolbrace_state
= (flags
& SX_WORD
) ? DOLBRACE_WORD
: DOLBRACE_PARAM
;
1405 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && (flags
& SX_POSIXEXP
))
1406 dolbrace_state
= DOLBRACE_QUOTE
;
1409 while (c
= string
[i
])
1414 ADVANCE_CHAR (string
, slen
, i
);
1418 /* CTLESCs and backslashes quote the next character. */
1419 if (c
== CTLESC
|| c
== '\\')
1426 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1436 if (nesting_level
== 0)
1442 /* Pass the contents of old-style command substitutions through
1447 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1452 /* Pass the contents of new-style command substitutions and
1453 arithmetic substitutions through verbatim. */
1454 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1457 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1462 /* Pass the contents of double-quoted strings through verbatim. */
1466 i
= skip_double_quoted (string
, slen
, si
);
1467 /* skip_XXX_quoted leaves index one past close quote */
1473 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1474 if (posixly_correct
&& shell_compatibility_level
> 42 && dolbrace_state
!= DOLBRACE_QUOTE
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1475 ADVANCE_CHAR (string
, slen
, i
);
1479 i
= skip_single_quoted (string
, slen
, si
);
1485 /* move past this character, which was not special. */
1486 ADVANCE_CHAR (string
, slen
, i
);
1488 /* This logic must agree with parse.y:parse_matched_pair, since they
1489 share the same defines. */
1490 if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '%' && (i
- *sindex
) > 1)
1491 dolbrace_state
= DOLBRACE_QUOTE
;
1492 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '#' && (i
- *sindex
) > 1)
1493 dolbrace_state
= DOLBRACE_QUOTE
;
1494 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '/' && (i
- *sindex
) > 1)
1495 dolbrace_state
= DOLBRACE_QUOTE2
; /* XXX */
1496 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '^' && (i
- *sindex
) > 1)
1497 dolbrace_state
= DOLBRACE_QUOTE
;
1498 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== ',' && (i
- *sindex
) > 1)
1499 dolbrace_state
= DOLBRACE_QUOTE
;
1500 else if (dolbrace_state
== DOLBRACE_PARAM
&& strchr ("#%^,~:-=?+/", c
) != 0)
1501 dolbrace_state
= DOLBRACE_OP
;
1502 else if (dolbrace_state
== DOLBRACE_OP
&& strchr ("#%^,~:-=?+/", c
) == 0)
1503 dolbrace_state
= DOLBRACE_WORD
;
1506 if (c
== 0 && nesting_level
)
1508 if (no_longjmp_on_fatal_error
== 0)
1510 last_command_exit_value
= EXECUTION_FAILURE
;
1511 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1512 exp_jump_to_top_level (DISCARD
);
1517 return ((char *)NULL
);
1521 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1527 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1528 STRING, and returns a pointer to it. */
1530 de_backslash (string
)
1533 register size_t slen
;
1534 register int i
, j
, prev_i
;
1537 slen
= strlen (string
);
1540 /* Loop copying string[i] to string[j], i >= j. */
1543 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1544 string
[i
+ 1] == '$'))
1547 ADVANCE_CHAR (string
, slen
, i
);
1549 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1560 /* Replace instances of \! in a string with !. */
1562 unquote_bang (string
)
1566 register char *temp
;
1568 temp
= (char *)xmalloc (1 + strlen (string
));
1570 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1572 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1578 strcpy (string
, temp
);
1583 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1585 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1586 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1587 matched pairs of quotes or backquotes, or skip word expansions; it is
1588 intended to be used after expansion has been performed and during final
1589 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1591 skip_matched_pair (string
, start
, open
, close
, flags
)
1593 int start
, open
, close
, flags
;
1595 int i
, pass_next
, backq
, si
, c
, count
;
1600 slen
= strlen (string
+ start
) + start
;
1601 no_longjmp_on_fatal_error
= 1;
1603 i
= start
+ 1; /* skip over leading bracket */
1605 pass_next
= backq
= 0;
1606 ss
= (char *)string
;
1607 while (c
= string
[i
])
1614 ADVANCE_CHAR (string
, slen
, i
);
1627 ADVANCE_CHAR (string
, slen
, i
);
1630 else if ((flags
& 1) == 0 && c
== '`')
1636 else if ((flags
& 1) == 0 && c
== open
)
1642 else if (c
== close
)
1650 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1652 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1653 : skip_double_quoted (ss
, slen
, ++i
);
1654 /* no increment, the skip functions increment past the closing quote. */
1656 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1659 if (string
[si
] == '\0')
1662 if (string
[i
+1] == LPAREN
)
1663 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1665 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1667 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1673 ADVANCE_CHAR (string
, slen
, i
);
1679 #if defined (ARRAY_VARS)
1681 skipsubscript (string
, start
, flags
)
1685 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1689 /* Skip characters in STRING until we find a character in DELIMS, and return
1690 the index of that character. START is the index into string at which we
1691 begin. This is similar in spirit to strpbrk, but it returns an index into
1692 STRING and takes a starting index. This little piece of code knows quite
1693 a lot of shell syntax. It's very similar to skip_double_quoted and other
1694 functions of that ilk. */
1696 skip_to_delim (string
, start
, delims
, flags
)
1702 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
, skipcmd
;
1704 char *temp
, open
[3];
1707 slen
= strlen (string
+ start
) + start
;
1708 if (flags
& SD_NOJMP
)
1709 no_longjmp_on_fatal_error
= 1;
1710 invert
= (flags
& SD_INVERT
);
1711 skipcmd
= (flags
& SD_NOSKIPCMD
) == 0;
1714 pass_next
= backq
= 0;
1715 while (c
= string
[i
])
1717 /* If this is non-zero, we should not let quote characters be delimiters
1718 and the current character is a single or double quote. We should not
1719 test whether or not it's a delimiter until after we skip single- or
1720 double-quoted strings. */
1721 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1727 ADVANCE_CHAR (string
, slen
, i
);
1740 ADVANCE_CHAR (string
, slen
, i
);
1749 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1751 else if (c
== '\'' || c
== '"')
1753 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1754 : skip_double_quoted (string
, slen
, ++i
);
1755 /* no increment, the skip functions increment past the closing quote. */
1757 else if (c
== '$' && ((skipcmd
&& string
[i
+1] == LPAREN
) || string
[i
+1] == LBRACE
))
1760 if (string
[si
] == '\0')
1763 if (string
[i
+1] == LPAREN
)
1764 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1766 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1768 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1773 #if defined (PROCESS_SUBSTITUTION)
1774 else if (skipcmd
&& (c
== '<' || c
== '>') && string
[i
+1] == LPAREN
)
1777 if (string
[si
] == '\0')
1779 temp
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &si
);
1780 free (temp
); /* no SX_ALLOC here */
1782 if (string
[i
] == '\0')
1787 #endif /* PROCESS_SUBSTITUTION */
1788 #if defined (EXTENDED_GLOB)
1789 else if ((flags
& SD_EXTGLOB
) && extended_glob
&& string
[i
+1] == LPAREN
&& member (c
, "?*+!@"))
1792 if (string
[si
] == '\0')
1798 temp
= extract_delimited_string (string
, &si
, open
, "(", ")", SX_NOALLOC
); /* ) */
1801 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1807 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1810 ADVANCE_CHAR (string
, slen
, i
);
1816 #if defined (READLINE)
1817 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1818 an unclosed quoted string), or if the character at EINDEX is quoted
1819 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1820 single and double-quoted string parsing functions should not return an
1821 error if there are unclosed quotes or braces. The characters that this
1822 recognizes need to be the same as the contents of
1823 rl_completer_quote_characters. */
1826 char_is_quoted (string
, eindex
)
1830 int i
, pass_next
, c
;
1834 slen
= strlen (string
);
1835 no_longjmp_on_fatal_error
= 1;
1844 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1846 ADVANCE_CHAR (string
, slen
, i
);
1855 else if (c
== '\'' || c
== '"')
1857 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1858 : skip_double_quoted (string
, slen
, ++i
);
1861 /* no increment, the skip_xxx functions go one past end */
1864 ADVANCE_CHAR (string
, slen
, i
);
1871 unclosed_pair (string
, eindex
, openstr
)
1876 int i
, pass_next
, openc
, olen
;
1880 slen
= strlen (string
);
1881 olen
= strlen (openstr
);
1882 i
= pass_next
= openc
= 0;
1888 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1890 ADVANCE_CHAR (string
, slen
, i
);
1893 else if (string
[i
] == '\\')
1899 else if (STREQN (string
+ i
, openstr
, olen
))
1904 else if (string
[i
] == '\'' || string
[i
] == '"')
1906 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1907 : skip_double_quoted (string
, slen
, i
);
1912 ADVANCE_CHAR (string
, slen
, i
);
1917 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1918 individual words. If DELIMS is NULL, the current value of $IFS is used
1919 to split the string, and the function follows the shell field splitting
1920 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1921 gets the number of words in the returned list. CWP, if non-NULL, gets
1922 the index of the word containing SENTINEL. Non-whitespace chars in
1923 DELIMS delimit separate fields. */
1925 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1929 int sentinel
, flags
;
1932 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1933 char *token
, *d
, *d2
;
1934 WORD_LIST
*ret
, *tl
;
1936 if (string
== 0 || *string
== '\0')
1942 return ((WORD_LIST
*)NULL
);
1945 d
= (delims
== 0) ? ifs_value
: delims
;
1946 ifs_split
= delims
== 0;
1948 /* Make d2 the non-whitespace characters in delims */
1953 #if defined (HANDLE_MULTIBYTE)
1954 size_t mblength
= 1;
1958 slength
= strlen (delims
);
1959 d2
= (char *)xmalloc (slength
+ 1);
1963 #if defined (HANDLE_MULTIBYTE)
1964 mbstate_t state_bak
;
1966 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1967 if (MB_INVALIDCH (mblength
))
1969 else if (mblength
> 1)
1971 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1974 slength
-= mblength
;
1978 if (whitespace (delims
[i
]) == 0)
1979 d2
[ts
++] = delims
[i
];
1987 ret
= (WORD_LIST
*)NULL
;
1989 /* Remove sequences of whitespace characters at the start of the string, as
1990 long as those characters are delimiters. */
1991 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1993 if (string
[i
] == '\0')
1999 dflags
= flags
|SD_NOJMP
;
2002 te
= skip_to_delim (string
, ts
, d
, dflags
);
2004 /* If we have a non-whitespace delimiter character, use it to make a
2005 separate field. This is just about what $IFS splitting does and
2006 is closer to the behavior of the shell parser. */
2007 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
2010 /* If we're using IFS splitting, the non-whitespace delimiter char
2011 and any additional IFS whitespace delimits a field. */
2013 while (member (string
[te
], d
) && spctabnl (string
[te
]))
2016 while (member (string
[te
], d2
))
2020 token
= substring (string
, ts
, te
);
2022 ret
= add_string_to_list (token
, ret
);
2026 if (sentinel
>= ts
&& sentinel
<= te
)
2029 /* If the cursor is at whitespace just before word start, set the
2030 sentinel word to the current word. */
2031 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
2034 /* If the cursor is at whitespace between two words, make a new, empty
2035 word, add it before (well, after, since the list is in reverse order)
2036 the word we just added, and set the current word to that one. */
2037 if (cwp
&& cw
== -1 && sentinel
< ts
)
2039 tl
= make_word_list (make_word (""), ret
->next
);
2045 if (string
[te
] == 0)
2049 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
2058 /* Special case for SENTINEL at the end of STRING. If we haven't found
2059 the word containing SENTINEL yet, and the index we're looking for is at
2060 the end of STRING (or past the end of the previously-found token,
2061 possible if the end of the line is composed solely of IFS whitespace)
2062 add an additional null argument and set the current word pointer to that. */
2063 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
2065 if (whitespace (string
[sentinel
- 1]))
2068 ret
= add_string_to_list (token
, ret
);
2081 return (REVERSE_LIST (ret
, WORD_LIST
*));
2083 #endif /* READLINE */
2087 /* Extract the name of the variable to bind to from the assignment string. */
2089 assignment_name (string
)
2095 offset
= assignment (string
, 0);
2097 return (char *)NULL
;
2098 temp
= substring (string
, 0, offset
);
2103 /* **************************************************************** */
2105 /* Functions to convert strings to WORD_LISTs and vice versa */
2107 /* **************************************************************** */
2109 /* Return a single string of all the words in LIST. SEP is the separator
2110 to put between individual elements of LIST in the output string. */
2112 string_list_internal (list
, sep
)
2116 register WORD_LIST
*t
;
2118 int word_len
, sep_len
, result_size
;
2121 return ((char *)NULL
);
2123 /* Short-circuit quickly if we don't need to separate anything. */
2124 if (list
->next
== 0)
2125 return (savestring (list
->word
->word
));
2127 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2128 sep_len
= STRLEN (sep
);
2131 for (t
= list
; t
; t
= t
->next
)
2134 result_size
+= sep_len
;
2135 result_size
+= strlen (t
->word
->word
);
2138 r
= result
= (char *)xmalloc (result_size
+ 1);
2140 for (t
= list
; t
; t
= t
->next
)
2142 if (t
!= list
&& sep_len
)
2146 FASTCOPY (sep
, r
, sep_len
);
2153 word_len
= strlen (t
->word
->word
);
2154 FASTCOPY (t
->word
->word
, r
, word_len
);
2162 /* Return a single string of all the words present in LIST, separating
2163 each word with a space. */
2168 return (string_list_internal (list
, " "));
2171 /* An external interface that can be used by the rest of the shell to
2172 obtain a string containing the first character in $IFS. Handles all
2173 the multibyte complications. If LENP is non-null, it is set to the
2174 length of the returned string. */
2176 ifs_firstchar (lenp
)
2182 ret
= xmalloc (MB_LEN_MAX
+ 1);
2183 #if defined (HANDLE_MULTIBYTE)
2184 if (ifs_firstc_len
== 1)
2186 ret
[0] = ifs_firstc
[0];
2188 len
= ret
[0] ? 1 : 0;
2192 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2193 ret
[len
= ifs_firstc_len
] = '\0';
2196 ret
[0] = ifs_firstc
;
2198 len
= ret
[0] ? 0 : 1;
2207 /* Return a single string of all the words present in LIST, obeying the
2208 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2209 expansion [of $*] appears within a double quoted string, it expands
2210 to a single field with the value of each parameter separated by the
2211 first character of the IFS variable, or by a <space> if IFS is unset." */
2213 string_list_dollar_star (list
)
2217 #if defined (HANDLE_MULTIBYTE)
2218 # if defined (__GNUC__)
2219 char sep
[MB_CUR_MAX
+ 1];
2227 #if defined (HANDLE_MULTIBYTE)
2228 # if !defined (__GNUC__)
2229 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2230 # endif /* !__GNUC__ */
2231 if (ifs_firstc_len
== 1)
2233 sep
[0] = ifs_firstc
[0];
2238 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2239 sep
[ifs_firstc_len
] = '\0';
2242 sep
[0] = ifs_firstc
;
2246 ret
= string_list_internal (list
, sep
);
2247 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2253 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2254 is non-zero, the $@ appears within double quotes, and we should quote
2255 the list before converting it into a string. If IFS is unset, and the
2256 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2257 in the words in the list, because the default value of $IFS is
2258 <space><tab><newline>, IFS characters in the words in the list should
2259 also be split. If IFS is null, and the word is not quoted, we need
2260 to quote the words in the list to preserve the positional parameters
2263 string_list_dollar_at (list
, quoted
)
2268 #if defined (HANDLE_MULTIBYTE)
2269 # if defined (__GNUC__)
2270 char sep
[MB_CUR_MAX
+ 1];
2273 # endif /* !__GNUC__ */
2279 /* XXX this could just be ifs = ifs_value; */
2280 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2282 #if defined (HANDLE_MULTIBYTE)
2283 # if !defined (__GNUC__)
2284 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2285 # endif /* !__GNUC__ */
2288 if (ifs_firstc_len
== 1)
2290 sep
[0] = ifs_firstc
[0];
2295 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2296 sep
[ifs_firstc_len
] = '\0';
2305 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2309 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2310 it now that quote_escapes quotes spaces */
2311 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2313 : list_quote_escapes (list
);
2315 ret
= string_list_internal (tlist
, sep
);
2316 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2322 /* Turn the positional paramters into a string, understanding quoting and
2323 the various subtleties of using the first character of $IFS as the
2324 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2325 string_list as appropriate. */
2327 string_list_pos_params (pchar
, list
, quoted
)
2335 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2337 tlist
= quote_list (list
);
2338 word_list_remove_quoted_nulls (tlist
);
2339 ret
= string_list_dollar_star (tlist
);
2341 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2343 tlist
= quote_list (list
);
2344 word_list_remove_quoted_nulls (tlist
);
2345 ret
= string_list (tlist
);
2347 else if (pchar
== '*')
2349 /* Even when unquoted, string_list_dollar_star does the right thing
2350 making sure that the first character of $IFS is used as the
2352 ret
= string_list_dollar_star (list
);
2354 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2355 /* We use string_list_dollar_at, but only if the string is quoted, since
2356 that quotes the escapes if it's not, which we don't want. We could
2357 use string_list (the old code did), but that doesn't do the right
2358 thing if the first character of $IFS is not a space. We use
2359 string_list_dollar_star if the string is unquoted so we make sure that
2360 the elements of $@ are separated by the first character of $IFS for
2362 ret
= string_list_dollar_at (list
, quoted
);
2363 else if (pchar
== '@')
2364 ret
= string_list_dollar_star (list
);
2366 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2371 /* Return the list of words present in STRING. Separate the string into
2372 words at any of the characters found in SEPARATORS. If QUOTED is
2373 non-zero then word in the list will have its quoted flag set, otherwise
2374 the quoted flag is left as make_word () deemed fit.
2376 This obeys the P1003.2 word splitting semantics. If `separators' is
2377 exactly <space><tab><newline>, then the splitting algorithm is that of
2378 the Bourne shell, which treats any sequence of characters from `separators'
2379 as a delimiter. If IFS is unset, which results in `separators' being set
2380 to "", no splitting occurs. If separators has some other value, the
2381 following rules are applied (`IFS white space' means zero or more
2382 occurrences of <space>, <tab>, or <newline>, as long as those characters
2383 are in `separators'):
2385 1) IFS white space is ignored at the start and the end of the
2387 2) Each occurrence of a character in `separators' that is not
2388 IFS white space, along with any adjacent occurrences of
2389 IFS white space delimits a field.
2390 3) Any nonzero-length sequence of IFS white space delimits a field.
2393 /* BEWARE! list_string strips null arguments. Don't call it twice and
2394 expect to have "" preserved! */
2396 /* This performs word splitting and quoted null character removal on
2399 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2400 : (c) == (separators)[0]) \
2404 list_string (string
, separators
, quoted
)
2405 register char *string
, *separators
;
2410 char *current_word
, *s
;
2411 int sindex
, sh_style_split
, whitesep
, xflags
;
2414 if (!string
|| !*string
)
2415 return ((WORD_LIST
*)NULL
);
2417 sh_style_split
= separators
&& separators
[0] == ' ' &&
2418 separators
[1] == '\t' &&
2419 separators
[2] == '\n' &&
2420 separators
[3] == '\0';
2421 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2423 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2424 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2428 /* Remove sequences of whitespace at the beginning of STRING, as
2429 long as those characters appear in IFS. Do not do this if
2430 STRING is quoted or if there are no separator characters. */
2431 if (!quoted
|| !separators
|| !*separators
)
2433 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2436 return ((WORD_LIST
*)NULL
);
2441 /* OK, now STRING points to a word that does not begin with white space.
2442 The splitting algorithm is:
2443 extract a word, stopping at a separator
2444 skip sequences of spc, tab, or nl as long as they are separators
2445 This obeys the field splitting rules in Posix.2. */
2446 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2447 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2449 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2450 unless multibyte chars are possible. */
2451 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2452 if (current_word
== 0)
2455 /* If we have a quoted empty string, add a quoted null argument. We
2456 want to preserve the quoted null character iff this is a quoted
2457 empty string; otherwise the quoted null characters are removed
2459 if (QUOTED_NULL (current_word
))
2461 t
= alloc_word_desc ();
2462 t
->word
= make_quoted_char ('\0');
2463 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2464 result
= make_word_list (t
, result
);
2466 else if (current_word
[0] != '\0')
2468 /* If we have something, then add it regardless. However,
2469 perform quoted null character removal on the current word. */
2470 remove_quoted_nulls (current_word
);
2471 result
= add_string_to_list (current_word
, result
);
2472 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2473 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2474 result
->word
->flags
|= W_QUOTED
;
2477 /* If we're not doing sequences of separators in the traditional
2478 Bourne shell style, then add a quoted null argument. */
2479 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2481 t
= alloc_word_desc ();
2482 t
->word
= make_quoted_char ('\0');
2483 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2484 result
= make_word_list (t
, result
);
2487 free (current_word
);
2489 /* Note whether or not the separator is IFS whitespace, used later. */
2490 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2492 /* Move past the current separator character. */
2496 ADVANCE_CHAR (string
, slen
, sindex
);
2499 /* Now skip sequences of space, tab, or newline characters if they are
2500 in the list of separators. */
2501 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2504 /* If the first separator was IFS whitespace and the current character
2505 is a non-whitespace IFS character, it should be part of the current
2506 field delimiter, not a separate delimiter that would result in an
2507 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2508 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2511 /* An IFS character that is not IFS white space, along with any
2512 adjacent IFS white space, shall delimit a field. (SUSv3) */
2513 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2517 return (REVERSE_LIST (result
, WORD_LIST
*));
2520 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2521 ENDPTR is set to the first character after the word. This is used by
2522 the `read' builtin. This is never called with SEPARATORS != $IFS;
2523 it should be simplified.
2525 XXX - this function is very similar to list_string; they should be
2528 get_word_from_string (stringp
, separators
, endptr
)
2529 char **stringp
, *separators
, **endptr
;
2533 int sindex
, sh_style_split
, whitesep
, xflags
;
2536 if (!stringp
|| !*stringp
|| !**stringp
)
2537 return ((char *)NULL
);
2539 sh_style_split
= separators
&& separators
[0] == ' ' &&
2540 separators
[1] == '\t' &&
2541 separators
[2] == '\n' &&
2542 separators
[3] == '\0';
2543 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2545 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2546 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2552 /* Remove sequences of whitespace at the beginning of STRING, as
2553 long as those characters appear in IFS. */
2554 if (sh_style_split
|| !separators
|| !*separators
)
2556 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2558 /* If the string is nothing but whitespace, update it and return. */
2564 return ((char *)NULL
);
2568 /* OK, S points to a word that does not begin with white space.
2569 Now extract a word, stopping at a separator, save a pointer to
2570 the first character after the word, then skip sequences of spc,
2571 tab, or nl as long as they are separators.
2573 This obeys the field splitting rules in Posix.2. */
2575 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2576 unless multibyte chars are possible. */
2577 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2578 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2580 /* Set ENDPTR to the first character after the end of the word. */
2582 *endptr
= s
+ sindex
;
2584 /* Note whether or not the separator is IFS whitespace, used later. */
2585 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2587 /* Move past the current separator character. */
2591 ADVANCE_CHAR (s
, slen
, sindex
);
2594 /* Now skip sequences of space, tab, or newline characters if they are
2595 in the list of separators. */
2596 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2599 /* If the first separator was IFS whitespace and the current character is
2600 a non-whitespace IFS character, it should be part of the current field
2601 delimiter, not a separate delimiter that would result in an empty field.
2602 Look at POSIX.2, 3.6.5, (3)(b). */
2603 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2606 /* An IFS character that is not IFS white space, along with any adjacent
2607 IFS white space, shall delimit a field. */
2608 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2612 /* Update STRING to point to the next field. */
2613 *stringp
= s
+ sindex
;
2614 return (current_word
);
2617 /* Remove IFS white space at the end of STRING. Start at the end
2618 of the string and walk backwards until the beginning of the string
2619 or we find a character that's not IFS white space and not CTLESC.
2620 Only let CTLESC escape a white space character if SAW_ESCAPE is
2623 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2624 char *string
, *separators
;
2629 s
= string
+ STRLEN (string
) - 1;
2630 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2631 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2639 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2640 backslashes, single and double quotes. */
2642 list_string_with_quotes (string
)
2648 int c
, i
, tokstart
, len
;
2650 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2652 if (s
== 0 || *s
== 0)
2653 return ((WORD_LIST
*)NULL
);
2657 list
= (WORD_LIST
*)NULL
;
2668 i
= skip_single_quoted (s
, s_len
, ++i
);
2670 i
= skip_double_quoted (s
, s_len
, ++i
);
2671 else if (c
== 0 || spctabnl (c
))
2673 /* We have found the end of a token. Make a word out of it and
2674 add it to the word list. */
2675 token
= substring (s
, tokstart
, i
);
2676 list
= add_string_to_list (token
, list
);
2678 while (spctabnl (s
[i
]))
2686 i
++; /* normal character */
2688 return (REVERSE_LIST (list
, WORD_LIST
*));
2692 /********************************************************/
2694 /* Functions to perform assignment statements */
2696 /********************************************************/
2698 #if defined (ARRAY_VARS)
2700 do_compound_assignment (name
, value
, flags
)
2705 int mklocal
, mkassoc
, mkglobal
;
2708 mklocal
= flags
& ASS_MKLOCAL
;
2709 mkassoc
= flags
& ASS_MKASSOC
;
2710 mkglobal
= flags
& ASS_MKGLOBAL
;
2712 if (mklocal
&& variable_context
)
2714 v
= find_variable (name
);
2715 list
= expand_compound_array_assignment (v
, value
, flags
);
2717 v
= make_local_assoc_variable (name
);
2718 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2719 v
= make_local_array_variable (name
, 0);
2721 assign_compound_array_list (v
, list
, flags
);
2723 /* In a function but forcing assignment in global context */
2724 else if (mkglobal
&& variable_context
)
2726 v
= find_global_variable (name
);
2727 list
= expand_compound_array_assignment (v
, value
, flags
);
2728 if (v
== 0 && mkassoc
)
2729 v
= make_new_assoc_variable (name
);
2730 else if (v
&& mkassoc
&& assoc_p (v
) == 0)
2731 v
= convert_var_to_assoc (v
);
2733 v
= make_new_array_variable (name
);
2734 else if (v
&& mkassoc
== 0 && array_p (v
) == 0)
2735 v
= convert_var_to_array (v
);
2737 assign_compound_array_list (v
, list
, flags
);
2740 v
= assign_array_from_string (name
, value
, flags
);
2746 /* Given STRING, an assignment string, get the value of the right side
2747 of the `=', and bind it to the left side. If EXPAND is true, then
2748 perform parameter expansion, command substitution, and arithmetic
2749 expansion on the right-hand side. Perform tilde expansion in any
2750 case. Do not perform word splitting on the result of expansion. */
2752 do_assignment_internal (word
, expand
)
2753 const WORD_DESC
*word
;
2756 int offset
, appendop
, assign_list
, aflags
, retval
;
2757 char *name
, *value
, *temp
;
2759 #if defined (ARRAY_VARS)
2765 if (word
== 0 || word
->word
== 0)
2768 appendop
= assign_list
= aflags
= 0;
2769 string
= word
->word
;
2770 offset
= assignment (string
, 0);
2771 name
= savestring (string
);
2772 value
= (char *)NULL
;
2774 if (name
[offset
] == '=')
2776 if (name
[offset
- 1] == '+')
2779 name
[offset
- 1] = '\0';
2782 name
[offset
] = 0; /* might need this set later */
2783 temp
= name
+ offset
+ 1;
2785 #if defined (ARRAY_VARS)
2786 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2788 assign_list
= ni
= 1;
2789 value
= extract_array_assignment_list (temp
, &ni
);
2793 if (expand
&& temp
[0])
2794 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2796 value
= savestring (temp
);
2801 value
= (char *)xmalloc (1);
2805 if (echo_command_at_execute
)
2808 name
[offset
- 1] = '+';
2809 xtrace_print_assignment (name
, value
, assign_list
, 1);
2811 name
[offset
- 1] = '\0';
2814 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2817 aflags
|= ASS_APPEND
;
2819 #if defined (ARRAY_VARS)
2820 if (t
= mbschr (name
, '[')) /*]*/
2824 report_error (_("%s: cannot assign list to array member"), name
);
2827 entry
= assign_array_element (name
, value
, aflags
);
2831 else if (assign_list
)
2833 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
) == 0)
2834 aflags
|= ASS_MKLOCAL
;
2835 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
))
2836 aflags
|= ASS_MKGLOBAL
;
2837 if (word
->flags
& W_ASSIGNASSOC
)
2838 aflags
|= ASS_MKASSOC
;
2839 entry
= do_compound_assignment (name
, value
, aflags
);
2842 #endif /* ARRAY_VARS */
2843 entry
= bind_variable (name
, value
, aflags
);
2845 stupidly_hack_special_variables (name
);
2847 /* Return 1 if the assignment seems to have been performed correctly. */
2848 if (entry
== 0 || readonly_p (entry
))
2849 retval
= 0; /* assignment failure */
2850 else if (noassign_p (entry
))
2852 last_command_exit_value
= EXECUTION_FAILURE
;
2853 retval
= 1; /* error status, but not assignment failure */
2858 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2859 VUNSETATTR (entry
, att_invisible
);
2861 ASSIGN_RETURN (retval
);
2864 /* Perform the assignment statement in STRING, and expand the
2865 right side by doing tilde, command and parameter expansion. */
2867 do_assignment (string
)
2872 td
.flags
= W_ASSIGNMENT
;
2875 return do_assignment_internal (&td
, 1);
2879 do_word_assignment (word
, flags
)
2883 return do_assignment_internal (word
, 1);
2886 /* Given STRING, an assignment string, get the value of the right side
2887 of the `=', and bind it to the left side. Do not perform any word
2888 expansions on the right hand side. */
2890 do_assignment_no_expand (string
)
2895 td
.flags
= W_ASSIGNMENT
;
2898 return (do_assignment_internal (&td
, 0));
2901 /***************************************************
2903 * Functions to manage the positional parameters *
2905 ***************************************************/
2907 /* Return the word list that corresponds to `$*'. */
2909 list_rest_of_args ()
2911 register WORD_LIST
*list
, *args
;
2914 /* Break out of the loop as soon as one of the dollar variables is null. */
2915 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2916 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2918 for (args
= rest_of_args
; args
; args
= args
->next
)
2919 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2921 return (REVERSE_LIST (list
, WORD_LIST
*));
2927 register WORD_LIST
*list
;
2930 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2932 for (list
= rest_of_args
; list
; list
= list
->next
)
2937 /* Return the value of a positional parameter. This handles values > 10. */
2939 get_dollar_var_value (ind
)
2946 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2947 else /* We want something like ${11} */
2950 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2952 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2957 /* Make a single large string out of the dollar digit variables,
2958 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2959 case of "$*" with respect to IFS. */
2961 string_rest_of_args (dollar_star
)
2964 register WORD_LIST
*list
;
2967 list
= list_rest_of_args ();
2968 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2969 dispose_words (list
);
2973 /* Return a string containing the positional parameters from START to
2974 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2975 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2976 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2977 no quoting chars are added. */
2979 pos_params (string
, start
, end
, quoted
)
2981 int start
, end
, quoted
;
2983 WORD_LIST
*save
, *params
, *h
, *t
;
2987 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2989 return ((char *)NULL
);
2991 save
= params
= list_rest_of_args ();
2993 return ((char *)NULL
);
2995 if (start
== 0) /* handle ${@:0[:x]} specially */
2997 t
= make_word_list (make_word (dollar_vars
[0]), params
);
3001 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
3002 params
= params
->next
;
3004 return ((char *)NULL
);
3005 for (h
= t
= params
; params
&& i
< end
; i
++)
3008 params
= params
->next
;
3011 t
->next
= (WORD_LIST
*)NULL
;
3013 ret
= string_list_pos_params (string
[0], h
, quoted
);
3018 dispose_words (save
);
3022 /******************************************************************/
3024 /* Functions to expand strings to strings or WORD_LISTs */
3026 /******************************************************************/
3028 #if defined (PROCESS_SUBSTITUTION)
3029 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3031 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3034 /* If there are any characters in STRING that require full expansion,
3035 then call FUNC to expand STRING; otherwise just perform quote
3036 removal if necessary. This returns a new string. */
3038 expand_string_if_necessary (string
, quoted
, func
)
3049 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3050 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3054 if (EXP_CHAR (string
[i
]))
3056 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3058 ADVANCE_CHAR (string
, slen
, i
);
3063 list
= (*func
) (string
, quoted
);
3066 ret
= string_list (list
);
3067 dispose_words (list
);
3072 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3073 ret
= string_quote_removal (string
, quoted
);
3075 ret
= savestring (string
);
3080 static inline char *
3081 expand_string_to_string_internal (string
, quoted
, func
)
3089 if (string
== 0 || *string
== '\0')
3090 return ((char *)NULL
);
3092 list
= (*func
) (string
, quoted
);
3095 ret
= string_list (list
);
3096 dispose_words (list
);
3105 expand_string_to_string (string
, quoted
)
3109 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
3113 expand_string_unsplit_to_string (string
, quoted
)
3117 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3121 expand_assignment_string_to_string (string
, quoted
)
3125 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3129 expand_arith_string (string
, quoted
)
3134 WORD_LIST
*list
, *tlist
;
3140 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3141 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3145 if (EXP_CHAR (string
[i
]))
3147 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3149 ADVANCE_CHAR (string
, slen
, i
);
3154 /* This is expanded version of expand_string_internal as it's called by
3155 expand_string_leave_quoted */
3156 td
.flags
= W_NOPROCSUB
; /* don't want process substitution */
3157 td
.word
= savestring (string
);
3158 list
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3159 /* This takes care of the calls from expand_string_leave_quoted and
3163 tlist
= word_list_split (list
);
3164 dispose_words (list
);
3167 dequote_list (list
);
3169 /* This comes from expand_string_if_necessary */
3172 ret
= string_list (list
);
3173 dispose_words (list
);
3179 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3180 ret
= string_quote_removal (string
, quoted
);
3182 ret
= savestring (string
);
3187 #if defined (COND_COMMAND)
3188 /* Just remove backslashes in STRING. Returns a new string. */
3190 remove_backslashes (string
)
3195 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3196 for (s
= string
; s
&& *s
; )
3208 /* This needs better error handling. */
3209 /* Expand W for use as an argument to a unary or binary operator in a
3210 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3211 to the != or == operator, and should be treated as a pattern. In
3212 this case, we quote the string specially for the globbing code. If
3213 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3214 be quoted appropriately for regcomp/regexec. The caller is responsible
3215 for removing the backslashes if the unquoted word is needed later. */
3217 cond_expand_word (w
, special
)
3225 if (w
->word
== 0 || w
->word
[0] == '\0')
3226 return ((char *)NULL
);
3228 w
->flags
|= W_NOSPLIT2
;
3229 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3235 r
= string_list (l
);
3239 qflags
= QGLOB_CVTNULL
;
3241 qflags
|= QGLOB_REGEXP
;
3242 p
= string_list (l
);
3243 r
= quote_string_for_globbing (p
, qflags
);
3255 /* Call expand_word_internal to expand W and handle error returns.
3256 A convenience function for functions that don't want to handle
3257 any errors or free any memory before aborting. */
3259 call_expand_word_internal (w
, q
, i
, c
, e
)
3265 result
= expand_word_internal (w
, q
, i
, c
, e
);
3266 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3268 /* By convention, each time this error is returned, w->word has
3269 already been freed (it sometimes may not be in the fatal case,
3270 but that doesn't result in a memory leak because we're going
3271 to exit in most cases). */
3272 w
->word
= (char *)NULL
;
3273 last_command_exit_value
= EXECUTION_FAILURE
;
3274 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3282 /* Perform parameter expansion, command substitution, and arithmetic
3283 expansion on STRING, as if it were a word. Leave the result quoted.
3284 Since this does not perform word splitting, it leaves quoted nulls
3287 expand_string_internal (string
, quoted
)
3294 if (string
== 0 || *string
== 0)
3295 return ((WORD_LIST
*)NULL
);
3298 td
.word
= savestring (string
);
3300 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3306 /* Expand STRING by performing parameter expansion, command substitution,
3307 and arithmetic expansion. Dequote the resulting WORD_LIST before
3308 returning it, but do not perform word splitting. The call to
3309 remove_quoted_nulls () is in here because word splitting normally
3310 takes care of quote removal. */
3312 expand_string_unsplit (string
, quoted
)
3318 if (string
== 0 || *string
== '\0')
3319 return ((WORD_LIST
*)NULL
);
3321 expand_no_split_dollar_star
= 1;
3322 value
= expand_string_internal (string
, quoted
);
3323 expand_no_split_dollar_star
= 0;
3329 remove_quoted_nulls (value
->word
->word
);
3330 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3332 dequote_list (value
);
3337 /* Expand the rhs of an assignment statement */
3339 expand_string_assignment (string
, quoted
)
3346 if (string
== 0 || *string
== '\0')
3347 return ((WORD_LIST
*)NULL
);
3349 expand_no_split_dollar_star
= 1;
3351 td
.flags
= W_ASSIGNRHS
;
3352 td
.word
= savestring (string
);
3353 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3356 expand_no_split_dollar_star
= 0;
3362 remove_quoted_nulls (value
->word
->word
);
3363 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3365 dequote_list (value
);
3371 /* Expand one of the PS? prompt strings. This is a sort of combination of
3372 expand_string_unsplit and expand_string_internal, but returns the
3373 passed string when an error occurs. Might want to trap other calls
3374 to jump_to_top_level here so we don't endlessly loop. */
3376 expand_prompt_string (string
, quoted
, wflags
)
3384 if (string
== 0 || *string
== 0)
3385 return ((WORD_LIST
*)NULL
);
3388 td
.word
= savestring (string
);
3390 no_longjmp_on_fatal_error
= 1;
3391 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3392 no_longjmp_on_fatal_error
= 0;
3394 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3396 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3404 remove_quoted_nulls (value
->word
->word
);
3405 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3407 dequote_list (value
);
3412 /* Expand STRING just as if you were expanding a word, but do not dequote
3413 the resultant WORD_LIST. This is called only from within this file,
3414 and is used to correctly preserve quoted characters when expanding
3415 things like ${1+"$@"}. This does parameter expansion, command
3416 substitution, arithmetic expansion, and word splitting. */
3418 expand_string_leave_quoted (string
, quoted
)
3425 if (string
== 0 || *string
== '\0')
3426 return ((WORD_LIST
*)NULL
);
3428 tlist
= expand_string_internal (string
, quoted
);
3432 tresult
= word_list_split (tlist
);
3433 dispose_words (tlist
);
3436 return ((WORD_LIST
*)NULL
);
3439 /* This does not perform word splitting or dequote the WORD_LIST
3442 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3444 int quoted
, *dollar_at_p
, *has_dollar_at
;
3449 if (string
== 0 || *string
== '\0')
3450 return (WORD_LIST
*)NULL
;
3452 td
.flags
= W_NOSPLIT2
; /* no splitting, remove "" and '' */
3454 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3458 /* Expand STRING just as if you were expanding a word. This also returns
3459 a list of words. Note that filename globbing is *NOT* done for word
3460 or string expansion, just when the shell is expanding a command. This
3461 does parameter expansion, command substitution, arithmetic expansion,
3462 and word splitting. Dequote the resultant WORD_LIST before returning. */
3464 expand_string (string
, quoted
)
3470 if (string
== 0 || *string
== '\0')
3471 return ((WORD_LIST
*)NULL
);
3473 result
= expand_string_leave_quoted (string
, quoted
);
3474 return (result
? dequote_list (result
) : result
);
3477 /***************************************************
3479 * Functions to handle quoting chars *
3481 ***************************************************/
3485 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3486 The parser passes CTLNUL as CTLESC CTLNUL. */
3488 /* Quote escape characters in string s, but no other characters. This is
3489 used to protect CTLESC and CTLNUL in variable values from the rest of
3490 the word expansion process after the variable is expanded (word splitting
3491 and filename generation). If IFS is null, we quote spaces as well, just
3492 in case we split on spaces later (in the case of unquoted $@, we will
3493 eventually attempt to split the entire word on spaces). Corresponding
3494 code exists in dequote_escapes. Even if we don't end up splitting on
3495 spaces, quoting spaces is not a problem. This should never be called on
3496 a string that is quoted with single or double quotes or part of a here
3497 document (effectively double-quoted). */
3499 quote_escapes (string
)
3502 register char *s
, *t
;
3504 char *result
, *send
;
3505 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3508 slen
= strlen (string
);
3509 send
= string
+ slen
;
3511 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3513 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3514 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3516 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3521 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3523 COPY_CHAR_P (t
, s
, send
);
3530 list_quote_escapes (list
)
3533 register WORD_LIST
*w
;
3536 for (w
= list
; w
; w
= w
->next
)
3539 w
->word
->word
= quote_escapes (t
);
3545 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3547 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3548 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3549 data stream pass through properly.
3551 We need to remove doubled CTLESC characters inside quoted strings before
3552 quoting the entire string, so we do not double the number of CTLESC
3555 Also used by parts of the pattern substitution code. */
3557 dequote_escapes (string
)
3560 register char *s
, *t
, *s1
;
3562 char *result
, *send
;
3569 slen
= strlen (string
);
3570 send
= string
+ slen
;
3572 t
= result
= (char *)xmalloc (slen
+ 1);
3574 if (strchr (string
, CTLESC
) == 0)
3575 return (strcpy (result
, string
));
3577 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3582 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3588 COPY_CHAR_P (t
, s
, send
);
3594 /* Return a new string with the quoted representation of character C.
3595 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3596 set in any resultant WORD_DESC where this value is the word. */
3598 make_quoted_char (c
)
3603 temp
= (char *)xmalloc (3);
3618 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3619 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3620 this value is the word. */
3622 quote_string (string
)
3627 char *result
, *send
;
3631 result
= (char *)xmalloc (2);
3639 slen
= strlen (string
);
3640 send
= string
+ slen
;
3642 result
= (char *)xmalloc ((slen
* 2) + 1);
3644 for (t
= result
; string
< send
; )
3647 COPY_CHAR_P (t
, string
, send
);
3654 /* De-quote quoted characters in STRING. */
3656 dequote_string (string
)
3659 register char *s
, *t
;
3661 char *result
, *send
;
3664 slen
= strlen (string
);
3666 t
= result
= (char *)xmalloc (slen
+ 1);
3668 if (QUOTED_NULL (string
))
3674 /* If no character in the string can be quoted, don't bother examining
3675 each character. Just return a copy of the string passed to us. */
3676 if (strchr (string
, CTLESC
) == NULL
)
3677 return (strcpy (result
, string
));
3679 send
= string
+ slen
;
3689 COPY_CHAR_P (t
, s
, send
);
3696 /* Quote the entire WORD_LIST list. */
3701 register WORD_LIST
*w
;
3704 for (w
= list
; w
; w
= w
->next
)
3707 w
->word
->word
= quote_string (t
);
3709 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3710 w
->word
->flags
|= W_QUOTED
;
3716 /* De-quote quoted characters in each word in LIST. */
3722 register WORD_LIST
*tlist
;
3724 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3726 s
= dequote_string (tlist
->word
->word
);
3727 if (QUOTED_NULL (tlist
->word
->word
))
3728 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3729 free (tlist
->word
->word
);
3730 tlist
->word
->word
= s
;
3735 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3738 remove_quoted_escapes (string
)
3745 t
= dequote_escapes (string
);
3753 /* Perform quoted null character removal on STRING. We don't allow any
3754 quoted null characters in the middle or at the ends of strings because
3755 of how expand_word_internal works. remove_quoted_nulls () turns
3756 STRING into an empty string iff it only consists of a quoted null,
3757 and removes all unquoted CTLNUL characters. */
3759 remove_quoted_nulls (string
)
3762 register size_t slen
;
3763 register int i
, j
, prev_i
;
3766 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3767 return string
; /* XXX */
3769 slen
= strlen (string
);
3774 if (string
[i
] == CTLESC
)
3776 /* Old code had j++, but we cannot assume that i == j at this
3777 point -- what if a CTLNUL has already been removed from the
3778 string? We don't want to drop the CTLESC or recopy characters
3779 that we've already copied down. */
3780 i
++; string
[j
++] = CTLESC
;
3784 else if (string
[i
] == CTLNUL
)
3791 ADVANCE_CHAR (string
, slen
, i
);
3794 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3804 /* Perform quoted null character removal on each element of LIST.
3805 This modifies LIST. */
3807 word_list_remove_quoted_nulls (list
)
3810 register WORD_LIST
*t
;
3812 for (t
= list
; t
; t
= t
->next
)
3814 remove_quoted_nulls (t
->word
->word
);
3815 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3819 /* **************************************************************** */
3821 /* Functions for Matching and Removing Patterns */
3823 /* **************************************************************** */
3825 #if defined (HANDLE_MULTIBYTE)
3826 #if 0 /* Currently unused */
3827 static unsigned char *
3828 mb_getcharlens (string
, len
)
3832 int i
, offset
, last
;
3839 ret
= (unsigned char *)xmalloc (len
);
3840 memset (ret
, 0, len
);
3841 while (string
[last
])
3843 ADVANCE_CHAR (string
, len
, offset
);
3844 ret
[last
] = offset
- last
;
3852 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3853 can have one of 4 values:
3854 RP_LONG_LEFT remove longest matching portion at start of PARAM
3855 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3856 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3857 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3860 #define RP_LONG_LEFT 1
3861 #define RP_SHORT_LEFT 2
3862 #define RP_LONG_RIGHT 3
3863 #define RP_SHORT_RIGHT 4
3865 /* Returns its first argument if nothing matched; new memory otherwise */
3867 remove_upattern (param
, pattern
, op
)
3868 char *param
, *pattern
;
3873 register char *p
, *ret
, c
;
3875 len
= STRLEN (param
);
3880 case RP_LONG_LEFT
: /* remove longest match at start */
3881 for (p
= end
; p
>= param
; p
--)
3884 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3887 return (savestring (p
));
3894 case RP_SHORT_LEFT
: /* remove shortest match at start */
3895 for (p
= param
; p
<= end
; p
++)
3898 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3901 return (savestring (p
));
3907 case RP_LONG_RIGHT
: /* remove longest match at end */
3908 for (p
= param
; p
<= end
; p
++)
3910 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3913 ret
= savestring (param
);
3920 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3921 for (p
= end
; p
>= param
; p
--)
3923 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3926 ret
= savestring (param
);
3934 return (param
); /* no match, return original string */
3937 #if defined (HANDLE_MULTIBYTE)
3938 /* Returns its first argument if nothing matched; new memory otherwise */
3940 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3951 case RP_LONG_LEFT
: /* remove longest match at start */
3952 for (n
= wstrlen
; n
>= 0; n
--)
3954 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3955 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3958 return (wcsdup (wparam
+ n
));
3964 case RP_SHORT_LEFT
: /* remove shortest match at start */
3965 for (n
= 0; n
<= wstrlen
; n
++)
3967 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3968 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3971 return (wcsdup (wparam
+ n
));
3977 case RP_LONG_RIGHT
: /* remove longest match at end */
3978 for (n
= 0; n
<= wstrlen
; n
++)
3980 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3982 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3983 ret
= wcsdup (wparam
);
3990 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3991 for (n
= wstrlen
; n
>= 0; n
--)
3993 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3995 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3996 ret
= wcsdup (wparam
);
4004 return (wparam
); /* no match, return original string */
4006 #endif /* HANDLE_MULTIBYTE */
4009 remove_pattern (param
, pattern
, op
)
4010 char *param
, *pattern
;
4017 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
4018 return (savestring (param
));
4020 #if defined (HANDLE_MULTIBYTE)
4023 wchar_t *ret
, *oret
;
4025 wchar_t *wparam
, *wpattern
;
4028 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
4029 if (n
== (size_t)-1)
4031 xret
= remove_upattern (param
, pattern
, op
);
4032 return ((xret
== param
) ? savestring (param
) : xret
);
4034 n
= xdupmbstowcs (&wparam
, NULL
, param
);
4036 if (n
== (size_t)-1)
4039 xret
= remove_upattern (param
, pattern
, op
);
4040 return ((xret
== param
) ? savestring (param
) : xret
);
4042 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
4043 /* Don't bother to convert wparam back to multibyte string if nothing
4044 matched; just return copy of original string */
4049 return (savestring (param
));
4056 xret
= (char *)xmalloc (n
+ 1);
4057 memset (&ps
, '\0', sizeof (mbstate_t));
4058 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
4059 xret
[n
] = '\0'; /* just to make sure */
4066 xret
= remove_upattern (param
, pattern
, op
);
4067 return ((xret
== param
) ? savestring (param
) : xret
);
4071 /* Match PAT anywhere in STRING and return the match boundaries.
4072 This returns 1 in case of a successful match, 0 otherwise. SP
4073 and EP are pointers into the string where the match begins and
4074 ends, respectively. MTYPE controls what kind of match is attempted.
4075 MATCH_BEG and MATCH_END anchor the match at the beginning and end
4076 of the string, respectively. The longest match is returned. */
4078 match_upattern (string
, pat
, mtype
, sp
, ep
)
4084 register char *p
, *p1
, *npat
;
4088 /* If the pattern doesn't match anywhere in the string, go ahead and
4089 short-circuit right away. A minor optimization, saves a bunch of
4090 unnecessary calls to strmatch (up to N calls for a string of N
4091 characters) if the match is unsuccessful. To preserve the semantics
4092 of the substring matches below, we make sure that the pattern has
4093 `*' as first and last character, making a new pattern if necessary. */
4094 /* XXX - check this later if I ever implement `**' with special meaning,
4095 since this will potentially result in `**' at the beginning or end */
4097 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == LPAREN
&& extended_glob
) || pat
[len
- 1] != '*')
4099 p
= npat
= (char *)xmalloc (len
+ 3);
4101 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == LPAREN
&& extended_glob
))
4105 if (p1
[-1] != '*' || p
[-2] == '\\')
4111 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
4114 if (c
== FNM_NOMATCH
)
4117 len
= STRLEN (string
);
4120 mlen
= umatchlen (pat
, len
);
4125 for (p
= string
; p
<= end
; p
++)
4127 if (match_pattern_char (pat
, p
))
4129 p1
= (mlen
== -1) ? end
: p
+ mlen
;
4130 /* p1 - p = length of portion of string to be considered
4131 p = current position in string
4132 mlen = number of characters consumed by match (-1 for entire string)
4134 we want to break immediately if the potential match len
4135 is greater than the number of characters remaining in the
4140 for ( ; p1
>= p
; p1
--)
4142 c
= *p1
; *p1
= '\0';
4143 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4152 /* If MLEN != -1, we have a fixed length pattern. */
4163 if (match_pattern_char (pat
, string
) == 0)
4166 for (p
= (mlen
== -1) ? end
: string
+ mlen
; p
>= string
; p
--)
4169 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
4177 /* If MLEN != -1, we have a fixed length pattern. */
4185 for (p
= end
- ((mlen
== -1) ? len
: mlen
); p
<= end
; p
++)
4187 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4193 /* If MLEN != -1, we have a fixed length pattern. */
4204 #if defined (HANDLE_MULTIBYTE)
4205 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4206 This returns 1 in case of a successful match, 0 otherwise. Wide
4207 character version. */
4209 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4217 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4220 int n
, n1
, n2
, simple
;
4222 simple
= (wpat
[0] != L
'\\' && wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'[');
4223 #if defined (EXTENDED_GLOB)
4225 simple
&= (wpat
[1] != L
'(' || (wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'+' && wpat
[0] != L
'!' && wpat
[0] != L
'@')); /*)*/
4228 /* If the pattern doesn't match anywhere in the string, go ahead and
4229 short-circuit right away. A minor optimization, saves a bunch of
4230 unnecessary calls to strmatch (up to N calls for a string of N
4231 characters) if the match is unsuccessful. To preserve the semantics
4232 of the substring matches below, we make sure that the pattern has
4233 `*' as first and last character, making a new pattern if necessary. */
4234 len
= wcslen (wpat
);
4235 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == WLPAREN
&& extended_glob
) || wpat
[len
- 1] != L
'*')
4237 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4239 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == WLPAREN
&& extended_glob
))
4241 while (*wp1
!= L
'\0')
4243 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4249 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
4252 if (len
== FNM_NOMATCH
)
4255 mlen
= wmatchlen (wpat
, wstrlen
);
4257 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4261 for (n
= 0; n
<= wstrlen
; n
++)
4263 n2
= simple
? (*wpat
== wstring
[n
]) : match_pattern_wchar (wpat
, wstring
+ n
);
4266 n1
= (mlen
== -1) ? wstrlen
: n
+ mlen
;
4270 for ( ; n1
>= n
; n1
--)
4272 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4273 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4281 /* If MLEN != -1, we have a fixed length pattern. */
4291 if (match_pattern_wchar (wpat
, wstring
) == 0)
4294 for (n
= (mlen
== -1) ? wstrlen
: mlen
; n
>= 0; n
--)
4296 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4297 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
4305 /* If MLEN != -1, we have a fixed length pattern. */
4313 for (n
= wstrlen
- ((mlen
== -1) ? wstrlen
: mlen
); n
<= wstrlen
; n
++)
4315 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4318 *ep
= indices
[wstrlen
];
4321 /* If MLEN != -1, we have a fixed length pattern. */
4331 #endif /* HANDLE_MULTIBYTE */
4334 match_pattern (string
, pat
, mtype
, sp
, ep
)
4339 #if defined (HANDLE_MULTIBYTE)
4342 wchar_t *wstring
, *wpat
;
4344 size_t slen
, plen
, mslen
, mplen
;
4347 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4350 #if defined (HANDLE_MULTIBYTE)
4353 if (mbsmbchar (string
) == 0 && mbsmbchar (pat
) == 0)
4354 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4356 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4357 if (n
== (size_t)-1)
4358 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4359 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4360 if (n
== (size_t)-1)
4363 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4365 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4375 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4379 getpatspec (c
, value
)
4384 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4386 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4389 /* Posix.2 says that the WORD should be run through tilde expansion,
4390 parameter expansion, command substitution and arithmetic expansion.
4391 This leaves the result quoted, so quote_string_for_globbing () has
4392 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4393 it means that the entire expression was enclosed in double quotes.
4394 This means that quoting characters in the pattern do not make any
4395 special pattern characters quoted. For example, the `*' in the
4396 following retains its special meaning: "${foo#'*'}". */
4398 getpattern (value
, quoted
, expandpat
)
4400 int quoted
, expandpat
;
4407 /* There is a problem here: how to handle single or double quotes in the
4408 pattern string when the whole expression is between double quotes?
4409 POSIX.2 says that enclosing double quotes do not cause the pattern to
4410 be quoted, but does that leave us a problem with @ and array[@] and their
4411 expansions inside a pattern? */
4413 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4416 pat
= string_extract_double_quoted (tword
, &i
, 1);
4422 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4424 l
= *value
? expand_string_for_rhs (value
,
4425 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4426 (int *)NULL
, (int *)NULL
)
4428 pat
= string_list (l
);
4432 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4440 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4441 or ${name#[#]value}. */
4443 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4444 char *value
, *pattern
;
4445 int patspec
, quoted
;
4449 tword
= remove_pattern (value
, pattern
, patspec
);
4456 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4459 int patspec
, itype
, quoted
;
4465 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4467 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4468 w
= alloc_word_desc ();
4469 w
->word
= tword
? tword
: savestring ("");
4470 new = make_word_list (w
, new);
4473 l
= REVERSE_LIST (new, WORD_LIST
*);
4474 tword
= string_list_pos_params (itype
, l
, quoted
);
4481 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4484 int patspec
, quoted
;
4489 list
= list_rest_of_args ();
4491 return ((char *)NULL
);
4492 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4493 dispose_words (list
);
4497 #if defined (ARRAY_VARS)
4499 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4503 char *varname
; /* so we can figure out how it's indexed */
4513 /* compute itype from varname here */
4514 v
= array_variable_part (varname
, &ret
, 0);
4517 if (v
&& invisible_p (var
))
4518 return ((char *)NULL
);
4522 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4523 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4525 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4527 return ((char *)NULL
);
4528 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4529 dispose_words (list
);
4533 #endif /* ARRAY_VARS */
4536 parameter_brace_remove_pattern (varname
, value
, ind
, patstr
, rtype
, quoted
, flags
)
4537 char *varname
, *value
;
4540 int rtype
, quoted
, flags
;
4542 int vtype
, patspec
, starsub
;
4543 char *temp1
, *val
, *pattern
;
4547 return ((char *)NULL
);
4549 this_command_name
= varname
;
4551 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4553 return ((char *)NULL
);
4555 starsub
= vtype
& VT_STARSUB
;
4556 vtype
&= ~VT_STARSUB
;
4558 patspec
= getpatspec (rtype
, patstr
);
4559 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4562 /* Need to pass getpattern newly-allocated memory in case of expansion --
4563 the expansion code will free the passed string on an error. */
4564 temp1
= savestring (patstr
);
4565 pattern
= getpattern (temp1
, quoted
, 1);
4568 temp1
= (char *)NULL
; /* shut up gcc */
4572 case VT_ARRAYMEMBER
:
4573 temp1
= remove_pattern (val
, pattern
, patspec
);
4574 if (vtype
== VT_VARIABLE
)
4578 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4579 ? quote_string (temp1
)
4580 : quote_escapes (temp1
);
4585 #if defined (ARRAY_VARS)
4587 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4588 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4590 val
= quote_escapes (temp1
);
4597 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4598 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4600 val
= quote_escapes (temp1
);
4611 /*******************************************
4613 * Functions to expand WORD_DESCs *
4615 *******************************************/
4617 /* Expand WORD, performing word splitting on the result. This does
4618 parameter expansion, command substitution, arithmetic expansion,
4619 word splitting, and quote removal. */
4622 expand_word (word
, quoted
)
4626 WORD_LIST
*result
, *tresult
;
4628 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4629 result
= word_list_split (tresult
);
4630 dispose_words (tresult
);
4631 return (result
? dequote_list (result
) : result
);
4634 /* Expand WORD, but do not perform word splitting on the result. This
4635 does parameter expansion, command substitution, arithmetic expansion,
4636 and quote removal. */
4638 expand_word_unsplit (word
, quoted
)
4644 expand_no_split_dollar_star
= 1;
4645 #if defined (HANDLE_MULTIBYTE)
4646 if (ifs_firstc
[0] == 0)
4648 if (ifs_firstc
== 0)
4650 word
->flags
|= W_NOSPLIT
;
4651 word
->flags
|= W_NOSPLIT2
;
4652 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4653 expand_no_split_dollar_star
= 0;
4655 return (result
? dequote_list (result
) : result
);
4658 /* Perform shell expansions on WORD, but do not perform word splitting or
4659 quote removal on the result. Virtually identical to expand_word_unsplit;
4660 could be combined if implementations don't diverge. */
4662 expand_word_leave_quoted (word
, quoted
)
4668 expand_no_split_dollar_star
= 1;
4669 #if defined (HANDLE_MULTIBYTE)
4670 if (ifs_firstc
[0] == 0)
4672 if (ifs_firstc
== 0)
4674 word
->flags
|= W_NOSPLIT
;
4675 word
->flags
|= W_NOSPLIT2
;
4676 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4677 expand_no_split_dollar_star
= 0;
4682 #if defined (PROCESS_SUBSTITUTION)
4684 /*****************************************************************/
4686 /* Hacking Process Substitution */
4688 /*****************************************************************/
4690 #if !defined (HAVE_DEV_FD)
4691 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4692 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4693 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4694 list. NFIFO is a count of the number of FIFOs in the list. */
4695 #define FIFO_INCR 20
4702 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4704 static int fifo_list_size
;
4707 copy_fifo_list (sizep
)
4712 return (char *)NULL
;
4716 add_fifo_list (pathname
)
4719 if (nfifo
>= fifo_list_size
- 1)
4721 fifo_list_size
+= FIFO_INCR
;
4722 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4723 fifo_list_size
* sizeof (struct temp_fifo
));
4726 fifo_list
[nfifo
].file
= savestring (pathname
);
4734 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4736 unlink (fifo_list
[i
].file
);
4737 free (fifo_list
[i
].file
);
4738 fifo_list
[i
].file
= (char *)NULL
;
4739 fifo_list
[i
].proc
= -1;
4751 for (i
= saved
= 0; i
< nfifo
; i
++)
4753 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4755 unlink (fifo_list
[i
].file
);
4756 free (fifo_list
[i
].file
);
4757 fifo_list
[i
].file
= (char *)NULL
;
4758 fifo_list
[i
].proc
= -1;
4764 /* If we didn't remove some of the FIFOs, compact the list. */
4767 for (i
= j
= 0; i
< nfifo
; i
++)
4768 if (fifo_list
[i
].file
)
4770 fifo_list
[j
].file
= fifo_list
[i
].file
;
4771 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4780 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4781 from some point in the past, and close all open FIFOs in fifo_list
4782 that are not marked as active in LIST. If LIST is NULL, close
4783 everything in fifo_list. LSIZE is the number of elements in LIST, in
4784 case it's larger than fifo_list_size (size of fifo_list). */
4786 close_new_fifos (list
, lsize
)
4794 unlink_fifo_list ();
4798 for (i
= 0; i
< lsize
; i
++)
4799 if (list
[i
] == 0 && i
< fifo_list_size
&& fifo_list
[i
].proc
!= -1)
4802 for (i
= lsize
; i
< fifo_list_size
; i
++)
4823 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4824 if (mkfifo (tname
, 0600) < 0)
4827 return ((char *)NULL
);
4830 add_fifo_list (tname
);
4834 #else /* HAVE_DEV_FD */
4836 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4837 has open to children. NFDS is a count of the number of bits currently
4838 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4840 static char *dev_fd_list
= (char *)NULL
;
4842 static int totfds
; /* The highest possible number of open files. */
4845 copy_fifo_list (sizep
)
4850 if (nfds
== 0 || totfds
== 0)
4854 return (char *)NULL
;
4859 ret
= (char *)xmalloc (totfds
);
4860 return (memcpy (ret
, dev_fd_list
, totfds
));
4867 if (dev_fd_list
== 0 || fd
>= totfds
)
4872 totfds
= getdtablesize ();
4873 if (totfds
< 0 || totfds
> 256)
4878 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4879 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4882 dev_fd_list
[fd
] = 1;
4889 return 0; /* used for cleanup; not needed with /dev/fd */
4902 if (dev_fd_list
[fd
])
4905 dev_fd_list
[fd
] = 0;
4918 for (i
= 0; nfds
&& i
< totfds
; i
++)
4924 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4925 the past, and close all open fds in dev_fd_list that are not marked
4926 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4927 LSIZE is the number of elements in LIST, in case it's larger than
4928 totfds (size of dev_fd_list). */
4930 close_new_fifos (list
, lsize
)
4938 unlink_fifo_list ();
4942 for (i
= 0; i
< lsize
; i
++)
4943 if (list
[i
] == 0 && i
< totfds
&& dev_fd_list
[i
])
4946 for (i
= lsize
; i
< totfds
; i
++)
4950 #if defined (NOTDEF)
4951 print_dev_fd_list ()
4955 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4958 for (i
= 0; i
< totfds
; i
++)
4961 fprintf (stderr
, " %d", i
);
4963 fprintf (stderr
, "\n");
4968 make_dev_fd_filename (fd
)
4971 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4973 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4975 strcpy (ret
, DEV_FD_PREFIX
);
4976 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4977 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4983 #endif /* HAVE_DEV_FD */
4985 /* Return a filename that will open a connection to the process defined by
4986 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4987 a filename in /dev/fd corresponding to a descriptor that is one of the
4988 ends of the pipe. If not defined, we use named pipes on systems that have
4989 them. Systems without /dev/fd and named pipes are out of luck.
4991 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4992 use the read end of the pipe and dup that file descriptor to fd 0 in
4993 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4994 writing or use the write end of the pipe in the child, and dup that
4995 file descriptor to fd 1 in the child. The parent does the opposite. */
4998 process_substitute (string
, open_for_read_in_child
)
5000 int open_for_read_in_child
;
5005 #if defined (HAVE_DEV_FD)
5006 int parent_pipe_fd
, child_pipe_fd
;
5008 #endif /* HAVE_DEV_FD */
5009 #if defined (JOB_CONTROL)
5010 pid_t old_pipeline_pgrp
;
5013 if (!string
|| !*string
|| wordexp_only
)
5014 return ((char *)NULL
);
5016 #if !defined (HAVE_DEV_FD)
5017 pathname
= make_named_pipe ();
5018 #else /* HAVE_DEV_FD */
5019 if (pipe (fildes
) < 0)
5021 sys_error (_("cannot make pipe for process substitution"));
5022 return ((char *)NULL
);
5024 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
5025 the pipe in the parent, otherwise the read end. */
5026 parent_pipe_fd
= fildes
[open_for_read_in_child
];
5027 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
5028 /* Move the parent end of the pipe to some high file descriptor, to
5029 avoid clashes with FDs used by the script. */
5030 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
5032 pathname
= make_dev_fd_filename (parent_pipe_fd
);
5033 #endif /* HAVE_DEV_FD */
5037 sys_error (_("cannot make pipe for process substitution"));
5038 return ((char *)NULL
);
5041 old_pid
= last_made_pid
;
5043 #if defined (JOB_CONTROL)
5044 old_pipeline_pgrp
= pipeline_pgrp
;
5045 pipeline_pgrp
= shell_pgrp
;
5047 #endif /* JOB_CONTROL */
5049 pid
= make_child ((char *)NULL
, 1);
5052 reset_terminating_signals (); /* XXX */
5053 free_pushed_string_input ();
5054 /* Cancel traps, in trap.c. */
5055 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5056 setup_async_signals ();
5057 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
5060 #if defined (JOB_CONTROL)
5061 set_sigchld_handler ();
5062 stop_making_children ();
5063 /* XXX - should we only do this in the parent? (as in command subst) */
5064 pipeline_pgrp
= old_pipeline_pgrp
;
5065 #endif /* JOB_CONTROL */
5069 sys_error (_("cannot make child for process substitution"));
5071 #if defined (HAVE_DEV_FD)
5072 close (parent_pipe_fd
);
5073 close (child_pipe_fd
);
5074 #endif /* HAVE_DEV_FD */
5075 return ((char *)NULL
);
5080 #if defined (JOB_CONTROL)
5081 restore_pipeline (1);
5084 #if !defined (HAVE_DEV_FD)
5085 fifo_list
[nfifo
-1].proc
= pid
;
5088 last_made_pid
= old_pid
;
5090 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5092 #endif /* JOB_CONTROL && PGRP_PIPE */
5094 #if defined (HAVE_DEV_FD)
5095 close (child_pipe_fd
);
5096 #endif /* HAVE_DEV_FD */
5101 set_sigint_handler ();
5103 #if defined (JOB_CONTROL)
5104 set_job_control (0);
5105 #endif /* JOB_CONTROL */
5107 #if !defined (HAVE_DEV_FD)
5108 /* Open the named pipe in the child. */
5109 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
5112 /* Two separate strings for ease of translation. */
5113 if (open_for_read_in_child
)
5114 sys_error (_("cannot open named pipe %s for reading"), pathname
);
5116 sys_error (_("cannot open named pipe %s for writing"), pathname
);
5120 if (open_for_read_in_child
)
5122 if (sh_unset_nodelay_mode (fd
) < 0)
5124 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
5128 #else /* HAVE_DEV_FD */
5130 #endif /* HAVE_DEV_FD */
5132 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
5134 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
5135 open_for_read_in_child
? 0 : 1);
5139 if (fd
!= (open_for_read_in_child
? 0 : 1))
5142 /* Need to close any files that this process has open to pipes inherited
5144 if (current_fds_to_close
)
5146 close_fd_bitmap (current_fds_to_close
);
5147 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
5150 #if defined (HAVE_DEV_FD)
5151 /* Make sure we close the parent's end of the pipe and clear the slot
5152 in the fd list so it is not closed later, if reallocated by, for
5153 instance, pipe(2). */
5154 close (parent_pipe_fd
);
5155 dev_fd_list
[parent_pipe_fd
] = 0;
5156 #endif /* HAVE_DEV_FD */
5158 /* subshells shouldn't have this flag, which controls using the temporary
5159 environment for variable lookups. */
5160 expanding_redir
= 0;
5162 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
5164 #if !defined (HAVE_DEV_FD)
5165 /* Make sure we close the named pipe in the child before we exit. */
5166 close (open_for_read_in_child
? 0 : 1);
5167 #endif /* !HAVE_DEV_FD */
5169 last_command_exit_value
= result
;
5170 result
= run_exit_trap ();
5174 #endif /* PROCESS_SUBSTITUTION */
5176 /***********************************/
5178 /* Command Substitution */
5180 /***********************************/
5183 read_comsub (fd
, quoted
, rflag
)
5187 char *istring
, buf
[128], *bufp
, *s
;
5188 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
5191 istring
= (char *)NULL
;
5192 istring_index
= istring_size
= bufn
= tflag
= 0;
5194 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
5195 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
5197 /* Read the output of the command through the pipe. This may need to be
5198 changed to understand multibyte characters in the future. */
5205 bufn
= zread (fd
, buf
, sizeof (buf
));
5215 internal_warning ("read_comsub: ignored null byte in input");
5220 /* Add the character to ISTRING, possibly after resizing it. */
5221 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
5223 /* This is essentially quote_string inline */
5224 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
5225 istring
[istring_index
++] = CTLESC
;
5226 /* Escape CTLESC and CTLNUL in the output to protect those characters
5227 from the rest of the word expansions (word splitting and globbing.)
5228 This is essentially quote_escapes inline. */
5229 else if (skip_ctlesc
== 0 && c
== CTLESC
)
5231 tflag
|= W_HASCTLESC
;
5232 istring
[istring_index
++] = CTLESC
;
5234 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
5235 istring
[istring_index
++] = CTLESC
;
5237 istring
[istring_index
++] = c
;
5240 #if defined (__CYGWIN__)
5241 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
5244 istring
[istring_index
- 1] = '\n';
5251 istring
[istring_index
] = '\0';
5253 /* If we read no output, just return now and save ourselves some
5255 if (istring_index
== 0)
5260 return (char *)NULL
;
5263 /* Strip trailing newlines from the output of the command. */
5264 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5266 while (istring_index
> 0)
5268 if (istring
[istring_index
- 1] == '\n')
5272 /* If the newline was quoted, remove the quoting char. */
5273 if (istring
[istring_index
- 1] == CTLESC
)
5279 istring
[istring_index
] = '\0';
5282 strip_trailing (istring
, istring_index
- 1, 1);
5289 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5290 contained string possibly quoted. */
5292 command_substitute (string
, quoted
)
5296 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
5298 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
5301 istring
= (char *)NULL
;
5303 /* Don't fork () if there is no need to. In the case of no command to
5304 run, just return NULL. */
5305 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5306 return ((WORD_DESC
*)NULL
);
5308 if (wordexp_only
&& read_but_dont_execute
)
5310 last_command_exit_value
= EX_WEXPCOMSUB
;
5311 jump_to_top_level (EXITPROG
);
5314 /* We're making the assumption here that the command substitution will
5315 eventually run a command from the file system. Since we'll run
5316 maybe_make_export_env in this subshell before executing that command,
5317 the parent shell and any other shells it starts will have to remake
5318 the environment. If we make it before we fork, other shells won't
5319 have to. Don't bother if we have any temporary variable assignments,
5320 though, because the export environment will be remade after this
5321 command completes anyway, but do it if all the words to be expanded
5322 are variable assignments. */
5323 if (subst_assign_varlist
== 0 || garglist
== 0)
5324 maybe_make_export_env (); /* XXX */
5326 /* Flags to pass to parse_and_execute() */
5327 pflags
= (interactive
&& sourcelevel
== 0) ? SEVAL_RESETLINE
: 0;
5329 /* Pipe the output of executing STRING into the current shell. */
5330 if (pipe (fildes
) < 0)
5332 sys_error (_("cannot make pipe for command substitution"));
5336 old_pid
= last_made_pid
;
5337 #if defined (JOB_CONTROL)
5338 old_pipeline_pgrp
= pipeline_pgrp
;
5339 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5340 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5341 pipeline_pgrp
= shell_pgrp
;
5342 cleanup_the_pipeline ();
5343 #endif /* JOB_CONTROL */
5345 old_async_pid
= last_asynchronous_pid
;
5346 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5347 last_asynchronous_pid
= old_async_pid
;
5351 /* Reset the signal handlers in the child, but don't free the
5352 trap strings. Set a flag noting that we have to free the
5353 trap strings if we run trap to change a signal disposition. */
5354 reset_signal_handlers ();
5355 subshell_environment
|= SUBSHELL_RESETTRAP
;
5358 #if defined (JOB_CONTROL)
5359 /* XXX DO THIS ONLY IN PARENT ? XXX */
5360 set_sigchld_handler ();
5361 stop_making_children ();
5363 pipeline_pgrp
= old_pipeline_pgrp
;
5365 stop_making_children ();
5366 #endif /* JOB_CONTROL */
5370 sys_error (_("cannot make child for command substitution"));
5373 last_made_pid
= old_pid
;
5378 return ((WORD_DESC
*)NULL
);
5383 set_sigint_handler (); /* XXX */
5385 free_pushed_string_input ();
5387 if (dup2 (fildes
[1], 1) < 0)
5389 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5390 exit (EXECUTION_FAILURE
);
5393 /* If standard output is closed in the parent shell
5394 (such as after `exec >&-'), file descriptor 1 will be
5395 the lowest available file descriptor, and end up in
5396 fildes[0]. This can happen for stdin and stderr as well,
5397 but stdout is more important -- it will cause no output
5398 to be generated from this command. */
5399 if ((fildes
[1] != fileno (stdin
)) &&
5400 (fildes
[1] != fileno (stdout
)) &&
5401 (fildes
[1] != fileno (stderr
)))
5404 if ((fildes
[0] != fileno (stdin
)) &&
5405 (fildes
[0] != fileno (stdout
)) &&
5406 (fildes
[0] != fileno (stderr
)))
5410 /* Let stdio know the fd may have changed from text to binary mode, and
5411 make sure to preserve stdout line buffering. */
5412 freopen (NULL
, "w", stdout
);
5413 sh_setlinebuf (stdout
);
5414 #endif /* __CYGWIN__ */
5416 /* The currently executing shell is not interactive. */
5419 /* This is a subshell environment. */
5420 subshell_environment
|= SUBSHELL_COMSUB
;
5422 /* When not in POSIX mode, command substitution does not inherit
5424 if (posixly_correct
== 0)
5426 builtin_ignoring_errexit
= 0;
5427 change_flag ('e', FLAG_OFF
);
5431 remove_quoted_escapes (string
);
5433 startup_state
= 2; /* see if we can avoid a fork */
5434 /* Give command substitution a place to jump back to on failure,
5435 so we don't go back up to main (). */
5436 result
= setjmp_nosigs (top_level
);
5438 /* If we're running a command substitution inside a shell function,
5439 trap `return' so we don't return from the function in the subshell
5440 and go off to never-never land. */
5441 if (result
== 0 && return_catch_flag
)
5442 function_value
= setjmp_nosigs (return_catch
);
5446 if (result
== ERREXIT
)
5447 rc
= last_command_exit_value
;
5448 else if (result
== EXITPROG
)
5449 rc
= last_command_exit_value
;
5451 rc
= EXECUTION_FAILURE
;
5452 else if (function_value
)
5453 rc
= return_catch_value
;
5457 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5461 last_command_exit_value
= rc
;
5462 rc
= run_exit_trap ();
5463 #if defined (PROCESS_SUBSTITUTION)
5464 unlink_fifo_list ();
5470 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5472 #endif /* JOB_CONTROL && PGRP_PIPE */
5477 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5481 current_command_subst_pid
= pid
;
5482 last_command_exit_value
= wait_for (pid
);
5483 last_command_subst_pid
= pid
;
5484 last_made_pid
= old_pid
;
5486 #if defined (JOB_CONTROL)
5487 /* If last_command_exit_value > 128, then the substituted command
5488 was terminated by a signal. If that signal was SIGINT, then send
5489 SIGINT to ourselves. This will break out of loops, for instance. */
5490 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5491 kill (getpid (), SIGINT
);
5493 /* wait_for gives the terminal back to shell_pgrp. If some other
5494 process group should have it, give it away to that group here.
5495 pipeline_pgrp is non-zero only while we are constructing a
5496 pipline, so what we are concerned about is whether or not that
5497 pipeline was started in the background. A pipeline started in
5498 the background should never get the tty back here. */
5499 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5500 give_terminal_to (pipeline_pgrp
, 0);
5501 #endif /* JOB_CONTROL */
5503 ret
= alloc_word_desc ();
5504 ret
->word
= istring
;
5511 /********************************************************
5513 * Utility functions for parameter expansion *
5515 ********************************************************/
5517 #if defined (ARRAY_VARS)
5520 array_length_reference (s
)
5531 var
= array_variable_part (s
, &t
, &len
);
5533 /* If unbound variables should generate an error, report one and return
5535 if ((var
== 0 || invisible_p (var
) || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5539 last_command_exit_value
= EXECUTION_FAILURE
;
5544 else if (var
== 0 || invisible_p (var
))
5547 /* We support a couple of expansions for variables that are not arrays.
5548 We'll return the length of the value for v[0], and 1 for v[@] or
5549 v[*]. Return 0 for everything else. */
5551 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5552 h
= assoc_p (var
) ? assoc_cell (var
) : (HASH_TABLE
*)NULL
;
5554 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5557 return (h
? assoc_num_elements (h
) : 0);
5558 else if (array_p (var
))
5559 return (array
? array_num_elements (array
) : 0);
5561 return (var_isset (var
) ? 1 : 0);
5567 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5569 if (akey
== 0 || *akey
== 0)
5571 err_badarraysub (t
);
5575 t
= assoc_reference (assoc_cell (var
), akey
);
5580 ind
= array_expand_index (var
, t
, len
);
5581 /* negative subscripts to indexed arrays count back from end */
5582 if (var
&& array_p (var
) && ind
< 0)
5583 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
5586 err_badarraysub (t
);
5590 t
= array_reference (array
, ind
);
5592 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5595 len
= MB_STRLEN (t
);
5598 #endif /* ARRAY_VARS */
5601 valid_brace_expansion_word (name
, var_is_special
)
5605 if (DIGIT (*name
) && all_digits (name
))
5607 else if (var_is_special
)
5609 #if defined (ARRAY_VARS)
5610 else if (valid_array_reference (name
))
5612 #endif /* ARRAY_VARS */
5613 else if (legal_identifier (name
))
5620 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5623 int *quoted_dollar_atp
, *contains_dollar_at
;
5629 if (quoted_dollar_atp
)
5630 *quoted_dollar_atp
= 0;
5631 if (contains_dollar_at
)
5632 *contains_dollar_at
= 0;
5636 /* check for $@ and $* */
5637 if (name
[0] == '@' && name
[1] == 0)
5639 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5640 *quoted_dollar_atp
= 1;
5641 if (contains_dollar_at
)
5642 *contains_dollar_at
= 1;
5645 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5647 if (contains_dollar_at
)
5648 *contains_dollar_at
= 1;
5652 /* Now check for ${array[@]} and ${array[*]} */
5653 #if defined (ARRAY_VARS)
5654 else if (valid_array_reference (name
))
5656 temp1
= mbschr (name
, '[');
5657 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5659 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5660 *quoted_dollar_atp
= 1;
5661 if (contains_dollar_at
)
5662 *contains_dollar_at
= 1;
5665 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5666 which should result in separate words even when IFS is unset. */
5667 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5669 if (contains_dollar_at
)
5670 *contains_dollar_at
= 1;
5678 /* Parameter expand NAME, and return a new string which is the expansion,
5679 or NULL if there was no expansion.
5680 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5681 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5682 NAME was found inside of a double-quoted expression. */
5684 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
, indp
)
5686 int var_is_special
, quoted
, pflags
;
5703 /* Handle multiple digit arguments, as in ${11}. */
5704 if (legal_number (name
, &arg_index
))
5706 tt
= get_dollar_var_value (arg_index
);
5708 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5710 : quote_escapes (tt
);
5712 temp
= (char *)NULL
;
5715 else if (var_is_special
) /* ${@} */
5718 tt
= (char *)xmalloc (2 + strlen (name
));
5719 tt
[sindex
= 0] = '$';
5720 strcpy (tt
+ 1, name
);
5722 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5723 (int *)NULL
, (int *)NULL
, pflags
);
5726 #if defined (ARRAY_VARS)
5727 else if (valid_array_reference (name
))
5730 /* XXX - does this leak if name[@] or name[*]? */
5731 if (pflags
& PF_ASSIGNRHS
)
5733 temp
= array_variable_name (name
, &tt
, (int *)0);
5734 if (ALL_ELEMENT_SUB (tt
[0]) && tt
[1] == ']')
5735 temp
= array_value (name
, quoted
|Q_DOUBLE_QUOTES
, 0, &atype
, &ind
);
5737 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5740 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5741 if (atype
== 0 && temp
)
5743 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5744 ? quote_string (temp
)
5745 : quote_escapes (temp
);
5746 rflags
|= W_ARRAYIND
;
5750 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5751 rflags
|= W_HASQUOTEDNULL
;
5754 else if (var
= find_variable (name
))
5756 if (var_isset (var
) && invisible_p (var
) == 0)
5758 #if defined (ARRAY_VARS)
5760 temp
= assoc_reference (assoc_cell (var
), "0");
5761 else if (array_p (var
))
5762 temp
= array_reference (array_cell (var
), 0);
5764 temp
= value_cell (var
);
5766 temp
= value_cell (var
);
5770 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5771 ? quote_string (temp
)
5772 : quote_escapes (temp
);
5775 temp
= (char *)NULL
;
5777 else if (var
= find_variable_last_nameref (name
))
5779 temp
= nameref_cell (var
);
5780 #if defined (ARRAY_VARS)
5781 /* Handle expanding nameref whose value is x[n] */
5782 if (temp
&& *temp
&& valid_array_reference (temp
))
5785 goto expand_arrayref
;
5789 /* y=2 ; typeset -n x=y; echo ${x} is not the same as echo ${2} in ksh */
5790 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
5792 last_command_exit_value
= EXECUTION_FAILURE
;
5793 report_error (_("%s: invalid variable name for name reference"), temp
);
5794 temp
= &expand_param_error
;
5797 temp
= (char *)NULL
;
5800 temp
= (char *)NULL
;
5804 ret
= alloc_word_desc ();
5806 ret
->flags
|= rflags
;
5812 parameter_brace_find_indir (name
, var_is_special
, quoted
, find_nameref
)
5814 int var_is_special
, quoted
, find_nameref
;
5820 if (find_nameref
&& var_is_special
== 0 && (v
= find_variable_last_nameref (name
)) &&
5821 nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
5822 return (savestring (t
));
5824 /* If var_is_special == 0, and name is not an array reference, this does
5825 more expansion than necessary. It should really look up the variable's
5826 value and not try to expand it. */
5827 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
, 0);
5829 /* Have to dequote here if necessary */
5832 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5833 ? dequote_string (t
)
5834 : dequote_escapes (t
);
5838 dispose_word_desc (w
);
5843 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5844 value of the variable whose name is the value of NAME. */
5846 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5848 int var_is_special
, quoted
;
5849 int *quoted_dollar_atp
, *contains_dollar_at
;
5855 /* See if it's a nameref first, behave in ksh93-compatible fashion.
5856 There is at least one incompatibility: given ${!foo[0]} where foo=bar,
5857 bash performs an indirect lookup on foo[0] and expands the result;
5858 ksh93 expands bar[0]. We could do that here -- there are enough usable
5859 primitives to do that -- but do not at this point. */
5860 if (var_is_special
== 0 && (v
= find_variable_last_nameref (name
)))
5862 if (nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
5864 w
= alloc_word_desc ();
5865 w
->word
= savestring (t
);
5871 t
= parameter_brace_find_indir (name
, var_is_special
, quoted
, 0);
5873 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5875 return (WORD_DESC
*)NULL
;
5877 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0, 0);
5883 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5884 depending on the value of C, the separating character. C can be one of
5885 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5886 between double quotes. */
5888 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5890 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5894 char *t
, *t1
, *temp
;
5897 /* If the entire expression is between double quotes, we want to treat
5898 the value as a double-quoted string, with the exception that we strip
5899 embedded unescaped double quotes (for sh backwards compatibility). */
5900 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5903 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5908 w
= alloc_word_desc ();
5910 /* XXX was 0 not quoted */
5911 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5914 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5919 /* The expansion of TEMP returned something. We need to treat things
5920 slightly differently if HASDOL is non-zero. If we have "$@", the
5921 individual words have already been quoted. We need to turn them
5922 into a string with the words separated by the first character of
5923 $IFS without any additional quoting, so string_list_dollar_at won't
5924 do the right thing. We use string_list_dollar_star instead. */
5925 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5927 /* If l->next is not null, we know that TEMP contained "$@", since that
5928 is the only expansion that creates more than one word. */
5929 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5931 /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
5932 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
5933 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
5934 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5935 (which is more paranoia than anything else), we need to return the
5936 quoted null string and set the flags to indicate it. */
5937 if (l
->next
== 0 && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
) && QUOTED_NULL (l
->word
->word
) && (l
->word
->flags
& W_HASQUOTEDNULL
))
5939 w
->flags
|= W_HASQUOTEDNULL
;
5943 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5945 /* The brace expansion occurred between double quotes and there was
5946 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5947 it does not expand to anything. In this case, we want to return
5948 a quoted empty string. */
5949 temp
= make_quoted_char ('\0');
5950 w
->flags
|= W_HASQUOTEDNULL
;
5953 temp
= (char *)NULL
;
5955 if (c
== '-' || c
== '+')
5962 t
= temp
? savestring (temp
) : savestring ("");
5963 t1
= dequote_string (t
);
5965 #if defined (ARRAY_VARS)
5966 if (valid_array_reference (name
))
5967 assign_array_element (name
, t1
, 0);
5969 #endif /* ARRAY_VARS */
5970 bind_variable (name
, t1
, 0);
5972 if (STREQ (name
, "IFS") == 0)
5974 stupidly_hack_special_variables (name
);
5976 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5983 /* Deal with the right hand side of a ${name:?value} expansion in the case
5984 that NAME is null or not set. If VALUE is non-null it is expanded and
5985 used as the error message to print, otherwise a standard message is
5988 parameter_brace_expand_error (name
, value
)
5994 last_command_exit_value
= EXECUTION_FAILURE
; /* ensure it's non-zero */
5995 if (value
&& *value
)
5997 l
= expand_string (value
, 0);
5998 temp
= string_list (l
);
5999 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
6004 report_error (_("%s: parameter null or not set"), name
);
6006 /* Free the data we have allocated during this expansion, since we
6007 are about to longjmp out. */
6012 /* Return 1 if NAME is something for which parameter_brace_expand_length is
6015 valid_length_expression (name
)
6018 return (name
[1] == '\0' || /* ${#} */
6019 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
6020 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
6021 #if defined (ARRAY_VARS)
6022 valid_array_reference (name
+ 1) || /* ${#a[7]} */
6024 legal_identifier (name
+ 1)); /* ${#PS1} */
6027 /* Handle the parameter brace expansion that requires us to return the
6028 length of a parameter. */
6030 parameter_brace_expand_length (name
)
6034 intmax_t number
, arg_index
;
6036 #if defined (ARRAY_VARS)
6040 if (name
[1] == '\0') /* ${#} */
6041 number
= number_of_args ();
6042 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
6043 number
= number_of_args ();
6044 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
6046 /* Take the lengths of some of the shell's special parameters. */
6050 t
= which_set_flags ();
6053 t
= itos (last_command_exit_value
);
6056 t
= itos (dollar_dollar_pid
);
6059 if (last_asynchronous_pid
== NO_PID
)
6060 t
= (char *)NULL
; /* XXX - error if set -u set? */
6062 t
= itos (last_asynchronous_pid
);
6065 t
= itos (number_of_args ());
6068 number
= STRLEN (t
);
6071 #if defined (ARRAY_VARS)
6072 else if (valid_array_reference (name
+ 1))
6073 number
= array_length_reference (name
+ 1);
6074 #endif /* ARRAY_VARS */
6079 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
6081 t
= get_dollar_var_value (arg_index
);
6082 if (t
== 0 && unbound_vars_is_error
)
6084 number
= MB_STRLEN (t
);
6087 #if defined (ARRAY_VARS)
6088 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
6091 t
= assoc_reference (assoc_cell (var
), "0");
6093 t
= array_reference (array_cell (var
), 0);
6094 if (t
== 0 && unbound_vars_is_error
)
6096 number
= MB_STRLEN (t
);
6101 newname
= savestring (name
);
6103 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
6104 t
= list
? string_list (list
) : (char *)NULL
;
6107 dispose_words (list
);
6109 number
= t
? MB_STRLEN (t
) : 0;
6117 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
6118 so we do some ad-hoc parsing of an arithmetic expression to find
6119 the first DELIM, instead of using strchr(3). Two rules:
6120 1. If the substring contains a `(', read until closing `)'.
6121 2. If the substring contains a `?', read past one `:' for each `?'.
6125 skiparith (substr
, delim
)
6130 int skipcol
, pcount
, i
;
6133 sublen
= strlen (substr
);
6134 i
= skipcol
= pcount
= 0;
6137 /* Balance parens */
6138 if (substr
[i
] == LPAREN
)
6144 if (substr
[i
] == RPAREN
&& pcount
)
6152 ADVANCE_CHAR (substr
, sublen
, i
);
6156 /* Skip one `:' for each `?' */
6157 if (substr
[i
] == ':' && skipcol
)
6163 if (substr
[i
] == delim
)
6165 if (substr
[i
] == '?')
6171 ADVANCE_CHAR (substr
, sublen
, i
);
6174 return (substr
+ i
);
6177 /* Verify and limit the start and end of the desired substring. If
6178 VTYPE == 0, a regular shell variable is being used; if it is 1,
6179 then the positional parameters are being used; if it is 2, then
6180 VALUE is really a pointer to an array variable that should be used.
6181 Return value is 1 if both values were OK, 0 if there was a problem
6182 with an invalid expression, or -1 if the values were out of range. */
6184 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
6186 char *value
, *substr
;
6188 intmax_t *e1p
, *e2p
;
6190 char *t
, *temp1
, *temp2
;
6193 #if defined (ARRAY_VARS)
6198 /* duplicate behavior of strchr(3) */
6199 t
= skiparith (substr
, ':');
6200 if (*t
&& *t
== ':')
6205 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
6206 *e1p
= evalexp (temp1
, &expok
);
6211 len
= -1; /* paranoia */
6215 case VT_ARRAYMEMBER
:
6216 len
= MB_STRLEN (value
);
6219 len
= number_of_args () + 1;
6221 len
++; /* add one arg if counting from $0 */
6223 #if defined (ARRAY_VARS)
6225 /* For arrays, the first value deals with array indices. Negative
6226 offsets count from one past the array's maximum index. Associative
6227 arrays treat the number of elements as the maximum index. */
6231 len
= assoc_num_elements (h
) + (*e1p
< 0);
6236 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
6242 if (len
== -1) /* paranoia */
6245 if (*e1p
< 0) /* negative offsets count from end */
6248 if (*e1p
> len
|| *e1p
< 0)
6251 #if defined (ARRAY_VARS)
6252 /* For arrays, the second offset deals with the number of elements. */
6253 if (vtype
== VT_ARRAYVAR
)
6254 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
6260 temp2
= savestring (t
);
6261 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6264 *e2p
= evalexp (temp1
, &expok
);
6269 if ((vtype
== VT_ARRAYVAR
|| vtype
== VT_POSPARMS
) && *e2p
< 0)
6271 /* bash-4.3: allow positional parameter length < 0 to count backwards
6272 from end of positional parameters */
6273 if (vtype
== VT_ARRAYVAR
&& *e2p
< 0)
6276 internal_error (_("%s: substring expression < 0"), t
);
6279 #if defined (ARRAY_VARS)
6280 /* In order to deal with sparse arrays, push the intelligence about how
6281 to deal with the number of elements desired down to the array-
6282 specific functions. */
6283 if (vtype
!= VT_ARRAYVAR
)
6289 if (*e2p
< 0 || *e2p
< *e1p
)
6291 internal_error (_("%s: substring expression < 0"), t
);
6296 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
6307 /* Return the type of variable specified by VARNAME (simple variable,
6308 positional param, or array variable). Also return the value specified
6309 by VARNAME (value of a variable or a reference to an array element).
6310 QUOTED is the standard description of quoting state, using Q_* defines.
6311 FLAGS is currently a set of flags to pass to array_value. If IND is
6312 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6313 passed to array_value so the array index is not computed again.
6314 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6315 characters in the value are quoted with CTLESC and takes appropriate
6316 steps. For convenience, *VALP is set to the dequoted VALUE. */
6318 get_var_and_type (varname
, value
, ind
, quoted
, flags
, varp
, valp
)
6319 char *varname
, *value
;
6325 int vtype
, want_indir
;
6328 #if defined (ARRAY_VARS)
6333 want_indir
= *varname
== '!' &&
6334 (legal_variable_starter ((unsigned char)varname
[1]) || DIGIT (varname
[1])
6335 || VALID_INDIR_PARAM (varname
[1]));
6337 vname
= parameter_brace_find_indir (varname
+1, SPECIAL_VAR (varname
, 1), quoted
, 1);
6341 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6342 vtype
= (vname
[0] == '@' || vname
[0] == '*') && vname
[1] == '\0';
6343 if (vtype
== VT_POSPARMS
&& vname
[0] == '*')
6344 vtype
|= VT_STARSUB
;
6345 *varp
= (SHELL_VAR
*)NULL
;
6347 #if defined (ARRAY_VARS)
6348 if (valid_array_reference (vname
))
6350 v
= array_variable_part (vname
, &temp
, (int *)0);
6351 /* If we want to signal array_value to use an already-computed index,
6352 set LIND to that index */
6353 lind
= (ind
!= INTMAX_MIN
&& (flags
& AV_USEIND
)) ? ind
: 0;
6354 if (v
&& invisible_p (v
))
6356 vtype
= VT_ARRAYMEMBER
;
6357 *varp
= (SHELL_VAR
*)NULL
;
6358 *valp
= (char *)NULL
;
6360 if (v
&& (array_p (v
) || assoc_p (v
)))
6362 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
6364 /* Callers have to differentiate betwen indexed and associative */
6365 vtype
= VT_ARRAYVAR
;
6367 vtype
|= VT_STARSUB
;
6368 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
6372 vtype
= VT_ARRAYMEMBER
;
6373 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6377 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
6379 vtype
= VT_VARIABLE
;
6381 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6382 *valp
= dequote_string (value
);
6384 *valp
= dequote_escapes (value
);
6388 vtype
= VT_ARRAYMEMBER
;
6390 *valp
= array_value (vname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6393 else if ((v
= find_variable (vname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
6395 vtype
= VT_ARRAYMEMBER
;
6397 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
6402 if (value
&& vtype
== VT_VARIABLE
)
6404 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6405 *valp
= dequote_string (value
);
6407 *valp
= dequote_escapes (value
);
6419 /******************************************************/
6421 /* Functions to extract substrings of variable values */
6423 /******************************************************/
6425 #if defined (HANDLE_MULTIBYTE)
6426 /* Character-oriented rather than strictly byte-oriented substrings. S and
6427 E, rather being strict indices into STRING, indicate character (possibly
6428 multibyte character) positions that require calculation.
6429 Used by the ${param:offset[:length]} expansion. */
6431 mb_substring (string
, s
, e
)
6436 int start
, stop
, i
, slen
;
6440 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6441 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6444 while (string
[start
] && i
--)
6445 ADVANCE_CHAR (string
, slen
, start
);
6448 while (string
[stop
] && i
--)
6449 ADVANCE_CHAR (string
, slen
, stop
);
6450 tt
= substring (string
, start
, stop
);
6455 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6456 is `@', use the positional parameters; otherwise, use the value of
6457 VARNAME. If VARNAME is an array variable, use the array elements. */
6460 parameter_brace_substring (varname
, value
, ind
, substr
, quoted
, flags
)
6461 char *varname
, *value
;
6467 int vtype
, r
, starsub
;
6468 char *temp
, *val
, *tt
, *oname
;
6472 return ((char *)NULL
);
6474 oname
= this_command_name
;
6475 this_command_name
= varname
;
6477 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6480 this_command_name
= oname
;
6481 return ((char *)NULL
);
6484 starsub
= vtype
& VT_STARSUB
;
6485 vtype
&= ~VT_STARSUB
;
6487 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6488 this_command_name
= oname
;
6491 if (vtype
== VT_VARIABLE
)
6493 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6499 case VT_ARRAYMEMBER
:
6500 #if defined (HANDLE_MULTIBYTE)
6502 tt
= mb_substring (val
, e1
, e2
);
6505 tt
= substring (val
, e1
, e2
);
6507 if (vtype
== VT_VARIABLE
)
6509 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6510 temp
= quote_string (tt
);
6512 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6516 tt
= pos_params (varname
, e1
, e2
, quoted
);
6517 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6519 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6525 #if defined (ARRAY_VARS)
6528 /* we convert to list and take first e2 elements starting at e1th
6529 element -- officially undefined for now */
6530 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6532 /* We want E2 to be the number of elements desired (arrays can be sparse,
6533 so verify_substring_values just returns the numbers specified and we
6534 rely on array_subrange to understand how to deal with them). */
6535 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6536 /* array_subrange now calls array_quote_escapes as appropriate, so the
6537 caller no longer needs to. */
6541 temp
= (char *)NULL
;
6547 /****************************************************************/
6549 /* Functions to perform pattern substitution on variable values */
6551 /****************************************************************/
6554 shouldexp_replacement (s
)
6559 for (p
= s
; p
&& *p
; p
++)
6570 pat_subst (string
, pat
, rep
, mflags
)
6571 char *string
, *pat
, *rep
;
6574 char *ret
, *s
, *e
, *str
, *rstr
, *mstr
;
6575 int rsize
, rptr
, l
, replen
, mtype
, rxpand
, rslen
, mlen
;
6578 return (savestring (""));
6580 mtype
= mflags
& MATCH_TYPEMASK
;
6582 #if 0 /* bash-4.2 ? */
6583 rxpand
= (rep
&& *rep
) ? shouldexp_replacement (rep
) : 0;
6589 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6590 * with REP and return the result.
6591 * 2. A null pattern with mtype == MATCH_END means to append REP to
6592 * STRING and return the result.
6593 * These don't understand or process `&' in the replacement string.
6595 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
6597 replen
= STRLEN (rep
);
6598 l
= STRLEN (string
);
6599 ret
= (char *)xmalloc (replen
+ l
+ 2);
6601 strcpy (ret
, string
);
6602 else if (mtype
== MATCH_BEG
)
6605 strcpy (ret
+ replen
, string
);
6609 strcpy (ret
, string
);
6610 strcpy (ret
+ l
, rep
);
6615 ret
= (char *)xmalloc (rsize
= 64);
6618 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6620 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6628 mstr
= xmalloc (mlen
+ 1);
6629 for (x
= 0; x
< mlen
; x
++)
6632 rstr
= strcreplace (rep
, '&', mstr
, 0);
6633 rslen
= strlen (rstr
);
6641 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ rslen
), rsize
, 64);
6643 /* OK, now copy the leading unmatched portion of the string (from
6644 str to s) to ret starting at rptr (the current offset). Then copy
6645 the replacement string at ret + rptr + (s - str). Increment
6646 rptr (if necessary) and str and go on. */
6649 strncpy (ret
+ rptr
, str
, l
);
6654 strncpy (ret
+ rptr
, rstr
, rslen
);
6657 str
= e
; /* e == end of match */
6662 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6667 /* On a zero-length match, make sure we copy one character, since
6668 we increment one character to avoid infinite recursion. */
6669 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6670 ret
[rptr
++] = *str
++;
6671 e
++; /* avoid infinite recursion on zero-length match */
6675 /* Now copy the unmatched portion of the input string */
6678 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6679 strcpy (ret
+ rptr
, str
);
6687 /* Do pattern match and replacement on the positional parameters. */
6689 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6690 char *string
, *pat
, *rep
;
6693 WORD_LIST
*save
, *params
;
6698 save
= params
= list_rest_of_args ();
6700 return ((char *)NULL
);
6702 for ( ; params
; params
= params
->next
)
6704 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6705 w
= alloc_word_desc ();
6706 w
->word
= ret
? ret
: savestring ("");
6707 dispose_word (params
->word
);
6711 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6712 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6714 ret
= string_list_pos_params (pchar
, save
, qflags
);
6716 dispose_words (save
);
6721 /* Perform pattern substitution on VALUE, which is the expansion of
6722 VARNAME. PATSUB is an expression supplying the pattern to match
6723 and the string to substitute. QUOTED is a flags word containing
6724 the type of quoting currently in effect. */
6726 parameter_brace_patsub (varname
, value
, ind
, patsub
, quoted
, flags
)
6727 char *varname
, *value
;
6732 int vtype
, mflags
, starsub
, delim
;
6733 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6737 return ((char *)NULL
);
6739 this_command_name
= varname
;
6741 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6743 return ((char *)NULL
);
6745 starsub
= vtype
& VT_STARSUB
;
6746 vtype
&= ~VT_STARSUB
;
6749 /* PATSUB is never NULL when this is called. */
6752 mflags
|= MATCH_GLOBREP
;
6756 /* Malloc this because expand_string_if_necessary or one of the expansion
6757 functions in its call chain may free it on a substitution error. */
6758 lpatsub
= savestring (patsub
);
6760 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6761 mflags
|= MATCH_QUOTED
;
6764 mflags
|= MATCH_STARSUB
;
6766 /* If the pattern starts with a `/', make sure we skip over it when looking
6767 for the replacement delimiter. */
6768 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6769 if (lpatsub
[delim
] == '/')
6772 rep
= lpatsub
+ delim
+ 1;
6777 if (rep
&& *rep
== '\0')
6780 /* Perform the same expansions on the pattern as performed by the
6781 pattern removal expansions. */
6782 pat
= getpattern (lpatsub
, quoted
, 1);
6786 /* We want to perform quote removal on the expanded replacement even if
6787 the entire expansion is double-quoted because the parser and string
6788 extraction functions treated quotes in the replacement string as
6789 special. THIS IS NOT BACKWARDS COMPATIBLE WITH BASH-4.2. */
6790 if (shell_compatibility_level
> 42)
6791 rep
= expand_string_if_necessary (rep
, quoted
& ~(Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
), expand_string_unsplit
);
6792 /* This is the bash-4.2 code. */
6793 else if ((mflags
& MATCH_QUOTED
) == 0)
6794 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6796 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6799 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6800 pattern. This is an extension. Make sure we don't anchor the pattern
6801 at the beginning or end of the string if we're doing global replacement,
6804 if (mflags
& MATCH_GLOBREP
)
6805 mflags
|= MATCH_ANY
;
6806 else if (pat
&& pat
[0] == '#')
6808 mflags
|= MATCH_BEG
;
6811 else if (pat
&& pat
[0] == '%')
6813 mflags
|= MATCH_END
;
6817 mflags
|= MATCH_ANY
;
6819 /* OK, we now want to substitute REP for PAT in VAL. If
6820 flags & MATCH_GLOBREP is non-zero, the substitution is done
6821 everywhere, otherwise only the first occurrence of PAT is
6822 replaced. The pattern matching code doesn't understand
6823 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6824 values passed in (VT_VARIABLE) so the pattern substitution
6825 code works right. We need to requote special chars after
6826 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6827 other cases if QUOTED == 0, since the posparams and arrays
6828 indexed by * or @ do special things when QUOTED != 0. */
6833 case VT_ARRAYMEMBER
:
6834 temp
= pat_subst (val
, p
, rep
, mflags
);
6835 if (vtype
== VT_VARIABLE
)
6839 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6845 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6846 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6848 tt
= quote_escapes (temp
);
6853 #if defined (ARRAY_VARS)
6855 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6856 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6857 /* Don't call quote_escapes anymore; array_patsub calls
6858 array_quote_escapes as appropriate before adding the
6859 space separators; ditto for assoc_patsub. */
6871 /****************************************************************/
6873 /* Functions to perform case modification on variable values */
6875 /****************************************************************/
6877 /* Do case modification on the positional parameters. */
6880 pos_params_modcase (string
, pat
, modop
, mflags
)
6885 WORD_LIST
*save
, *params
;
6890 save
= params
= list_rest_of_args ();
6892 return ((char *)NULL
);
6894 for ( ; params
; params
= params
->next
)
6896 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6897 w
= alloc_word_desc ();
6898 w
->word
= ret
? ret
: savestring ("");
6899 dispose_word (params
->word
);
6903 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6904 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6906 ret
= string_list_pos_params (pchar
, save
, qflags
);
6907 dispose_words (save
);
6912 /* Perform case modification on VALUE, which is the expansion of
6913 VARNAME. MODSPEC is an expression supplying the type of modification
6914 to perform. QUOTED is a flags word containing the type of quoting
6915 currently in effect. */
6917 parameter_brace_casemod (varname
, value
, ind
, modspec
, patspec
, quoted
, flags
)
6918 char *varname
, *value
;
6923 int vtype
, starsub
, modop
, mflags
, x
;
6924 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6928 return ((char *)NULL
);
6930 this_command_name
= varname
;
6932 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6934 return ((char *)NULL
);
6936 starsub
= vtype
& VT_STARSUB
;
6937 vtype
&= ~VT_STARSUB
;
6941 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6942 mflags
|= MATCH_QUOTED
;
6944 mflags
|= MATCH_STARSUB
;
6949 x
= p
&& p
[0] == modspec
;
6950 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6953 else if (modspec
== ',')
6955 x
= p
&& p
[0] == modspec
;
6956 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6959 else if (modspec
== '~')
6961 x
= p
&& p
[0] == modspec
;
6962 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6966 lpat
= p
? savestring (p
) : 0;
6967 /* Perform the same expansions on the pattern as performed by the
6968 pattern removal expansions. FOR LATER */
6969 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6971 /* OK, now we do the case modification. */
6975 case VT_ARRAYMEMBER
:
6976 temp
= sh_modcase (val
, pat
, modop
);
6977 if (vtype
== VT_VARIABLE
)
6981 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6988 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6989 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6991 tt
= quote_escapes (temp
);
6997 #if defined (ARRAY_VARS)
6999 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
7000 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
7001 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
7002 as appropriate before adding the space separators; ditto for
7014 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
7015 any occur, this must be a nested command substitution, so return 0.
7016 Otherwise, return 1. A valid arithmetic expression must always have a
7017 ( before a matching ), so any cases where there are more right parens
7018 means that this must not be an arithmetic expression, though the parser
7019 will not accept it without a balanced total number of parens. */
7021 chk_arithsub (s
, len
)
7033 else if (s
[i
] == RPAREN
)
7043 ADVANCE_CHAR (s
, len
, i
);
7049 ADVANCE_CHAR (s
, len
, i
);
7053 i
= skip_single_quoted (s
, len
, ++i
);
7057 i
= skip_double_quoted ((char *)s
, len
, ++i
);
7062 return (count
== 0);
7065 /****************************************************************/
7067 /* Functions to perform parameter expansion on a string */
7069 /****************************************************************/
7071 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
7073 parameter_brace_expand (string
, indexp
, quoted
, pflags
, quoted_dollar_atp
, contains_dollar_at
)
7075 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
, pflags
;
7077 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
7078 int want_substring
, want_indir
, want_patsub
, want_casemod
;
7079 char *name
, *value
, *temp
, *temp1
;
7080 WORD_DESC
*tdesc
, *ret
;
7081 int t_index
, sindex
, c
, tflag
, modspec
;
7085 temp
= temp1
= value
= (char *)NULL
;
7086 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
7087 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
7091 /* ${#var} doesn't have any of the other parameter expansions on it. */
7092 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
7093 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
7095 #if defined (CASEMOD_EXPANSIONS)
7096 /* To enable case-toggling expansions using the `~' operator character
7097 change the 1 to 0. */
7098 # if defined (CASEMOD_CAPCASE)
7099 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
7101 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
7102 # endif /* CASEMOD_CAPCASE */
7104 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
7105 #endif /* CASEMOD_EXPANSIONS */
7112 /* If the name really consists of a special variable, then make sure
7113 that we have the entire name. We don't allow indirect references
7114 to special variables except `#', `?', `@' and `*'. */
7115 if ((sindex
== t_index
&& VALID_SPECIAL_LENGTH_PARAM (string
[t_index
])) ||
7116 (sindex
== t_index
- 1 && string
[sindex
] == '!' && VALID_INDIR_PARAM (string
[t_index
])))
7119 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
7120 name
= (char *)xrealloc (name
, 3 + (strlen (temp1
)));
7121 *name
= string
[sindex
];
7122 if (string
[sindex
] == '!')
7124 /* indirect reference of $#, $?, $@, or $* */
7125 name
[1] = string
[sindex
+ 1];
7126 strcpy (name
+ 2, temp1
);
7129 strcpy (name
+ 1, temp1
);
7134 /* Find out what character ended the variable name. Then
7135 do the appropriate thing. */
7136 if (c
= string
[sindex
])
7139 /* If c is followed by one of the valid parameter expansion
7140 characters, move past it as normal. If not, assume that
7141 a substring specification is being given, and do not move
7143 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
7146 if (c
= string
[sindex
])
7149 else if (c
== ':' && string
[sindex
] != RBRACE
)
7151 else if (c
== '/' /* && string[sindex] != RBRACE */) /* XXX */
7153 #if defined (CASEMOD_EXPANSIONS)
7154 else if (c
== '^' || c
== ',' || c
== '~')
7161 /* Catch the valid and invalid brace expressions that made it through the
7163 /* ${#-} is a valid expansion and means to take the length of $-.
7164 Similarly for ${#?} and ${##}... */
7165 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7166 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
7168 name
= (char *)xrealloc (name
, 3);
7171 c
= string
[sindex
++];
7174 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7175 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7176 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
7178 temp
= (char *)NULL
;
7179 goto bad_substitution
;
7182 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7183 either a variable name, one of the positional parameters or a special
7184 variable that expands to one of the positional parameters. */
7185 want_indir
= *name
== '!' &&
7186 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
7187 || VALID_INDIR_PARAM (name
[1]));
7189 /* Determine the value of this variable. */
7191 /* Check for special variables, directly referenced. */
7192 if (SPECIAL_VAR (name
, want_indir
))
7195 /* Check for special expansion things, like the length of a parameter */
7196 if (*name
== '#' && name
[1])
7198 /* If we are not pointing at the character just after the
7199 closing brace, then we haven't gotten all of the name.
7200 Since it begins with a special character, this is a bad
7201 substitution. Also check NAME for validity before trying
7203 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
7205 temp
= (char *)NULL
;
7206 goto bad_substitution
;
7209 number
= parameter_brace_expand_length (name
);
7210 if (number
== INTMAX_MIN
&& unbound_vars_is_error
)
7212 last_command_exit_value
= EXECUTION_FAILURE
;
7213 err_unboundvar (name
+1);
7215 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7221 return (&expand_wdesc_error
);
7224 ret
= alloc_word_desc ();
7225 ret
->word
= itos (number
);
7230 /* ${@} is identical to $@. */
7231 if (name
[0] == '@' && name
[1] == '\0')
7233 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7234 *quoted_dollar_atp
= 1;
7236 if (contains_dollar_at
)
7237 *contains_dollar_at
= 1;
7239 tflag
|= W_DOLLARAT
;
7242 /* Process ${!PREFIX*} expansion. */
7243 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7244 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
7245 legal_variable_starter ((unsigned char) name
[1]))
7250 temp1
= savestring (name
+ 1);
7251 number
= strlen (temp1
);
7252 temp1
[number
- 1] = '\0';
7253 x
= all_variables_matching_prefix (temp1
);
7254 xlist
= strvec_to_word_list (x
, 0, 0);
7255 if (string
[sindex
- 2] == '*')
7256 temp
= string_list_dollar_star (xlist
);
7259 temp
= string_list_dollar_at (xlist
, quoted
);
7260 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7261 *quoted_dollar_atp
= 1;
7262 if (contains_dollar_at
)
7263 *contains_dollar_at
= 1;
7265 tflag
|= W_DOLLARAT
;
7268 dispose_words (xlist
);
7274 ret
= alloc_word_desc ();
7276 ret
->flags
= tflag
; /* XXX */
7280 #if defined (ARRAY_VARS)
7281 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7282 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7283 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
7287 temp1
= savestring (name
+ 1);
7288 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
7290 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
7292 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
7295 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7296 *quoted_dollar_atp
= 1;
7297 if (contains_dollar_at
)
7298 *contains_dollar_at
= 1;
7300 tflag
|= W_DOLLARAT
;
7306 ret
= alloc_word_desc ();
7308 ret
->flags
= tflag
; /* XXX */
7314 #endif /* ARRAY_VARS */
7316 /* Make sure that NAME is valid before trying to go on. */
7317 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
7318 var_is_special
) == 0)
7320 temp
= (char *)NULL
;
7321 goto bad_substitution
;
7325 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7327 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
|(pflags
&(PF_NOSPLIT2
|PF_ASSIGNRHS
)), &ind
);
7332 tflag
= tdesc
->flags
;
7333 dispose_word_desc (tdesc
);
7338 if (temp
== &expand_param_error
|| temp
== &expand_param_fatal
)
7342 return (temp
== &expand_param_error
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7345 #if defined (ARRAY_VARS)
7346 if (valid_array_reference (name
))
7347 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7350 var_is_set
= temp
!= (char *)0;
7351 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
7352 /* XXX - this may not need to be restricted to special variables */
7354 var_is_null
|= var_is_set
&& var_is_special
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
);
7356 /* Get the rest of the stuff inside the braces. */
7357 if (c
&& c
!= RBRACE
)
7359 /* Extract the contents of the ${ ... } expansion
7360 according to the Posix.2 rules. */
7361 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, (c
== '%' || c
== '#' || c
=='/' || c
== '^' || c
== ',' || c
==':') ? SX_POSIXEXP
|SX_WORD
: SX_WORD
);
7362 if (string
[sindex
] == RBRACE
)
7365 goto bad_substitution
;
7368 value
= (char *)NULL
;
7372 /* All the cases where an expansion can possibly generate an unbound
7374 if (want_substring
|| want_patsub
|| want_casemod
|| c
== '#' || c
== '%' || c
== RBRACE
)
7376 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
7378 last_command_exit_value
= EXECUTION_FAILURE
;
7379 err_unboundvar (name
);
7383 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7387 /* If this is a substring spec, process it and add the result. */
7390 temp1
= parameter_brace_substring (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7395 if (temp1
== &expand_param_error
)
7396 return (&expand_wdesc_error
);
7397 else if (temp1
== &expand_param_fatal
)
7398 return (&expand_wdesc_fatal
);
7400 ret
= alloc_word_desc ();
7402 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7403 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7406 else if (want_patsub
)
7408 temp1
= parameter_brace_patsub (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7413 if (temp1
== &expand_param_error
)
7414 return (&expand_wdesc_error
);
7415 else if (temp1
== &expand_param_fatal
)
7416 return (&expand_wdesc_fatal
);
7418 ret
= alloc_word_desc ();
7420 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7421 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7424 #if defined (CASEMOD_EXPANSIONS)
7425 else if (want_casemod
)
7427 temp1
= parameter_brace_casemod (name
, temp
, ind
, modspec
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7432 if (temp1
== &expand_param_error
)
7433 return (&expand_wdesc_error
);
7434 else if (temp1
== &expand_param_fatal
)
7435 return (&expand_wdesc_fatal
);
7437 ret
= alloc_word_desc ();
7439 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7440 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7445 /* Do the right thing based on which character ended the variable name. */
7451 last_command_exit_value
= EXECUTION_FAILURE
;
7452 report_error (_("%s: bad substitution"), string
? string
: "??");
7456 return &expand_wdesc_error
;
7461 case '#': /* ${param#[#]pattern} */
7462 case '%': /* ${param%[%]pattern} */
7463 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
7468 temp1
= parameter_brace_remove_pattern (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7473 ret
= alloc_word_desc ();
7475 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7476 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7483 if (var_is_set
&& var_is_null
== 0)
7485 /* If the operator is `+', we don't want the value of the named
7486 variable for anything, just the value of the right hand side. */
7489 /* XXX -- if we're double-quoted and the named variable is "$@",
7490 we want to turn off any special handling of "$@" --
7491 we're not using it, so whatever is on the rhs applies. */
7492 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7493 *quoted_dollar_atp
= 0;
7494 if (contains_dollar_at
)
7495 *contains_dollar_at
= 0;
7500 /* From Posix discussion on austin-group list. Issue 221
7501 requires that backslashes escaping `}' inside
7502 double-quoted ${...} be removed. */
7503 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7504 quoted
|= Q_DOLBRACE
;
7505 ret
= parameter_brace_expand_rhs (name
, value
, c
,
7508 contains_dollar_at
);
7509 /* XXX - fix up later, esp. noting presence of
7510 W_HASQUOTEDNULL in ret->flags */
7514 temp
= (char *)NULL
;
7520 /* Otherwise do nothing; just use the value in TEMP. */
7522 else /* VAR not set or VAR is NULL. */
7525 temp
= (char *)NULL
;
7526 if (c
== '=' && var_is_special
)
7528 last_command_exit_value
= EXECUTION_FAILURE
;
7529 report_error (_("$%s: cannot assign in this way"), name
);
7532 return &expand_wdesc_error
;
7536 parameter_brace_expand_error (name
, value
);
7537 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7541 /* XXX -- if we're double-quoted and the named variable is "$@",
7542 we want to turn off any special handling of "$@" --
7543 we're not using it, so whatever is on the rhs applies. */
7544 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7545 *quoted_dollar_atp
= 0;
7546 if (contains_dollar_at
)
7547 *contains_dollar_at
= 0;
7549 /* From Posix discussion on austin-group list. Issue 221 requires
7550 that backslashes escaping `}' inside double-quoted ${...} be
7552 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7553 quoted
|= Q_DOLBRACE
;
7554 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
7556 contains_dollar_at
);
7557 /* XXX - fix up later, esp. noting presence of
7558 W_HASQUOTEDNULL in tdesc->flags */
7569 ret
= alloc_word_desc ();
7576 /* Expand a single ${xxx} expansion. The braces are optional. When
7577 the braces are used, parameter_brace_expand() does the work,
7578 possibly calling param_expand recursively. */
7580 param_expand (string
, sindex
, quoted
, expanded_something
,
7581 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
7584 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
7585 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
7587 char *temp
, *temp1
, uerror
[3];
7588 int zindex
, t_index
, expok
;
7593 WORD_DESC
*tdesc
, *ret
;
7597 c
= string
[++zindex
];
7599 temp
= (char *)NULL
;
7600 ret
= tdesc
= (WORD_DESC
*)NULL
;
7603 /* Do simple cases first. Switch on what follows '$'. */
7617 temp1
= dollar_vars
[TODIGIT (c
)];
7618 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
7623 last_command_exit_value
= EXECUTION_FAILURE
;
7624 err_unboundvar (uerror
);
7625 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7628 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7629 ? quote_string (temp1
)
7630 : quote_escapes (temp1
);
7632 temp
= (char *)NULL
;
7636 /* $$ -- pid of the invoking shell. */
7638 temp
= itos (dollar_dollar_pid
);
7641 /* $# -- number of positional parameters. */
7643 temp
= itos (number_of_args ());
7646 /* $? -- return value of the last synchronous command. */
7648 temp
= itos (last_command_exit_value
);
7651 /* $- -- flags supplied to the shell on invocation or by `set'. */
7653 temp
= which_set_flags ();
7656 /* $! -- Pid of the last asynchronous command. */
7658 /* If no asynchronous pids have been created, expand to nothing.
7659 If `set -u' has been executed, and no async processes have
7660 been created, this is an expansion error. */
7661 if (last_asynchronous_pid
== NO_PID
)
7663 if (expanded_something
)
7664 *expanded_something
= 0;
7665 temp
= (char *)NULL
;
7666 if (unbound_vars_is_error
)
7671 last_command_exit_value
= EXECUTION_FAILURE
;
7672 err_unboundvar (uerror
);
7673 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7677 temp
= itos (last_asynchronous_pid
);
7680 /* The only difference between this and $@ is when the arg is quoted. */
7681 case '*': /* `$*' */
7682 list
= list_rest_of_args ();
7685 /* According to austin-group posix proposal by Geoff Clare in
7686 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7688 "The shell shall write a message to standard error and
7689 immediately exit when it tries to expand an unset parameter
7690 other than the '@' and '*' special parameters."
7693 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7698 last_command_exit_value
= EXECUTION_FAILURE
;
7699 err_unboundvar (uerror
);
7700 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7704 /* If there are no command-line arguments, this should just
7705 disappear if there are other characters in the expansion,
7706 even if it's quoted. */
7707 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7708 temp
= (char *)NULL
;
7709 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7711 /* If we have "$*" we want to make a string of the positional
7712 parameters, separated by the first character of $IFS, and
7713 quote the whole string, including the separators. If IFS
7714 is unset, the parameters are separated by ' '; if $IFS is
7715 null, the parameters are concatenated. */
7716 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7719 temp1
= quote_string (temp
);
7721 tflag
|= W_HASQUOTEDNULL
;
7728 /* We check whether or not we're eventually going to split $* here,
7729 for example when IFS is empty and we are processing the rhs of
7730 an assignment statement. In that case, we don't separate the
7731 arguments at all. Otherwise, if the $* is not quoted it is
7733 # if defined (HANDLE_MULTIBYTE)
7734 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7736 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7738 temp
= string_list_dollar_star (list
);
7741 temp
= string_list_dollar_at (list
, quoted
);
7742 if (quoted
== 0 && (ifs_is_set
== 0 || ifs_is_null
))
7743 tflag
|= W_SPLITSPACE
;
7746 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7747 *contains_dollar_at
= 1;
7750 dispose_words (list
);
7753 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7754 means that we have to turn quoting off after we split into
7755 the individually quoted arguments so that the final split
7756 on the first character of $IFS is still done. */
7757 case '@': /* `$@' */
7758 list
= list_rest_of_args ();
7761 /* According to austin-group posix proposal by Geoff Clare in
7762 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7764 "The shell shall write a message to standard error and
7765 immediately exit when it tries to expand an unset parameter
7766 other than the '@' and '*' special parameters."
7769 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7774 last_command_exit_value
= EXECUTION_FAILURE
;
7775 err_unboundvar (uerror
);
7776 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7780 /* We want to flag the fact that we saw this. We can't turn
7781 off quoting entirely, because other characters in the
7782 string might need it (consider "\"$@\""), but we need some
7783 way to signal that the final split on the first character
7784 of $IFS should be done, even though QUOTED is 1. */
7785 /* XXX - should this test include Q_PATQUOTE? */
7786 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7787 *quoted_dollar_at_p
= 1;
7788 if (contains_dollar_at
)
7789 *contains_dollar_at
= 1;
7791 /* We want to separate the positional parameters with the first
7792 character of $IFS in case $IFS is something other than a space.
7793 We also want to make sure that splitting is done no matter what --
7794 according to POSIX.2, this expands to a list of the positional
7795 parameters no matter what IFS is set to. */
7796 temp
= string_list_dollar_at (list
, (pflags
& PF_ASSIGNRHS
) ? (quoted
|Q_DOUBLE_QUOTES
) : quoted
);
7798 tflag
|= W_DOLLARAT
;
7799 dispose_words (list
);
7803 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
, pflags
,
7805 contains_dollar_at
);
7807 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7809 temp
= tdesc
? tdesc
->word
: (char *)0;
7812 /* Quoted nulls should be removed if there is anything else
7814 /* Note that we saw the quoted null so we can add one back at
7815 the end of this function if there are no other characters
7816 in the string, discard TEMP, and go on. The exception to
7817 this is when we have "${@}" and $1 is '', since $@ needs
7818 special handling. */
7819 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7821 if (had_quoted_null_p
)
7822 *had_quoted_null_p
= 1;
7823 if (*quoted_dollar_at_p
== 0)
7826 tdesc
->word
= temp
= (char *)NULL
;
7834 /* Do command or arithmetic substitution. */
7836 /* We have to extract the contents of this paren substitution. */
7837 t_index
= zindex
+ 1;
7838 temp
= extract_command_subst (string
, &t_index
, 0);
7841 /* For Posix.2-style `$(( ))' arithmetic substitution,
7842 extract the expression and pass it to the evaluator. */
7843 if (temp
&& *temp
== LPAREN
)
7847 temp2
= savestring (temp1
);
7848 t_index
= strlen (temp2
) - 1;
7850 if (temp2
[t_index
] != RPAREN
)
7856 /* Cut off ending `)' */
7857 temp2
[t_index
] = '\0';
7859 if (chk_arithsub (temp2
, t_index
) == 0)
7863 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7868 /* Expand variables found inside the expression. */
7869 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7873 /* No error messages. */
7874 this_command_name
= (char *)NULL
;
7875 number
= evalexp (temp1
, &expok
);
7880 if (interactive_shell
== 0 && posixly_correct
)
7882 last_command_exit_value
= EXECUTION_FAILURE
;
7883 return (&expand_wdesc_fatal
);
7886 return (&expand_wdesc_error
);
7888 temp
= itos (number
);
7893 if (pflags
& PF_NOCOMSUB
)
7894 /* we need zindex+1 because string[zindex] == RPAREN */
7895 temp1
= substring (string
, *sindex
, zindex
+1);
7898 tdesc
= command_substitute (temp
, quoted
);
7899 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7901 dispose_word_desc (tdesc
);
7907 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7908 away in a future bash release. */
7910 /* Extract the contents of this arithmetic substitution. */
7911 t_index
= zindex
+ 1;
7912 temp
= extract_arithmetic_subst (string
, &t_index
);
7916 temp
= savestring (string
);
7917 if (expanded_something
)
7918 *expanded_something
= 0;
7922 /* Do initial variable expansion. */
7923 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7928 /* Find the variable in VARIABLE_LIST. */
7929 temp
= (char *)NULL
;
7931 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7933 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7935 /* If this isn't a variable name, then just output the `$'. */
7936 if (temp1
== 0 || *temp1
== '\0')
7939 temp
= (char *)xmalloc (2);
7942 if (expanded_something
)
7943 *expanded_something
= 0;
7947 /* If the variable exists, return its value cell. */
7948 var
= find_variable (temp1
);
7950 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7952 #if defined (ARRAY_VARS)
7953 if (assoc_p (var
) || array_p (var
))
7955 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7956 : assoc_reference (assoc_cell (var
), "0");
7958 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7959 ? quote_string (temp
)
7960 : quote_escapes (temp
);
7961 else if (unbound_vars_is_error
)
7962 goto unbound_variable
;
7967 temp
= value_cell (var
);
7969 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7970 ? quote_string (temp
)
7971 : quote_escapes (temp
);
7978 else if (var
= find_variable_last_nameref (temp1
))
7980 temp
= nameref_cell (var
);
7981 #if defined (ARRAY_VARS)
7982 if (temp
&& *temp
&& valid_array_reference (temp
))
7984 tdesc
= parameter_brace_expand_word (temp
, SPECIAL_VAR (temp
, 0), quoted
, pflags
, (arrayind_t
*)NULL
);
7985 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7992 /* y=2 ; typeset -n x=y; echo $x is not the same as echo $2 in ksh */
7993 if (temp
&& *temp
&& legal_identifier (temp
) == 0)
7995 last_command_exit_value
= EXECUTION_FAILURE
;
7996 report_error (_("%s: invalid variable name for name reference"), temp
);
7997 return (&expand_wdesc_error
); /* XXX */
8000 temp
= (char *)NULL
;
8003 temp
= (char *)NULL
;
8006 if (unbound_vars_is_error
)
8008 last_command_exit_value
= EXECUTION_FAILURE
;
8009 err_unboundvar (temp1
);
8018 last_command_exit_value
= EXECUTION_FAILURE
;
8019 return ((unbound_vars_is_error
&& interactive_shell
== 0)
8020 ? &expand_wdesc_fatal
8021 : &expand_wdesc_error
);
8032 ret
= alloc_word_desc ();
8033 ret
->flags
= tflag
; /* XXX */
8039 /* Make a word list which is the result of parameter and variable
8040 expansion, command substitution, arithmetic substitution, and
8041 quote removal of WORD. Return a pointer to a WORD_LIST which is
8042 the result of the expansion. If WORD contains a null word, the
8043 word list returned is also null.
8045 QUOTED contains flag values defined in shell.h.
8047 ISEXP is used to tell expand_word_internal that the word should be
8048 treated as the result of an expansion. This has implications for
8049 how IFS characters in the word are treated.
8051 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
8052 they point to an integer value which receives information about expansion.
8053 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
8054 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
8057 This only does word splitting in the case of $@ expansion. In that
8058 case, we split on ' '. */
8060 /* Values for the local variable quoted_state. */
8062 #define PARTIALLY_QUOTED 1
8063 #define WHOLLY_QUOTED 2
8066 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
8069 int *contains_dollar_at
;
8070 int *expanded_something
;
8075 /* The intermediate string that we build while expanding. */
8078 /* The current size of the above object. */
8081 /* Index into ISTRING. */
8084 /* Temporary string storage. */
8087 /* The text of WORD. */
8088 register char *string
;
8090 /* The size of STRING. */
8093 /* The index into STRING. */
8096 /* This gets 1 if we see a $@ while quoted. */
8097 int quoted_dollar_at
;
8099 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
8100 whether WORD contains no quoting characters, a partially quoted
8101 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
8105 int had_quoted_null
;
8106 int has_dollar_at
, temp_has_dollar_at
;
8107 int split_on_spaces
;
8109 int pflags
; /* flags passed to param_expand */
8111 int assignoff
; /* If assignment, offset of `=' */
8113 register unsigned char c
; /* Current character. */
8114 int t_index
; /* For calls to string_extract_xxx. */
8120 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
8121 istring
[istring_index
= 0] = '\0';
8122 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
8123 split_on_spaces
= 0;
8124 quoted_state
= UNQUOTED
;
8126 string
= word
->word
;
8128 goto finished_with_string
;
8129 /* Don't need the string length for the SADD... and COPY_ macros unless
8130 multibyte characters are possible. */
8131 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
8133 if (contains_dollar_at
)
8134 *contains_dollar_at
= 0;
8138 /* Begin the expansion. */
8144 /* Case on toplevel character. */
8148 goto finished_with_string
;
8152 #if HANDLE_MULTIBYTE
8153 if (MB_CUR_MAX
> 1 && string
[sindex
])
8155 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8160 temp
= (char *)xmalloc (3);
8162 temp
[1] = c
= string
[sindex
];
8173 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
8179 #if defined (PROCESS_SUBSTITUTION)
8180 /* Process substitution. */
8184 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
8186 sindex
--; /* add_character: label increments sindex */
8190 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
8192 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
8195 /* If the process substitution specification is `<()', we want to
8196 open the pipe for writing in the child and produce output; if
8197 it is `>()', we want to open the pipe for reading in the child
8198 and consume input. */
8199 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
8203 goto dollar_add_string
;
8205 #endif /* PROCESS_SUBSTITUTION */
8208 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8209 which are not assignment statements are not expanded. If the
8210 shell isn't in posix mode, though, we perform tilde expansion
8211 on `likely candidate' unquoted assignment statements (flags
8212 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8213 contains an unquoted :~ or =~. Something to think about: we
8214 now have a flag that says to perform tilde expansion on arguments
8215 to `assignment builtins' like declare and export that look like
8216 assignment statements. We now do tilde expansion on such words
8217 even in POSIX mode. */
8218 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
8220 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8221 goto add_ifs_character
;
8225 /* If we're not in posix mode or forcing assignment-statement tilde
8226 expansion, note where the `=' appears in the word and prepare to
8227 do tilde expansion following the first `='. */
8228 if ((word
->flags
& W_ASSIGNMENT
) &&
8229 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8230 assignoff
== -1 && sindex
> 0)
8232 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
8233 word
->flags
|= W_ITILDE
;
8235 else if ((word
->flags
& W_ASSIGNMENT
) &&
8236 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8237 string
[sindex
+1] == '~')
8238 word
->flags
|= W_ITILDE
;
8240 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8241 goto add_ifs_character
;
8246 if (word
->flags
& W_NOTILDE
)
8248 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8249 goto add_ifs_character
;
8254 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
8255 string
[sindex
+1] == '~')
8256 word
->flags
|= W_ITILDE
;
8258 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8259 goto add_ifs_character
;
8264 /* If the word isn't supposed to be tilde expanded, or we're not
8265 at the start of a word or after an unquoted : or = in an
8266 assignment statement, we don't do tilde expansion. */
8267 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
8268 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
8269 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8271 word
->flags
&= ~W_ITILDE
;
8272 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
8273 goto add_ifs_character
;
8278 if (word
->flags
& W_ASSIGNRHS
)
8280 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
8285 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
8287 word
->flags
&= ~W_ITILDE
;
8289 if (temp
&& *temp
&& t_index
> 0)
8291 temp1
= bash_tilde_expand (temp
, tflag
);
8292 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
8296 goto add_character
; /* tilde expansion failed */
8301 goto add_quoted_string
; /* XXX was add_string */
8310 if (expanded_something
)
8311 *expanded_something
= 1;
8313 temp_has_dollar_at
= 0;
8314 pflags
= (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0;
8315 if (word
->flags
& W_NOSPLIT2
)
8316 pflags
|= PF_NOSPLIT2
;
8317 if (word
->flags
& W_ASSIGNRHS
)
8318 pflags
|= PF_ASSIGNRHS
;
8319 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
8320 &temp_has_dollar_at
, "ed_dollar_at
,
8321 &had_quoted_null
, pflags
);
8322 has_dollar_at
+= temp_has_dollar_at
;
8323 split_on_spaces
+= (tword
->flags
& W_SPLITSPACE
);
8325 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
8329 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
8330 : &expand_word_fatal
);
8332 if (contains_dollar_at
&& has_dollar_at
)
8333 *contains_dollar_at
= 1;
8335 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
8336 had_quoted_null
= 1;
8338 temp
= tword
? tword
->word
: (char *)NULL
;
8339 dispose_word_desc (tword
);
8341 /* Kill quoted nulls; we will add them back at the end of
8342 expand_word_internal if nothing else in the string */
8343 if (had_quoted_null
&& temp
&& QUOTED_NULL (temp
))
8346 temp
= (char *)NULL
;
8352 case '`': /* Backquoted command substitution. */
8356 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
8357 /* The test of sindex against t_index is to allow bare instances of
8358 ` to pass through, for backwards compatibility. */
8359 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
8361 if (sindex
- 1 == t_index
)
8366 last_command_exit_value
= EXECUTION_FAILURE
;
8367 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
8370 return ((temp
== &extract_string_error
) ? &expand_word_error
8371 : &expand_word_fatal
);
8374 if (expanded_something
)
8375 *expanded_something
= 1;
8377 if (word
->flags
& W_NOCOMSUB
)
8378 /* sindex + 1 because string[sindex] == '`' */
8379 temp1
= substring (string
, t_index
, sindex
+ 1);
8382 de_backslash (temp
);
8383 tword
= command_substitute (temp
, quoted
);
8384 temp1
= tword
? tword
->word
: (char *)NULL
;
8386 dispose_word_desc (tword
);
8390 goto dollar_add_string
;
8394 if (string
[sindex
+ 1] == '\n')
8400 c
= string
[++sindex
];
8402 if (quoted
& Q_HERE_DOCUMENT
)
8404 else if (quoted
& Q_DOUBLE_QUOTES
)
8409 /* From Posix discussion on austin-group list: Backslash escaping
8410 a } in ${...} is removed. Issue 0000221 */
8411 if ((quoted
& Q_DOLBRACE
) && c
== RBRACE
)
8413 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8415 /* This is the fix for " $@\ " */
8416 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0) & isexp
== 0 && isifs (c
))
8418 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8419 DEFAULT_ARRAY_SIZE
);
8420 istring
[istring_index
++] = CTLESC
;
8421 istring
[istring_index
++] = '\\';
8422 istring
[istring_index
] = '\0';
8424 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8426 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
8428 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
8433 sindex
--; /* add_character: label increments sindex */
8438 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8443 /* BEFORE jumping here, we need to increment sindex if appropriate */
8444 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8445 DEFAULT_ARRAY_SIZE
);
8446 istring
[istring_index
++] = twochars
[0];
8447 istring
[istring_index
++] = twochars
[1];
8448 istring
[istring_index
] = '\0';
8453 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8457 temp
= string_extract_double_quoted (string
, &sindex
, 0);
8459 /* If the quotes surrounded the entire string, then the
8460 whole word was quoted. */
8461 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8467 tword
= alloc_word_desc ();
8470 temp
= (char *)NULL
;
8472 temp_has_dollar_at
= 0; /* XXX */
8473 /* Need to get W_HASQUOTEDNULL flag through this function. */
8474 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &temp_has_dollar_at
, (int *)NULL
);
8475 has_dollar_at
+= temp_has_dollar_at
;
8477 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
8481 /* expand_word_internal has already freed temp_word->word
8482 for us because of the way it prints error messages. */
8483 tword
->word
= (char *)NULL
;
8484 dispose_word (tword
);
8488 dispose_word (tword
);
8490 /* "$@" (a double-quoted dollar-at) expands into nothing,
8491 not even a NULL word, when there are no positional
8493 if (list
== 0 && has_dollar_at
)
8499 /* If we get "$@", we know we have expanded something, so we
8500 need to remember it for the final split on $IFS. This is
8501 a special case; it's the only case where a quoted string
8502 can expand into more than one word. It's going to come back
8503 from the above call to expand_word_internal as a list with
8504 a single word, in which all characters are quoted and
8505 separated by blanks. What we want to do is to turn it back
8506 into a list for the next piece of code. */
8508 dequote_list (list
);
8510 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
8511 had_quoted_null
= 1; /* XXX */
8516 if (contains_dollar_at
)
8517 *contains_dollar_at
= 1;
8518 if (expanded_something
)
8519 *expanded_something
= 1;
8524 /* What we have is "". This is a minor optimization. */
8526 list
= (WORD_LIST
*)NULL
;
8529 /* The code above *might* return a list (consider the case of "$@",
8530 where it returns "$1", "$2", etc.). We can't throw away the
8531 rest of the list, and we have to make sure each word gets added
8532 as quoted. We test on tresult->next: if it is non-NULL, we
8533 quote the whole list, save it to a string with string_list, and
8534 add that string. We don't need to quote the results of this
8535 (and it would be wrong, since that would quote the separators
8536 as well), so we go directly to add_string. */
8541 /* Testing quoted_dollar_at makes sure that "$@" is
8542 split correctly when $IFS does not contain a space. */
8543 temp
= quoted_dollar_at
8544 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
8545 : string_list (quote_list (list
));
8546 dispose_words (list
);
8551 temp
= savestring (list
->word
->word
);
8552 tflag
= list
->word
->flags
;
8553 dispose_words (list
);
8555 /* If the string is not a quoted null string, we want
8556 to remove any embedded unquoted CTLNUL characters.
8557 We do not want to turn quoted null strings back into
8558 the empty string, though. We do this because we
8559 want to remove any quoted nulls from expansions that
8560 contain other characters. For example, if we have
8561 x"$*"y or "x$*y" and there are no positional parameters,
8562 the $* should expand into nothing. */
8563 /* We use the W_HASQUOTEDNULL flag to differentiate the
8564 cases: a quoted null character as above and when
8565 CTLNUL is contained in the (non-null) expansion
8566 of some variable. We use the had_quoted_null flag to
8567 pass the value through this function to its caller. */
8568 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
8569 remove_quoted_nulls (temp
); /* XXX */
8573 temp
= (char *)NULL
;
8575 /* We do not want to add quoted nulls to strings that are only
8576 partially quoted; we can throw them away. The exception to
8577 this is when we are going to be performing word splitting,
8578 since we have to preserve a null argument if the next character
8579 will cause word splitting. */
8580 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
&& (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)))
8588 temp
= quote_string (temp
);
8596 sindex
--; /* add_character: label increments sindex */
8603 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8607 temp
= string_extract_single_quoted (string
, &sindex
);
8609 /* If the entire STRING was surrounded by single quotes,
8610 then the string is wholly quoted. */
8611 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8615 /* If all we had was '', it is a null expansion. */
8619 temp
= (char *)NULL
;
8622 remove_quoted_escapes (temp
); /* ??? */
8624 /* We do not want to add quoted nulls to strings that are only
8625 partially quoted; such nulls are discarded. */
8626 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
8629 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8633 sindex
--; /* add_character: label increments sindex */
8637 goto add_quoted_string
;
8642 /* This is the fix for " $@ " */
8644 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
8646 if (string
[sindex
]) /* from old goto dollar_add_string */
8655 #if HANDLE_MULTIBYTE
8661 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8666 twochars
[0] = CTLESC
;
8673 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
8676 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
8677 DEFAULT_ARRAY_SIZE
);
8678 istring
[istring_index
++] = c
;
8679 istring
[istring_index
] = '\0';
8681 /* Next character. */
8686 finished_with_string
:
8687 /* OK, we're ready to return. If we have a quoted string, and
8688 quoted_dollar_at is not set, we do no splitting at all; otherwise
8689 we split on ' '. The routines that call this will handle what to
8690 do if nothing has been expanded. */
8692 /* Partially and wholly quoted strings which expand to the empty
8693 string are retained as an empty arguments. Unquoted strings
8694 which expand to the empty string are discarded. The single
8695 exception is the case of expanding "$@" when there are no
8696 positional parameters. In that case, we discard the expansion. */
8698 /* Because of how the code that handles "" and '' in partially
8699 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8700 if we saw quoting characters, but the expansion was empty.
8701 "" and '' are tossed away before we get to this point when
8702 processing partially quoted strings. This makes "" and $xxx""
8703 equivalent when xxx is unset. We also look to see whether we
8704 saw a quoted null from a ${} expansion and add one back if we
8707 /* If we expand to nothing and there were no single or double quotes
8708 in the word, we throw it away. Otherwise, we return a NULL word.
8709 The single exception is for $@ surrounded by double quotes when
8710 there are no positional parameters. In that case, we also throw
8713 if (*istring
== '\0')
8715 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
8717 istring
[0] = CTLNUL
;
8719 tword
= make_bare_word (istring
);
8720 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8721 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8722 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8723 tword
->flags
|= W_QUOTED
;
8725 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8726 and a double-quoted "$@" appears anywhere in it, then the entire
8728 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8729 list
= (WORD_LIST
*)NULL
;
8733 tword
= make_bare_word (istring
);
8734 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8735 tword
->flags
|= W_QUOTED
;
8736 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8740 list
= (WORD_LIST
*)NULL
;
8743 else if (word
->flags
& W_NOSPLIT
)
8745 tword
= make_bare_word (istring
);
8746 if (word
->flags
& W_ASSIGNMENT
)
8747 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8748 if (word
->flags
& W_COMPASSIGN
)
8749 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8750 if (word
->flags
& W_NOGLOB
)
8751 tword
->flags
|= W_NOGLOB
; /* XXX */
8752 if (word
->flags
& W_NOBRACE
)
8753 tword
->flags
|= W_NOBRACE
; /* XXX */
8754 if (word
->flags
& W_NOEXPAND
)
8755 tword
->flags
|= W_NOEXPAND
; /* XXX */
8756 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8757 tword
->flags
|= W_QUOTED
;
8758 if (had_quoted_null
&& QUOTED_NULL (istring
))
8759 tword
->flags
|= W_HASQUOTEDNULL
;
8760 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8766 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8768 /* If we have $@, we need to split the results no matter what. If
8769 IFS is unset or NULL, string_list_dollar_at has separated the
8770 positional parameters with a space, so we split on space (we have
8771 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8772 string_list_dollar_at has separated the positional parameters
8773 with the first character of $IFS, so we split on $IFS. If
8774 SPLIT_ON_SPACES is set, we expanded $* (unquoted) with IFS either
8775 unset or null, and we want to make sure that we split on spaces
8776 regardless of what else has happened to IFS since the expansion. */
8777 if (split_on_spaces
)
8778 list
= list_string (istring
, " ", 1); /* XXX quoted == 1? */
8779 else if (has_dollar_at
&& ifs_chars
)
8780 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8783 tword
= make_bare_word (istring
);
8784 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8785 tword
->flags
|= W_QUOTED
;
8786 if (word
->flags
& W_ASSIGNMENT
)
8787 tword
->flags
|= W_ASSIGNMENT
;
8788 if (word
->flags
& W_COMPASSIGN
)
8789 tword
->flags
|= W_COMPASSIGN
;
8790 if (word
->flags
& W_NOGLOB
)
8791 tword
->flags
|= W_NOGLOB
;
8792 if (word
->flags
& W_NOBRACE
)
8793 tword
->flags
|= W_NOBRACE
;
8794 if (word
->flags
& W_NOEXPAND
)
8795 tword
->flags
|= W_NOEXPAND
;
8796 if (had_quoted_null
&& QUOTED_NULL (istring
))
8797 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8798 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8806 /* **************************************************************** */
8808 /* Functions for Quote Removal */
8810 /* **************************************************************** */
8812 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8813 backslash quoting rules for within double quotes or a here document. */
8815 string_quote_removal (string
, quoted
)
8820 char *r
, *result_string
, *temp
, *send
;
8821 int sindex
, tindex
, dquote
;
8825 /* The result can be no longer than the original string. */
8826 slen
= strlen (string
);
8827 send
= string
+ slen
;
8829 r
= result_string
= (char *)xmalloc (slen
+ 1);
8831 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8836 c
= string
[++sindex
];
8842 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8847 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8851 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8857 tindex
= sindex
+ 1;
8858 temp
= string_extract_single_quoted (string
, &tindex
);
8869 dquote
= 1 - dquote
;
8875 return (result_string
);
8880 /* Perform quote removal on word WORD. This allocates and returns a new
8883 word_quote_removal (word
, quoted
)
8890 t
= string_quote_removal (word
->word
, quoted
);
8891 w
= alloc_word_desc ();
8892 w
->word
= t
? t
: savestring ("");
8896 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8897 the members of the list are treated as if they are surrounded by
8898 double quotes. Return a new list, or NULL if LIST is NULL. */
8900 word_list_quote_removal (list
, quoted
)
8904 WORD_LIST
*result
, *t
, *tresult
, *e
;
8906 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8908 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8910 result
= (WORD_LIST
*) list_append (result
, tresult
);
8913 result
= e
= tresult
;
8926 /*******************************************
8928 * Functions to perform word splitting *
8930 *******************************************/
8940 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8942 ifs_is_set
= ifs_var
!= 0;
8943 ifs_is_null
= ifs_is_set
&& (*ifs_value
== 0);
8945 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8946 handle multibyte chars in IFS */
8947 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8948 for (t
= ifs_value
; t
&& *t
; t
++)
8954 #if defined (HANDLE_MULTIBYTE)
8957 ifs_firstc
[0] = '\0';
8963 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8964 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8965 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8967 ifs_firstc
[0] = ifs_value
[0];
8968 ifs_firstc
[1] = '\0';
8972 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8975 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8985 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8986 is not quoted. list_string () performs quote removal for us, even if we
8987 don't do any splitting. */
8989 word_split (w
, ifs_chars
)
8999 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
9000 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
9003 result
= (WORD_LIST
*)NULL
;
9008 /* Perform word splitting on LIST and return the RESULT. It is possible
9009 to return (WORD_LIST *)NULL. */
9011 word_list_split (list
)
9014 WORD_LIST
*result
, *t
, *tresult
, *e
;
9016 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
9018 tresult
= word_split (t
->word
, ifs_value
);
9020 result
= e
= tresult
;
9031 /**************************************************
9033 * Functions to expand an entire WORD_LIST *
9035 **************************************************/
9037 /* Do any word-expansion-specific cleanup and jump to top_level */
9039 exp_jump_to_top_level (v
)
9042 set_pipestatus_from_exit (last_command_exit_value
);
9044 /* Cleanup code goes here. */
9045 expand_no_split_dollar_star
= 0; /* XXX */
9046 expanding_redir
= 0;
9047 assigning_in_environment
= 0;
9049 if (parse_and_execute_level
== 0)
9050 top_level_cleanup (); /* from sig.c */
9052 jump_to_top_level (v
);
9055 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
9056 ELIST, and set ELIST to the new list. */
9057 #define PREPEND_LIST(nlist, elist) \
9058 do { nlist->next = elist; elist = nlist; } while (0)
9060 /* Separate out any initial variable assignments from TLIST. If set -k has
9061 been executed, remove all assignment statements from TLIST. Initial
9062 variable assignments and other environment assignments are placed
9063 on SUBST_ASSIGN_VARLIST. */
9065 separate_out_assignments (tlist
)
9068 register WORD_LIST
*vp
, *lp
;
9071 return ((WORD_LIST
*)NULL
);
9073 if (subst_assign_varlist
)
9074 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
9076 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9079 /* Separate out variable assignments at the start of the command.
9080 Loop invariant: vp->next == lp
9082 lp = list of words left after assignment statements skipped
9083 tlist = original list of words
9085 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
9091 /* If lp != tlist, we have some initial assignment statements.
9092 We make SUBST_ASSIGN_VARLIST point to the list of assignment
9093 words and TLIST point to the remaining words. */
9096 subst_assign_varlist
= tlist
;
9097 /* ASSERT(vp->next == lp); */
9098 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
9099 tlist
= lp
; /* remainder of word list */
9102 /* vp == end of variable list */
9103 /* tlist == remainder of original word list without variable assignments */
9105 /* All the words in tlist were assignment statements */
9106 return ((WORD_LIST
*)NULL
);
9108 /* ASSERT(tlist != NULL); */
9109 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
9111 /* If the -k option is in effect, we need to go through the remaining
9112 words, separate out the assignment words, and place them on
9113 SUBST_ASSIGN_VARLIST. */
9114 if (place_keywords_in_env
)
9116 WORD_LIST
*tp
; /* tp == running pointer into tlist */
9121 /* Loop Invariant: tp->next == lp */
9122 /* Loop postcondition: tlist == word list without assignment statements */
9125 if (lp
->word
->flags
& W_ASSIGNMENT
)
9127 /* Found an assignment statement, add this word to end of
9128 subst_assign_varlist (vp). */
9129 if (!subst_assign_varlist
)
9130 subst_assign_varlist
= vp
= lp
;
9137 /* Remove the word pointed to by LP from TLIST. */
9138 tp
->next
= lp
->next
;
9139 /* ASSERT(vp == lp); */
9140 lp
->next
= (WORD_LIST
*)NULL
;
9153 #define WEXP_VARASSIGN 0x001
9154 #define WEXP_BRACEEXP 0x002
9155 #define WEXP_TILDEEXP 0x004
9156 #define WEXP_PARAMEXP 0x008
9157 #define WEXP_PATHEXP 0x010
9159 /* All of the expansions, including variable assignments at the start of
9161 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9163 /* All of the expansions except variable assignments at the start of
9165 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9167 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
9168 expansion, command substitution, arithmetic expansion, word splitting, and
9170 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
9172 /* Take the list of words in LIST and do the various substitutions. Return
9173 a new list of words which is the expanded list, and without things like
9174 variable assignments. */
9180 return (expand_word_list_internal (list
, WEXP_ALL
));
9183 /* Same as expand_words (), but doesn't hack variable or environment
9186 expand_words_no_vars (list
)
9189 return (expand_word_list_internal (list
, WEXP_NOVARS
));
9193 expand_words_shellexp (list
)
9196 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
9200 glob_expand_word_list (tlist
, eflags
)
9204 char **glob_array
, *temp_string
;
9205 register int glob_index
;
9206 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
9209 output_list
= disposables
= (WORD_LIST
*)NULL
;
9210 glob_array
= (char **)NULL
;
9213 /* For each word, either globbing is attempted or the word is
9214 added to orig_list. If globbing succeeds, the results are
9215 added to orig_list and the word (tlist) is added to the list
9216 of disposable words. If globbing fails and failed glob
9217 expansions are left unchanged (the shell default), the
9218 original word is added to orig_list. If globbing fails and
9219 failed glob expansions are removed, the original word is
9220 added to the list of disposable words. orig_list ends up
9221 in reverse order and requires a call to REVERSE_LIST to
9222 be set right. After all words are examined, the disposable
9226 /* If the word isn't an assignment and contains an unquoted
9227 pattern matching character, then glob it. */
9228 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
9229 unquoted_glob_pattern_p (tlist
->word
->word
))
9231 glob_array
= shell_glob_filename (tlist
->word
->word
);
9233 /* Handle error cases.
9234 I don't think we should report errors like "No such file
9235 or directory". However, I would like to report errors
9236 like "Read failed". */
9238 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
9240 glob_array
= (char **)xmalloc (sizeof (char *));
9241 glob_array
[0] = (char *)NULL
;
9244 /* Dequote the current word in case we have to use it. */
9245 if (glob_array
[0] == NULL
)
9247 temp_string
= dequote_string (tlist
->word
->word
);
9248 free (tlist
->word
->word
);
9249 tlist
->word
->word
= temp_string
;
9252 /* Make the array into a word list. */
9253 glob_list
= (WORD_LIST
*)NULL
;
9254 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
9256 tword
= make_bare_word (glob_array
[glob_index
]);
9257 glob_list
= make_word_list (tword
, glob_list
);
9262 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
9263 PREPEND_LIST (tlist
, disposables
);
9265 else if (fail_glob_expansion
!= 0)
9267 last_command_exit_value
= EXECUTION_FAILURE
;
9268 report_error (_("no match: %s"), tlist
->word
->word
);
9269 exp_jump_to_top_level (DISCARD
);
9271 else if (allow_null_glob_expansion
== 0)
9273 /* Failed glob expressions are left unchanged. */
9274 PREPEND_LIST (tlist
, output_list
);
9278 /* Failed glob expressions are removed. */
9279 PREPEND_LIST (tlist
, disposables
);
9284 /* Dequote the string. */
9285 temp_string
= dequote_string (tlist
->word
->word
);
9286 free (tlist
->word
->word
);
9287 tlist
->word
->word
= temp_string
;
9288 PREPEND_LIST (tlist
, output_list
);
9291 strvec_dispose (glob_array
);
9292 glob_array
= (char **)NULL
;
9298 dispose_words (disposables
);
9301 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9303 return (output_list
);
9306 #if defined (BRACE_EXPANSION)
9308 brace_expand_word_list (tlist
, eflags
)
9312 register char **expansions
;
9314 WORD_LIST
*disposables
, *output_list
, *next
;
9318 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
9322 if (tlist
->word
->flags
& W_NOBRACE
)
9324 /*itrace("brace_expand_word_list: %s: W_NOBRACE", tlist->word->word);*/
9325 PREPEND_LIST (tlist
, output_list
);
9329 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9331 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9332 PREPEND_LIST (tlist
, output_list
);
9336 /* Only do brace expansion if the word has a brace character. If
9337 not, just add the word list element to BRACES and continue. In
9338 the common case, at least when running shell scripts, this will
9339 degenerate to a bunch of calls to `mbschr', and then what is
9340 basically a reversal of TLIST into BRACES, which is corrected
9341 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9343 if (mbschr (tlist
->word
->word
, LBRACE
))
9345 expansions
= brace_expand (tlist
->word
->word
);
9347 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
9349 w
= alloc_word_desc ();
9350 w
->word
= temp_string
;
9352 /* If brace expansion didn't change the word, preserve
9353 the flags. We may want to preserve the flags
9354 unconditionally someday -- XXX */
9355 if (STREQ (temp_string
, tlist
->word
->word
))
9356 w
->flags
= tlist
->word
->flags
;
9358 w
= make_word_flags (w
, temp_string
);
9360 output_list
= make_word_list (w
, output_list
);
9364 /* Add TLIST to the list of words to be freed after brace
9365 expansion has been performed. */
9366 PREPEND_LIST (tlist
, disposables
);
9369 PREPEND_LIST (tlist
, output_list
);
9373 dispose_words (disposables
);
9376 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9378 return (output_list
);
9382 #if defined (ARRAY_VARS)
9383 /* Take WORD, a compound associative array assignment, and internally run
9384 'declare -A w', where W is the variable name portion of WORD. */
9386 make_internal_declare (word
, option
)
9394 w
= make_word (word
);
9396 t
= assignment (w
->word
, 0);
9399 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
9400 wl
= make_word_list (make_word (option
), wl
);
9402 return (declare_builtin (wl
));
9407 shell_expand_word_list (tlist
, eflags
)
9411 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
9412 int expanded_something
, has_dollar_at
;
9415 /* We do tilde expansion all the time. This is what 1003.2 says. */
9416 new_list
= (WORD_LIST
*)NULL
;
9417 for (orig_list
= tlist
; tlist
; tlist
= next
)
9419 temp_string
= tlist
->word
->word
;
9423 #if defined (ARRAY_VARS)
9424 /* If this is a compound array assignment to a builtin that accepts
9425 such assignments (e.g., `declare'), take the assignment and perform
9426 it separately, handling the semantics of declarations inside shell
9427 functions. This avoids the double-evaluation of such arguments,
9428 because `declare' does some evaluation of compound assignments on
9430 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9434 if ((tlist
->word
->flags
& (W_ASSIGNASSOC
|W_ASSNGLOBAL
)) == (W_ASSIGNASSOC
|W_ASSNGLOBAL
))
9435 make_internal_declare (tlist
->word
->word
, "-gA");
9436 else if (tlist
->word
->flags
& W_ASSIGNASSOC
)
9437 make_internal_declare (tlist
->word
->word
, "-A");
9438 else if ((tlist
->word
->flags
& (W_ASSIGNARRAY
|W_ASSNGLOBAL
)) == (W_ASSIGNARRAY
|W_ASSNGLOBAL
))
9439 make_internal_declare (tlist
->word
->word
, "-ga");
9440 else if (tlist
->word
->flags
& W_ASSIGNARRAY
)
9441 make_internal_declare (tlist
->word
->word
, "-a");
9442 else if (tlist
->word
->flags
& W_ASSNGLOBAL
)
9443 make_internal_declare (tlist
->word
->word
, "-g");
9445 t
= do_word_assignment (tlist
->word
, 0);
9448 last_command_exit_value
= EXECUTION_FAILURE
;
9449 exp_jump_to_top_level (DISCARD
);
9452 /* Now transform the word as ksh93 appears to do and go on */
9453 t
= assignment (tlist
->word
->word
, 0);
9454 tlist
->word
->word
[t
] = '\0';
9455 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
|W_ASSIGNARRAY
);
9459 expanded_something
= 0;
9460 expanded
= expand_word_internal
9461 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
9463 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
9465 /* By convention, each time this error is returned,
9466 tlist->word->word has already been freed. */
9467 tlist
->word
->word
= (char *)NULL
;
9469 /* Dispose our copy of the original list. */
9470 dispose_words (orig_list
);
9471 /* Dispose the new list we're building. */
9472 dispose_words (new_list
);
9474 last_command_exit_value
= EXECUTION_FAILURE
;
9475 if (expanded
== &expand_word_error
)
9476 exp_jump_to_top_level (DISCARD
);
9478 exp_jump_to_top_level (FORCE_EOF
);
9481 /* Don't split words marked W_NOSPLIT. */
9482 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
9484 temp_list
= word_list_split (expanded
);
9485 dispose_words (expanded
);
9489 /* If no parameter expansion, command substitution, process
9490 substitution, or arithmetic substitution took place, then
9491 do not do word splitting. We still have to remove quoted
9492 null characters from the result. */
9493 word_list_remove_quoted_nulls (expanded
);
9494 temp_list
= expanded
;
9497 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
9498 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
9502 dispose_words (orig_list
);
9505 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
9510 /* The workhorse for expand_words () and expand_words_no_vars ().
9511 First arg is LIST, a WORD_LIST of words.
9512 Second arg EFLAGS is a flags word controlling which expansions are
9515 This does all of the substitutions: brace expansion, tilde expansion,
9516 parameter expansion, command substitution, arithmetic expansion,
9517 process substitution, word splitting, and pathname expansion, according
9518 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9519 set, or for which no expansion is done, do not undergo word splitting.
9520 Words with the W_NOGLOB bit set do not undergo pathname expansion; words
9521 with W_NOBRACE set do not undergo brace expansion (see
9522 brace_expand_word_list above). */
9524 expand_word_list_internal (list
, eflags
)
9528 WORD_LIST
*new_list
, *temp_list
;
9531 tempenv_assign_error
= 0;
9533 return ((WORD_LIST
*)NULL
);
9535 garglist
= new_list
= copy_word_list (list
);
9536 if (eflags
& WEXP_VARASSIGN
)
9538 garglist
= new_list
= separate_out_assignments (new_list
);
9541 if (subst_assign_varlist
)
9543 /* All the words were variable assignments, so they are placed
9544 into the shell's environment. */
9545 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9547 this_command_name
= (char *)NULL
; /* no arithmetic errors */
9548 tint
= do_word_assignment (temp_list
->word
, 0);
9549 /* Variable assignment errors in non-interactive shells
9550 running in Posix.2 mode cause the shell to exit. */
9553 last_command_exit_value
= EXECUTION_FAILURE
;
9554 if (interactive_shell
== 0 && posixly_correct
)
9555 exp_jump_to_top_level (FORCE_EOF
);
9557 exp_jump_to_top_level (DISCARD
);
9560 dispose_words (subst_assign_varlist
);
9561 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9563 return ((WORD_LIST
*)NULL
);
9567 /* Begin expanding the words that remain. The expansions take place on
9568 things that aren't really variable assignments. */
9570 #if defined (BRACE_EXPANSION)
9571 /* Do brace expansion on this word if there are any brace characters
9573 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
9574 new_list
= brace_expand_word_list (new_list
, eflags
);
9575 #endif /* BRACE_EXPANSION */
9577 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9578 variable substitution, command substitution, arithmetic expansion,
9579 and word splitting. */
9580 new_list
= shell_expand_word_list (new_list
, eflags
);
9582 /* Okay, we're almost done. Now let's just do some filename
9586 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
9587 /* Glob expand the word list unless globbing has been disabled. */
9588 new_list
= glob_expand_word_list (new_list
, eflags
);
9590 /* Dequote the words, because we're not performing globbing. */
9591 new_list
= dequote_list (new_list
);
9594 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
9596 sh_wassign_func_t
*assign_func
;
9597 int is_special_builtin
, is_builtin_or_func
;
9599 /* If the remainder of the words expand to nothing, Posix.2 requires
9600 that the variable and environment assignments affect the shell's
9602 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
9603 tempenv_assign_error
= 0;
9605 is_builtin_or_func
= (new_list
&& new_list
->word
&& (find_shell_builtin (new_list
->word
->word
) || find_function (new_list
->word
->word
)));
9606 /* Posix says that special builtins exit if a variable assignment error
9607 occurs in an assignment preceding it. */
9608 is_special_builtin
= (posixly_correct
&& new_list
&& new_list
->word
&& find_special_builtin (new_list
->word
->word
));
9610 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9612 this_command_name
= (char *)NULL
;
9613 assigning_in_environment
= (assign_func
== assign_in_env
);
9614 tint
= (*assign_func
) (temp_list
->word
, is_builtin_or_func
);
9615 assigning_in_environment
= 0;
9616 /* Variable assignment errors in non-interactive shells running
9617 in Posix.2 mode cause the shell to exit. */
9620 if (assign_func
== do_word_assignment
)
9622 last_command_exit_value
= EXECUTION_FAILURE
;
9623 if (interactive_shell
== 0 && posixly_correct
&& is_special_builtin
)
9624 exp_jump_to_top_level (FORCE_EOF
);
9626 exp_jump_to_top_level (DISCARD
);
9629 tempenv_assign_error
++;
9633 dispose_words (subst_assign_varlist
);
9634 subst_assign_varlist
= (WORD_LIST
*)NULL
;