1 /* subst.c -- The part of the shell that does parameter, command, arithmetic,
2 and globbing substitutions. */
4 /* ``Have a little faith, there's magic in the night. You ain't a
5 beauty, but, hey, you're alright.'' */
7 /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
47 #include "execute_cmd.h"
51 #include "mailcheck.h"
55 #include "builtins/getopt.h"
56 #include "builtins/common.h"
58 #include "builtins/builtext.h"
60 #include <tilde/tilde.h>
61 #include <glob/strmatch.h>
67 /* The size that strings change by. */
68 #define DEFAULT_INITIAL_ARRAY_SIZE 112
69 #define DEFAULT_ARRAY_SIZE 128
75 #define VT_ARRAYMEMBER 3
78 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
80 /* Flags for quoted_strchr */
81 #define ST_BACKSL 0x01
82 #define ST_CTLESC 0x02
83 #define ST_SQUOTE 0x04 /* unused yet */
84 #define ST_DQUOTE 0x08 /* unused yet */
86 /* Flags for the `pflags' argument to param_expand() */
87 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
88 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
90 /* These defs make it easier to use the editor. */
96 /* Evaluates to 1 if C is one of the shell's special parameters whose length
97 can be taken, but is also one of the special expansion characters. */
98 #define VALID_SPECIAL_LENGTH_PARAM(c) \
99 ((c) == '-' || (c) == '?' || (c) == '#')
101 /* Evaluates to 1 if C is one of the shell's special parameters for which an
102 indirect variable reference may be made. */
103 #define VALID_INDIR_PARAM(c) \
104 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
106 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
107 in ${parameter[:]OPword}. */
108 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
110 /* Evaluates to 1 if this is one of the shell's special variables. */
111 #define SPECIAL_VAR(name, wi) \
112 ((DIGIT (*name) && all_digits (name)) || \
113 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
114 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
116 /* An expansion function that takes a string and a quoted flag and returns
117 a WORD_LIST *. Used as the type of the third argument to
118 expand_string_if_necessary(). */
119 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
121 /* Process ID of the last command executed within command substitution. */
122 pid_t last_command_subst_pid
= NO_PID
;
123 pid_t current_command_subst_pid
= NO_PID
;
125 /* Variables used to keep track of the characters in IFS. */
128 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
130 #if defined (HANDLE_MULTIBYTE)
131 unsigned char ifs_firstc
[MB_LEN_MAX
];
132 size_t ifs_firstc_len
;
134 unsigned char ifs_firstc
;
137 int assigning_in_environment
;
139 /* Extern functions and variables from different files. */
140 extern int last_command_exit_value
, last_command_exit_signal
;
141 extern int subshell_environment
;
142 extern int subshell_level
, parse_and_execute_level
;
143 extern int eof_encountered
;
144 extern int return_catch_flag
, return_catch_value
;
145 extern pid_t dollar_dollar_pid
;
146 extern int posixly_correct
;
147 extern char *this_command_name
;
148 extern struct fd_bitmap
*current_fds_to_close
;
149 extern int wordexp_only
;
150 extern int expanding_redir
;
151 extern int tempenv_assign_error
;
153 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
154 extern wchar_t *wcsdup
__P((const wchar_t *));
157 /* Non-zero means to allow unmatched globbed filenames to expand to
159 int allow_null_glob_expansion
;
161 /* Non-zero means to throw an error when globbing fails to match anything. */
162 int fail_glob_expansion
;
165 /* Variables to keep track of which words in an expanded word list (the
166 output of expand_word_list_internal) are the result of globbing
167 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
168 (CURRENTLY UNUSED). */
169 char *glob_argv_flags
;
170 static int glob_argv_flags_size
;
173 static WORD_LIST expand_word_error
, expand_word_fatal
;
174 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
175 static char expand_param_error
, expand_param_fatal
;
176 static char extract_string_error
, extract_string_fatal
;
178 /* Tell the expansion functions to not longjmp back to top_level on fatal
179 errors. Enabled when doing completion and prompt string expansion. */
180 static int no_longjmp_on_fatal_error
= 0;
182 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
183 $* on $IFS, primarily when doing assignment statements. */
184 static int expand_no_split_dollar_star
= 0;
186 /* Used to hold a list of variable assignments preceding a command. Global
187 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
189 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
191 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
192 without any leading variable assignments. */
193 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
195 static char *quoted_substring
__P((char *, int, int));
196 static int quoted_strlen
__P((char *));
197 static char *quoted_strchr
__P((char *, int, int));
199 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
200 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
201 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
202 static WORD_LIST
*expand_string_internal
__P((char *, int));
203 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
204 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
206 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
207 static char *make_quoted_char
__P((int));
208 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
210 static int unquoted_substring
__P((char *, char *));
211 static int unquoted_member
__P((int, char *));
213 #if defined (ARRAY_VARS)
214 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
216 static int do_assignment_internal
__P((const WORD_DESC
*, int));
218 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
219 static char *string_extract
__P((char *, int *, char *, int));
220 static char *string_extract_double_quoted
__P((char *, int *, int));
221 static inline char *string_extract_single_quoted
__P((char *, int *));
222 static inline int skip_single_quoted
__P((const char *, size_t, int));
223 static int skip_double_quoted
__P((char *, size_t, int));
224 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
225 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
226 static int skip_matched_pair
__P((const char *, int, int, int, int));
228 static char *pos_params
__P((char *, int, int, int));
230 static unsigned char *mb_getcharlens
__P((char *, int));
232 static char *remove_upattern
__P((char *, char *, int));
233 #if defined (HANDLE_MULTIBYTE)
234 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
236 static char *remove_pattern
__P((char *, char *, int));
238 static int match_pattern_char
__P((char *, char *));
239 static int match_upattern
__P((char *, char *, int, char **, char **));
240 #if defined (HANDLE_MULTIBYTE)
241 static int match_pattern_wchar
__P((wchar_t *, wchar_t *));
242 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
244 static int match_pattern
__P((char *, char *, int, char **, char **));
245 static int getpatspec
__P((int, char *));
246 static char *getpattern
__P((char *, int, int));
247 static char *variable_remove_pattern
__P((char *, char *, int, int));
248 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
249 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
251 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
253 static char *parameter_brace_remove_pattern
__P((char *, char *, char *, int, int));
255 static char *process_substitute
__P((char *, int));
257 static char *read_comsub
__P((int, int, int *));
260 static arrayind_t array_length_reference
__P((char *));
263 static int valid_brace_expansion_word
__P((char *, int));
264 static int chk_atstar
__P((char *, int, int *, int *));
265 static int chk_arithsub
__P((const char *, int));
267 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int));
268 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
269 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
270 static void parameter_brace_expand_error
__P((char *, char *));
272 static int valid_length_expression
__P((char *));
273 static intmax_t parameter_brace_expand_length
__P((char *));
275 static char *skiparith
__P((char *, int));
276 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
277 static int get_var_and_type
__P((char *, char *, int, SHELL_VAR
**, char **));
278 static char *mb_substring
__P((char *, int, int));
279 static char *parameter_brace_substring
__P((char *, char *, char *, int));
281 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
283 static char *parameter_brace_patsub
__P((char *, char *, char *, int));
285 static char *pos_params_casemod
__P((char *, char *, int, int));
286 static char *parameter_brace_casemod
__P((char *, char *, int, char *, int));
288 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int *, int *));
289 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
291 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
293 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
295 static void exp_jump_to_top_level
__P((int));
297 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
298 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
299 #ifdef BRACE_EXPANSION
300 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
302 #if defined (ARRAY_VARS)
303 static int make_internal_declare
__P((char *, char *));
305 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
306 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
308 /* **************************************************************** */
310 /* Utility Functions */
312 /* **************************************************************** */
314 #ifdef INCLUDE_UNUSED
316 quoted_substring (string
, start
, end
)
321 register char *result
, *s
, *r
;
325 /* Move to string[start], skipping quoted characters. */
326 for (s
= string
, l
= 0; *s
&& l
< start
; )
338 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
340 /* Copy LEN characters, including quote characters. */
342 for (l
= 0; l
< len
; s
++)
356 #ifdef INCLUDE_UNUSED
357 /* Return the length of S, skipping over quoted characters */
381 /* Find the first occurrence of character C in string S, obeying shell
382 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
383 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
384 escaped with CTLESC are skipped. */
386 quoted_strchr (s
, c
, flags
)
394 if (((flags
& ST_BACKSL
) && *p
== '\\')
395 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
399 return ((char *)NULL
);
405 return ((char *)NULL
);
408 /* Return 1 if CHARACTER appears in an unquoted portion of
409 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
411 unquoted_member (character
, string
)
419 slen
= strlen (string
);
421 while (c
= string
[sindex
])
429 ADVANCE_CHAR (string
, slen
, sindex
);
435 ADVANCE_CHAR (string
, slen
, sindex
);
439 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
443 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
450 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
452 unquoted_substring (substr
, string
)
453 char *substr
, *string
;
456 int sindex
, c
, sublen
;
459 if (substr
== 0 || *substr
== '\0')
462 slen
= strlen (string
);
463 sublen
= strlen (substr
);
464 for (sindex
= 0; c
= string
[sindex
]; )
466 if (STREQN (string
+ sindex
, substr
, sublen
))
475 ADVANCE_CHAR (string
, slen
, sindex
);
479 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
483 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
487 ADVANCE_CHAR (string
, slen
, sindex
);
494 /* Most of the substitutions must be done in parallel. In order
495 to avoid using tons of unclear goto's, I have some functions
496 for manipulating malloc'ed strings. They all take INDX, a
497 pointer to an integer which is the offset into the string
498 where manipulation is taking place. They also take SIZE, a
499 pointer to an integer which is the current length of the
500 character array for this string. */
502 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
503 of space allocated to TARGET. SOURCE can be NULL, in which
504 case nothing happens. Gets rid of SOURCE by freeing it.
505 Returns TARGET in case the location has changed. */
507 sub_append_string (source
, target
, indx
, size
)
508 char *source
, *target
;
515 srclen
= STRLEN (source
);
516 if (srclen
>= (int)(*size
- *indx
))
519 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
520 target
= (char *)xrealloc (target
, (*size
= n
));
523 FASTCOPY (source
, target
+ *indx
, srclen
);
525 target
[*indx
] = '\0';
534 /* Append the textual representation of NUMBER to TARGET.
535 INDX and SIZE are as in SUB_APPEND_STRING. */
537 sub_append_number (number
, target
, indx
, size
)
544 temp
= itos (number
);
545 return (sub_append_string (temp
, target
, indx
, size
));
549 /* Extract a substring from STRING, starting at SINDEX and ending with
550 one of the characters in CHARLIST. Don't make the ending character
551 part of the string. Leave SINDEX pointing at the ending character.
552 Understand about backslashes in the string. If (flags & SX_VARNAME)
553 is non-zero, and array variables have been compiled into the shell,
554 everything between a `[' and a corresponding `]' is skipped over.
555 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
556 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
557 contain a closing character from CHARLIST. */
559 string_extract (string
, sindex
, charlist
, flags
)
571 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
574 while (c
= string
[i
])
583 #if defined (ARRAY_VARS)
584 else if ((flags
& SX_VARNAME
) && c
== '[')
587 /* If this is an array subscript, skip over it and continue. */
588 ni
= skipsubscript (string
, i
);
589 if (string
[ni
] == ']')
593 else if (MEMBER (c
, charlist
))
599 ADVANCE_CHAR (string
, slen
, i
);
602 /* If we had to have a matching delimiter and didn't find one, return an
603 error and let the caller deal with it. */
604 if ((flags
& SX_REQMATCH
) && found
== 0)
607 return (&extract_string_error
);
610 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
616 /* Extract the contents of STRING as if it is enclosed in double quotes.
617 SINDEX, when passed in, is the offset of the character immediately
618 following the opening double quote; on exit, SINDEX is left pointing after
619 the closing double quote. If STRIPDQ is non-zero, unquoted double
620 quotes are stripped and the string is terminated by a null byte.
621 Backslashes between the embedded double quotes are processed. If STRIPDQ
622 is zero, an unquoted `"' terminates the string. */
624 string_extract_double_quoted (string
, sindex
, stripdq
)
626 int *sindex
, stripdq
;
632 char *temp
, *ret
; /* The new string we return. */
633 int pass_next
, backquote
, si
; /* State variables for the machine. */
637 slen
= strlen (string
+ *sindex
) + *sindex
;
638 send
= string
+ slen
;
640 pass_next
= backquote
= dquote
= 0;
641 temp
= (char *)xmalloc (1 + slen
- *sindex
);
645 while (c
= string
[i
])
647 /* Process a character that was quoted by a backslash. */
652 ``The backslash shall retain its special meaning as an escape
653 character only when followed by one of the characters:
656 If STRIPDQ is zero, we handle the double quotes here and let
657 expand_word_internal handle the rest. If STRIPDQ is non-zero,
658 we have already been through one round of backslash stripping,
659 and want to strip these backslashes only if DQUOTE is non-zero,
660 indicating that we are inside an embedded double-quoted string. */
662 /* If we are in an embedded quoted string, then don't strip
663 backslashes before characters for which the backslash
664 retains its special meaning, but remove backslashes in
665 front of other characters. If we are not in an
666 embedded quoted string, don't strip backslashes at all.
667 This mess is necessary because the string was already
668 surrounded by double quotes (and sh has some really weird
670 The returned string will be run through expansion as if
671 it were double-quoted. */
672 if ((stripdq
== 0 && c
!= '"') ||
673 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
678 COPY_CHAR_I (temp
, j
, string
, send
, i
);
682 /* A backslash protects the next character. The code just above
683 handles preserving the backslash in front of any character but
692 /* Inside backquotes, ``the portion of the quoted string from the
693 initial backquote and the characters up to the next backquote
694 that is not preceded by a backslash, having escape characters
695 removed, defines that command''. */
713 /* Pass everything between `$(' and the matching `)' or a quoted
714 ${ ... } pair through according to the Posix.2 specification. */
715 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
720 if (string
[i
+ 1] == LPAREN
)
721 ret
= extract_command_subst (string
, &si
, 0);
723 ret
= extract_dollar_brace_string (string
, &si
, 1, 0);
726 temp
[j
++] = string
[i
+ 1];
728 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
730 if (ret
== 0 && no_longjmp_on_fatal_error
)
733 ret
= string
+ i
+ 2;
736 for (t
= 0; ret
[t
]; t
++, j
++)
738 temp
[j
] = string
[si
];
753 /* Add any character but a double quote to the quoted string we're
756 goto add_one_character
;
770 /* Point to after the closing quote. */
778 /* This should really be another option to string_extract_double_quoted. */
780 skip_double_quoted (string
, slen
, sind
)
787 int pass_next
, backquote
, si
;
790 pass_next
= backquote
= 0;
792 while (c
= string
[i
])
797 ADVANCE_CHAR (string
, slen
, i
);
810 ADVANCE_CHAR (string
, slen
, i
);
819 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
822 if (string
[i
+ 1] == LPAREN
)
823 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
825 ret
= extract_dollar_brace_string (string
, &si
, 1, SX_NOALLOC
);
832 ADVANCE_CHAR (string
, slen
, i
);
845 /* Extract the contents of STRING as if it is enclosed in single quotes.
846 SINDEX, when passed in, is the offset of the character immediately
847 following the opening single quote; on exit, SINDEX is left pointing after
848 the closing single quote. */
850 string_extract_single_quoted (string
, sindex
)
859 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
860 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
862 while (string
[i
] && string
[i
] != '\'')
863 ADVANCE_CHAR (string
, slen
, i
);
865 t
= substring (string
, *sindex
, i
);
875 skip_single_quoted (string
, slen
, sind
)
884 while (string
[c
] && string
[c
] != '\'')
885 ADVANCE_CHAR (string
, slen
, c
);
892 /* Just like string_extract, but doesn't hack backslashes or any of
893 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
895 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
902 register int i
= *sindex
;
903 #if defined (HANDLE_MULTIBYTE)
911 if (charlist
[0] == '\'' && charlist
[1] == '\0')
913 temp
= string_extract_single_quoted (string
, sindex
);
914 --*sindex
; /* leave *sindex at separator character */
920 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
921 this only if MB_CUR_MAX > 1. */
922 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
924 #if defined (HANDLE_MULTIBYTE)
925 clen
= strlen (charlist
);
928 while (c
= string
[i
])
930 #if defined (HANDLE_MULTIBYTE)
933 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
938 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
939 through, to protect the CTLNULs from later calls to
940 remove_quoted_nulls. */
941 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
947 #if defined (HANDLE_MULTIBYTE)
948 mblength
= MBLEN (string
+ i
, slen
- i
);
952 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
953 if (MB_INVALIDCH (mblength
))
955 if (MEMBER (c
, charlist
))
963 len
= mbstowcs (wcharlist
, charlist
, 0);
966 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
967 mbstowcs (wcharlist
, charlist
, len
+ 1);
970 if (wcschr (wcharlist
, wc
))
976 if (MEMBER (c
, charlist
))
979 ADVANCE_CHAR (string
, slen
, i
);
982 #if defined (HANDLE_MULTIBYTE)
986 temp
= substring (string
, *sindex
, i
);
992 /* Extract the $( construct in STRING, and return a new string.
993 Start extracting at (SINDEX) as if we had just seen "$(".
994 Make (SINDEX) get the position of the matching ")". )
995 XFLAGS is additional flags to pass to other extraction functions, */
997 extract_command_subst (string
, sindex
, xflags
)
1002 if (string
[*sindex
] == '(') /*)*/
1003 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1006 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1007 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1011 /* Extract the $[ construct in STRING, and return a new string. (])
1012 Start extracting at (SINDEX) as if we had just seen "$[".
1013 Make (SINDEX) get the position of the matching "]". */
1015 extract_arithmetic_subst (string
, sindex
)
1019 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1022 #if defined (PROCESS_SUBSTITUTION)
1023 /* Extract the <( or >( construct in STRING, and return a new string.
1024 Start extracting at (SINDEX) as if we had just seen "<(".
1025 Make (SINDEX) get the position of the matching ")". */ /*))*/
1027 extract_process_subst (string
, starter
, sindex
)
1032 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", 0));
1034 #endif /* PROCESS_SUBSTITUTION */
1036 #if defined (ARRAY_VARS)
1037 /* This can be fooled by unquoted right parens in the passed string. If
1038 each caller verifies that the last character in STRING is a right paren,
1039 we don't even need to call extract_delimited_string. */
1041 extract_array_assignment_list (string
, sindex
)
1048 slen
= strlen (string
); /* ( */
1049 if (string
[slen
- 1] == ')')
1051 ret
= substring (string
, *sindex
, slen
- 1);
1059 /* Extract and create a new string from the contents of STRING, a
1060 character string delimited with OPENER and CLOSER. SINDEX is
1061 the address of an int describing the current offset in STRING;
1062 it should point to just after the first OPENER found. On exit,
1063 SINDEX gets the position of the last character of the matching CLOSER.
1064 If OPENER is more than a single character, ALT_OPENER, if non-null,
1065 contains a character string that can also match CLOSER and thus
1066 needs to be skipped. */
1068 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1071 char *opener
, *alt_opener
, *closer
;
1077 int pass_character
, nesting_level
, in_comment
;
1078 int len_closer
, len_opener
, len_alt_opener
;
1081 slen
= strlen (string
+ *sindex
) + *sindex
;
1082 len_opener
= STRLEN (opener
);
1083 len_alt_opener
= STRLEN (alt_opener
);
1084 len_closer
= STRLEN (closer
);
1086 pass_character
= in_comment
= 0;
1091 while (nesting_level
)
1102 ADVANCE_CHAR (string
, slen
, i
);
1106 if (pass_character
) /* previous char was backslash */
1109 ADVANCE_CHAR (string
, slen
, i
);
1113 /* Not exactly right yet; should handle shell metacharacters and
1114 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1115 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1118 ADVANCE_CHAR (string
, slen
, i
);
1122 if (c
== CTLESC
|| c
== '\\')
1129 /* Process a nested OPENER. */
1130 if (STREQN (string
+ i
, opener
, len_opener
))
1132 si
= i
+ len_opener
;
1133 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1138 /* Process a nested ALT_OPENER */
1139 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1141 si
= i
+ len_alt_opener
;
1142 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1147 /* If the current substring terminates the delimited string, decrement
1148 the nesting level. */
1149 if (STREQN (string
+ i
, closer
, len_closer
))
1151 i
+= len_closer
- 1; /* move to last byte of the closer */
1153 if (nesting_level
== 0)
1157 /* Pass old-style command substitution through verbatim. */
1161 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1166 /* Pass single-quoted and double-quoted strings through verbatim. */
1167 if (c
== '\'' || c
== '"')
1170 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1171 : skip_double_quoted (string
, slen
, si
);
1175 /* move past this character, which was not special. */
1176 ADVANCE_CHAR (string
, slen
, i
);
1179 if (c
== 0 && nesting_level
)
1181 if (no_longjmp_on_fatal_error
== 0)
1183 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1184 last_command_exit_value
= EXECUTION_FAILURE
;
1185 exp_jump_to_top_level (DISCARD
);
1190 return (char *)NULL
;
1194 si
= i
- *sindex
- len_closer
+ 1;
1195 if (flags
& SX_NOALLOC
)
1196 result
= (char *)NULL
;
1199 result
= (char *)xmalloc (1 + si
);
1200 strncpy (result
, string
+ *sindex
, si
);
1208 /* Extract a parameter expansion expression within ${ and } from STRING.
1209 Obey the Posix.2 rules for finding the ending `}': count braces while
1210 skipping over enclosed quoted strings and command substitutions.
1211 SINDEX is the address of an int describing the current offset in STRING;
1212 it should point to just after the first `{' found. On exit, SINDEX
1213 gets the position of the matching `}'. QUOTED is non-zero if this
1214 occurs inside double quotes. */
1215 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1217 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1219 int *sindex
, quoted
, flags
;
1223 int pass_character
, nesting_level
, si
;
1229 slen
= strlen (string
+ *sindex
) + *sindex
;
1232 while (c
= string
[i
])
1237 ADVANCE_CHAR (string
, slen
, i
);
1241 /* CTLESCs and backslashes quote the next character. */
1242 if (c
== CTLESC
|| c
== '\\')
1249 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1259 if (nesting_level
== 0)
1265 /* Pass the contents of old-style command substitutions through
1270 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1275 /* Pass the contents of new-style command substitutions and
1276 arithmetic substitutions through verbatim. */
1277 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1280 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1285 /* Pass the contents of single-quoted and double-quoted strings
1286 through verbatim. */
1287 if (c
== '\'' || c
== '"')
1290 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1291 : skip_double_quoted (string
, slen
, si
);
1292 /* skip_XXX_quoted leaves index one past close quote */
1296 /* move past this character, which was not special. */
1297 ADVANCE_CHAR (string
, slen
, i
);
1300 if (c
== 0 && nesting_level
)
1302 if (no_longjmp_on_fatal_error
== 0)
1304 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1305 last_command_exit_value
= EXECUTION_FAILURE
;
1306 exp_jump_to_top_level (DISCARD
);
1311 return ((char *)NULL
);
1315 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1321 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1322 STRING, and returns a pointer to it. */
1324 de_backslash (string
)
1327 register size_t slen
;
1328 register int i
, j
, prev_i
;
1331 slen
= strlen (string
);
1334 /* Loop copying string[i] to string[j], i >= j. */
1337 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1338 string
[i
+ 1] == '$'))
1341 ADVANCE_CHAR (string
, slen
, i
);
1343 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1354 /* Replace instances of \! in a string with !. */
1356 unquote_bang (string
)
1360 register char *temp
;
1362 temp
= (char *)xmalloc (1 + strlen (string
));
1364 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1366 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1372 strcpy (string
, temp
);
1377 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1379 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1380 parse array subscripts. FLAGS currently unused. */
1382 skip_matched_pair (string
, start
, open
, close
, flags
)
1384 int start
, open
, close
, flags
;
1386 int i
, pass_next
, backq
, si
, c
, count
;
1391 slen
= strlen (string
+ start
) + start
;
1392 no_longjmp_on_fatal_error
= 1;
1394 i
= start
+ 1; /* skip over leading bracket */
1396 pass_next
= backq
= 0;
1397 ss
= (char *)string
;
1398 while (c
= string
[i
])
1405 ADVANCE_CHAR (string
, slen
, i
);
1418 ADVANCE_CHAR (string
, slen
, i
);
1433 else if (c
== close
)
1441 else if (c
== '\'' || c
== '"')
1443 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1444 : skip_double_quoted (ss
, slen
, ++i
);
1445 /* no increment, the skip functions increment past the closing quote. */
1447 else if (c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1450 if (string
[si
] == '\0')
1453 if (string
[i
+1] == LPAREN
)
1454 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1456 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1458 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1464 ADVANCE_CHAR (string
, slen
, i
);
1470 #if defined (ARRAY_VARS)
1472 skipsubscript (string
, start
)
1476 return (skip_matched_pair (string
, start
, '[', ']', 0));
1480 /* Skip characters in STRING until we find a character in DELIMS, and return
1481 the index of that character. START is the index into string at which we
1482 begin. This is similar in spirit to strpbrk, but it returns an index into
1483 STRING and takes a starting index. This little piece of code knows quite
1484 a lot of shell syntax. It's very similar to skip_double_quoted and other
1485 functions of that ilk. */
1487 skip_to_delim (string
, start
, delims
, flags
)
1493 int i
, pass_next
, backq
, si
, c
, invert
;
1498 slen
= strlen (string
+ start
) + start
;
1499 if (flags
& SD_NOJMP
)
1500 no_longjmp_on_fatal_error
= 1;
1501 invert
= (flags
& SD_INVERT
);
1504 pass_next
= backq
= 0;
1505 while (c
= string
[i
])
1512 ADVANCE_CHAR (string
, slen
, i
);
1525 ADVANCE_CHAR (string
, slen
, i
);
1534 else if (invert
== 0 && member (c
, delims
))
1536 else if (c
== '\'' || c
== '"')
1538 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1539 : skip_double_quoted (string
, slen
, ++i
);
1540 /* no increment, the skip functions increment past the closing quote. */
1542 else if (c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1545 if (string
[si
] == '\0')
1548 if (string
[i
+1] == LPAREN
)
1549 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1551 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1553 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1558 else if (invert
&& (member (c
, delims
) == 0))
1561 ADVANCE_CHAR (string
, slen
, i
);
1567 #if defined (READLINE)
1568 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1569 an unclosed quoted string), or if the character at EINDEX is quoted
1570 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1571 single and double-quoted string parsing functions should not return an
1572 error if there are unclosed quotes or braces. The characters that this
1573 recognizes need to be the same as the contents of
1574 rl_completer_quote_characters. */
1577 char_is_quoted (string
, eindex
)
1581 int i
, pass_next
, c
;
1585 slen
= strlen (string
);
1586 no_longjmp_on_fatal_error
= 1;
1595 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1597 ADVANCE_CHAR (string
, slen
, i
);
1606 else if (c
== '\'' || c
== '"')
1608 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1609 : skip_double_quoted (string
, slen
, ++i
);
1612 /* no increment, the skip_xxx functions go one past end */
1615 ADVANCE_CHAR (string
, slen
, i
);
1622 unclosed_pair (string
, eindex
, openstr
)
1627 int i
, pass_next
, openc
, olen
;
1631 slen
= strlen (string
);
1632 olen
= strlen (openstr
);
1633 i
= pass_next
= openc
= 0;
1639 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1641 ADVANCE_CHAR (string
, slen
, i
);
1644 else if (string
[i
] == '\\')
1650 else if (STREQN (string
+ i
, openstr
, olen
))
1655 else if (string
[i
] == '\'' || string
[i
] == '"')
1657 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1658 : skip_double_quoted (string
, slen
, i
);
1663 ADVANCE_CHAR (string
, slen
, i
);
1668 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1669 individual words. If DELIMS is NULL, the current value of $IFS is used
1670 to split the string, and the function follows the shell field splitting
1671 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1672 gets the number of words in the returned list. CWP, if non-NULL, gets
1673 the index of the word containing SENTINEL. Non-whitespace chars in
1674 DELIMS delimit separate fields. */
1676 split_at_delims (string
, slen
, delims
, sentinel
, nwp
, cwp
)
1683 int ts
, te
, i
, nw
, cw
, ifs_split
;
1684 char *token
, *d
, *d2
;
1685 WORD_LIST
*ret
, *tl
;
1687 if (string
== 0 || *string
== '\0')
1693 return ((WORD_LIST
*)NULL
);
1696 d
= (delims
== 0) ? ifs_value
: delims
;
1697 ifs_split
= delims
== 0;
1699 /* Make d2 the non-whitespace characters in delims */
1704 #if defined (HANDLE_MULTIBYTE)
1705 size_t mblength
= 1;
1709 slength
= strlen (delims
);
1710 d2
= (char *)xmalloc (slength
+ 1);
1714 #if defined (HANDLE_MULTIBYTE)
1715 mbstate_t state_bak
;
1717 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1718 if (MB_INVALIDCH (mblength
))
1720 else if (mblength
> 1)
1722 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1725 slength
-= mblength
;
1729 if (whitespace (delims
[i
]) == 0)
1730 d2
[ts
++] = delims
[i
];
1738 ret
= (WORD_LIST
*)NULL
;
1740 /* Remove sequences of whitspace characters at the start of the string, as
1741 long as those characters are delimiters. */
1742 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1744 if (string
[i
] == '\0')
1752 te
= skip_to_delim (string
, ts
, d
, SD_NOJMP
);
1754 /* If we have a non-whitespace delimiter character, use it to make a
1755 separate field. This is just about what $IFS splitting does and
1756 is closer to the behavior of the shell parser. */
1757 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
1760 /* If we're using IFS splitting, the non-whitespace delimiter char
1761 and any additional IFS whitespace delimits a field. */
1763 while (member (string
[te
], d
) && spctabnl (string
[te
]))
1766 while (member (string
[te
], d2
))
1770 token
= substring (string
, ts
, te
);
1772 ret
= add_string_to_list (token
, ret
);
1776 if (sentinel
>= ts
&& sentinel
<= te
)
1779 /* If the cursor is at whitespace just before word start, set the
1780 sentinel word to the current word. */
1781 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
1784 /* If the cursor is at whitespace between two words, make a new, empty
1785 word, add it before (well, after, since the list is in reverse order)
1786 the word we just added, and set the current word to that one. */
1787 if (cwp
&& cw
== -1 && sentinel
< ts
)
1789 tl
= make_word_list (make_word (""), ret
->next
);
1795 if (string
[te
] == 0)
1799 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
1808 /* Special case for SENTINEL at the end of STRING. If we haven't found
1809 the word containing SENTINEL yet, and the index we're looking for is at
1810 the end of STRING, add an additional null argument and set the current
1811 word pointer to that. */
1812 if (cwp
&& cw
== -1 && sentinel
>= slen
)
1814 if (whitespace (string
[sentinel
- 1]))
1817 ret
= add_string_to_list (token
, ret
);
1828 return (REVERSE_LIST (ret
, WORD_LIST
*));
1830 #endif /* READLINE */
1834 /* Extract the name of the variable to bind to from the assignment string. */
1836 assignment_name (string
)
1842 offset
= assignment (string
, 0);
1844 return (char *)NULL
;
1845 temp
= substring (string
, 0, offset
);
1850 /* **************************************************************** */
1852 /* Functions to convert strings to WORD_LISTs and vice versa */
1854 /* **************************************************************** */
1856 /* Return a single string of all the words in LIST. SEP is the separator
1857 to put between individual elements of LIST in the output string. */
1859 string_list_internal (list
, sep
)
1863 register WORD_LIST
*t
;
1865 int word_len
, sep_len
, result_size
;
1868 return ((char *)NULL
);
1870 /* Short-circuit quickly if we don't need to separate anything. */
1871 if (list
->next
== 0)
1872 return (savestring (list
->word
->word
));
1874 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1875 sep_len
= STRLEN (sep
);
1878 for (t
= list
; t
; t
= t
->next
)
1881 result_size
+= sep_len
;
1882 result_size
+= strlen (t
->word
->word
);
1885 r
= result
= (char *)xmalloc (result_size
+ 1);
1887 for (t
= list
; t
; t
= t
->next
)
1889 if (t
!= list
&& sep_len
)
1893 FASTCOPY (sep
, r
, sep_len
);
1900 word_len
= strlen (t
->word
->word
);
1901 FASTCOPY (t
->word
->word
, r
, word_len
);
1909 /* Return a single string of all the words present in LIST, separating
1910 each word with a space. */
1915 return (string_list_internal (list
, " "));
1918 /* An external interface that can be used by the rest of the shell to
1919 obtain a string containing the first character in $IFS. Handles all
1920 the multibyte complications. If LENP is non-null, it is set to the
1921 length of the returned string. */
1923 ifs_firstchar (lenp
)
1929 ret
= xmalloc (MB_LEN_MAX
+ 1);
1930 #if defined (HANDLE_MULTIBYTE)
1931 if (ifs_firstc_len
== 1)
1933 ret
[0] = ifs_firstc
[0];
1935 len
= ret
[0] ? 1 : 0;
1939 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
1940 ret
[len
= ifs_firstc_len
] = '\0';
1943 ret
[0] = ifs_firstc
;
1945 len
= ret
[0] ? 0 : 1;
1954 /* Return a single string of all the words present in LIST, obeying the
1955 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1956 expansion [of $*] appears within a double quoted string, it expands
1957 to a single field with the value of each parameter separated by the
1958 first character of the IFS variable, or by a <space> if IFS is unset." */
1960 string_list_dollar_star (list
)
1964 #if defined (HANDLE_MULTIBYTE)
1965 # if defined (__GNUC__)
1966 char sep
[MB_CUR_MAX
+ 1];
1974 #if defined (HANDLE_MULTIBYTE)
1975 # if !defined (__GNUC__)
1976 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
1977 # endif /* !__GNUC__ */
1978 if (ifs_firstc_len
== 1)
1980 sep
[0] = ifs_firstc
[0];
1985 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
1986 sep
[ifs_firstc_len
] = '\0';
1989 sep
[0] = ifs_firstc
;
1993 ret
= string_list_internal (list
, sep
);
1994 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2000 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2001 is non-zero, the $@ appears within double quotes, and we should quote
2002 the list before converting it into a string. If IFS is unset, and the
2003 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2004 in the words in the list, because the default value of $IFS is
2005 <space><tab><newline>, IFS characters in the words in the list should
2006 also be split. If IFS is null, and the word is not quoted, we need
2007 to quote the words in the list to preserve the positional parameters
2010 string_list_dollar_at (list
, quoted
)
2015 #if defined (HANDLE_MULTIBYTE)
2016 # if defined (__GNUC__)
2017 char sep
[MB_CUR_MAX
+ 1];
2020 # endif /* !__GNUC__ */
2026 /* XXX this could just be ifs = ifs_value; */
2027 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2029 #if defined (HANDLE_MULTIBYTE)
2030 # if !defined (__GNUC__)
2031 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2032 # endif /* !__GNUC__ */
2035 if (ifs_firstc_len
== 1)
2037 sep
[0] = ifs_firstc
[0];
2042 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2043 sep
[ifs_firstc_len
] = '\0';
2052 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2056 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2057 it now that quote_escapes quotes spaces */
2059 tlist
= ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (ifs
&& *ifs
== 0))
2061 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2064 : list_quote_escapes (list
);
2066 ret
= string_list_internal (tlist
, sep
);
2067 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2073 /* Turn the positional paramters into a string, understanding quoting and
2074 the various subtleties of using the first character of $IFS as the
2075 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2076 string_list as appropriate. */
2078 string_list_pos_params (pchar
, list
, quoted
)
2086 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2088 tlist
= quote_list (list
);
2089 word_list_remove_quoted_nulls (tlist
);
2090 ret
= string_list_dollar_star (tlist
);
2092 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2094 tlist
= quote_list (list
);
2095 word_list_remove_quoted_nulls (tlist
);
2096 ret
= string_list (tlist
);
2098 else if (pchar
== '*')
2100 /* Even when unquoted, string_list_dollar_star does the right thing
2101 making sure that the first character of $IFS is used as the
2103 ret
= string_list_dollar_star (list
);
2105 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2106 /* We use string_list_dollar_at, but only if the string is quoted, since
2107 that quotes the escapes if it's not, which we don't want. We could
2108 use string_list (the old code did), but that doesn't do the right
2109 thing if the first character of $IFS is not a space. We use
2110 string_list_dollar_star if the string is unquoted so we make sure that
2111 the elements of $@ are separated by the first character of $IFS for
2113 ret
= string_list_dollar_at (list
, quoted
);
2114 else if (pchar
== '@')
2115 ret
= string_list_dollar_star (list
);
2117 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2122 /* Return the list of words present in STRING. Separate the string into
2123 words at any of the characters found in SEPARATORS. If QUOTED is
2124 non-zero then word in the list will have its quoted flag set, otherwise
2125 the quoted flag is left as make_word () deemed fit.
2127 This obeys the P1003.2 word splitting semantics. If `separators' is
2128 exactly <space><tab><newline>, then the splitting algorithm is that of
2129 the Bourne shell, which treats any sequence of characters from `separators'
2130 as a delimiter. If IFS is unset, which results in `separators' being set
2131 to "", no splitting occurs. If separators has some other value, the
2132 following rules are applied (`IFS white space' means zero or more
2133 occurrences of <space>, <tab>, or <newline>, as long as those characters
2134 are in `separators'):
2136 1) IFS white space is ignored at the start and the end of the
2138 2) Each occurrence of a character in `separators' that is not
2139 IFS white space, along with any adjacent occurrences of
2140 IFS white space delimits a field.
2141 3) Any nonzero-length sequence of IFS white space delimits a field.
2144 /* BEWARE! list_string strips null arguments. Don't call it twice and
2145 expect to have "" preserved! */
2147 /* This performs word splitting and quoted null character removal on
2150 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2151 : (c) == (separators)[0]) \
2155 list_string (string
, separators
, quoted
)
2156 register char *string
, *separators
;
2161 char *current_word
, *s
;
2162 int sindex
, sh_style_split
, whitesep
, xflags
;
2165 if (!string
|| !*string
)
2166 return ((WORD_LIST
*)NULL
);
2168 sh_style_split
= separators
&& separators
[0] == ' ' &&
2169 separators
[1] == '\t' &&
2170 separators
[2] == '\n' &&
2171 separators
[3] == '\0';
2172 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2174 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2175 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2179 /* Remove sequences of whitespace at the beginning of STRING, as
2180 long as those characters appear in IFS. Do not do this if
2181 STRING is quoted or if there are no separator characters. */
2182 if (!quoted
|| !separators
|| !*separators
)
2184 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2187 return ((WORD_LIST
*)NULL
);
2192 /* OK, now STRING points to a word that does not begin with white space.
2193 The splitting algorithm is:
2194 extract a word, stopping at a separator
2195 skip sequences of spc, tab, or nl as long as they are separators
2196 This obeys the field splitting rules in Posix.2. */
2197 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2198 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2200 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2201 unless multibyte chars are possible. */
2202 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2203 if (current_word
== 0)
2206 /* If we have a quoted empty string, add a quoted null argument. We
2207 want to preserve the quoted null character iff this is a quoted
2208 empty string; otherwise the quoted null characters are removed
2210 if (QUOTED_NULL (current_word
))
2212 t
= alloc_word_desc ();
2213 t
->word
= make_quoted_char ('\0');
2214 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2215 result
= make_word_list (t
, result
);
2217 else if (current_word
[0] != '\0')
2219 /* If we have something, then add it regardless. However,
2220 perform quoted null character removal on the current word. */
2221 remove_quoted_nulls (current_word
);
2222 result
= add_string_to_list (current_word
, result
);
2223 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2224 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2225 result
->word
->flags
|= W_QUOTED
;
2228 /* If we're not doing sequences of separators in the traditional
2229 Bourne shell style, then add a quoted null argument. */
2230 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2232 t
= alloc_word_desc ();
2233 t
->word
= make_quoted_char ('\0');
2234 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2235 result
= make_word_list (t
, result
);
2238 free (current_word
);
2240 /* Note whether or not the separator is IFS whitespace, used later. */
2241 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2243 /* Move past the current separator character. */
2247 ADVANCE_CHAR (string
, slen
, sindex
);
2250 /* Now skip sequences of space, tab, or newline characters if they are
2251 in the list of separators. */
2252 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2255 /* If the first separator was IFS whitespace and the current character
2256 is a non-whitespace IFS character, it should be part of the current
2257 field delimiter, not a separate delimiter that would result in an
2258 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2259 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2262 /* An IFS character that is not IFS white space, along with any
2263 adjacent IFS white space, shall delimit a field. (SUSv3) */
2264 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2268 return (REVERSE_LIST (result
, WORD_LIST
*));
2271 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2272 ENDPTR is set to the first character after the word. This is used by
2273 the `read' builtin. This is never called with SEPARATORS != $IFS;
2274 it should be simplified.
2276 XXX - this function is very similar to list_string; they should be
2279 get_word_from_string (stringp
, separators
, endptr
)
2280 char **stringp
, *separators
, **endptr
;
2284 int sindex
, sh_style_split
, whitesep
, xflags
;
2287 if (!stringp
|| !*stringp
|| !**stringp
)
2288 return ((char *)NULL
);
2290 sh_style_split
= separators
&& separators
[0] == ' ' &&
2291 separators
[1] == '\t' &&
2292 separators
[2] == '\n' &&
2293 separators
[3] == '\0';
2294 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2296 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2297 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2303 /* Remove sequences of whitespace at the beginning of STRING, as
2304 long as those characters appear in IFS. */
2305 if (sh_style_split
|| !separators
|| !*separators
)
2307 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2309 /* If the string is nothing but whitespace, update it and return. */
2315 return ((char *)NULL
);
2319 /* OK, S points to a word that does not begin with white space.
2320 Now extract a word, stopping at a separator, save a pointer to
2321 the first character after the word, then skip sequences of spc,
2322 tab, or nl as long as they are separators.
2324 This obeys the field splitting rules in Posix.2. */
2326 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2327 unless multibyte chars are possible. */
2328 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2329 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2331 /* Set ENDPTR to the first character after the end of the word. */
2333 *endptr
= s
+ sindex
;
2335 /* Note whether or not the separator is IFS whitespace, used later. */
2336 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2338 /* Move past the current separator character. */
2342 ADVANCE_CHAR (s
, slen
, sindex
);
2345 /* Now skip sequences of space, tab, or newline characters if they are
2346 in the list of separators. */
2347 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2350 /* If the first separator was IFS whitespace and the current character is
2351 a non-whitespace IFS character, it should be part of the current field
2352 delimiter, not a separate delimiter that would result in an empty field.
2353 Look at POSIX.2, 3.6.5, (3)(b). */
2354 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2357 /* An IFS character that is not IFS white space, along with any adjacent
2358 IFS white space, shall delimit a field. */
2359 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2363 /* Update STRING to point to the next field. */
2364 *stringp
= s
+ sindex
;
2365 return (current_word
);
2368 /* Remove IFS white space at the end of STRING. Start at the end
2369 of the string and walk backwards until the beginning of the string
2370 or we find a character that's not IFS white space and not CTLESC.
2371 Only let CTLESC escape a white space character if SAW_ESCAPE is
2374 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2375 char *string
, *separators
;
2380 s
= string
+ STRLEN (string
) - 1;
2381 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2382 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2390 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2391 backslashes, single and double quotes. */
2393 list_string_with_quotes (string
)
2399 int c
, i
, tokstart
, len
;
2401 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2403 if (s
== 0 || *s
== 0)
2404 return ((WORD_LIST
*)NULL
);
2408 list
= (WORD_LIST
*)NULL
;
2419 i
= skip_single_quoted (s
, s_len
, ++i
);
2421 i
= skip_double_quoted (s
, s_len
, ++i
);
2422 else if (c
== 0 || spctabnl (c
))
2424 /* We have found the end of a token. Make a word out of it and
2425 add it to the word list. */
2426 token
= substring (s
, tokstart
, i
);
2427 list
= add_string_to_list (token
, list
);
2429 while (spctabnl (s
[i
]))
2437 i
++; /* normal character */
2439 return (REVERSE_LIST (list
, WORD_LIST
*));
2443 /********************************************************/
2445 /* Functions to perform assignment statements */
2447 /********************************************************/
2449 #if defined (ARRAY_VARS)
2451 do_compound_assignment (name
, value
, flags
)
2456 int mklocal
, mkassoc
;
2459 mklocal
= flags
& ASS_MKLOCAL
;
2460 mkassoc
= flags
& ASS_MKASSOC
;
2462 if (mklocal
&& variable_context
)
2464 v
= find_variable (name
);
2465 list
= expand_compound_array_assignment (v
, value
, flags
);
2467 v
= make_local_assoc_variable (name
);
2468 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2469 v
= make_local_array_variable (name
);
2470 assign_compound_array_list (v
, list
, flags
);
2473 v
= assign_array_from_string (name
, value
, flags
);
2479 /* Given STRING, an assignment string, get the value of the right side
2480 of the `=', and bind it to the left side. If EXPAND is true, then
2481 perform parameter expansion, command substitution, and arithmetic
2482 expansion on the right-hand side. Perform tilde expansion in any
2483 case. Do not perform word splitting on the result of expansion. */
2485 do_assignment_internal (word
, expand
)
2486 const WORD_DESC
*word
;
2489 int offset
, tlen
, appendop
, assign_list
, aflags
, retval
;
2492 #if defined (ARRAY_VARS)
2498 if (word
== 0 || word
->word
== 0)
2501 appendop
= assign_list
= aflags
= 0;
2502 string
= word
->word
;
2503 offset
= assignment (string
, 0);
2504 name
= savestring (string
);
2505 value
= (char *)NULL
;
2507 if (name
[offset
] == '=')
2511 if (name
[offset
- 1] == '+')
2514 name
[offset
- 1] = '\0';
2517 name
[offset
] = 0; /* might need this set later */
2518 temp
= name
+ offset
+ 1;
2519 tlen
= STRLEN (temp
);
2521 #if defined (ARRAY_VARS)
2522 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2524 assign_list
= ni
= 1;
2525 value
= extract_array_assignment_list (temp
, &ni
);
2530 if (expand
&& temp
[0])
2531 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2533 value
= savestring (temp
);
2538 value
= (char *)xmalloc (1);
2542 if (echo_command_at_execute
)
2545 name
[offset
- 1] = '+';
2546 xtrace_print_assignment (name
, value
, assign_list
, 1);
2548 name
[offset
- 1] = '\0';
2551 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2554 aflags
|= ASS_APPEND
;
2556 #if defined (ARRAY_VARS)
2557 if (t
= mbschr (name
, '[')) /*]*/
2561 report_error (_("%s: cannot assign list to array member"), name
);
2564 entry
= assign_array_element (name
, value
, aflags
);
2568 else if (assign_list
)
2570 if (word
->flags
& W_ASSIGNARG
)
2571 aflags
|= ASS_MKLOCAL
;
2572 if (word
->flags
& W_ASSIGNASSOC
)
2573 aflags
|= ASS_MKASSOC
;
2574 entry
= do_compound_assignment (name
, value
, aflags
);
2577 #endif /* ARRAY_VARS */
2578 entry
= bind_variable (name
, value
, aflags
);
2580 stupidly_hack_special_variables (name
);
2583 /* Return 1 if the assignment seems to have been performed correctly. */
2584 if (entry
== 0 || readonly_p (entry
))
2585 retval
= 0; /* assignment failure */
2586 else if (noassign_p (entry
))
2588 last_command_exit_value
= EXECUTION_FAILURE
;
2589 retval
= 1; /* error status, but not assignment failure */
2594 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2595 VUNSETATTR (entry
, att_invisible
);
2597 ASSIGN_RETURN (retval
);
2600 VUNSETATTR (entry
, att_invisible
);
2602 ASSIGN_RETURN (entry
? ((readonly_p (entry
) == 0) && noassign_p (entry
) == 0) : 0);
2606 /* Perform the assignment statement in STRING, and expand the
2607 right side by doing tilde, command and parameter expansion. */
2609 do_assignment (string
)
2614 td
.flags
= W_ASSIGNMENT
;
2617 return do_assignment_internal (&td
, 1);
2621 do_word_assignment (word
)
2624 return do_assignment_internal (word
, 1);
2627 /* Given STRING, an assignment string, get the value of the right side
2628 of the `=', and bind it to the left side. Do not perform any word
2629 expansions on the right hand side. */
2631 do_assignment_no_expand (string
)
2636 td
.flags
= W_ASSIGNMENT
;
2639 return (do_assignment_internal (&td
, 0));
2642 /***************************************************
2644 * Functions to manage the positional parameters *
2646 ***************************************************/
2648 /* Return the word list that corresponds to `$*'. */
2650 list_rest_of_args ()
2652 register WORD_LIST
*list
, *args
;
2655 /* Break out of the loop as soon as one of the dollar variables is null. */
2656 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2657 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2659 for (args
= rest_of_args
; args
; args
= args
->next
)
2660 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2662 return (REVERSE_LIST (list
, WORD_LIST
*));
2668 register WORD_LIST
*list
;
2671 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2673 for (list
= rest_of_args
; list
; list
= list
->next
)
2678 /* Return the value of a positional parameter. This handles values > 10. */
2680 get_dollar_var_value (ind
)
2687 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2688 else /* We want something like ${11} */
2691 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2693 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2698 /* Make a single large string out of the dollar digit variables,
2699 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2700 case of "$*" with respect to IFS. */
2702 string_rest_of_args (dollar_star
)
2705 register WORD_LIST
*list
;
2708 list
= list_rest_of_args ();
2709 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2710 dispose_words (list
);
2714 /* Return a string containing the positional parameters from START to
2715 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2716 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2717 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2718 no quoting chars are added. */
2720 pos_params (string
, start
, end
, quoted
)
2722 int start
, end
, quoted
;
2724 WORD_LIST
*save
, *params
, *h
, *t
;
2728 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2730 return ((char *)NULL
);
2732 save
= params
= list_rest_of_args ();
2734 return ((char *)NULL
);
2736 if (start
== 0) /* handle ${@:0[:x]} specially */
2738 t
= make_word_list (make_word (dollar_vars
[0]), params
);
2742 for (i
= 1; params
&& i
< start
; i
++)
2743 params
= params
->next
;
2745 return ((char *)NULL
);
2746 for (h
= t
= params
; params
&& i
< end
; i
++)
2749 params
= params
->next
;
2752 t
->next
= (WORD_LIST
*)NULL
;
2754 ret
= string_list_pos_params (string
[0], h
, quoted
);
2759 dispose_words (save
);
2763 /******************************************************************/
2765 /* Functions to expand strings to strings or WORD_LISTs */
2767 /******************************************************************/
2769 #if defined (PROCESS_SUBSTITUTION)
2770 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
2772 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
2775 /* If there are any characters in STRING that require full expansion,
2776 then call FUNC to expand STRING; otherwise just perform quote
2777 removal if necessary. This returns a new string. */
2779 expand_string_if_necessary (string
, quoted
, func
)
2790 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
2791 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
2795 if (EXP_CHAR (string
[i
]))
2797 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
2799 ADVANCE_CHAR (string
, slen
, i
);
2804 list
= (*func
) (string
, quoted
);
2807 ret
= string_list (list
);
2808 dispose_words (list
);
2813 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
2814 ret
= string_quote_removal (string
, quoted
);
2816 ret
= savestring (string
);
2821 static inline char *
2822 expand_string_to_string_internal (string
, quoted
, func
)
2830 if (string
== 0 || *string
== '\0')
2831 return ((char *)NULL
);
2833 list
= (*func
) (string
, quoted
);
2836 ret
= string_list (list
);
2837 dispose_words (list
);
2846 expand_string_to_string (string
, quoted
)
2850 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
2854 expand_string_unsplit_to_string (string
, quoted
)
2858 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
2862 expand_assignment_string_to_string (string
, quoted
)
2866 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
2870 expand_arith_string (string
, quoted
)
2874 return (expand_string_if_necessary (string
, quoted
, expand_string
));
2877 #if defined (COND_COMMAND)
2878 /* Just remove backslashes in STRING. Returns a new string. */
2880 remove_backslashes (string
)
2885 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
2886 for (s
= string
; s
&& *s
; )
2898 /* This needs better error handling. */
2899 /* Expand W for use as an argument to a unary or binary operator in a
2900 [[...]] expression. If SPECIAL is 1, this is the rhs argument
2901 to the != or == operator, and should be treated as a pattern. In
2902 this case, we quote the string specially for the globbing code. If
2903 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
2904 be quoted appropriately for regcomp/regexec. The caller is responsible
2905 for removing the backslashes if the unquoted word is needed later. */
2907 cond_expand_word (w
, special
)
2915 if (w
->word
== 0 || w
->word
[0] == '\0')
2916 return ((char *)NULL
);
2918 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
2924 r
= string_list (l
);
2928 qflags
= QGLOB_CVTNULL
;
2930 qflags
|= QGLOB_REGEXP
;
2931 p
= string_list (l
);
2932 r
= quote_string_for_globbing (p
, qflags
);
2944 /* Call expand_word_internal to expand W and handle error returns.
2945 A convenience function for functions that don't want to handle
2946 any errors or free any memory before aborting. */
2948 call_expand_word_internal (w
, q
, i
, c
, e
)
2954 result
= expand_word_internal (w
, q
, i
, c
, e
);
2955 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
2957 /* By convention, each time this error is returned, w->word has
2958 already been freed (it sometimes may not be in the fatal case,
2959 but that doesn't result in a memory leak because we're going
2960 to exit in most cases). */
2961 w
->word
= (char *)NULL
;
2962 last_command_exit_value
= EXECUTION_FAILURE
;
2963 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
2970 /* Perform parameter expansion, command substitution, and arithmetic
2971 expansion on STRING, as if it were a word. Leave the result quoted. */
2973 expand_string_internal (string
, quoted
)
2980 if (string
== 0 || *string
== 0)
2981 return ((WORD_LIST
*)NULL
);
2984 td
.word
= savestring (string
);
2986 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
2992 /* Expand STRING by performing parameter expansion, command substitution,
2993 and arithmetic expansion. Dequote the resulting WORD_LIST before
2994 returning it, but do not perform word splitting. The call to
2995 remove_quoted_nulls () is in here because word splitting normally
2996 takes care of quote removal. */
2998 expand_string_unsplit (string
, quoted
)
3004 if (string
== 0 || *string
== '\0')
3005 return ((WORD_LIST
*)NULL
);
3007 expand_no_split_dollar_star
= 1;
3008 value
= expand_string_internal (string
, quoted
);
3009 expand_no_split_dollar_star
= 0;
3015 remove_quoted_nulls (value
->word
->word
);
3016 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3018 dequote_list (value
);
3023 /* Expand the rhs of an assignment statement */
3025 expand_string_assignment (string
, quoted
)
3032 if (string
== 0 || *string
== '\0')
3033 return ((WORD_LIST
*)NULL
);
3035 expand_no_split_dollar_star
= 1;
3037 td
.flags
= W_ASSIGNRHS
;
3038 td
.word
= savestring (string
);
3039 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3042 expand_no_split_dollar_star
= 0;
3048 remove_quoted_nulls (value
->word
->word
);
3049 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3051 dequote_list (value
);
3057 /* Expand one of the PS? prompt strings. This is a sort of combination of
3058 expand_string_unsplit and expand_string_internal, but returns the
3059 passed string when an error occurs. Might want to trap other calls
3060 to jump_to_top_level here so we don't endlessly loop. */
3062 expand_prompt_string (string
, quoted
, wflags
)
3070 if (string
== 0 || *string
== 0)
3071 return ((WORD_LIST
*)NULL
);
3074 td
.word
= savestring (string
);
3076 no_longjmp_on_fatal_error
= 1;
3077 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3078 no_longjmp_on_fatal_error
= 0;
3080 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3082 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3090 remove_quoted_nulls (value
->word
->word
);
3091 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3093 dequote_list (value
);
3098 /* Expand STRING just as if you were expanding a word, but do not dequote
3099 the resultant WORD_LIST. This is called only from within this file,
3100 and is used to correctly preserve quoted characters when expanding
3101 things like ${1+"$@"}. This does parameter expansion, command
3102 substitution, arithmetic expansion, and word splitting. */
3104 expand_string_leave_quoted (string
, quoted
)
3111 if (string
== 0 || *string
== '\0')
3112 return ((WORD_LIST
*)NULL
);
3114 tlist
= expand_string_internal (string
, quoted
);
3118 tresult
= word_list_split (tlist
);
3119 dispose_words (tlist
);
3122 return ((WORD_LIST
*)NULL
);
3125 /* This does not perform word splitting or dequote the WORD_LIST
3128 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3130 int quoted
, *dollar_at_p
, *has_dollar_at
;
3135 if (string
== 0 || *string
== '\0')
3136 return (WORD_LIST
*)NULL
;
3140 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3144 /* Expand STRING just as if you were expanding a word. This also returns
3145 a list of words. Note that filename globbing is *NOT* done for word
3146 or string expansion, just when the shell is expanding a command. This
3147 does parameter expansion, command substitution, arithmetic expansion,
3148 and word splitting. Dequote the resultant WORD_LIST before returning. */
3150 expand_string (string
, quoted
)
3156 if (string
== 0 || *string
== '\0')
3157 return ((WORD_LIST
*)NULL
);
3159 result
= expand_string_leave_quoted (string
, quoted
);
3160 return (result
? dequote_list (result
) : result
);
3163 /***************************************************
3165 * Functions to handle quoting chars *
3167 ***************************************************/
3171 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3172 The parser passes CTLNUL as CTLESC CTLNUL. */
3174 /* Quote escape characters in string s, but no other characters. This is
3175 used to protect CTLESC and CTLNUL in variable values from the rest of
3176 the word expansion process after the variable is expanded (word splitting
3177 and filename generation). If IFS is null, we quote spaces as well, just
3178 in case we split on spaces later (in the case of unquoted $@, we will
3179 eventually attempt to split the entire word on spaces). Corresponding
3180 code exists in dequote_escapes. Even if we don't end up splitting on
3181 spaces, quoting spaces is not a problem. This should never be called on
3182 a string that is quoted with single or double quotes or part of a here
3183 document (effectively double-quoted). */
3185 quote_escapes (string
)
3188 register char *s
, *t
;
3190 char *result
, *send
;
3191 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3194 slen
= strlen (string
);
3195 send
= string
+ slen
;
3197 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3199 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3200 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3202 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3207 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3209 COPY_CHAR_P (t
, s
, send
);
3216 list_quote_escapes (list
)
3219 register WORD_LIST
*w
;
3222 for (w
= list
; w
; w
= w
->next
)
3225 w
->word
->word
= quote_escapes (t
);
3231 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3233 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3234 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3235 data stream pass through properly.
3237 We need to remove doubled CTLESC characters inside quoted strings before
3238 quoting the entire string, so we do not double the number of CTLESC
3241 Also used by parts of the pattern substitution code. */
3243 dequote_escapes (string
)
3246 register char *s
, *t
, *s1
;
3248 char *result
, *send
;
3255 slen
= strlen (string
);
3256 send
= string
+ slen
;
3258 t
= result
= (char *)xmalloc (slen
+ 1);
3260 if (strchr (string
, CTLESC
) == 0)
3261 return (strcpy (result
, string
));
3263 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3268 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3274 COPY_CHAR_P (t
, s
, send
);
3280 /* Return a new string with the quoted representation of character C.
3281 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3282 set in any resultant WORD_DESC where this value is the word. */
3284 make_quoted_char (c
)
3289 temp
= (char *)xmalloc (3);
3304 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3305 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3306 this value is the word. */
3308 quote_string (string
)
3313 char *result
, *send
;
3317 result
= (char *)xmalloc (2);
3325 slen
= strlen (string
);
3326 send
= string
+ slen
;
3328 result
= (char *)xmalloc ((slen
* 2) + 1);
3330 for (t
= result
; string
< send
; )
3333 COPY_CHAR_P (t
, string
, send
);
3340 /* De-quote quoted characters in STRING. */
3342 dequote_string (string
)
3345 register char *s
, *t
;
3347 char *result
, *send
;
3350 slen
= strlen (string
);
3352 t
= result
= (char *)xmalloc (slen
+ 1);
3354 if (QUOTED_NULL (string
))
3360 /* If no character in the string can be quoted, don't bother examining
3361 each character. Just return a copy of the string passed to us. */
3362 if (strchr (string
, CTLESC
) == NULL
)
3363 return (strcpy (result
, string
));
3365 send
= string
+ slen
;
3375 COPY_CHAR_P (t
, s
, send
);
3382 /* Quote the entire WORD_LIST list. */
3387 register WORD_LIST
*w
;
3390 for (w
= list
; w
; w
= w
->next
)
3393 w
->word
->word
= quote_string (t
);
3395 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3396 w
->word
->flags
|= W_QUOTED
;
3402 /* De-quote quoted characters in each word in LIST. */
3408 register WORD_LIST
*tlist
;
3410 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3412 s
= dequote_string (tlist
->word
->word
);
3413 if (QUOTED_NULL (tlist
->word
->word
))
3414 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3415 free (tlist
->word
->word
);
3416 tlist
->word
->word
= s
;
3421 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3424 remove_quoted_escapes (string
)
3431 t
= dequote_escapes (string
);
3439 /* Perform quoted null character removal on STRING. We don't allow any
3440 quoted null characters in the middle or at the ends of strings because
3441 of how expand_word_internal works. remove_quoted_nulls () turns
3442 STRING into an empty string iff it only consists of a quoted null,
3443 and removes all unquoted CTLNUL characters. */
3445 remove_quoted_nulls (string
)
3448 register size_t slen
;
3449 register int i
, j
, prev_i
;
3452 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3453 return string
; /* XXX */
3455 slen
= strlen (string
);
3460 if (string
[i
] == CTLESC
)
3462 /* Old code had j++, but we cannot assume that i == j at this
3463 point -- what if a CTLNUL has already been removed from the
3464 string? We don't want to drop the CTLESC or recopy characters
3465 that we've already copied down. */
3466 i
++; string
[j
++] = CTLESC
;
3470 else if (string
[i
] == CTLNUL
)
3474 ADVANCE_CHAR (string
, slen
, i
);
3477 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3487 /* Perform quoted null character removal on each element of LIST.
3488 This modifies LIST. */
3490 word_list_remove_quoted_nulls (list
)
3493 register WORD_LIST
*t
;
3495 for (t
= list
; t
; t
= t
->next
)
3497 remove_quoted_nulls (t
->word
->word
);
3498 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3502 /* **************************************************************** */
3504 /* Functions for Matching and Removing Patterns */
3506 /* **************************************************************** */
3508 #if defined (HANDLE_MULTIBYTE)
3509 #if 0 /* Currently unused */
3510 static unsigned char *
3511 mb_getcharlens (string
, len
)
3515 int i
, offset
, last
;
3522 ret
= (unsigned char *)xmalloc (len
);
3523 memset (ret
, 0, len
);
3524 while (string
[last
])
3526 ADVANCE_CHAR (string
, len
, offset
);
3527 ret
[last
] = offset
- last
;
3535 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3536 can have one of 4 values:
3537 RP_LONG_LEFT remove longest matching portion at start of PARAM
3538 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3539 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3540 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3543 #define RP_LONG_LEFT 1
3544 #define RP_SHORT_LEFT 2
3545 #define RP_LONG_RIGHT 3
3546 #define RP_SHORT_RIGHT 4
3549 remove_upattern (param
, pattern
, op
)
3550 char *param
, *pattern
;
3555 register char *p
, *ret
, c
;
3557 len
= STRLEN (param
);
3562 case RP_LONG_LEFT
: /* remove longest match at start */
3563 for (p
= end
; p
>= param
; p
--)
3566 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3569 return (savestring (p
));
3576 case RP_SHORT_LEFT
: /* remove shortest match at start */
3577 for (p
= param
; p
<= end
; p
++)
3580 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3583 return (savestring (p
));
3589 case RP_LONG_RIGHT
: /* remove longest match at end */
3590 for (p
= param
; p
<= end
; p
++)
3592 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3595 ret
= savestring (param
);
3602 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3603 for (p
= end
; p
>= param
; p
--)
3605 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3608 ret
= savestring (param
);
3616 return (savestring (param
)); /* no match, return original string */
3619 #if defined (HANDLE_MULTIBYTE)
3621 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3632 case RP_LONG_LEFT
: /* remove longest match at start */
3633 for (n
= wstrlen
; n
>= 0; n
--)
3635 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3636 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3639 return (wcsdup (wparam
+ n
));
3645 case RP_SHORT_LEFT
: /* remove shortest match at start */
3646 for (n
= 0; n
<= wstrlen
; n
++)
3648 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3649 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3652 return (wcsdup (wparam
+ n
));
3658 case RP_LONG_RIGHT
: /* remove longest match at end */
3659 for (n
= 0; n
<= wstrlen
; n
++)
3661 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3663 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3664 ret
= wcsdup (wparam
);
3671 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3672 for (n
= wstrlen
; n
>= 0; n
--)
3674 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3676 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3677 ret
= wcsdup (wparam
);
3685 return (wcsdup (wparam
)); /* no match, return original string */
3687 #endif /* HANDLE_MULTIBYTE */
3690 remove_pattern (param
, pattern
, op
)
3691 char *param
, *pattern
;
3696 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3697 return (savestring (param
));
3699 #if defined (HANDLE_MULTIBYTE)
3702 wchar_t *ret
, *oret
;
3704 wchar_t *wparam
, *wpattern
;
3708 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3709 if (n
== (size_t)-1)
3710 return (remove_upattern (param
, pattern
, op
));
3711 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3712 if (n
== (size_t)-1)
3715 return (remove_upattern (param
, pattern
, op
));
3717 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3723 xret
= (char *)xmalloc (n
+ 1);
3724 memset (&ps
, '\0', sizeof (mbstate_t));
3725 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3726 xret
[n
] = '\0'; /* just to make sure */
3732 return (remove_upattern (param
, pattern
, op
));
3735 /* Return 1 of the first character of STRING could match the first
3736 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
3738 match_pattern_char (pat
, string
)
3749 return (*string
== c
);
3751 return (*string
== *pat
);
3753 return (*pat
== LPAREN
? 1 : (*string
!= '\0'));
3759 return (*pat
== LPAREN
? 1 : (*string
== c
));
3761 return (*string
!= '\0');
3765 /* Match PAT anywhere in STRING and return the match boundaries.
3766 This returns 1 in case of a successful match, 0 otherwise. SP
3767 and EP are pointers into the string where the match begins and
3768 ends, respectively. MTYPE controls what kind of match is attempted.
3769 MATCH_BEG and MATCH_END anchor the match at the beginning and end
3770 of the string, respectively. The longest match is returned. */
3772 match_upattern (string
, pat
, mtype
, sp
, ep
)
3778 register char *p
, *p1
, *npat
;
3781 /* If the pattern doesn't match anywhere in the string, go ahead and
3782 short-circuit right away. A minor optimization, saves a bunch of
3783 unnecessary calls to strmatch (up to N calls for a string of N
3784 characters) if the match is unsuccessful. To preserve the semantics
3785 of the substring matches below, we make sure that the pattern has
3786 `*' as first and last character, making a new pattern if necessary. */
3787 /* XXX - check this later if I ever implement `**' with special meaning,
3788 since this will potentially result in `**' at the beginning or end */
3790 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == '(' && extended_glob
) || pat
[len
- 1] != '*') /*)*/
3792 p
= npat
= (char *)xmalloc (len
+ 3);
3794 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == '(' && extended_glob
)) /*)*/
3798 if (p1
[-1] != '*' || p
[-2] == '\\')
3804 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
3807 if (c
== FNM_NOMATCH
)
3810 len
= STRLEN (string
);
3816 for (p
= string
; p
<= end
; p
++)
3818 if (match_pattern_char (pat
, p
))
3820 for (p1
= end
; p1
>= p
; p1
--)
3822 c
= *p1
; *p1
= '\0';
3823 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3838 if (match_pattern_char (pat
, string
) == 0)
3841 for (p
= end
; p
>= string
; p
--)
3844 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
3857 for (p
= string
; p
<= end
; p
++)
3859 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
3874 #if defined (HANDLE_MULTIBYTE)
3875 /* Return 1 of the first character of WSTRING could match the first
3876 character of pattern WPAT. Wide character version. */
3878 match_pattern_wchar (wpat
, wstring
)
3879 wchar_t *wpat
, *wstring
;
3886 switch (wc
= *wpat
++)
3889 return (*wstring
== wc
);
3891 return (*wstring
== *wpat
);
3893 return (*wpat
== LPAREN
? 1 : (*wstring
!= L
'\0'));
3899 return (*wpat
== LPAREN
? 1 : (*wstring
== wc
));
3901 return (*wstring
!= L
'\0');
3905 /* Match WPAT anywhere in WSTRING and return the match boundaries.
3906 This returns 1 in case of a successful match, 0 otherwise. Wide
3907 character version. */
3909 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
3917 wchar_t wc
, *wp
, *nwpat
, *wp1
;
3920 size_t n
, n1
; /* Apple's gcc seems to miscompile this badly */
3925 /* If the pattern doesn't match anywhere in the string, go ahead and
3926 short-circuit right away. A minor optimization, saves a bunch of
3927 unnecessary calls to strmatch (up to N calls for a string of N
3928 characters) if the match is unsuccessful. To preserve the semantics
3929 of the substring matches below, we make sure that the pattern has
3930 `*' as first and last character, making a new pattern if necessary. */
3931 /* XXX - check this later if I ever implement `**' with special meaning,
3932 since this will potentially result in `**' at the beginning or end */
3933 len
= wcslen (wpat
);
3934 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == L
'(' && extended_glob
) || wpat
[len
- 1] != L
'*') /*)*/
3936 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
3938 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == '(' && extended_glob
)) /*)*/
3940 while (*wp1
!= L
'\0')
3942 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
3948 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
3951 if (len
== FNM_NOMATCH
)
3957 for (n
= 0; n
<= wstrlen
; n
++)
3959 if (match_pattern_wchar (wpat
, wstring
+ n
))
3961 for (n1
= wstrlen
; n1
>= n
; n1
--)
3963 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
3964 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
3979 if (match_pattern_wchar (wpat
, wstring
) == 0)
3982 for (n
= wstrlen
; n
>= 0; n
--)
3984 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
3985 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
3998 for (n
= 0; n
<= wstrlen
; n
++)
4000 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4003 *ep
= indices
[wstrlen
];
4013 #endif /* HANDLE_MULTIBYTE */
4016 match_pattern (string
, pat
, mtype
, sp
, ep
)
4021 #if defined (HANDLE_MULTIBYTE)
4024 wchar_t *wstring
, *wpat
;
4028 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4031 #if defined (HANDLE_MULTIBYTE)
4034 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4035 if (n
== (size_t)-1)
4036 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4037 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4038 if (n
== (size_t)-1)
4041 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4043 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4053 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4057 getpatspec (c
, value
)
4062 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4064 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4067 /* Posix.2 says that the WORD should be run through tilde expansion,
4068 parameter expansion, command substitution and arithmetic expansion.
4069 This leaves the result quoted, so quote_string_for_globbing () has
4070 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4071 it means that the entire expression was enclosed in double quotes.
4072 This means that quoting characters in the pattern do not make any
4073 special pattern characters quoted. For example, the `*' in the
4074 following retains its special meaning: "${foo#'*'}". */
4076 getpattern (value
, quoted
, expandpat
)
4078 int quoted
, expandpat
;
4085 /* There is a problem here: how to handle single or double quotes in the
4086 pattern string when the whole expression is between double quotes?
4087 POSIX.2 says that enclosing double quotes do not cause the pattern to
4088 be quoted, but does that leave us a problem with @ and array[@] and their
4089 expansions inside a pattern? */
4091 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4094 pat
= string_extract_double_quoted (tword
, &i
, 1);
4100 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4102 l
= *value
? expand_string_for_rhs (value
,
4103 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4104 (int *)NULL
, (int *)NULL
)
4106 pat
= string_list (l
);
4110 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4118 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4119 or ${name#[#]value}. */
4121 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4122 char *value
, *pattern
;
4123 int patspec
, quoted
;
4127 tword
= remove_pattern (value
, pattern
, patspec
);
4134 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4137 int patspec
, itype
, quoted
;
4143 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4145 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4146 w
= alloc_word_desc ();
4147 w
->word
= tword
? tword
: savestring ("");
4148 new = make_word_list (w
, new);
4151 l
= REVERSE_LIST (new, WORD_LIST
*);
4152 tword
= string_list_pos_params (itype
, l
, quoted
);
4159 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4162 int patspec
, quoted
;
4167 list
= list_rest_of_args ();
4169 return ((char *)NULL
);
4170 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4171 dispose_words (list
);
4175 #if defined (ARRAY_VARS)
4177 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4181 char *varname
; /* so we can figure out how it's indexed */
4191 /* compute itype from varname here */
4192 v
= array_variable_part (varname
, &ret
, 0);
4195 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4196 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4198 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4200 return ((char *)NULL
);
4201 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4202 dispose_words (list
);
4206 #endif /* ARRAY_VARS */
4209 parameter_brace_remove_pattern (varname
, value
, patstr
, rtype
, quoted
)
4210 char *varname
, *value
, *patstr
;
4213 int vtype
, patspec
, starsub
;
4214 char *temp1
, *val
, *pattern
;
4218 return ((char *)NULL
);
4220 this_command_name
= varname
;
4222 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
4224 return ((char *)NULL
);
4226 starsub
= vtype
& VT_STARSUB
;
4227 vtype
&= ~VT_STARSUB
;
4229 patspec
= getpatspec (rtype
, patstr
);
4230 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4233 /* Need to pass getpattern newly-allocated memory in case of expansion --
4234 the expansion code will free the passed string on an error. */
4235 temp1
= savestring (patstr
);
4236 pattern
= getpattern (temp1
, quoted
, 1);
4239 temp1
= (char *)NULL
; /* shut up gcc */
4243 case VT_ARRAYMEMBER
:
4244 temp1
= remove_pattern (val
, pattern
, patspec
);
4245 if (vtype
== VT_VARIABLE
)
4249 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4250 ? quote_string (temp1
)
4251 : quote_escapes (temp1
);
4256 #if defined (ARRAY_VARS)
4258 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4259 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4261 val
= quote_escapes (temp1
);
4268 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4269 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4271 val
= quote_escapes (temp1
);
4282 /*******************************************
4284 * Functions to expand WORD_DESCs *
4286 *******************************************/
4288 /* Expand WORD, performing word splitting on the result. This does
4289 parameter expansion, command substitution, arithmetic expansion,
4290 word splitting, and quote removal. */
4293 expand_word (word
, quoted
)
4297 WORD_LIST
*result
, *tresult
;
4299 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4300 result
= word_list_split (tresult
);
4301 dispose_words (tresult
);
4302 return (result
? dequote_list (result
) : result
);
4305 /* Expand WORD, but do not perform word splitting on the result. This
4306 does parameter expansion, command substitution, arithmetic expansion,
4307 and quote removal. */
4309 expand_word_unsplit (word
, quoted
)
4315 expand_no_split_dollar_star
= 1;
4316 #if defined (HANDLE_MULTIBYTE)
4317 if (ifs_firstc
[0] == 0)
4319 if (ifs_firstc
== 0)
4321 word
->flags
|= W_NOSPLIT
;
4322 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4323 expand_no_split_dollar_star
= 0;
4325 return (result
? dequote_list (result
) : result
);
4328 /* Perform shell expansions on WORD, but do not perform word splitting or
4329 quote removal on the result. Virtually identical to expand_word_unsplit;
4330 could be combined if implementations don't diverge. */
4332 expand_word_leave_quoted (word
, quoted
)
4338 expand_no_split_dollar_star
= 1;
4339 #if defined (HANDLE_MULTIBYTE)
4340 if (ifs_firstc
[0] == 0)
4342 if (ifs_firstc
== 0)
4344 word
->flags
|= W_NOSPLIT
;
4345 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4346 expand_no_split_dollar_star
= 0;
4351 #if defined (PROCESS_SUBSTITUTION)
4353 /*****************************************************************/
4355 /* Hacking Process Substitution */
4357 /*****************************************************************/
4359 #if !defined (HAVE_DEV_FD)
4360 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4361 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4362 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4363 list. NFIFO is a count of the number of FIFOs in the list. */
4364 #define FIFO_INCR 20
4371 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4373 static int fifo_list_size
;
4376 add_fifo_list (pathname
)
4379 if (nfifo
>= fifo_list_size
- 1)
4381 fifo_list_size
+= FIFO_INCR
;
4382 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4383 fifo_list_size
* sizeof (struct temp_fifo
));
4386 fifo_list
[nfifo
].file
= savestring (pathname
);
4398 for (i
= saved
= 0; i
< nfifo
; i
++)
4400 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4402 unlink (fifo_list
[i
].file
);
4403 free (fifo_list
[i
].file
);
4404 fifo_list
[i
].file
= (char *)NULL
;
4405 fifo_list
[i
].proc
= -1;
4411 /* If we didn't remove some of the FIFOs, compact the list. */
4414 for (i
= j
= 0; i
< nfifo
; i
++)
4415 if (fifo_list
[i
].file
)
4417 fifo_list
[j
].file
= fifo_list
[i
].file
;
4418 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4438 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4439 if (mkfifo (tname
, 0600) < 0)
4442 return ((char *)NULL
);
4445 add_fifo_list (tname
);
4449 #else /* HAVE_DEV_FD */
4451 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4452 has open to children. NFDS is a count of the number of bits currently
4453 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4455 static char *dev_fd_list
= (char *)NULL
;
4457 static int totfds
; /* The highest possible number of open files. */
4463 if (!dev_fd_list
|| fd
>= totfds
)
4468 totfds
= getdtablesize ();
4469 if (totfds
< 0 || totfds
> 256)
4474 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4475 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4478 dev_fd_list
[fd
] = 1;
4485 return 0; /* used for cleanup; not needed with /dev/fd */
4496 for (i
= 0; nfds
&& i
< totfds
; i
++)
4507 #if defined (NOTDEF)
4508 print_dev_fd_list ()
4512 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4515 for (i
= 0; i
< totfds
; i
++)
4518 fprintf (stderr
, " %d", i
);
4520 fprintf (stderr
, "\n");
4525 make_dev_fd_filename (fd
)
4528 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4530 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4532 strcpy (ret
, DEV_FD_PREFIX
);
4533 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4534 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4540 #endif /* HAVE_DEV_FD */
4542 /* Return a filename that will open a connection to the process defined by
4543 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4544 a filename in /dev/fd corresponding to a descriptor that is one of the
4545 ends of the pipe. If not defined, we use named pipes on systems that have
4546 them. Systems without /dev/fd and named pipes are out of luck.
4548 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4549 use the read end of the pipe and dup that file descriptor to fd 0 in
4550 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4551 writing or use the write end of the pipe in the child, and dup that
4552 file descriptor to fd 1 in the child. The parent does the opposite. */
4555 process_substitute (string
, open_for_read_in_child
)
4557 int open_for_read_in_child
;
4562 #if defined (HAVE_DEV_FD)
4563 int parent_pipe_fd
, child_pipe_fd
;
4565 #endif /* HAVE_DEV_FD */
4566 #if defined (JOB_CONTROL)
4567 pid_t old_pipeline_pgrp
;
4570 if (!string
|| !*string
|| wordexp_only
)
4571 return ((char *)NULL
);
4573 #if !defined (HAVE_DEV_FD)
4574 pathname
= make_named_pipe ();
4575 #else /* HAVE_DEV_FD */
4576 if (pipe (fildes
) < 0)
4578 sys_error (_("cannot make pipe for process substitution"));
4579 return ((char *)NULL
);
4581 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4582 the pipe in the parent, otherwise the read end. */
4583 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4584 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4585 /* Move the parent end of the pipe to some high file descriptor, to
4586 avoid clashes with FDs used by the script. */
4587 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4589 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4590 #endif /* HAVE_DEV_FD */
4594 sys_error (_("cannot make pipe for process substitution"));
4595 return ((char *)NULL
);
4598 old_pid
= last_made_pid
;
4600 #if defined (JOB_CONTROL)
4601 old_pipeline_pgrp
= pipeline_pgrp
;
4602 pipeline_pgrp
= shell_pgrp
;
4604 #endif /* JOB_CONTROL */
4606 pid
= make_child ((char *)NULL
, 1);
4609 reset_terminating_signals (); /* XXX */
4610 free_pushed_string_input ();
4611 /* Cancel traps, in trap.c. */
4612 restore_original_signals ();
4613 setup_async_signals ();
4614 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
4617 #if defined (JOB_CONTROL)
4618 set_sigchld_handler ();
4619 stop_making_children ();
4620 /* XXX - should we only do this in the parent? (as in command subst) */
4621 pipeline_pgrp
= old_pipeline_pgrp
;
4622 #endif /* JOB_CONTROL */
4626 sys_error (_("cannot make child for process substitution"));
4628 #if defined (HAVE_DEV_FD)
4629 close (parent_pipe_fd
);
4630 close (child_pipe_fd
);
4631 #endif /* HAVE_DEV_FD */
4632 return ((char *)NULL
);
4637 #if defined (JOB_CONTROL)
4638 restore_pipeline (1);
4641 #if !defined (HAVE_DEV_FD)
4642 fifo_list
[nfifo
-1].proc
= pid
;
4645 last_made_pid
= old_pid
;
4647 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4649 #endif /* JOB_CONTROL && PGRP_PIPE */
4651 #if defined (HAVE_DEV_FD)
4652 close (child_pipe_fd
);
4653 #endif /* HAVE_DEV_FD */
4658 set_sigint_handler ();
4660 #if defined (JOB_CONTROL)
4661 set_job_control (0);
4662 #endif /* JOB_CONTROL */
4664 #if !defined (HAVE_DEV_FD)
4665 /* Open the named pipe in the child. */
4666 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4669 /* Two separate strings for ease of translation. */
4670 if (open_for_read_in_child
)
4671 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4673 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4677 if (open_for_read_in_child
)
4679 if (sh_unset_nodelay_mode (fd
) < 0)
4681 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
4685 #else /* HAVE_DEV_FD */
4687 #endif /* HAVE_DEV_FD */
4689 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4691 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4692 open_for_read_in_child
? 0 : 1);
4696 if (fd
!= (open_for_read_in_child
? 0 : 1))
4699 /* Need to close any files that this process has open to pipes inherited
4701 if (current_fds_to_close
)
4703 close_fd_bitmap (current_fds_to_close
);
4704 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4707 #if defined (HAVE_DEV_FD)
4708 /* Make sure we close the parent's end of the pipe and clear the slot
4709 in the fd list so it is not closed later, if reallocated by, for
4710 instance, pipe(2). */
4711 close (parent_pipe_fd
);
4712 dev_fd_list
[parent_pipe_fd
] = 0;
4713 #endif /* HAVE_DEV_FD */
4715 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4717 #if !defined (HAVE_DEV_FD)
4718 /* Make sure we close the named pipe in the child before we exit. */
4719 close (open_for_read_in_child
? 0 : 1);
4720 #endif /* !HAVE_DEV_FD */
4725 #endif /* PROCESS_SUBSTITUTION */
4727 /***********************************/
4729 /* Command Substitution */
4731 /***********************************/
4734 read_comsub (fd
, quoted
, rflag
)
4738 char *istring
, buf
[128], *bufp
, *s
;
4739 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
4742 istring
= (char *)NULL
;
4743 istring_index
= istring_size
= bufn
= tflag
= 0;
4745 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
4746 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
4749 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4752 /* Read the output of the command through the pipe. This may need to be
4753 changed to understand multibyte characters in the future. */
4760 bufn
= zread (fd
, buf
, sizeof (buf
));
4770 internal_warning ("read_comsub: ignored null byte in input");
4775 /* Add the character to ISTRING, possibly after resizing it. */
4776 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4778 /* This is essentially quote_string inline */
4779 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
4780 istring
[istring_index
++] = CTLESC
;
4781 /* Escape CTLESC and CTLNUL in the output to protect those characters
4782 from the rest of the word expansions (word splitting and globbing.)
4783 This is essentially quote_escapes inline. */
4784 else if (skip_ctlesc
== 0 && c
== CTLESC
)
4786 tflag
|= W_HASCTLESC
;
4787 istring
[istring_index
++] = CTLESC
;
4789 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
4790 istring
[istring_index
++] = CTLESC
;
4792 istring
[istring_index
++] = c
;
4795 #if defined (__CYGWIN__)
4796 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4799 istring
[istring_index
- 1] = '\n';
4806 istring
[istring_index
] = '\0';
4808 /* If we read no output, just return now and save ourselves some
4810 if (istring_index
== 0)
4815 return (char *)NULL
;
4818 /* Strip trailing newlines from the output of the command. */
4819 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4821 while (istring_index
> 0)
4823 if (istring
[istring_index
- 1] == '\n')
4827 /* If the newline was quoted, remove the quoting char. */
4828 if (istring
[istring_index
- 1] == CTLESC
)
4834 istring
[istring_index
] = '\0';
4837 strip_trailing (istring
, istring_index
- 1, 1);
4844 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
4845 contained string possibly quoted. */
4847 command_substitute (string
, quoted
)
4851 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4853 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
4856 istring
= (char *)NULL
;
4858 /* Don't fork () if there is no need to. In the case of no command to
4859 run, just return NULL. */
4860 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
4861 return ((WORD_DESC
*)NULL
);
4863 if (wordexp_only
&& read_but_dont_execute
)
4865 last_command_exit_value
= 125;
4866 jump_to_top_level (EXITPROG
);
4869 /* We're making the assumption here that the command substitution will
4870 eventually run a command from the file system. Since we'll run
4871 maybe_make_export_env in this subshell before executing that command,
4872 the parent shell and any other shells it starts will have to remake
4873 the environment. If we make it before we fork, other shells won't
4874 have to. Don't bother if we have any temporary variable assignments,
4875 though, because the export environment will be remade after this
4876 command completes anyway, but do it if all the words to be expanded
4877 are variable assignments. */
4878 if (subst_assign_varlist
== 0 || garglist
== 0)
4879 maybe_make_export_env (); /* XXX */
4881 /* Flags to pass to parse_and_execute() */
4882 pflags
= interactive
? SEVAL_RESETLINE
: 0;
4884 /* Pipe the output of executing STRING into the current shell. */
4885 if (pipe (fildes
) < 0)
4887 sys_error (_("cannot make pipe for command substitution"));
4891 old_pid
= last_made_pid
;
4892 #if defined (JOB_CONTROL)
4893 old_pipeline_pgrp
= pipeline_pgrp
;
4894 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4895 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
4896 pipeline_pgrp
= shell_pgrp
;
4897 cleanup_the_pipeline ();
4898 #endif /* JOB_CONTROL */
4900 old_async_pid
= last_asynchronous_pid
;
4901 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
4902 last_asynchronous_pid
= old_async_pid
;
4905 /* Reset the signal handlers in the child, but don't free the
4907 reset_signal_handlers ();
4909 #if defined (JOB_CONTROL)
4910 /* XXX DO THIS ONLY IN PARENT ? XXX */
4911 set_sigchld_handler ();
4912 stop_making_children ();
4914 pipeline_pgrp
= old_pipeline_pgrp
;
4916 stop_making_children ();
4917 #endif /* JOB_CONTROL */
4921 sys_error (_("cannot make child for command substitution"));
4927 return ((WORD_DESC
*)NULL
);
4932 set_sigint_handler (); /* XXX */
4934 free_pushed_string_input ();
4936 if (dup2 (fildes
[1], 1) < 0)
4938 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4939 exit (EXECUTION_FAILURE
);
4942 /* If standard output is closed in the parent shell
4943 (such as after `exec >&-'), file descriptor 1 will be
4944 the lowest available file descriptor, and end up in
4945 fildes[0]. This can happen for stdin and stderr as well,
4946 but stdout is more important -- it will cause no output
4947 to be generated from this command. */
4948 if ((fildes
[1] != fileno (stdin
)) &&
4949 (fildes
[1] != fileno (stdout
)) &&
4950 (fildes
[1] != fileno (stderr
)))
4953 if ((fildes
[0] != fileno (stdin
)) &&
4954 (fildes
[0] != fileno (stdout
)) &&
4955 (fildes
[0] != fileno (stderr
)))
4958 /* The currently executing shell is not interactive. */
4961 /* This is a subshell environment. */
4962 subshell_environment
|= SUBSHELL_COMSUB
;
4964 /* When not in POSIX mode, command substitution does not inherit
4966 if (posixly_correct
== 0)
4967 exit_immediately_on_error
= 0;
4969 remove_quoted_escapes (string
);
4971 startup_state
= 2; /* see if we can avoid a fork */
4972 /* Give command substitution a place to jump back to on failure,
4973 so we don't go back up to main (). */
4974 result
= setjmp (top_level
);
4976 /* If we're running a command substitution inside a shell function,
4977 trap `return' so we don't return from the function in the subshell
4978 and go off to never-never land. */
4979 if (result
== 0 && return_catch_flag
)
4980 function_value
= setjmp (return_catch
);
4984 if (result
== ERREXIT
)
4985 rc
= last_command_exit_value
;
4986 else if (result
== EXITPROG
)
4987 rc
= last_command_exit_value
;
4989 rc
= EXECUTION_FAILURE
;
4990 else if (function_value
)
4991 rc
= return_catch_value
;
4995 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
4999 last_command_exit_value
= rc
;
5000 rc
= run_exit_trap ();
5001 #if defined (PROCESS_SUBSTITUTION)
5002 unlink_fifo_list ();
5008 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5010 #endif /* JOB_CONTROL && PGRP_PIPE */
5015 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5019 current_command_subst_pid
= pid
;
5020 last_command_exit_value
= wait_for (pid
);
5021 last_command_subst_pid
= pid
;
5022 last_made_pid
= old_pid
;
5024 #if defined (JOB_CONTROL)
5025 /* If last_command_exit_value > 128, then the substituted command
5026 was terminated by a signal. If that signal was SIGINT, then send
5027 SIGINT to ourselves. This will break out of loops, for instance. */
5028 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5029 kill (getpid (), SIGINT
);
5031 /* wait_for gives the terminal back to shell_pgrp. If some other
5032 process group should have it, give it away to that group here.
5033 pipeline_pgrp is non-zero only while we are constructing a
5034 pipline, so what we are concerned about is whether or not that
5035 pipeline was started in the background. A pipeline started in
5036 the background should never get the tty back here. */
5038 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
5040 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5042 give_terminal_to (pipeline_pgrp
, 0);
5043 #endif /* JOB_CONTROL */
5045 ret
= alloc_word_desc ();
5046 ret
->word
= istring
;
5053 /********************************************************
5055 * Utility functions for parameter expansion *
5057 ********************************************************/
5059 #if defined (ARRAY_VARS)
5062 array_length_reference (s
)
5072 var
= array_variable_part (s
, &t
, &len
);
5074 /* If unbound variables should generate an error, report one and return
5076 if ((var
== 0 || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5080 last_command_exit_value
= EXECUTION_FAILURE
;
5088 /* We support a couple of expansions for variables that are not arrays.
5089 We'll return the length of the value for v[0], and 1 for v[@] or
5090 v[*]. Return 0 for everything else. */
5092 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5094 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5097 return (assoc_num_elements (assoc_cell (var
)));
5098 else if (array_p (var
))
5099 return (array_num_elements (array
));
5107 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5109 if (akey
== 0 || *akey
== 0)
5111 err_badarraysub (t
);
5114 t
= assoc_reference (assoc_cell (var
), akey
);
5118 ind
= array_expand_index (t
, len
);
5121 err_badarraysub (t
);
5125 t
= array_reference (array
, ind
);
5127 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5130 len
= MB_STRLEN (t
);
5133 #endif /* ARRAY_VARS */
5136 valid_brace_expansion_word (name
, var_is_special
)
5140 if (DIGIT (*name
) && all_digits (name
))
5142 else if (var_is_special
)
5144 #if defined (ARRAY_VARS)
5145 else if (valid_array_reference (name
))
5147 #endif /* ARRAY_VARS */
5148 else if (legal_identifier (name
))
5155 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5158 int *quoted_dollar_atp
, *contains_dollar_at
;
5164 if (quoted_dollar_atp
)
5165 *quoted_dollar_atp
= 0;
5166 if (contains_dollar_at
)
5167 *contains_dollar_at
= 0;
5171 /* check for $@ and $* */
5172 if (name
[0] == '@' && name
[1] == 0)
5174 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5175 *quoted_dollar_atp
= 1;
5176 if (contains_dollar_at
)
5177 *contains_dollar_at
= 1;
5180 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5182 if (contains_dollar_at
)
5183 *contains_dollar_at
= 1;
5187 /* Now check for ${array[@]} and ${array[*]} */
5188 #if defined (ARRAY_VARS)
5189 else if (valid_array_reference (name
))
5191 temp1
= mbschr (name
, '[');
5192 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5194 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5195 *quoted_dollar_atp
= 1;
5196 if (contains_dollar_at
)
5197 *contains_dollar_at
= 1;
5200 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5201 which should result in separate words even when IFS is unset. */
5202 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5204 if (contains_dollar_at
)
5205 *contains_dollar_at
= 1;
5213 /* Parameter expand NAME, and return a new string which is the expansion,
5214 or NULL if there was no expansion.
5215 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5216 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5217 NAME was found inside of a double-quoted expression. */
5219 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
)
5221 int var_is_special
, quoted
, pflags
;
5233 /* Handle multiple digit arguments, as in ${11}. */
5234 if (legal_number (name
, &arg_index
))
5236 tt
= get_dollar_var_value (arg_index
);
5238 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5240 : quote_escapes (tt
);
5242 temp
= (char *)NULL
;
5245 else if (var_is_special
) /* ${@} */
5248 tt
= (char *)xmalloc (2 + strlen (name
));
5249 tt
[sindex
= 0] = '$';
5250 strcpy (tt
+ 1, name
);
5252 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5253 (int *)NULL
, (int *)NULL
, pflags
);
5256 #if defined (ARRAY_VARS)
5257 else if (valid_array_reference (name
))
5259 temp
= array_value (name
, quoted
, &atype
);
5260 if (atype
== 0 && temp
)
5261 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5262 ? quote_string (temp
)
5263 : quote_escapes (temp
);
5264 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5265 rflags
|= W_HASQUOTEDNULL
;
5268 else if (var
= find_variable (name
))
5270 if (var_isset (var
) && invisible_p (var
) == 0)
5272 #if defined (ARRAY_VARS)
5274 temp
= assoc_reference (assoc_cell (var
), "0");
5275 else if (array_p (var
))
5276 temp
= array_reference (array_cell (var
), 0);
5278 temp
= value_cell (var
);
5280 temp
= value_cell (var
);
5284 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5285 ? quote_string (temp
)
5286 : quote_escapes (temp
);
5289 temp
= (char *)NULL
;
5292 temp
= (char *)NULL
;
5296 ret
= alloc_word_desc ();
5298 ret
->flags
|= rflags
;
5303 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5304 value of the variable whose name is the value of NAME. */
5306 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5308 int var_is_special
, quoted
;
5309 int *quoted_dollar_atp
, *contains_dollar_at
;
5314 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
5316 /* Have to dequote here if necessary */
5319 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5320 ? dequote_string (t
)
5321 : dequote_escapes (t
);
5325 dispose_word_desc (w
);
5327 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5329 return (WORD_DESC
*)NULL
;
5331 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0);
5337 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5338 depending on the value of C, the separating character. C can be one of
5339 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5340 between double quotes. */
5342 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5344 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5348 char *t
, *t1
, *temp
;
5351 /* If the entire expression is between double quotes, we want to treat
5352 the value as a double-quoted string, with the exception that we strip
5353 embedded unescaped double quotes (for sh backwards compatibility). */
5354 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5357 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5362 w
= alloc_word_desc ();
5364 /* XXX was 0 not quoted */
5365 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5368 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5373 /* The expansion of TEMP returned something. We need to treat things
5374 slightly differently if HASDOL is non-zero. If we have "$@", the
5375 individual words have already been quoted. We need to turn them
5376 into a string with the words separated by the first character of
5377 $IFS without any additional quoting, so string_list_dollar_at won't
5378 do the right thing. We use string_list_dollar_star instead. */
5379 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5381 /* If l->next is not null, we know that TEMP contained "$@", since that
5382 is the only expansion that creates more than one word. */
5383 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5387 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5389 /* The brace expansion occurred between double quotes and there was
5390 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5391 it does not expand to anything. In this case, we want to return
5392 a quoted empty string. */
5393 temp
= make_quoted_char ('\0');
5394 w
->flags
|= W_HASQUOTEDNULL
;
5397 temp
= (char *)NULL
;
5399 if (c
== '-' || c
== '+')
5406 t
= temp
? savestring (temp
) : savestring ("");
5407 t1
= dequote_string (t
);
5409 #if defined (ARRAY_VARS)
5410 if (valid_array_reference (name
))
5411 assign_array_element (name
, t1
, 0);
5413 #endif /* ARRAY_VARS */
5414 bind_variable (name
, t1
, 0);
5421 /* Deal with the right hand side of a ${name:?value} expansion in the case
5422 that NAME is null or not set. If VALUE is non-null it is expanded and
5423 used as the error message to print, otherwise a standard message is
5426 parameter_brace_expand_error (name
, value
)
5432 if (value
&& *value
)
5434 l
= expand_string (value
, 0);
5435 temp
= string_list (l
);
5436 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5441 report_error (_("%s: parameter null or not set"), name
);
5443 /* Free the data we have allocated during this expansion, since we
5444 are about to longjmp out. */
5449 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5452 valid_length_expression (name
)
5455 return (name
[1] == '\0' || /* ${#} */
5456 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5457 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5458 #if defined (ARRAY_VARS)
5459 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5461 legal_identifier (name
+ 1)); /* ${#PS1} */
5464 #if defined (HANDLE_MULTIBYTE)
5470 mbstate_t mbs
, mbsbak
;
5473 memset (&mbs
, 0, sizeof (mbs
));
5475 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5477 if (MB_INVALIDCH(clen
))
5479 clen
= 1; /* assume single byte */
5492 /* Handle the parameter brace expansion that requires us to return the
5493 length of a parameter. */
5495 parameter_brace_expand_length (name
)
5499 intmax_t number
, arg_index
;
5501 #if defined (ARRAY_VARS)
5505 if (name
[1] == '\0') /* ${#} */
5506 number
= number_of_args ();
5507 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5508 number
= number_of_args ();
5509 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5511 /* Take the lengths of some of the shell's special parameters. */
5515 t
= which_set_flags ();
5518 t
= itos (last_command_exit_value
);
5521 t
= itos (dollar_dollar_pid
);
5524 if (last_asynchronous_pid
== NO_PID
)
5527 t
= itos (last_asynchronous_pid
);
5530 t
= itos (number_of_args ());
5533 number
= STRLEN (t
);
5536 #if defined (ARRAY_VARS)
5537 else if (valid_array_reference (name
+ 1))
5538 number
= array_length_reference (name
+ 1);
5539 #endif /* ARRAY_VARS */
5544 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5546 t
= get_dollar_var_value (arg_index
);
5547 number
= MB_STRLEN (t
);
5550 #if defined (ARRAY_VARS)
5551 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
5554 t
= assoc_reference (assoc_cell (var
), "0");
5556 t
= array_reference (array_cell (var
), 0);
5557 number
= MB_STRLEN (t
);
5562 newname
= savestring (name
);
5564 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5565 t
= list
? string_list (list
) : (char *)NULL
;
5568 dispose_words (list
);
5570 number
= MB_STRLEN (t
);
5578 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5579 so we do some ad-hoc parsing of an arithmetic expression to find
5580 the first DELIM, instead of using strchr(3). Two rules:
5581 1. If the substring contains a `(', read until closing `)'.
5582 2. If the substring contains a `?', read past one `:' for each `?'.
5586 skiparith (substr
, delim
)
5591 int skipcol
, pcount
, i
;
5594 sublen
= strlen (substr
);
5595 i
= skipcol
= pcount
= 0;
5598 /* Balance parens */
5599 if (substr
[i
] == LPAREN
)
5605 if (substr
[i
] == RPAREN
&& pcount
)
5613 ADVANCE_CHAR (substr
, sublen
, i
);
5617 /* Skip one `:' for each `?' */
5618 if (substr
[i
] == ':' && skipcol
)
5624 if (substr
[i
] == delim
)
5626 if (substr
[i
] == '?')
5632 ADVANCE_CHAR (substr
, sublen
, i
);
5635 return (substr
+ i
);
5638 /* Verify and limit the start and end of the desired substring. If
5639 VTYPE == 0, a regular shell variable is being used; if it is 1,
5640 then the positional parameters are being used; if it is 2, then
5641 VALUE is really a pointer to an array variable that should be used.
5642 Return value is 1 if both values were OK, 0 if there was a problem
5643 with an invalid expression, or -1 if the values were out of range. */
5645 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
5647 char *value
, *substr
;
5649 intmax_t *e1p
, *e2p
;
5651 char *t
, *temp1
, *temp2
;
5654 #if defined (ARRAY_VARS)
5659 /* duplicate behavior of strchr(3) */
5660 t
= skiparith (substr
, ':');
5661 if (*t
&& *t
== ':')
5666 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5667 *e1p
= evalexp (temp1
, &expok
);
5672 len
= -1; /* paranoia */
5676 case VT_ARRAYMEMBER
:
5677 len
= MB_STRLEN (value
);
5680 len
= number_of_args () + 1;
5682 len
++; /* add one arg if counting from $0 */
5684 #if defined (ARRAY_VARS)
5686 /* For arrays, the first value deals with array indices. Negative
5687 offsets count from one past the array's maximum index. Associative
5688 arrays treat the number of elements as the maximum index. */
5692 len
= assoc_num_elements (h
) + (*e1p
< 0);
5697 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5703 if (len
== -1) /* paranoia */
5706 if (*e1p
< 0) /* negative offsets count from end */
5709 if (*e1p
> len
|| *e1p
< 0)
5712 #if defined (ARRAY_VARS)
5713 /* For arrays, the second offset deals with the number of elements. */
5714 if (vtype
== VT_ARRAYVAR
)
5715 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
5721 temp2
= savestring (t
);
5722 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5725 *e2p
= evalexp (temp1
, &expok
);
5731 internal_error (_("%s: substring expression < 0"), t
);
5734 #if defined (ARRAY_VARS)
5735 /* In order to deal with sparse arrays, push the intelligence about how
5736 to deal with the number of elements desired down to the array-
5737 specific functions. */
5738 if (vtype
!= VT_ARRAYVAR
)
5741 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5752 /* Return the type of variable specified by VARNAME (simple variable,
5753 positional param, or array variable). Also return the value specified
5754 by VARNAME (value of a variable or a reference to an array element).
5755 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5756 characters in the value are quoted with CTLESC and takes appropriate
5757 steps. For convenience, *VALP is set to the dequoted VALUE. */
5759 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5760 char *varname
, *value
;
5767 #if defined (ARRAY_VARS)
5771 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5772 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5773 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5774 vtype
|= VT_STARSUB
;
5775 *varp
= (SHELL_VAR
*)NULL
;
5777 #if defined (ARRAY_VARS)
5778 if (valid_array_reference (varname
))
5780 v
= array_variable_part (varname
, &temp
, (int *)0);
5781 if (v
&& (array_p (v
) || assoc_p (v
)))
5783 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5785 /* Callers have to differentiate betwen indexed and associative */
5786 vtype
= VT_ARRAYVAR
;
5788 vtype
|= VT_STARSUB
;
5789 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
5793 vtype
= VT_ARRAYMEMBER
;
5794 *valp
= array_value (varname
, 1, (int *)NULL
);
5798 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5800 vtype
= VT_VARIABLE
;
5802 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5803 *valp
= dequote_string (value
);
5805 *valp
= dequote_escapes (value
);
5809 vtype
= VT_ARRAYMEMBER
;
5811 *valp
= array_value (varname
, 1, (int *)NULL
);
5814 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
5816 vtype
= VT_ARRAYMEMBER
;
5818 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
5823 if (value
&& vtype
== VT_VARIABLE
)
5825 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5826 *valp
= dequote_string (value
);
5828 *valp
= dequote_escapes (value
);
5837 /******************************************************/
5839 /* Functions to extract substrings of variable values */
5841 /******************************************************/
5843 #if defined (HANDLE_MULTIBYTE)
5844 /* Character-oriented rather than strictly byte-oriented substrings. S and
5845 E, rather being strict indices into STRING, indicate character (possibly
5846 multibyte character) positions that require calculation.
5847 Used by the ${param:offset[:length]} expansion. */
5849 mb_substring (string
, s
, e
)
5854 int start
, stop
, i
, slen
;
5858 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5859 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
5862 while (string
[start
] && i
--)
5863 ADVANCE_CHAR (string
, slen
, start
);
5866 while (string
[stop
] && i
--)
5867 ADVANCE_CHAR (string
, slen
, stop
);
5868 tt
= substring (string
, start
, stop
);
5873 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5874 is `@', use the positional parameters; otherwise, use the value of
5875 VARNAME. If VARNAME is an array variable, use the array elements. */
5878 parameter_brace_substring (varname
, value
, substr
, quoted
)
5879 char *varname
, *value
, *substr
;
5883 int vtype
, r
, starsub
;
5884 char *temp
, *val
, *tt
, *oname
;
5888 return ((char *)NULL
);
5890 oname
= this_command_name
;
5891 this_command_name
= varname
;
5893 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5896 this_command_name
= oname
;
5897 return ((char *)NULL
);
5900 starsub
= vtype
& VT_STARSUB
;
5901 vtype
&= ~VT_STARSUB
;
5903 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
5904 this_command_name
= oname
;
5906 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
5911 case VT_ARRAYMEMBER
:
5912 #if defined (HANDLE_MULTIBYTE)
5914 tt
= mb_substring (val
, e1
, e2
);
5917 tt
= substring (val
, e1
, e2
);
5919 if (vtype
== VT_VARIABLE
)
5921 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5922 temp
= quote_string (tt
);
5924 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5928 tt
= pos_params (varname
, e1
, e2
, quoted
);
5929 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5931 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5937 #if defined (ARRAY_VARS)
5940 /* we convert to list and take first e2 elements starting at e1th
5941 element -- officially undefined for now */
5942 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
5944 /* We want E2 to be the number of elements desired (arrays can be sparse,
5945 so verify_substring_values just returns the numbers specified and we
5946 rely on array_subrange to understand how to deal with them). */
5947 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
5948 /* array_subrange now calls array_quote_escapes as appropriate, so the
5949 caller no longer needs to. */
5953 temp
= (char *)NULL
;
5959 /****************************************************************/
5961 /* Functions to perform pattern substitution on variable values */
5963 /****************************************************************/
5966 pat_subst (string
, pat
, rep
, mflags
)
5967 char *string
, *pat
, *rep
;
5970 char *ret
, *s
, *e
, *str
;
5971 int rsize
, rptr
, l
, replen
, mtype
;
5973 mtype
= mflags
& MATCH_TYPEMASK
;
5976 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5977 * with REP and return the result.
5978 * 2. A null pattern with mtype == MATCH_END means to append REP to
5979 * STRING and return the result.
5981 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
5983 replen
= STRLEN (rep
);
5984 l
= strlen (string
);
5985 ret
= (char *)xmalloc (replen
+ l
+ 2);
5987 strcpy (ret
, string
);
5988 else if (mtype
== MATCH_BEG
)
5991 strcpy (ret
+ replen
, string
);
5995 strcpy (ret
, string
);
5996 strcpy (ret
+ l
, rep
);
6001 ret
= (char *)xmalloc (rsize
= 64);
6004 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6006 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6009 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
6011 /* OK, now copy the leading unmatched portion of the string (from
6012 str to s) to ret starting at rptr (the current offset). Then copy
6013 the replacement string at ret + rptr + (s - str). Increment
6014 rptr (if necessary) and str and go on. */
6017 strncpy (ret
+ rptr
, str
, l
);
6022 strncpy (ret
+ rptr
, rep
, replen
);
6025 str
= e
; /* e == end of match */
6027 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6032 /* On a zero-length match, make sure we copy one character, since
6033 we increment one character to avoid infinite recursion. */
6034 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6035 ret
[rptr
++] = *str
++;
6036 e
++; /* avoid infinite recursion on zero-length match */
6040 /* Now copy the unmatched portion of the input string */
6043 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6044 strcpy (ret
+ rptr
, str
);
6052 /* Do pattern match and replacement on the positional parameters. */
6054 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6055 char *string
, *pat
, *rep
;
6058 WORD_LIST
*save
, *params
;
6063 save
= params
= list_rest_of_args ();
6065 return ((char *)NULL
);
6067 for ( ; params
; params
= params
->next
)
6069 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6070 w
= alloc_word_desc ();
6071 w
->word
= ret
? ret
: savestring ("");
6072 dispose_word (params
->word
);
6076 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6077 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6080 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
6081 ret
= string_list_dollar_star (quote_list (save
));
6082 else if ((mflags
& MATCH_STARSUB
) == MATCH_STARSUB
)
6083 ret
= string_list_dollar_star (save
);
6084 else if ((mflags
& MATCH_QUOTED
) == MATCH_QUOTED
)
6085 ret
= string_list_dollar_at (save
, qflags
);
6087 ret
= string_list_dollar_star (save
);
6089 ret
= string_list_pos_params (pchar
, save
, qflags
);
6092 dispose_words (save
);
6097 /* Perform pattern substitution on VALUE, which is the expansion of
6098 VARNAME. PATSUB is an expression supplying the pattern to match
6099 and the string to substitute. QUOTED is a flags word containing
6100 the type of quoting currently in effect. */
6102 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
6103 char *varname
, *value
, *patsub
;
6106 int vtype
, mflags
, starsub
, delim
;
6107 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6111 return ((char *)NULL
);
6113 this_command_name
= varname
;
6115 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6117 return ((char *)NULL
);
6119 starsub
= vtype
& VT_STARSUB
;
6120 vtype
&= ~VT_STARSUB
;
6123 if (patsub
&& *patsub
== '/')
6125 mflags
|= MATCH_GLOBREP
;
6129 /* Malloc this because expand_string_if_necessary or one of the expansion
6130 functions in its call chain may free it on a substitution error. */
6131 lpatsub
= savestring (patsub
);
6133 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6134 mflags
|= MATCH_QUOTED
;
6137 mflags
|= MATCH_STARSUB
;
6139 /* If the pattern starts with a `/', make sure we skip over it when looking
6140 for the replacement delimiter. */
6142 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
6147 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6148 if (lpatsub
[delim
] == '/')
6151 rep
= lpatsub
+ delim
+ 1;
6157 if (rep
&& *rep
== '\0')
6160 /* Perform the same expansions on the pattern as performed by the
6161 pattern removal expansions. */
6162 pat
= getpattern (lpatsub
, quoted
, 1);
6166 if ((mflags
& MATCH_QUOTED
) == 0)
6167 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6169 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6172 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6173 pattern. This is an extension. Make sure we don't anchor the pattern
6174 at the beginning or end of the string if we're doing global replacement,
6177 if (mflags
& MATCH_GLOBREP
)
6178 mflags
|= MATCH_ANY
;
6179 else if (pat
&& pat
[0] == '#')
6181 mflags
|= MATCH_BEG
;
6184 else if (pat
&& pat
[0] == '%')
6186 mflags
|= MATCH_END
;
6190 mflags
|= MATCH_ANY
;
6192 /* OK, we now want to substitute REP for PAT in VAL. If
6193 flags & MATCH_GLOBREP is non-zero, the substitution is done
6194 everywhere, otherwise only the first occurrence of PAT is
6195 replaced. The pattern matching code doesn't understand
6196 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6197 values passed in (VT_VARIABLE) so the pattern substitution
6198 code works right. We need to requote special chars after
6199 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6200 other cases if QUOTED == 0, since the posparams and arrays
6201 indexed by * or @ do special things when QUOTED != 0. */
6206 case VT_ARRAYMEMBER
:
6207 temp
= pat_subst (val
, p
, rep
, mflags
);
6208 if (vtype
== VT_VARIABLE
)
6212 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6218 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6219 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6221 tt
= quote_escapes (temp
);
6226 #if defined (ARRAY_VARS)
6228 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6229 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6230 /* Don't call quote_escapes anymore; array_patsub calls
6231 array_quote_escapes as appropriate before adding the
6232 space separators; ditto for assoc_patsub. */
6244 /****************************************************************/
6246 /* Functions to perform case modification on variable values */
6248 /****************************************************************/
6250 /* Do case modification on the positional parameters. */
6253 pos_params_modcase (string
, pat
, modop
, mflags
)
6258 WORD_LIST
*save
, *params
;
6263 save
= params
= list_rest_of_args ();
6265 return ((char *)NULL
);
6267 for ( ; params
; params
= params
->next
)
6269 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6270 w
= alloc_word_desc ();
6271 w
->word
= ret
? ret
: savestring ("");
6272 dispose_word (params
->word
);
6276 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6277 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6279 ret
= string_list_pos_params (pchar
, save
, qflags
);
6280 dispose_words (save
);
6285 /* Perform case modification on VALUE, which is the expansion of
6286 VARNAME. MODSPEC is an expression supplying the type of modification
6287 to perform. QUOTED is a flags word containing the type of quoting
6288 currently in effect. */
6290 parameter_brace_casemod (varname
, value
, modspec
, patspec
, quoted
)
6291 char *varname
, *value
;
6296 int vtype
, starsub
, modop
, mflags
, x
;
6297 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6301 return ((char *)NULL
);
6303 this_command_name
= varname
;
6305 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6307 return ((char *)NULL
);
6309 starsub
= vtype
& VT_STARSUB
;
6310 vtype
&= ~VT_STARSUB
;
6314 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6315 mflags
|= MATCH_QUOTED
;
6317 mflags
|= MATCH_STARSUB
;
6322 x
= p
&& p
[0] == modspec
;
6323 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6326 else if (modspec
== ',')
6328 x
= p
&& p
[0] == modspec
;
6329 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6332 else if (modspec
== '~')
6334 x
= p
&& p
[0] == modspec
;
6335 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6339 lpat
= p
? savestring (p
) : 0;
6340 /* Perform the same expansions on the pattern as performed by the
6341 pattern removal expansions. FOR LATER */
6342 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6344 /* OK, now we do the case modification. */
6348 case VT_ARRAYMEMBER
:
6349 temp
= sh_modcase (val
, pat
, modop
);
6350 if (vtype
== VT_VARIABLE
)
6354 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6361 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6362 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6364 tt
= quote_escapes (temp
);
6370 #if defined (ARRAY_VARS)
6372 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
6373 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
6374 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6375 as appropriate before adding the space separators; ditto for
6387 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6388 any occur, this must be a nested command substitution, so return 0.
6389 Otherwise, return 1. A valid arithmetic expression must always have a
6390 ( before a matching ), so any cases where there are more right parens
6391 means that this must not be an arithmetic expression, though the parser
6392 will not accept it without a balanced total number of parens. */
6394 chk_arithsub (s
, len
)
6406 else if (s
[i
] == ')')
6416 ADVANCE_CHAR (s
, len
, i
);
6422 ADVANCE_CHAR (s
, len
, i
);
6426 i
= skip_single_quoted (s
, len
, ++i
);
6430 i
= skip_double_quoted ((char *)s
, len
, ++i
);
6435 return (count
== 0);
6438 /****************************************************************/
6440 /* Functions to perform parameter expansion on a string */
6442 /****************************************************************/
6444 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6446 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
6448 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
6450 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
6451 int want_substring
, want_indir
, want_patsub
, want_casemod
;
6452 char *name
, *value
, *temp
, *temp1
;
6453 WORD_DESC
*tdesc
, *ret
;
6454 int t_index
, sindex
, c
, tflag
, modspec
;
6457 temp
= temp1
= value
= (char *)NULL
;
6458 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
6459 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
6463 /* ${#var} doesn't have any of the other parameter expansions on it. */
6464 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
6465 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
6467 #if defined (CASEMOD_EXPANSIONS)
6468 /* To enable case-toggling expansions using the `~' operator character
6469 change the 1 to 0. */
6470 # if defined (CASEMOD_CAPCASE)
6471 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
6473 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
6474 # endif /* CASEMOD_CAPCASE */
6476 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
6477 #endif /* CASEMOD_EXPANSIONS */
6482 /* If the name really consists of a special variable, then make sure
6483 that we have the entire name. We don't allow indirect references
6484 to special variables except `#', `?', `@' and `*'. */
6485 if ((sindex
== t_index
&&
6486 (string
[t_index
] == '-' ||
6487 string
[t_index
] == '?' ||
6488 string
[t_index
] == '#')) ||
6489 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
6490 (string
[t_index
] == '#' ||
6491 string
[t_index
] == '?' ||
6492 string
[t_index
] == '@' ||
6493 string
[t_index
] == '*')))
6497 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
6498 name
= (char *)xmalloc (3 + (strlen (temp1
)));
6499 *name
= string
[sindex
];
6500 if (string
[sindex
] == '!')
6502 /* indirect reference of $#, $?, $@, or $* */
6503 name
[1] = string
[sindex
+ 1];
6504 strcpy (name
+ 2, temp1
);
6507 strcpy (name
+ 1, temp1
);
6512 /* Find out what character ended the variable name. Then
6513 do the appropriate thing. */
6514 if (c
= string
[sindex
])
6517 /* If c is followed by one of the valid parameter expansion
6518 characters, move past it as normal. If not, assume that
6519 a substring specification is being given, and do not move
6521 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
6524 if (c
= string
[sindex
])
6527 else if (c
== ':' && string
[sindex
] != RBRACE
)
6529 else if (c
== '/' && string
[sindex
] != RBRACE
)
6531 #if defined (CASEMOD_EXPANSIONS)
6532 else if (c
== '^' || c
== ',' || c
== '~')
6539 /* Catch the valid and invalid brace expressions that made it through the
6541 /* ${#-} is a valid expansion and means to take the length of $-.
6542 Similarly for ${#?} and ${##}... */
6543 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6544 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
6546 name
= (char *)xrealloc (name
, 3);
6549 c
= string
[sindex
++];
6552 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6553 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6554 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
6556 temp
= (char *)NULL
;
6557 goto bad_substitution
;
6560 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6561 either a variable name, one of the positional parameters or a special
6562 variable that expands to one of the positional parameters. */
6563 want_indir
= *name
== '!' &&
6564 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
6565 || VALID_INDIR_PARAM (name
[1]));
6567 /* Determine the value of this variable. */
6569 /* Check for special variables, directly referenced. */
6570 if (SPECIAL_VAR (name
, want_indir
))
6573 /* Check for special expansion things, like the length of a parameter */
6574 if (*name
== '#' && name
[1])
6576 /* If we are not pointing at the character just after the
6577 closing brace, then we haven't gotten all of the name.
6578 Since it begins with a special character, this is a bad
6579 substitution. Also check NAME for validity before trying
6581 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6583 temp
= (char *)NULL
;
6584 goto bad_substitution
;
6587 number
= parameter_brace_expand_length (name
);
6592 return (&expand_wdesc_error
);
6595 ret
= alloc_word_desc ();
6596 ret
->word
= itos (number
);
6601 /* ${@} is identical to $@. */
6602 if (name
[0] == '@' && name
[1] == '\0')
6604 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6605 *quoted_dollar_atp
= 1;
6607 if (contains_dollar_at
)
6608 *contains_dollar_at
= 1;
6611 /* Process ${!PREFIX*} expansion. */
6612 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6613 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6614 legal_variable_starter ((unsigned char) name
[1]))
6619 temp1
= savestring (name
+ 1);
6620 number
= strlen (temp1
);
6621 temp1
[number
- 1] = '\0';
6622 x
= all_variables_matching_prefix (temp1
);
6623 xlist
= strvec_to_word_list (x
, 0, 0);
6624 if (string
[sindex
- 2] == '*')
6625 temp
= string_list_dollar_star (xlist
);
6628 temp
= string_list_dollar_at (xlist
, quoted
);
6629 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6630 *quoted_dollar_atp
= 1;
6631 if (contains_dollar_at
)
6632 *contains_dollar_at
= 1;
6639 ret
= alloc_word_desc ();
6644 #if defined (ARRAY_VARS)
6645 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6646 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6647 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6651 temp1
= savestring (name
+ 1);
6652 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6654 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6656 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
6659 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6660 *quoted_dollar_atp
= 1;
6661 if (contains_dollar_at
)
6662 *contains_dollar_at
= 1;
6668 ret
= alloc_word_desc ();
6675 #endif /* ARRAY_VARS */
6677 /* Make sure that NAME is valid before trying to go on. */
6678 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6679 var_is_special
) == 0)
6681 temp
= (char *)NULL
;
6682 goto bad_substitution
;
6686 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6688 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
6693 tflag
= tdesc
->flags
;
6694 dispose_word_desc (tdesc
);
6699 #if defined (ARRAY_VARS)
6700 if (valid_array_reference (name
))
6701 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6704 var_is_set
= temp
!= (char *)0;
6705 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6707 /* Get the rest of the stuff inside the braces. */
6708 if (c
&& c
!= RBRACE
)
6710 /* Extract the contents of the ${ ... } expansion
6711 according to the Posix.2 rules. */
6712 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6713 if (string
[sindex
] == RBRACE
)
6716 goto bad_substitution
;
6719 value
= (char *)NULL
;
6723 /* If this is a substring spec, process it and add the result. */
6726 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6731 if (temp1
== &expand_param_error
)
6732 return (&expand_wdesc_error
);
6733 else if (temp1
== &expand_param_fatal
)
6734 return (&expand_wdesc_fatal
);
6736 ret
= alloc_word_desc ();
6738 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6739 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6742 else if (want_patsub
)
6744 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6749 if (temp1
== &expand_param_error
)
6750 return (&expand_wdesc_error
);
6751 else if (temp1
== &expand_param_fatal
)
6752 return (&expand_wdesc_fatal
);
6754 ret
= alloc_word_desc ();
6756 ret
= alloc_word_desc ();
6758 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6759 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6762 #if defined (CASEMOD_EXPANSIONS)
6763 else if (want_casemod
)
6765 temp1
= parameter_brace_casemod (name
, temp
, modspec
, value
, quoted
);
6770 if (temp1
== &expand_param_error
)
6771 return (&expand_wdesc_error
);
6772 else if (temp1
== &expand_param_fatal
)
6773 return (&expand_wdesc_fatal
);
6775 ret
= alloc_word_desc ();
6777 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6778 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6783 /* Do the right thing based on which character ended the variable name. */
6789 report_error (_("%s: bad substitution"), string
? string
: "??");
6793 return &expand_wdesc_error
;
6796 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
6798 last_command_exit_value
= EXECUTION_FAILURE
;
6799 err_unboundvar (name
);
6803 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6807 case '#': /* ${param#[#]pattern} */
6808 case '%': /* ${param%[%]pattern} */
6809 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6814 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6818 ret
= alloc_word_desc ();
6820 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6821 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6828 if (var_is_set
&& var_is_null
== 0)
6830 /* If the operator is `+', we don't want the value of the named
6831 variable for anything, just the value of the right hand side. */
6835 /* XXX -- if we're double-quoted and the named variable is "$@",
6836 we want to turn off any special handling of "$@" --
6837 we're not using it, so whatever is on the rhs applies. */
6838 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6839 *quoted_dollar_atp
= 0;
6840 if (contains_dollar_at
)
6841 *contains_dollar_at
= 0;
6846 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6849 contains_dollar_at
);
6850 /* XXX - fix up later, esp. noting presence of
6851 W_HASQUOTEDNULL in ret->flags */
6855 temp
= (char *)NULL
;
6861 /* Otherwise do nothing; just use the value in TEMP. */
6863 else /* VAR not set or VAR is NULL. */
6866 temp
= (char *)NULL
;
6867 if (c
== '=' && var_is_special
)
6869 report_error (_("$%s: cannot assign in this way"), name
);
6872 return &expand_wdesc_error
;
6876 parameter_brace_expand_error (name
, value
);
6877 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6881 /* XXX -- if we're double-quoted and the named variable is "$@",
6882 we want to turn off any special handling of "$@" --
6883 we're not using it, so whatever is on the rhs applies. */
6884 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6885 *quoted_dollar_atp
= 0;
6886 if (contains_dollar_at
)
6887 *contains_dollar_at
= 0;
6889 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
6891 contains_dollar_at
);
6892 /* XXX - fix up later, esp. noting presence of
6893 W_HASQUOTEDNULL in tdesc->flags */
6904 ret
= alloc_word_desc ();
6911 /* Expand a single ${xxx} expansion. The braces are optional. When
6912 the braces are used, parameter_brace_expand() does the work,
6913 possibly calling param_expand recursively. */
6915 param_expand (string
, sindex
, quoted
, expanded_something
,
6916 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
6919 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
6920 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
6922 char *temp
, *temp1
, uerror
[3];
6923 int zindex
, t_index
, expok
;
6928 WORD_DESC
*tdesc
, *ret
;
6932 c
= string
[++zindex
];
6934 temp
= (char *)NULL
;
6935 ret
= tdesc
= (WORD_DESC
*)NULL
;
6938 /* Do simple cases first. Switch on what follows '$'. */
6952 temp1
= dollar_vars
[TODIGIT (c
)];
6953 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
6958 last_command_exit_value
= EXECUTION_FAILURE
;
6959 err_unboundvar (uerror
);
6960 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6963 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6964 ? quote_string (temp1
)
6965 : quote_escapes (temp1
);
6967 temp
= (char *)NULL
;
6971 /* $$ -- pid of the invoking shell. */
6973 temp
= itos (dollar_dollar_pid
);
6976 /* $# -- number of positional parameters. */
6978 temp
= itos (number_of_args ());
6981 /* $? -- return value of the last synchronous command. */
6983 temp
= itos (last_command_exit_value
);
6986 /* $- -- flags supplied to the shell on invocation or by `set'. */
6988 temp
= which_set_flags ();
6991 /* $! -- Pid of the last asynchronous command. */
6993 /* If no asynchronous pids have been created, expand to nothing.
6994 If `set -u' has been executed, and no async processes have
6995 been created, this is an expansion error. */
6996 if (last_asynchronous_pid
== NO_PID
)
6998 if (expanded_something
)
6999 *expanded_something
= 0;
7000 temp
= (char *)NULL
;
7001 if (unbound_vars_is_error
)
7006 last_command_exit_value
= EXECUTION_FAILURE
;
7007 err_unboundvar (uerror
);
7008 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7012 temp
= itos (last_asynchronous_pid
);
7015 /* The only difference between this and $@ is when the arg is quoted. */
7016 case '*': /* `$*' */
7017 list
= list_rest_of_args ();
7020 /* According to austin-group posix proposal by Geoff Clare in
7021 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7023 "The shell shall write a message to standard error and
7024 immediately exit when it tries to expand an unset parameter
7025 other than the '@' and '*' special parameters."
7028 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7033 last_command_exit_value
= EXECUTION_FAILURE
;
7034 err_unboundvar (uerror
);
7035 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7039 /* If there are no command-line arguments, this should just
7040 disappear if there are other characters in the expansion,
7041 even if it's quoted. */
7042 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7043 temp
= (char *)NULL
;
7044 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7046 /* If we have "$*" we want to make a string of the positional
7047 parameters, separated by the first character of $IFS, and
7048 quote the whole string, including the separators. If IFS
7049 is unset, the parameters are separated by ' '; if $IFS is
7050 null, the parameters are concatenated. */
7051 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7052 temp1
= quote_string (temp
);
7054 tflag
|= W_HASQUOTEDNULL
;
7060 /* We check whether or not we're eventually going to split $* here,
7061 for example when IFS is empty and we are processing the rhs of
7062 an assignment statement. In that case, we don't separate the
7063 arguments at all. Otherwise, if the $* is not quoted it is
7066 # if defined (HANDLE_MULTIBYTE)
7067 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7069 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7071 temp
= string_list_dollar_star (list
);
7073 temp
= string_list_dollar_at (list
, quoted
);
7075 temp
= string_list_dollar_at (list
, quoted
);
7077 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7078 *contains_dollar_at
= 1;
7081 dispose_words (list
);
7084 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7085 means that we have to turn quoting off after we split into
7086 the individually quoted arguments so that the final split
7087 on the first character of $IFS is still done. */
7088 case '@': /* `$@' */
7089 list
= list_rest_of_args ();
7092 /* According to austin-group posix proposal by Geoff Clare in
7093 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7095 "The shell shall write a message to standard error and
7096 immediately exit when it tries to expand an unset parameter
7097 other than the '@' and '*' special parameters."
7100 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7105 last_command_exit_value
= EXECUTION_FAILURE
;
7106 err_unboundvar (uerror
);
7107 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7111 /* We want to flag the fact that we saw this. We can't turn
7112 off quoting entirely, because other characters in the
7113 string might need it (consider "\"$@\""), but we need some
7114 way to signal that the final split on the first character
7115 of $IFS should be done, even though QUOTED is 1. */
7116 /* XXX - should this test include Q_PATQUOTE? */
7117 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7118 *quoted_dollar_at_p
= 1;
7119 if (contains_dollar_at
)
7120 *contains_dollar_at
= 1;
7122 /* We want to separate the positional parameters with the first
7123 character of $IFS in case $IFS is something other than a space.
7124 We also want to make sure that splitting is done no matter what --
7125 according to POSIX.2, this expands to a list of the positional
7126 parameters no matter what IFS is set to. */
7127 temp
= string_list_dollar_at (list
, quoted
);
7129 dispose_words (list
);
7133 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
7135 contains_dollar_at
);
7137 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7139 temp
= tdesc
? tdesc
->word
: (char *)0;
7142 /* Quoted nulls should be removed if there is anything else
7144 /* Note that we saw the quoted null so we can add one back at
7145 the end of this function if there are no other characters
7146 in the string, discard TEMP, and go on. The exception to
7147 this is when we have "${@}" and $1 is '', since $@ needs
7148 special handling. */
7149 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7151 if (had_quoted_null_p
)
7152 *had_quoted_null_p
= 1;
7153 if (*quoted_dollar_at_p
== 0)
7156 tdesc
->word
= temp
= (char *)NULL
;
7164 /* Do command or arithmetic substitution. */
7166 /* We have to extract the contents of this paren substitution. */
7167 t_index
= zindex
+ 1;
7168 temp
= extract_command_subst (string
, &t_index
, 0);
7171 /* For Posix.2-style `$(( ))' arithmetic substitution,
7172 extract the expression and pass it to the evaluator. */
7173 if (temp
&& *temp
== LPAREN
)
7177 temp2
= savestring (temp1
);
7178 t_index
= strlen (temp2
) - 1;
7180 if (temp2
[t_index
] != RPAREN
)
7186 /* Cut off ending `)' */
7187 temp2
[t_index
] = '\0';
7189 if (chk_arithsub (temp2
, t_index
) == 0)
7195 /* Expand variables found inside the expression. */
7196 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7200 /* No error messages. */
7201 this_command_name
= (char *)NULL
;
7202 number
= evalexp (temp1
, &expok
);
7207 if (interactive_shell
== 0 && posixly_correct
)
7209 last_command_exit_value
= EXECUTION_FAILURE
;
7210 return (&expand_wdesc_fatal
);
7213 return (&expand_wdesc_error
);
7215 temp
= itos (number
);
7220 if (pflags
& PF_NOCOMSUB
)
7221 /* we need zindex+1 because string[zindex] == RPAREN */
7222 temp1
= substring (string
, *sindex
, zindex
+1);
7225 tdesc
= command_substitute (temp
, quoted
);
7226 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7228 dispose_word_desc (tdesc
);
7234 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7235 away in a future bash release. */
7237 /* Extract the contents of this arithmetic substitution. */
7238 t_index
= zindex
+ 1;
7239 temp
= extract_arithmetic_subst (string
, &t_index
);
7243 temp
= savestring (string
);
7244 if (expanded_something
)
7245 *expanded_something
= 0;
7249 /* Do initial variable expansion. */
7250 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7255 /* Find the variable in VARIABLE_LIST. */
7256 temp
= (char *)NULL
;
7258 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7260 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7262 /* If this isn't a variable name, then just output the `$'. */
7263 if (temp1
== 0 || *temp1
== '\0')
7266 temp
= (char *)xmalloc (2);
7269 if (expanded_something
)
7270 *expanded_something
= 0;
7274 /* If the variable exists, return its value cell. */
7275 var
= find_variable (temp1
);
7277 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7279 #if defined (ARRAY_VARS)
7280 if (assoc_p (var
) || array_p (var
))
7282 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7283 : assoc_reference (assoc_cell (var
), "0");
7285 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7286 ? quote_string (temp
)
7287 : quote_escapes (temp
);
7288 else if (unbound_vars_is_error
)
7289 goto unbound_variable
;
7294 temp
= value_cell (var
);
7296 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7297 ? quote_string (temp
)
7298 : quote_escapes (temp
);
7306 temp
= (char *)NULL
;
7309 if (unbound_vars_is_error
)
7311 last_command_exit_value
= EXECUTION_FAILURE
;
7312 err_unboundvar (temp1
);
7321 last_command_exit_value
= EXECUTION_FAILURE
;
7322 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7323 ? &expand_wdesc_fatal
7324 : &expand_wdesc_error
);
7335 ret
= alloc_word_desc ();
7336 ret
->flags
= tflag
; /* XXX */
7342 /* Make a word list which is the result of parameter and variable
7343 expansion, command substitution, arithmetic substitution, and
7344 quote removal of WORD. Return a pointer to a WORD_LIST which is
7345 the result of the expansion. If WORD contains a null word, the
7346 word list returned is also null.
7348 QUOTED contains flag values defined in shell.h.
7350 ISEXP is used to tell expand_word_internal that the word should be
7351 treated as the result of an expansion. This has implications for
7352 how IFS characters in the word are treated.
7354 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7355 they point to an integer value which receives information about expansion.
7356 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7357 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7360 This only does word splitting in the case of $@ expansion. In that
7361 case, we split on ' '. */
7363 /* Values for the local variable quoted_state. */
7365 #define PARTIALLY_QUOTED 1
7366 #define WHOLLY_QUOTED 2
7369 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7372 int *contains_dollar_at
;
7373 int *expanded_something
;
7378 /* The intermediate string that we build while expanding. */
7381 /* The current size of the above object. */
7384 /* Index into ISTRING. */
7387 /* Temporary string storage. */
7390 /* The text of WORD. */
7391 register char *string
;
7393 /* The size of STRING. */
7396 /* The index into STRING. */
7399 /* This gets 1 if we see a $@ while quoted. */
7400 int quoted_dollar_at
;
7402 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7403 whether WORD contains no quoting characters, a partially quoted
7404 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7408 int had_quoted_null
;
7412 int assignoff
; /* If assignment, offset of `=' */
7414 register unsigned char c
; /* Current character. */
7415 int t_index
; /* For calls to string_extract_xxx. */
7421 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
7422 istring
[istring_index
= 0] = '\0';
7423 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
7424 quoted_state
= UNQUOTED
;
7426 string
= word
->word
;
7428 goto finished_with_string
;
7429 /* Don't need the string length for the SADD... and COPY_ macros unless
7430 multibyte characters are possible. */
7431 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
7433 if (contains_dollar_at
)
7434 *contains_dollar_at
= 0;
7438 /* Begin the expansion. */
7444 /* Case on toplevel character. */
7448 goto finished_with_string
;
7452 #if HANDLE_MULTIBYTE
7453 if (MB_CUR_MAX
> 1 && string
[sindex
])
7455 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7460 temp
= (char *)xmalloc (3);
7462 temp
[1] = c
= string
[sindex
];
7473 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
7479 #if defined (PROCESS_SUBSTITUTION)
7480 /* Process substitution. */
7484 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
7486 sindex
--; /* add_character: label increments sindex */
7490 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
7492 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
7495 /* If the process substitution specification is `<()', we want to
7496 open the pipe for writing in the child and produce output; if
7497 it is `>()', we want to open the pipe for reading in the child
7498 and consume input. */
7499 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
7503 goto dollar_add_string
;
7505 #endif /* PROCESS_SUBSTITUTION */
7508 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7509 which are not assignment statements are not expanded. If the
7510 shell isn't in posix mode, though, we perform tilde expansion
7511 on `likely candidate' unquoted assignment statements (flags
7512 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7513 contains an unquoted :~ or =~. Something to think about: we
7514 now have a flag that says to perform tilde expansion on arguments
7515 to `assignment builtins' like declare and export that look like
7516 assignment statements. We now do tilde expansion on such words
7517 even in POSIX mode. */
7518 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
7520 if (isexp
== 0 && isifs (c
))
7521 goto add_ifs_character
;
7525 /* If we're not in posix mode or forcing assignment-statement tilde
7526 expansion, note where the `=' appears in the word and prepare to
7527 do tilde expansion following the first `='. */
7528 if ((word
->flags
& W_ASSIGNMENT
) &&
7529 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7530 assignoff
== -1 && sindex
> 0)
7532 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
7533 word
->flags
|= W_ITILDE
;
7535 else if ((word
->flags
& W_ASSIGNMENT
) &&
7536 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7537 string
[sindex
+1] == '~')
7538 word
->flags
|= W_ITILDE
;
7540 if (isexp
== 0 && isifs (c
))
7541 goto add_ifs_character
;
7546 if (word
->flags
& W_NOTILDE
)
7548 if (isexp
== 0 && isifs (c
))
7549 goto add_ifs_character
;
7554 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
7555 string
[sindex
+1] == '~')
7556 word
->flags
|= W_ITILDE
;
7558 if (isexp
== 0 && isifs (c
))
7559 goto add_ifs_character
;
7564 /* If the word isn't supposed to be tilde expanded, or we're not
7565 at the start of a word or after an unquoted : or = in an
7566 assignment statement, we don't do tilde expansion. */
7567 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
7568 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
7569 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7571 word
->flags
&= ~W_ITILDE
;
7572 if (isexp
== 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
7573 goto add_ifs_character
;
7578 if (word
->flags
& W_ASSIGNRHS
)
7580 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
7585 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
7587 word
->flags
&= ~W_ITILDE
;
7589 if (temp
&& *temp
&& t_index
> 0)
7591 temp1
= bash_tilde_expand (temp
, tflag
);
7592 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
7596 goto add_character
; /* tilde expansion failed */
7601 goto add_quoted_string
; /* XXX was add_string */
7610 if (expanded_something
)
7611 *expanded_something
= 1;
7614 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
7615 &has_dollar_at
, "ed_dollar_at
,
7617 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
7619 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
7623 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
7624 : &expand_word_fatal
);
7626 if (contains_dollar_at
&& has_dollar_at
)
7627 *contains_dollar_at
= 1;
7629 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
7630 had_quoted_null
= 1;
7633 dispose_word_desc (tword
);
7638 case '`': /* Backquoted command substitution. */
7642 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
7643 /* The test of sindex against t_index is to allow bare instances of
7644 ` to pass through, for backwards compatibility. */
7645 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
7647 if (sindex
- 1 == t_index
)
7652 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
7655 return ((temp
== &extract_string_error
) ? &expand_word_error
7656 : &expand_word_fatal
);
7659 if (expanded_something
)
7660 *expanded_something
= 1;
7662 if (word
->flags
& W_NOCOMSUB
)
7663 /* sindex + 1 because string[sindex] == '`' */
7664 temp1
= substring (string
, t_index
, sindex
+ 1);
7667 de_backslash (temp
);
7668 tword
= command_substitute (temp
, quoted
);
7669 temp1
= tword
? tword
->word
: (char *)NULL
;
7671 dispose_word_desc (tword
);
7675 goto dollar_add_string
;
7679 if (string
[sindex
+ 1] == '\n')
7685 c
= string
[++sindex
];
7687 if (quoted
& Q_HERE_DOCUMENT
)
7689 else if (quoted
& Q_DOUBLE_QUOTES
)
7694 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7696 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7701 sindex
--; /* add_character: label increments sindex */
7706 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7711 /* BEFORE jumping here, we need to increment sindex if appropriate */
7712 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7713 DEFAULT_ARRAY_SIZE
);
7714 istring
[istring_index
++] = twochars
[0];
7715 istring
[istring_index
++] = twochars
[1];
7716 istring
[istring_index
] = '\0';
7722 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7724 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7729 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7731 /* If the quotes surrounded the entire string, then the
7732 whole word was quoted. */
7733 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7739 tword
= alloc_word_desc ();
7742 temp
= (char *)NULL
;
7745 /* Need to get W_HASQUOTEDNULL flag through this function. */
7746 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7748 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7752 /* expand_word_internal has already freed temp_word->word
7753 for us because of the way it prints error messages. */
7754 tword
->word
= (char *)NULL
;
7755 dispose_word (tword
);
7759 dispose_word (tword
);
7761 /* "$@" (a double-quoted dollar-at) expands into nothing,
7762 not even a NULL word, when there are no positional
7764 if (list
== 0 && has_dollar_at
)
7770 /* If we get "$@", we know we have expanded something, so we
7771 need to remember it for the final split on $IFS. This is
7772 a special case; it's the only case where a quoted string
7773 can expand into more than one word. It's going to come back
7774 from the above call to expand_word_internal as a list with
7775 a single word, in which all characters are quoted and
7776 separated by blanks. What we want to do is to turn it back
7777 into a list for the next piece of code. */
7779 dequote_list (list
);
7781 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7782 had_quoted_null
= 1;
7787 if (contains_dollar_at
)
7788 *contains_dollar_at
= 1;
7789 if (expanded_something
)
7790 *expanded_something
= 1;
7795 /* What we have is "". This is a minor optimization. */
7797 list
= (WORD_LIST
*)NULL
;
7800 /* The code above *might* return a list (consider the case of "$@",
7801 where it returns "$1", "$2", etc.). We can't throw away the
7802 rest of the list, and we have to make sure each word gets added
7803 as quoted. We test on tresult->next: if it is non-NULL, we
7804 quote the whole list, save it to a string with string_list, and
7805 add that string. We don't need to quote the results of this
7806 (and it would be wrong, since that would quote the separators
7807 as well), so we go directly to add_string. */
7812 /* Testing quoted_dollar_at makes sure that "$@" is
7813 split correctly when $IFS does not contain a space. */
7814 temp
= quoted_dollar_at
7815 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7816 : string_list (quote_list (list
));
7817 dispose_words (list
);
7822 temp
= savestring (list
->word
->word
);
7823 tflag
= list
->word
->flags
;
7824 dispose_words (list
);
7826 /* If the string is not a quoted null string, we want
7827 to remove any embedded unquoted CTLNUL characters.
7828 We do not want to turn quoted null strings back into
7829 the empty string, though. We do this because we
7830 want to remove any quoted nulls from expansions that
7831 contain other characters. For example, if we have
7832 x"$*"y or "x$*y" and there are no positional parameters,
7833 the $* should expand into nothing. */
7834 /* We use the W_HASQUOTEDNULL flag to differentiate the
7835 cases: a quoted null character as above and when
7836 CTLNUL is contained in the (non-null) expansion
7837 of some variable. We use the had_quoted_null flag to
7838 pass the value through this function to its caller. */
7839 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7840 remove_quoted_nulls (temp
); /* XXX */
7844 temp
= (char *)NULL
;
7846 /* We do not want to add quoted nulls to strings that are only
7847 partially quoted; we can throw them away. */
7848 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7856 temp
= quote_string (temp
);
7864 sindex
--; /* add_character: label increments sindex */
7872 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7874 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7879 temp
= string_extract_single_quoted (string
, &sindex
);
7881 /* If the entire STRING was surrounded by single quotes,
7882 then the string is wholly quoted. */
7883 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7887 /* If all we had was '', it is a null expansion. */
7891 temp
= (char *)NULL
;
7894 remove_quoted_escapes (temp
); /* ??? */
7896 /* We do not want to add quoted nulls to strings that are only
7897 partially quoted; such nulls are discarded. */
7898 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7901 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7905 sindex
--; /* add_character: label increments sindex */
7909 goto add_quoted_string
;
7914 /* This is the fix for " $@ " */
7916 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7918 if (string
[sindex
]) /* from old goto dollar_add_string */
7927 #if HANDLE_MULTIBYTE
7933 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7938 twochars
[0] = CTLESC
;
7945 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7948 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7949 DEFAULT_ARRAY_SIZE
);
7950 istring
[istring_index
++] = c
;
7951 istring
[istring_index
] = '\0';
7953 /* Next character. */
7958 finished_with_string
:
7959 /* OK, we're ready to return. If we have a quoted string, and
7960 quoted_dollar_at is not set, we do no splitting at all; otherwise
7961 we split on ' '. The routines that call this will handle what to
7962 do if nothing has been expanded. */
7964 /* Partially and wholly quoted strings which expand to the empty
7965 string are retained as an empty arguments. Unquoted strings
7966 which expand to the empty string are discarded. The single
7967 exception is the case of expanding "$@" when there are no
7968 positional parameters. In that case, we discard the expansion. */
7970 /* Because of how the code that handles "" and '' in partially
7971 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7972 if we saw quoting characters, but the expansion was empty.
7973 "" and '' are tossed away before we get to this point when
7974 processing partially quoted strings. This makes "" and $xxx""
7975 equivalent when xxx is unset. We also look to see whether we
7976 saw a quoted null from a ${} expansion and add one back if we
7979 /* If we expand to nothing and there were no single or double quotes
7980 in the word, we throw it away. Otherwise, we return a NULL word.
7981 The single exception is for $@ surrounded by double quotes when
7982 there are no positional parameters. In that case, we also throw
7985 if (*istring
== '\0')
7987 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7989 istring
[0] = CTLNUL
;
7991 tword
= make_bare_word (istring
);
7992 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7993 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7994 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7995 tword
->flags
|= W_QUOTED
;
7997 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7998 and a double-quoted "$@" appears anywhere in it, then the entire
8000 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8001 list
= (WORD_LIST
*)NULL
;
8005 tword
= make_bare_word (istring
);
8006 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8007 tword
->flags
|= W_QUOTED
;
8008 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8012 list
= (WORD_LIST
*)NULL
;
8015 else if (word
->flags
& W_NOSPLIT
)
8017 tword
= make_bare_word (istring
);
8018 if (word
->flags
& W_ASSIGNMENT
)
8019 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8020 if (word
->flags
& W_COMPASSIGN
)
8021 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8022 if (word
->flags
& W_NOGLOB
)
8023 tword
->flags
|= W_NOGLOB
; /* XXX */
8024 if (word
->flags
& W_NOEXPAND
)
8025 tword
->flags
|= W_NOEXPAND
; /* XXX */
8026 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8027 tword
->flags
|= W_QUOTED
;
8028 if (had_quoted_null
)
8029 tword
->flags
|= W_HASQUOTEDNULL
;
8030 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8036 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8038 /* If we have $@, we need to split the results no matter what. If
8039 IFS is unset or NULL, string_list_dollar_at has separated the
8040 positional parameters with a space, so we split on space (we have
8041 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8042 string_list_dollar_at has separated the positional parameters
8043 with the first character of $IFS, so we split on $IFS. */
8044 if (has_dollar_at
&& ifs_chars
)
8045 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8048 tword
= make_bare_word (istring
);
8049 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8050 tword
->flags
|= W_QUOTED
;
8051 if (word
->flags
& W_ASSIGNMENT
)
8052 tword
->flags
|= W_ASSIGNMENT
;
8053 if (word
->flags
& W_COMPASSIGN
)
8054 tword
->flags
|= W_COMPASSIGN
;
8055 if (word
->flags
& W_NOGLOB
)
8056 tword
->flags
|= W_NOGLOB
;
8057 if (word
->flags
& W_NOEXPAND
)
8058 tword
->flags
|= W_NOEXPAND
;
8059 if (had_quoted_null
)
8060 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8061 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8069 /* **************************************************************** */
8071 /* Functions for Quote Removal */
8073 /* **************************************************************** */
8075 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8076 backslash quoting rules for within double quotes or a here document. */
8078 string_quote_removal (string
, quoted
)
8083 char *r
, *result_string
, *temp
, *send
;
8084 int sindex
, tindex
, dquote
;
8088 /* The result can be no longer than the original string. */
8089 slen
= strlen (string
);
8090 send
= string
+ slen
;
8092 r
= result_string
= (char *)xmalloc (slen
+ 1);
8094 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8099 c
= string
[++sindex
];
8105 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8110 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8114 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8120 tindex
= sindex
+ 1;
8121 temp
= string_extract_single_quoted (string
, &tindex
);
8132 dquote
= 1 - dquote
;
8138 return (result_string
);
8143 /* Perform quote removal on word WORD. This allocates and returns a new
8146 word_quote_removal (word
, quoted
)
8153 t
= string_quote_removal (word
->word
, quoted
);
8154 w
= alloc_word_desc ();
8155 w
->word
= t
? t
: savestring ("");
8159 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8160 the members of the list are treated as if they are surrounded by
8161 double quotes. Return a new list, or NULL if LIST is NULL. */
8163 word_list_quote_removal (list
, quoted
)
8167 WORD_LIST
*result
, *t
, *tresult
, *e
;
8169 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8171 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8173 result
= (WORD_LIST
*) list_append (result
, tresult
);
8176 result
= e
= tresult
;
8189 /*******************************************
8191 * Functions to perform word splitting *
8193 *******************************************/
8203 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8205 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8206 handle multibyte chars in IFS */
8207 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8208 for (t
= ifs_value
; t
&& *t
; t
++)
8214 #if defined (HANDLE_MULTIBYTE)
8217 ifs_firstc
[0] = '\0';
8223 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8224 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8225 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8227 ifs_firstc
[0] = ifs_value
[0];
8228 ifs_firstc
[1] = '\0';
8232 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8235 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8245 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8246 is not quoted. list_string () performs quote removal for us, even if we
8247 don't do any splitting. */
8249 word_split (w
, ifs_chars
)
8259 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8260 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8263 result
= (WORD_LIST
*)NULL
;
8268 /* Perform word splitting on LIST and return the RESULT. It is possible
8269 to return (WORD_LIST *)NULL. */
8271 word_list_split (list
)
8274 WORD_LIST
*result
, *t
, *tresult
, *e
;
8276 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8278 tresult
= word_split (t
->word
, ifs_value
);
8280 result
= e
= tresult
;
8291 /**************************************************
8293 * Functions to expand an entire WORD_LIST *
8295 **************************************************/
8297 /* Do any word-expansion-specific cleanup and jump to top_level */
8299 exp_jump_to_top_level (v
)
8302 set_pipestatus_from_exit (last_command_exit_value
);
8304 /* Cleanup code goes here. */
8305 expand_no_split_dollar_star
= 0; /* XXX */
8306 expanding_redir
= 0;
8307 assigning_in_environment
= 0;
8309 if (parse_and_execute_level
== 0)
8310 top_level_cleanup (); /* from sig.c */
8312 jump_to_top_level (v
);
8315 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8316 ELIST, and set ELIST to the new list. */
8317 #define PREPEND_LIST(nlist, elist) \
8318 do { nlist->next = elist; elist = nlist; } while (0)
8320 /* Separate out any initial variable assignments from TLIST. If set -k has
8321 been executed, remove all assignment statements from TLIST. Initial
8322 variable assignments and other environment assignments are placed
8323 on SUBST_ASSIGN_VARLIST. */
8325 separate_out_assignments (tlist
)
8328 register WORD_LIST
*vp
, *lp
;
8331 return ((WORD_LIST
*)NULL
);
8333 if (subst_assign_varlist
)
8334 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8336 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8339 /* Separate out variable assignments at the start of the command.
8340 Loop invariant: vp->next == lp
8342 lp = list of words left after assignment statements skipped
8343 tlist = original list of words
8345 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8351 /* If lp != tlist, we have some initial assignment statements.
8352 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8353 words and TLIST point to the remaining words. */
8356 subst_assign_varlist
= tlist
;
8357 /* ASSERT(vp->next == lp); */
8358 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8359 tlist
= lp
; /* remainder of word list */
8362 /* vp == end of variable list */
8363 /* tlist == remainder of original word list without variable assignments */
8365 /* All the words in tlist were assignment statements */
8366 return ((WORD_LIST
*)NULL
);
8368 /* ASSERT(tlist != NULL); */
8369 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8371 /* If the -k option is in effect, we need to go through the remaining
8372 words, separate out the assignment words, and place them on
8373 SUBST_ASSIGN_VARLIST. */
8374 if (place_keywords_in_env
)
8376 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8381 /* Loop Invariant: tp->next == lp */
8382 /* Loop postcondition: tlist == word list without assignment statements */
8385 if (lp
->word
->flags
& W_ASSIGNMENT
)
8387 /* Found an assignment statement, add this word to end of
8388 subst_assign_varlist (vp). */
8389 if (!subst_assign_varlist
)
8390 subst_assign_varlist
= vp
= lp
;
8397 /* Remove the word pointed to by LP from TLIST. */
8398 tp
->next
= lp
->next
;
8399 /* ASSERT(vp == lp); */
8400 lp
->next
= (WORD_LIST
*)NULL
;
8413 #define WEXP_VARASSIGN 0x001
8414 #define WEXP_BRACEEXP 0x002
8415 #define WEXP_TILDEEXP 0x004
8416 #define WEXP_PARAMEXP 0x008
8417 #define WEXP_PATHEXP 0x010
8419 /* All of the expansions, including variable assignments at the start of
8421 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8423 /* All of the expansions except variable assignments at the start of
8425 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8427 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8428 expansion, command substitution, arithmetic expansion, word splitting, and
8430 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8432 /* Take the list of words in LIST and do the various substitutions. Return
8433 a new list of words which is the expanded list, and without things like
8434 variable assignments. */
8440 return (expand_word_list_internal (list
, WEXP_ALL
));
8443 /* Same as expand_words (), but doesn't hack variable or environment
8446 expand_words_no_vars (list
)
8449 return (expand_word_list_internal (list
, WEXP_NOVARS
));
8453 expand_words_shellexp (list
)
8456 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
8460 glob_expand_word_list (tlist
, eflags
)
8464 char **glob_array
, *temp_string
;
8465 register int glob_index
;
8466 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
8469 output_list
= disposables
= (WORD_LIST
*)NULL
;
8470 glob_array
= (char **)NULL
;
8473 /* For each word, either globbing is attempted or the word is
8474 added to orig_list. If globbing succeeds, the results are
8475 added to orig_list and the word (tlist) is added to the list
8476 of disposable words. If globbing fails and failed glob
8477 expansions are left unchanged (the shell default), the
8478 original word is added to orig_list. If globbing fails and
8479 failed glob expansions are removed, the original word is
8480 added to the list of disposable words. orig_list ends up
8481 in reverse order and requires a call to REVERSE_LIST to
8482 be set right. After all words are examined, the disposable
8486 /* If the word isn't an assignment and contains an unquoted
8487 pattern matching character, then glob it. */
8488 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
8489 unquoted_glob_pattern_p (tlist
->word
->word
))
8491 glob_array
= shell_glob_filename (tlist
->word
->word
);
8493 /* Handle error cases.
8494 I don't think we should report errors like "No such file
8495 or directory". However, I would like to report errors
8496 like "Read failed". */
8498 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
8500 glob_array
= (char **)xmalloc (sizeof (char *));
8501 glob_array
[0] = (char *)NULL
;
8504 /* Dequote the current word in case we have to use it. */
8505 if (glob_array
[0] == NULL
)
8507 temp_string
= dequote_string (tlist
->word
->word
);
8508 free (tlist
->word
->word
);
8509 tlist
->word
->word
= temp_string
;
8512 /* Make the array into a word list. */
8513 glob_list
= (WORD_LIST
*)NULL
;
8514 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
8516 tword
= make_bare_word (glob_array
[glob_index
]);
8517 tword
->flags
|= W_GLOBEXP
; /* XXX */
8518 glob_list
= make_word_list (tword
, glob_list
);
8523 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
8524 PREPEND_LIST (tlist
, disposables
);
8526 else if (fail_glob_expansion
!= 0)
8528 report_error (_("no match: %s"), tlist
->word
->word
);
8529 exp_jump_to_top_level (DISCARD
);
8531 else if (allow_null_glob_expansion
== 0)
8533 /* Failed glob expressions are left unchanged. */
8534 PREPEND_LIST (tlist
, output_list
);
8538 /* Failed glob expressions are removed. */
8539 PREPEND_LIST (tlist
, disposables
);
8544 /* Dequote the string. */
8545 temp_string
= dequote_string (tlist
->word
->word
);
8546 free (tlist
->word
->word
);
8547 tlist
->word
->word
= temp_string
;
8548 PREPEND_LIST (tlist
, output_list
);
8551 strvec_dispose (glob_array
);
8552 glob_array
= (char **)NULL
;
8558 dispose_words (disposables
);
8561 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8563 return (output_list
);
8566 #if defined (BRACE_EXPANSION)
8568 brace_expand_word_list (tlist
, eflags
)
8572 register char **expansions
;
8574 WORD_LIST
*disposables
, *output_list
, *next
;
8578 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
8582 /* Only do brace expansion if the word has a brace character. If
8583 not, just add the word list element to BRACES and continue. In
8584 the common case, at least when running shell scripts, this will
8585 degenerate to a bunch of calls to `mbschr', and then what is
8586 basically a reversal of TLIST into BRACES, which is corrected
8587 by a call to REVERSE_LIST () on BRACES when the end of TLIST
8589 if (mbschr (tlist
->word
->word
, LBRACE
))
8591 expansions
= brace_expand (tlist
->word
->word
);
8593 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
8595 w
= make_word (temp_string
);
8596 /* If brace expansion didn't change the word, preserve
8597 the flags. We may want to preserve the flags
8598 unconditionally someday -- XXX */
8599 if (STREQ (temp_string
, tlist
->word
->word
))
8600 w
->flags
= tlist
->word
->flags
;
8601 output_list
= make_word_list (w
, output_list
);
8602 free (expansions
[eindex
]);
8606 /* Add TLIST to the list of words to be freed after brace
8607 expansion has been performed. */
8608 PREPEND_LIST (tlist
, disposables
);
8611 PREPEND_LIST (tlist
, output_list
);
8615 dispose_words (disposables
);
8618 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8620 return (output_list
);
8624 #if defined (ARRAY_VARS)
8625 /* Take WORD, a compound associative array assignment, and internally run
8626 'declare -A w', where W is the variable name portion of WORD. */
8628 make_internal_declare (word
, option
)
8636 w
= make_word (word
);
8638 t
= assignment (w
->word
, 0);
8641 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
8642 wl
= make_word_list (make_word (option
), wl
);
8644 return (declare_builtin (wl
));
8649 shell_expand_word_list (tlist
, eflags
)
8653 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
8654 int expanded_something
, has_dollar_at
;
8657 /* We do tilde expansion all the time. This is what 1003.2 says. */
8658 new_list
= (WORD_LIST
*)NULL
;
8659 for (orig_list
= tlist
; tlist
; tlist
= next
)
8661 temp_string
= tlist
->word
->word
;
8665 #if defined (ARRAY_VARS)
8666 /* If this is a compound array assignment to a builtin that accepts
8667 such assignments (e.g., `declare'), take the assignment and perform
8668 it separately, handling the semantics of declarations inside shell
8669 functions. This avoids the double-evaluation of such arguments,
8670 because `declare' does some evaluation of compound assignments on
8672 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8676 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
8677 make_internal_declare (tlist
->word
->word
, "-A");
8679 t
= do_word_assignment (tlist
->word
);
8682 last_command_exit_value
= EXECUTION_FAILURE
;
8683 exp_jump_to_top_level (DISCARD
);
8686 /* Now transform the word as ksh93 appears to do and go on */
8687 t
= assignment (tlist
->word
->word
, 0);
8688 tlist
->word
->word
[t
] = '\0';
8689 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
8693 expanded_something
= 0;
8694 expanded
= expand_word_internal
8695 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
8697 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
8699 /* By convention, each time this error is returned,
8700 tlist->word->word has already been freed. */
8701 tlist
->word
->word
= (char *)NULL
;
8703 /* Dispose our copy of the original list. */
8704 dispose_words (orig_list
);
8705 /* Dispose the new list we're building. */
8706 dispose_words (new_list
);
8708 last_command_exit_value
= EXECUTION_FAILURE
;
8709 if (expanded
== &expand_word_error
)
8710 exp_jump_to_top_level (DISCARD
);
8712 exp_jump_to_top_level (FORCE_EOF
);
8715 /* Don't split words marked W_NOSPLIT. */
8716 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
8718 temp_list
= word_list_split (expanded
);
8719 dispose_words (expanded
);
8723 /* If no parameter expansion, command substitution, process
8724 substitution, or arithmetic substitution took place, then
8725 do not do word splitting. We still have to remove quoted
8726 null characters from the result. */
8727 word_list_remove_quoted_nulls (expanded
);
8728 temp_list
= expanded
;
8731 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8732 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8736 dispose_words (orig_list
);
8739 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8744 /* The workhorse for expand_words () and expand_words_no_vars ().
8745 First arg is LIST, a WORD_LIST of words.
8746 Second arg EFLAGS is a flags word controlling which expansions are
8749 This does all of the substitutions: brace expansion, tilde expansion,
8750 parameter expansion, command substitution, arithmetic expansion,
8751 process substitution, word splitting, and pathname expansion, according
8752 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8753 set, or for which no expansion is done, do not undergo word splitting.
8754 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8756 expand_word_list_internal (list
, eflags
)
8760 WORD_LIST
*new_list
, *temp_list
;
8764 return ((WORD_LIST
*)NULL
);
8766 garglist
= new_list
= copy_word_list (list
);
8767 if (eflags
& WEXP_VARASSIGN
)
8769 garglist
= new_list
= separate_out_assignments (new_list
);
8772 if (subst_assign_varlist
)
8774 /* All the words were variable assignments, so they are placed
8775 into the shell's environment. */
8776 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8778 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8779 tint
= do_word_assignment (temp_list
->word
);
8780 /* Variable assignment errors in non-interactive shells
8781 running in Posix.2 mode cause the shell to exit. */
8784 last_command_exit_value
= EXECUTION_FAILURE
;
8785 if (interactive_shell
== 0 && posixly_correct
)
8786 exp_jump_to_top_level (FORCE_EOF
);
8788 exp_jump_to_top_level (DISCARD
);
8791 dispose_words (subst_assign_varlist
);
8792 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8794 return ((WORD_LIST
*)NULL
);
8798 /* Begin expanding the words that remain. The expansions take place on
8799 things that aren't really variable assignments. */
8801 #if defined (BRACE_EXPANSION)
8802 /* Do brace expansion on this word if there are any brace characters
8804 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8805 new_list
= brace_expand_word_list (new_list
, eflags
);
8806 #endif /* BRACE_EXPANSION */
8808 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8809 variable substitution, command substitution, arithmetic expansion,
8810 and word splitting. */
8811 new_list
= shell_expand_word_list (new_list
, eflags
);
8813 /* Okay, we're almost done. Now let's just do some filename
8817 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8818 /* Glob expand the word list unless globbing has been disabled. */
8819 new_list
= glob_expand_word_list (new_list
, eflags
);
8821 /* Dequote the words, because we're not performing globbing. */
8822 new_list
= dequote_list (new_list
);
8825 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8827 sh_wassign_func_t
*assign_func
;
8829 /* If the remainder of the words expand to nothing, Posix.2 requires
8830 that the variable and environment assignments affect the shell's
8832 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8833 tempenv_assign_error
= 0;
8835 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8837 this_command_name
= (char *)NULL
;
8838 assigning_in_environment
= (assign_func
== assign_in_env
);
8839 tint
= (*assign_func
) (temp_list
->word
);
8840 assigning_in_environment
= 0;
8841 /* Variable assignment errors in non-interactive shells running
8842 in Posix.2 mode cause the shell to exit. */
8845 if (assign_func
== do_word_assignment
)
8847 last_command_exit_value
= EXECUTION_FAILURE
;
8848 if (interactive_shell
== 0 && posixly_correct
)
8849 exp_jump_to_top_level (FORCE_EOF
);
8851 exp_jump_to_top_level (DISCARD
);
8854 tempenv_assign_error
++;
8858 dispose_words (subst_assign_varlist
);
8859 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8863 tint
= list_length (new_list
) + 1;
8864 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8865 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8866 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8867 glob_argv_flags
[tint
] = '\0';