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. */
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
))
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
= xstrchr (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 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4317 expand_no_split_dollar_star
= 0;
4319 return (result
? dequote_list (result
) : result
);
4322 /* Perform shell expansions on WORD, but do not perform word splitting or
4323 quote removal on the result. */
4325 expand_word_leave_quoted (word
, quoted
)
4329 return (call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
));
4332 #if defined (PROCESS_SUBSTITUTION)
4334 /*****************************************************************/
4336 /* Hacking Process Substitution */
4338 /*****************************************************************/
4340 #if !defined (HAVE_DEV_FD)
4341 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4342 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4343 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4344 list. NFIFO is a count of the number of FIFOs in the list. */
4345 #define FIFO_INCR 20
4352 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4354 static int fifo_list_size
;
4357 add_fifo_list (pathname
)
4360 if (nfifo
>= fifo_list_size
- 1)
4362 fifo_list_size
+= FIFO_INCR
;
4363 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4364 fifo_list_size
* sizeof (struct temp_fifo
));
4367 fifo_list
[nfifo
].file
= savestring (pathname
);
4379 for (i
= saved
= 0; i
< nfifo
; i
++)
4381 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4383 unlink (fifo_list
[i
].file
);
4384 free (fifo_list
[i
].file
);
4385 fifo_list
[i
].file
= (char *)NULL
;
4386 fifo_list
[i
].proc
= -1;
4392 /* If we didn't remove some of the FIFOs, compact the list. */
4395 for (i
= j
= 0; i
< nfifo
; i
++)
4396 if (fifo_list
[i
].file
)
4398 fifo_list
[j
].file
= fifo_list
[i
].file
;
4399 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4419 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4420 if (mkfifo (tname
, 0600) < 0)
4423 return ((char *)NULL
);
4426 add_fifo_list (tname
);
4430 #else /* HAVE_DEV_FD */
4432 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4433 has open to children. NFDS is a count of the number of bits currently
4434 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4436 static char *dev_fd_list
= (char *)NULL
;
4438 static int totfds
; /* The highest possible number of open files. */
4444 if (!dev_fd_list
|| fd
>= totfds
)
4449 totfds
= getdtablesize ();
4450 if (totfds
< 0 || totfds
> 256)
4455 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4456 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4459 dev_fd_list
[fd
] = 1;
4466 return 0; /* used for cleanup; not needed with /dev/fd */
4477 for (i
= 0; nfds
&& i
< totfds
; i
++)
4488 #if defined (NOTDEF)
4489 print_dev_fd_list ()
4493 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4496 for (i
= 0; i
< totfds
; i
++)
4499 fprintf (stderr
, " %d", i
);
4501 fprintf (stderr
, "\n");
4506 make_dev_fd_filename (fd
)
4509 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4511 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4513 strcpy (ret
, DEV_FD_PREFIX
);
4514 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4515 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4521 #endif /* HAVE_DEV_FD */
4523 /* Return a filename that will open a connection to the process defined by
4524 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4525 a filename in /dev/fd corresponding to a descriptor that is one of the
4526 ends of the pipe. If not defined, we use named pipes on systems that have
4527 them. Systems without /dev/fd and named pipes are out of luck.
4529 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4530 use the read end of the pipe and dup that file descriptor to fd 0 in
4531 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4532 writing or use the write end of the pipe in the child, and dup that
4533 file descriptor to fd 1 in the child. The parent does the opposite. */
4536 process_substitute (string
, open_for_read_in_child
)
4538 int open_for_read_in_child
;
4543 #if defined (HAVE_DEV_FD)
4544 int parent_pipe_fd
, child_pipe_fd
;
4546 #endif /* HAVE_DEV_FD */
4547 #if defined (JOB_CONTROL)
4548 pid_t old_pipeline_pgrp
;
4551 if (!string
|| !*string
|| wordexp_only
)
4552 return ((char *)NULL
);
4554 #if !defined (HAVE_DEV_FD)
4555 pathname
= make_named_pipe ();
4556 #else /* HAVE_DEV_FD */
4557 if (pipe (fildes
) < 0)
4559 sys_error (_("cannot make pipe for process substitution"));
4560 return ((char *)NULL
);
4562 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4563 the pipe in the parent, otherwise the read end. */
4564 parent_pipe_fd
= fildes
[open_for_read_in_child
];
4565 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
4566 /* Move the parent end of the pipe to some high file descriptor, to
4567 avoid clashes with FDs used by the script. */
4568 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
4570 pathname
= make_dev_fd_filename (parent_pipe_fd
);
4571 #endif /* HAVE_DEV_FD */
4575 sys_error (_("cannot make pipe for process substitution"));
4576 return ((char *)NULL
);
4579 old_pid
= last_made_pid
;
4581 #if defined (JOB_CONTROL)
4582 old_pipeline_pgrp
= pipeline_pgrp
;
4583 pipeline_pgrp
= shell_pgrp
;
4585 #endif /* JOB_CONTROL */
4587 pid
= make_child ((char *)NULL
, 1);
4590 reset_terminating_signals (); /* XXX */
4591 free_pushed_string_input ();
4592 /* Cancel traps, in trap.c. */
4593 restore_original_signals ();
4594 setup_async_signals ();
4595 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
4598 #if defined (JOB_CONTROL)
4599 set_sigchld_handler ();
4600 stop_making_children ();
4601 /* XXX - should we only do this in the parent? (as in command subst) */
4602 pipeline_pgrp
= old_pipeline_pgrp
;
4603 #endif /* JOB_CONTROL */
4607 sys_error (_("cannot make child for process substitution"));
4609 #if defined (HAVE_DEV_FD)
4610 close (parent_pipe_fd
);
4611 close (child_pipe_fd
);
4612 #endif /* HAVE_DEV_FD */
4613 return ((char *)NULL
);
4618 #if defined (JOB_CONTROL)
4619 restore_pipeline (1);
4622 #if !defined (HAVE_DEV_FD)
4623 fifo_list
[nfifo
-1].proc
= pid
;
4626 last_made_pid
= old_pid
;
4628 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4630 #endif /* JOB_CONTROL && PGRP_PIPE */
4632 #if defined (HAVE_DEV_FD)
4633 close (child_pipe_fd
);
4634 #endif /* HAVE_DEV_FD */
4639 set_sigint_handler ();
4641 #if defined (JOB_CONTROL)
4642 set_job_control (0);
4643 #endif /* JOB_CONTROL */
4645 #if !defined (HAVE_DEV_FD)
4646 /* Open the named pipe in the child. */
4647 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
4650 /* Two separate strings for ease of translation. */
4651 if (open_for_read_in_child
)
4652 sys_error (_("cannot open named pipe %s for reading"), pathname
);
4654 sys_error (_("cannot open named pipe %s for writing"), pathname
);
4658 if (open_for_read_in_child
)
4660 if (sh_unset_nodelay_mode (fd
) < 0)
4662 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
4666 #else /* HAVE_DEV_FD */
4668 #endif /* HAVE_DEV_FD */
4670 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
4672 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
4673 open_for_read_in_child
? 0 : 1);
4677 if (fd
!= (open_for_read_in_child
? 0 : 1))
4680 /* Need to close any files that this process has open to pipes inherited
4682 if (current_fds_to_close
)
4684 close_fd_bitmap (current_fds_to_close
);
4685 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
4688 #if defined (HAVE_DEV_FD)
4689 /* Make sure we close the parent's end of the pipe and clear the slot
4690 in the fd list so it is not closed later, if reallocated by, for
4691 instance, pipe(2). */
4692 close (parent_pipe_fd
);
4693 dev_fd_list
[parent_pipe_fd
] = 0;
4694 #endif /* HAVE_DEV_FD */
4696 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
4698 #if !defined (HAVE_DEV_FD)
4699 /* Make sure we close the named pipe in the child before we exit. */
4700 close (open_for_read_in_child
? 0 : 1);
4701 #endif /* !HAVE_DEV_FD */
4706 #endif /* PROCESS_SUBSTITUTION */
4708 /***********************************/
4710 /* Command Substitution */
4712 /***********************************/
4715 read_comsub (fd
, quoted
, rflag
)
4719 char *istring
, buf
[128], *bufp
, *s
;
4720 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
4723 istring
= (char *)NULL
;
4724 istring_index
= istring_size
= bufn
= tflag
= 0;
4726 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
4727 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
4730 setmode (fd
, O_TEXT
); /* we don't want CR/LF, we want Unix-style */
4733 /* Read the output of the command through the pipe. This may need to be
4734 changed to understand multibyte characters in the future. */
4741 bufn
= zread (fd
, buf
, sizeof (buf
));
4751 internal_warning ("read_comsub: ignored null byte in input");
4756 /* Add the character to ISTRING, possibly after resizing it. */
4757 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
4759 /* This is essentially quote_string inline */
4760 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
4761 istring
[istring_index
++] = CTLESC
;
4762 /* Escape CTLESC and CTLNUL in the output to protect those characters
4763 from the rest of the word expansions (word splitting and globbing.)
4764 This is essentially quote_escapes inline. */
4765 else if (skip_ctlesc
== 0 && c
== CTLESC
)
4767 tflag
|= W_HASCTLESC
;
4768 istring
[istring_index
++] = CTLESC
;
4770 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
4771 istring
[istring_index
++] = CTLESC
;
4773 istring
[istring_index
++] = c
;
4776 #if defined (__CYGWIN__)
4777 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
4780 istring
[istring_index
- 1] = '\n';
4787 istring
[istring_index
] = '\0';
4789 /* If we read no output, just return now and save ourselves some
4791 if (istring_index
== 0)
4796 return (char *)NULL
;
4799 /* Strip trailing newlines from the output of the command. */
4800 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4802 while (istring_index
> 0)
4804 if (istring
[istring_index
- 1] == '\n')
4808 /* If the newline was quoted, remove the quoting char. */
4809 if (istring
[istring_index
- 1] == CTLESC
)
4815 istring
[istring_index
] = '\0';
4818 strip_trailing (istring
, istring_index
- 1, 1);
4825 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
4826 contained string possibly quoted. */
4828 command_substitute (string
, quoted
)
4832 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
4834 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
4837 istring
= (char *)NULL
;
4839 /* Don't fork () if there is no need to. In the case of no command to
4840 run, just return NULL. */
4841 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
4842 return ((WORD_DESC
*)NULL
);
4844 if (wordexp_only
&& read_but_dont_execute
)
4846 last_command_exit_value
= 125;
4847 jump_to_top_level (EXITPROG
);
4850 /* We're making the assumption here that the command substitution will
4851 eventually run a command from the file system. Since we'll run
4852 maybe_make_export_env in this subshell before executing that command,
4853 the parent shell and any other shells it starts will have to remake
4854 the environment. If we make it before we fork, other shells won't
4855 have to. Don't bother if we have any temporary variable assignments,
4856 though, because the export environment will be remade after this
4857 command completes anyway, but do it if all the words to be expanded
4858 are variable assignments. */
4859 if (subst_assign_varlist
== 0 || garglist
== 0)
4860 maybe_make_export_env (); /* XXX */
4862 /* Flags to pass to parse_and_execute() */
4863 pflags
= interactive
? SEVAL_RESETLINE
: 0;
4865 /* Pipe the output of executing STRING into the current shell. */
4866 if (pipe (fildes
) < 0)
4868 sys_error (_("cannot make pipe for command substitution"));
4872 old_pid
= last_made_pid
;
4873 #if defined (JOB_CONTROL)
4874 old_pipeline_pgrp
= pipeline_pgrp
;
4875 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
4876 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
4877 pipeline_pgrp
= shell_pgrp
;
4878 cleanup_the_pipeline ();
4879 #endif /* JOB_CONTROL */
4881 old_async_pid
= last_asynchronous_pid
;
4882 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
4883 last_asynchronous_pid
= old_async_pid
;
4886 /* Reset the signal handlers in the child, but don't free the
4888 reset_signal_handlers ();
4890 #if defined (JOB_CONTROL)
4891 /* XXX DO THIS ONLY IN PARENT ? XXX */
4892 set_sigchld_handler ();
4893 stop_making_children ();
4895 pipeline_pgrp
= old_pipeline_pgrp
;
4897 stop_making_children ();
4898 #endif /* JOB_CONTROL */
4902 sys_error (_("cannot make child for command substitution"));
4908 return ((WORD_DESC
*)NULL
);
4913 set_sigint_handler (); /* XXX */
4915 free_pushed_string_input ();
4917 if (dup2 (fildes
[1], 1) < 0)
4919 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
4920 exit (EXECUTION_FAILURE
);
4923 /* If standard output is closed in the parent shell
4924 (such as after `exec >&-'), file descriptor 1 will be
4925 the lowest available file descriptor, and end up in
4926 fildes[0]. This can happen for stdin and stderr as well,
4927 but stdout is more important -- it will cause no output
4928 to be generated from this command. */
4929 if ((fildes
[1] != fileno (stdin
)) &&
4930 (fildes
[1] != fileno (stdout
)) &&
4931 (fildes
[1] != fileno (stderr
)))
4934 if ((fildes
[0] != fileno (stdin
)) &&
4935 (fildes
[0] != fileno (stdout
)) &&
4936 (fildes
[0] != fileno (stderr
)))
4939 /* The currently executing shell is not interactive. */
4942 /* This is a subshell environment. */
4943 subshell_environment
|= SUBSHELL_COMSUB
;
4945 /* When not in POSIX mode, command substitution does not inherit
4947 if (posixly_correct
== 0)
4948 exit_immediately_on_error
= 0;
4950 remove_quoted_escapes (string
);
4952 startup_state
= 2; /* see if we can avoid a fork */
4953 /* Give command substitution a place to jump back to on failure,
4954 so we don't go back up to main (). */
4955 result
= setjmp (top_level
);
4957 /* If we're running a command substitution inside a shell function,
4958 trap `return' so we don't return from the function in the subshell
4959 and go off to never-never land. */
4960 if (result
== 0 && return_catch_flag
)
4961 function_value
= setjmp (return_catch
);
4965 if (result
== ERREXIT
)
4966 rc
= last_command_exit_value
;
4967 else if (result
== EXITPROG
)
4968 rc
= last_command_exit_value
;
4970 rc
= EXECUTION_FAILURE
;
4971 else if (function_value
)
4972 rc
= return_catch_value
;
4976 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
4980 last_command_exit_value
= rc
;
4981 rc
= run_exit_trap ();
4982 #if defined (PROCESS_SUBSTITUTION)
4983 unlink_fifo_list ();
4989 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
4991 #endif /* JOB_CONTROL && PGRP_PIPE */
4996 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5000 current_command_subst_pid
= pid
;
5001 last_command_exit_value
= wait_for (pid
);
5002 last_command_subst_pid
= pid
;
5003 last_made_pid
= old_pid
;
5005 #if defined (JOB_CONTROL)
5006 /* If last_command_exit_value > 128, then the substituted command
5007 was terminated by a signal. If that signal was SIGINT, then send
5008 SIGINT to ourselves. This will break out of loops, for instance. */
5009 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5010 kill (getpid (), SIGINT
);
5012 /* wait_for gives the terminal back to shell_pgrp. If some other
5013 process group should have it, give it away to that group here.
5014 pipeline_pgrp is non-zero only while we are constructing a
5015 pipline, so what we are concerned about is whether or not that
5016 pipeline was started in the background. A pipeline started in
5017 the background should never get the tty back here. */
5019 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && pipeline_pgrp
!= last_asynchronous_pid
)
5021 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5023 give_terminal_to (pipeline_pgrp
, 0);
5024 #endif /* JOB_CONTROL */
5026 ret
= alloc_word_desc ();
5027 ret
->word
= istring
;
5034 /********************************************************
5036 * Utility functions for parameter expansion *
5038 ********************************************************/
5040 #if defined (ARRAY_VARS)
5043 array_length_reference (s
)
5053 var
= array_variable_part (s
, &t
, &len
);
5055 /* If unbound variables should generate an error, report one and return
5057 if ((var
== 0 || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5068 /* We support a couple of expansions for variables that are not arrays.
5069 We'll return the length of the value for v[0], and 1 for v[@] or
5070 v[*]. Return 0 for everything else. */
5072 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5074 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5077 return (assoc_num_elements (assoc_cell (var
)));
5078 else if (array_p (var
))
5079 return (array_num_elements (array
));
5087 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5089 if (akey
== 0 || *akey
== 0)
5091 err_badarraysub (t
);
5094 t
= assoc_reference (assoc_cell (var
), akey
);
5098 ind
= array_expand_index (t
, len
);
5101 err_badarraysub (t
);
5105 t
= array_reference (array
, ind
);
5107 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5110 len
= MB_STRLEN (t
);
5113 #endif /* ARRAY_VARS */
5116 valid_brace_expansion_word (name
, var_is_special
)
5120 if (DIGIT (*name
) && all_digits (name
))
5122 else if (var_is_special
)
5124 #if defined (ARRAY_VARS)
5125 else if (valid_array_reference (name
))
5127 #endif /* ARRAY_VARS */
5128 else if (legal_identifier (name
))
5135 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5138 int *quoted_dollar_atp
, *contains_dollar_at
;
5144 if (quoted_dollar_atp
)
5145 *quoted_dollar_atp
= 0;
5146 if (contains_dollar_at
)
5147 *contains_dollar_at
= 0;
5151 /* check for $@ and $* */
5152 if (name
[0] == '@' && name
[1] == 0)
5154 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5155 *quoted_dollar_atp
= 1;
5156 if (contains_dollar_at
)
5157 *contains_dollar_at
= 1;
5160 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5162 if (contains_dollar_at
)
5163 *contains_dollar_at
= 1;
5167 /* Now check for ${array[@]} and ${array[*]} */
5168 #if defined (ARRAY_VARS)
5169 else if (valid_array_reference (name
))
5171 temp1
= xstrchr (name
, '[');
5172 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
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 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5181 which should result in separate words even when IFS is unset. */
5182 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5184 if (contains_dollar_at
)
5185 *contains_dollar_at
= 1;
5193 /* Parameter expand NAME, and return a new string which is the expansion,
5194 or NULL if there was no expansion.
5195 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5196 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5197 NAME was found inside of a double-quoted expression. */
5199 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
)
5201 int var_is_special
, quoted
, pflags
;
5213 /* Handle multiple digit arguments, as in ${11}. */
5214 if (legal_number (name
, &arg_index
))
5216 tt
= get_dollar_var_value (arg_index
);
5218 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5220 : quote_escapes (tt
);
5222 temp
= (char *)NULL
;
5225 else if (var_is_special
) /* ${@} */
5228 tt
= (char *)xmalloc (2 + strlen (name
));
5229 tt
[sindex
= 0] = '$';
5230 strcpy (tt
+ 1, name
);
5232 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5233 (int *)NULL
, (int *)NULL
, pflags
);
5236 #if defined (ARRAY_VARS)
5237 else if (valid_array_reference (name
))
5239 temp
= array_value (name
, quoted
, &atype
);
5240 if (atype
== 0 && temp
)
5241 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5242 ? quote_string (temp
)
5243 : quote_escapes (temp
);
5244 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5245 rflags
|= W_HASQUOTEDNULL
;
5248 else if (var
= find_variable (name
))
5250 if (var_isset (var
) && invisible_p (var
) == 0)
5252 #if defined (ARRAY_VARS)
5254 temp
= assoc_reference (assoc_cell (var
), "0");
5255 else if (array_p (var
))
5256 temp
= array_reference (array_cell (var
), 0);
5258 temp
= value_cell (var
);
5260 temp
= value_cell (var
);
5264 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5265 ? quote_string (temp
)
5266 : quote_escapes (temp
);
5269 temp
= (char *)NULL
;
5272 temp
= (char *)NULL
;
5276 ret
= alloc_word_desc ();
5278 ret
->flags
|= rflags
;
5283 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5284 value of the variable whose name is the value of NAME. */
5286 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5288 int var_is_special
, quoted
;
5289 int *quoted_dollar_atp
, *contains_dollar_at
;
5294 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
5296 /* Have to dequote here if necessary */
5299 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5300 ? dequote_string (t
)
5301 : dequote_escapes (t
);
5305 dispose_word_desc (w
);
5307 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5309 return (WORD_DESC
*)NULL
;
5311 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0);
5317 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5318 depending on the value of C, the separating character. C can be one of
5319 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5320 between double quotes. */
5322 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5324 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5328 char *t
, *t1
, *temp
;
5331 /* If the entire expression is between double quotes, we want to treat
5332 the value as a double-quoted string, with the exception that we strip
5333 embedded unescaped double quotes (for sh backwards compatibility). */
5334 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5337 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5342 w
= alloc_word_desc ();
5344 /* XXX was 0 not quoted */
5345 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5348 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5353 /* The expansion of TEMP returned something. We need to treat things
5354 slightly differently if HASDOL is non-zero. If we have "$@", the
5355 individual words have already been quoted. We need to turn them
5356 into a string with the words separated by the first character of
5357 $IFS without any additional quoting, so string_list_dollar_at won't
5358 do the right thing. We use string_list_dollar_star instead. */
5359 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5361 /* If l->next is not null, we know that TEMP contained "$@", since that
5362 is the only expansion that creates more than one word. */
5363 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5367 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5369 /* The brace expansion occurred between double quotes and there was
5370 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5371 it does not expand to anything. In this case, we want to return
5372 a quoted empty string. */
5373 temp
= make_quoted_char ('\0');
5374 w
->flags
|= W_HASQUOTEDNULL
;
5377 temp
= (char *)NULL
;
5379 if (c
== '-' || c
== '+')
5386 t
= temp
? savestring (temp
) : savestring ("");
5387 t1
= dequote_string (t
);
5389 #if defined (ARRAY_VARS)
5390 if (valid_array_reference (name
))
5391 assign_array_element (name
, t1
, 0);
5393 #endif /* ARRAY_VARS */
5394 bind_variable (name
, t1
, 0);
5401 /* Deal with the right hand side of a ${name:?value} expansion in the case
5402 that NAME is null or not set. If VALUE is non-null it is expanded and
5403 used as the error message to print, otherwise a standard message is
5406 parameter_brace_expand_error (name
, value
)
5412 if (value
&& *value
)
5414 l
= expand_string (value
, 0);
5415 temp
= string_list (l
);
5416 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5421 report_error (_("%s: parameter null or not set"), name
);
5423 /* Free the data we have allocated during this expansion, since we
5424 are about to longjmp out. */
5429 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5432 valid_length_expression (name
)
5435 return (name
[1] == '\0' || /* ${#} */
5436 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5437 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5438 #if defined (ARRAY_VARS)
5439 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5441 legal_identifier (name
+ 1)); /* ${#PS1} */
5444 #if defined (HANDLE_MULTIBYTE)
5450 mbstate_t mbs
, mbsbak
;
5453 memset (&mbs
, 0, sizeof (mbs
));
5455 while ((clen
= mbrlen(s
, MB_CUR_MAX
, &mbs
)) != 0)
5457 if (MB_INVALIDCH(clen
))
5459 clen
= 1; /* assume single byte */
5472 /* Handle the parameter brace expansion that requires us to return the
5473 length of a parameter. */
5475 parameter_brace_expand_length (name
)
5479 intmax_t number
, arg_index
;
5481 #if defined (ARRAY_VARS)
5485 if (name
[1] == '\0') /* ${#} */
5486 number
= number_of_args ();
5487 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5488 number
= number_of_args ();
5489 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5491 /* Take the lengths of some of the shell's special parameters. */
5495 t
= which_set_flags ();
5498 t
= itos (last_command_exit_value
);
5501 t
= itos (dollar_dollar_pid
);
5504 if (last_asynchronous_pid
== NO_PID
)
5507 t
= itos (last_asynchronous_pid
);
5510 t
= itos (number_of_args ());
5513 number
= STRLEN (t
);
5516 #if defined (ARRAY_VARS)
5517 else if (valid_array_reference (name
+ 1))
5518 number
= array_length_reference (name
+ 1);
5519 #endif /* ARRAY_VARS */
5524 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
5526 t
= get_dollar_var_value (arg_index
);
5527 number
= MB_STRLEN (t
);
5530 #if defined (ARRAY_VARS)
5531 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
5534 t
= assoc_reference (assoc_cell (var
), "0");
5536 t
= array_reference (array_cell (var
), 0);
5537 number
= MB_STRLEN (t
);
5542 newname
= savestring (name
);
5544 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
5545 t
= list
? string_list (list
) : (char *)NULL
;
5548 dispose_words (list
);
5550 number
= MB_STRLEN (t
);
5558 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
5559 so we do some ad-hoc parsing of an arithmetic expression to find
5560 the first DELIM, instead of using strchr(3). Two rules:
5561 1. If the substring contains a `(', read until closing `)'.
5562 2. If the substring contains a `?', read past one `:' for each `?'.
5566 skiparith (substr
, delim
)
5571 int skipcol
, pcount
, i
;
5574 sublen
= strlen (substr
);
5575 i
= skipcol
= pcount
= 0;
5578 /* Balance parens */
5579 if (substr
[i
] == LPAREN
)
5585 if (substr
[i
] == RPAREN
&& pcount
)
5593 ADVANCE_CHAR (substr
, sublen
, i
);
5597 /* Skip one `:' for each `?' */
5598 if (substr
[i
] == ':' && skipcol
)
5604 if (substr
[i
] == delim
)
5606 if (substr
[i
] == '?')
5612 ADVANCE_CHAR (substr
, sublen
, i
);
5615 return (substr
+ i
);
5618 /* Verify and limit the start and end of the desired substring. If
5619 VTYPE == 0, a regular shell variable is being used; if it is 1,
5620 then the positional parameters are being used; if it is 2, then
5621 VALUE is really a pointer to an array variable that should be used.
5622 Return value is 1 if both values were OK, 0 if there was a problem
5623 with an invalid expression, or -1 if the values were out of range. */
5625 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
5627 char *value
, *substr
;
5629 intmax_t *e1p
, *e2p
;
5631 char *t
, *temp1
, *temp2
;
5634 #if defined (ARRAY_VARS)
5639 /* duplicate behavior of strchr(3) */
5640 t
= skiparith (substr
, ':');
5641 if (*t
&& *t
== ':')
5646 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
5647 *e1p
= evalexp (temp1
, &expok
);
5652 len
= -1; /* paranoia */
5656 case VT_ARRAYMEMBER
:
5657 len
= MB_STRLEN (value
);
5660 len
= number_of_args () + 1;
5662 len
++; /* add one arg if counting from $0 */
5664 #if defined (ARRAY_VARS)
5666 /* For arrays, the first value deals with array indices. Negative
5667 offsets count from one past the array's maximum index. Associative
5668 arrays treat the number of elements as the maximum index. */
5672 len
= assoc_num_elements (h
) + (*e1p
< 0);
5677 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
5683 if (len
== -1) /* paranoia */
5686 if (*e1p
< 0) /* negative offsets count from end */
5689 if (*e1p
> len
|| *e1p
< 0)
5692 #if defined (ARRAY_VARS)
5693 /* For arrays, the second offset deals with the number of elements. */
5694 if (vtype
== VT_ARRAYVAR
)
5695 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
5701 temp2
= savestring (t
);
5702 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
5705 *e2p
= evalexp (temp1
, &expok
);
5711 internal_error (_("%s: substring expression < 0"), t
);
5714 #if defined (ARRAY_VARS)
5715 /* In order to deal with sparse arrays, push the intelligence about how
5716 to deal with the number of elements desired down to the array-
5717 specific functions. */
5718 if (vtype
!= VT_ARRAYVAR
)
5721 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
5732 /* Return the type of variable specified by VARNAME (simple variable,
5733 positional param, or array variable). Also return the value specified
5734 by VARNAME (value of a variable or a reference to an array element).
5735 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
5736 characters in the value are quoted with CTLESC and takes appropriate
5737 steps. For convenience, *VALP is set to the dequoted VALUE. */
5739 get_var_and_type (varname
, value
, quoted
, varp
, valp
)
5740 char *varname
, *value
;
5747 #if defined (ARRAY_VARS)
5751 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
5752 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
5753 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
5754 vtype
|= VT_STARSUB
;
5755 *varp
= (SHELL_VAR
*)NULL
;
5757 #if defined (ARRAY_VARS)
5758 if (valid_array_reference (varname
))
5760 v
= array_variable_part (varname
, &temp
, (int *)0);
5761 if (v
&& (array_p (v
) || assoc_p (v
)))
5763 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
5765 /* Callers have to differentiate betwen indexed and associative */
5766 vtype
= VT_ARRAYVAR
;
5768 vtype
|= VT_STARSUB
;
5769 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
5773 vtype
= VT_ARRAYMEMBER
;
5774 *valp
= array_value (varname
, 1, (int *)NULL
);
5778 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
5780 vtype
= VT_VARIABLE
;
5782 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5783 *valp
= dequote_string (value
);
5785 *valp
= dequote_escapes (value
);
5789 vtype
= VT_ARRAYMEMBER
;
5791 *valp
= array_value (varname
, 1, (int *)NULL
);
5794 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
5796 vtype
= VT_ARRAYMEMBER
;
5798 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
5803 if (value
&& vtype
== VT_VARIABLE
)
5805 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5806 *valp
= dequote_string (value
);
5808 *valp
= dequote_escapes (value
);
5817 /******************************************************/
5819 /* Functions to extract substrings of variable values */
5821 /******************************************************/
5823 #if defined (HANDLE_MULTIBYTE)
5824 /* Character-oriented rather than strictly byte-oriented substrings. S and
5825 E, rather being strict indices into STRING, indicate character (possibly
5826 multibyte character) positions that require calculation.
5827 Used by the ${param:offset[:length]} expansion. */
5829 mb_substring (string
, s
, e
)
5834 int start
, stop
, i
, slen
;
5838 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
5839 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
5842 while (string
[start
] && i
--)
5843 ADVANCE_CHAR (string
, slen
, start
);
5846 while (string
[stop
] && i
--)
5847 ADVANCE_CHAR (string
, slen
, stop
);
5848 tt
= substring (string
, start
, stop
);
5853 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
5854 is `@', use the positional parameters; otherwise, use the value of
5855 VARNAME. If VARNAME is an array variable, use the array elements. */
5858 parameter_brace_substring (varname
, value
, substr
, quoted
)
5859 char *varname
, *value
, *substr
;
5863 int vtype
, r
, starsub
;
5864 char *temp
, *val
, *tt
, *oname
;
5868 return ((char *)NULL
);
5870 oname
= this_command_name
;
5871 this_command_name
= varname
;
5873 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
5876 this_command_name
= oname
;
5877 return ((char *)NULL
);
5880 starsub
= vtype
& VT_STARSUB
;
5881 vtype
&= ~VT_STARSUB
;
5883 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
5884 this_command_name
= oname
;
5886 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
5891 case VT_ARRAYMEMBER
:
5892 #if defined (HANDLE_MULTIBYTE)
5894 tt
= mb_substring (val
, e1
, e2
);
5897 tt
= substring (val
, e1
, e2
);
5899 if (vtype
== VT_VARIABLE
)
5901 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5902 temp
= quote_string (tt
);
5904 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5908 tt
= pos_params (varname
, e1
, e2
, quoted
);
5909 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
5911 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
5917 #if defined (ARRAY_VARS)
5920 /* we convert to list and take first e2 elements starting at e1th
5921 element -- officially undefined for now */
5922 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
5924 /* We want E2 to be the number of elements desired (arrays can be sparse,
5925 so verify_substring_values just returns the numbers specified and we
5926 rely on array_subrange to understand how to deal with them). */
5927 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
5928 /* array_subrange now calls array_quote_escapes as appropriate, so the
5929 caller no longer needs to. */
5933 temp
= (char *)NULL
;
5939 /****************************************************************/
5941 /* Functions to perform pattern substitution on variable values */
5943 /****************************************************************/
5946 pat_subst (string
, pat
, rep
, mflags
)
5947 char *string
, *pat
, *rep
;
5950 char *ret
, *s
, *e
, *str
;
5951 int rsize
, rptr
, l
, replen
, mtype
;
5953 mtype
= mflags
& MATCH_TYPEMASK
;
5956 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
5957 * with REP and return the result.
5958 * 2. A null pattern with mtype == MATCH_END means to append REP to
5959 * STRING and return the result.
5961 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
5963 replen
= STRLEN (rep
);
5964 l
= strlen (string
);
5965 ret
= (char *)xmalloc (replen
+ l
+ 2);
5967 strcpy (ret
, string
);
5968 else if (mtype
== MATCH_BEG
)
5971 strcpy (ret
+ replen
, string
);
5975 strcpy (ret
, string
);
5976 strcpy (ret
+ l
, rep
);
5981 ret
= (char *)xmalloc (rsize
= 64);
5984 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
5986 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
5989 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
5991 /* OK, now copy the leading unmatched portion of the string (from
5992 str to s) to ret starting at rptr (the current offset). Then copy
5993 the replacement string at ret + rptr + (s - str). Increment
5994 rptr (if necessary) and str and go on. */
5997 strncpy (ret
+ rptr
, str
, l
);
6002 strncpy (ret
+ rptr
, rep
, replen
);
6005 str
= e
; /* e == end of match */
6007 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6011 e
++, str
++; /* avoid infinite recursion on zero-length match */
6014 /* Now copy the unmatched portion of the input string */
6017 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6018 strcpy (ret
+ rptr
, str
);
6026 /* Do pattern match and replacement on the positional parameters. */
6028 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6029 char *string
, *pat
, *rep
;
6032 WORD_LIST
*save
, *params
;
6037 save
= params
= list_rest_of_args ();
6039 return ((char *)NULL
);
6041 for ( ; params
; params
= params
->next
)
6043 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6044 w
= alloc_word_desc ();
6045 w
->word
= ret
? ret
: savestring ("");
6046 dispose_word (params
->word
);
6050 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6051 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6054 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
6055 ret
= string_list_dollar_star (quote_list (save
));
6056 else if ((mflags
& MATCH_STARSUB
) == MATCH_STARSUB
)
6057 ret
= string_list_dollar_star (save
);
6058 else if ((mflags
& MATCH_QUOTED
) == MATCH_QUOTED
)
6059 ret
= string_list_dollar_at (save
, qflags
);
6061 ret
= string_list_dollar_star (save
);
6063 ret
= string_list_pos_params (pchar
, save
, qflags
);
6066 dispose_words (save
);
6071 /* Perform pattern substitution on VALUE, which is the expansion of
6072 VARNAME. PATSUB is an expression supplying the pattern to match
6073 and the string to substitute. QUOTED is a flags word containing
6074 the type of quoting currently in effect. */
6076 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
6077 char *varname
, *value
, *patsub
;
6080 int vtype
, mflags
, starsub
, delim
;
6081 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6085 return ((char *)NULL
);
6087 this_command_name
= varname
;
6089 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6091 return ((char *)NULL
);
6093 starsub
= vtype
& VT_STARSUB
;
6094 vtype
&= ~VT_STARSUB
;
6097 if (patsub
&& *patsub
== '/')
6099 mflags
|= MATCH_GLOBREP
;
6103 /* Malloc this because expand_string_if_necessary or one of the expansion
6104 functions in its call chain may free it on a substitution error. */
6105 lpatsub
= savestring (patsub
);
6107 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6108 mflags
|= MATCH_QUOTED
;
6111 mflags
|= MATCH_STARSUB
;
6113 /* If the pattern starts with a `/', make sure we skip over it when looking
6114 for the replacement delimiter. */
6116 if (rep
= quoted_strchr ((*patsub
== '/') ? lpatsub
+1 : lpatsub
, '/', ST_BACKSL
))
6121 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6122 if (lpatsub
[delim
] == '/')
6125 rep
= lpatsub
+ delim
+ 1;
6131 if (rep
&& *rep
== '\0')
6134 /* Perform the same expansions on the pattern as performed by the
6135 pattern removal expansions. */
6136 pat
= getpattern (lpatsub
, quoted
, 1);
6140 if ((mflags
& MATCH_QUOTED
) == 0)
6141 rep
= expand_string_if_necessary (rep
, quoted
, expand_string_unsplit
);
6143 rep
= expand_string_to_string_internal (rep
, quoted
, expand_string_unsplit
);
6146 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6147 pattern. This is an extension. Make sure we don't anchor the pattern
6148 at the beginning or end of the string if we're doing global replacement,
6151 if (mflags
& MATCH_GLOBREP
)
6152 mflags
|= MATCH_ANY
;
6153 else if (pat
&& pat
[0] == '#')
6155 mflags
|= MATCH_BEG
;
6158 else if (pat
&& pat
[0] == '%')
6160 mflags
|= MATCH_END
;
6164 mflags
|= MATCH_ANY
;
6166 /* OK, we now want to substitute REP for PAT in VAL. If
6167 flags & MATCH_GLOBREP is non-zero, the substitution is done
6168 everywhere, otherwise only the first occurrence of PAT is
6169 replaced. The pattern matching code doesn't understand
6170 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6171 values passed in (VT_VARIABLE) so the pattern substitution
6172 code works right. We need to requote special chars after
6173 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6174 other cases if QUOTED == 0, since the posparams and arrays
6175 indexed by * or @ do special things when QUOTED != 0. */
6180 case VT_ARRAYMEMBER
:
6181 temp
= pat_subst (val
, p
, rep
, mflags
);
6182 if (vtype
== VT_VARIABLE
)
6186 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6192 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6193 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6195 tt
= quote_escapes (temp
);
6200 #if defined (ARRAY_VARS)
6202 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6203 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6204 /* Don't call quote_escapes anymore; array_patsub calls
6205 array_quote_escapes as appropriate before adding the
6206 space separators; ditto for assoc_patsub. */
6218 /****************************************************************/
6220 /* Functions to perform case modification on variable values */
6222 /****************************************************************/
6224 /* Do case modification on the positional parameters. */
6227 pos_params_modcase (string
, pat
, modop
, mflags
)
6232 WORD_LIST
*save
, *params
;
6237 save
= params
= list_rest_of_args ();
6239 return ((char *)NULL
);
6241 for ( ; params
; params
= params
->next
)
6243 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6244 w
= alloc_word_desc ();
6245 w
->word
= ret
? ret
: savestring ("");
6246 dispose_word (params
->word
);
6250 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6251 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6253 ret
= string_list_pos_params (pchar
, save
, qflags
);
6254 dispose_words (save
);
6259 /* Perform case modification on VALUE, which is the expansion of
6260 VARNAME. MODSPEC is an expression supplying the type of modification
6261 to perform. QUOTED is a flags word containing the type of quoting
6262 currently in effect. */
6264 parameter_brace_casemod (varname
, value
, modspec
, patspec
, quoted
)
6265 char *varname
, *value
;
6270 int vtype
, starsub
, modop
, mflags
, x
;
6271 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6275 return ((char *)NULL
);
6277 this_command_name
= varname
;
6279 vtype
= get_var_and_type (varname
, value
, quoted
, &v
, &val
);
6281 return ((char *)NULL
);
6283 starsub
= vtype
& VT_STARSUB
;
6284 vtype
&= ~VT_STARSUB
;
6288 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6289 mflags
|= MATCH_QUOTED
;
6291 mflags
|= MATCH_STARSUB
;
6296 x
= p
&& p
[0] == modspec
;
6297 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6300 else if (modspec
== ',')
6302 x
= p
&& p
[0] == modspec
;
6303 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6306 else if (modspec
== '~')
6308 x
= p
&& p
[0] == modspec
;
6309 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6313 lpat
= p
? savestring (p
) : 0;
6314 /* Perform the same expansions on the pattern as performed by the
6315 pattern removal expansions. FOR LATER */
6316 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6318 /* OK, now we do the case modification. */
6322 case VT_ARRAYMEMBER
:
6323 temp
= sh_modcase (val
, pat
, modop
);
6324 if (vtype
== VT_VARIABLE
)
6328 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6335 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6336 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6338 tt
= quote_escapes (temp
);
6344 #if defined (ARRAY_VARS)
6346 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
6347 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
6348 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6349 as appropriate before adding the space separators; ditto for
6361 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6362 any occur, this must be a nested command substitution, so return 0.
6363 Otherwise, return 1. A valid arithmetic expression must always have a
6364 ( before a matching ), so any cases where there are more right parens
6365 means that this must not be an arithmetic expression, though the parser
6366 will not accept it without a balanced total number of parens. */
6368 chk_arithsub (s
, len
)
6380 else if (s
[i
] == ')')
6390 ADVANCE_CHAR (s
, len
, i
);
6396 ADVANCE_CHAR (s
, len
, i
);
6400 i
= skip_single_quoted (s
, len
, ++i
);
6404 i
= skip_double_quoted ((char *)s
, len
, ++i
);
6409 return (count
== 0);
6412 /****************************************************************/
6414 /* Functions to perform parameter expansion on a string */
6416 /****************************************************************/
6418 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6420 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
6422 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
6424 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
6425 int want_substring
, want_indir
, want_patsub
, want_casemod
;
6426 char *name
, *value
, *temp
, *temp1
;
6427 WORD_DESC
*tdesc
, *ret
;
6428 int t_index
, sindex
, c
, tflag
, modspec
;
6431 temp
= temp1
= value
= (char *)NULL
;
6432 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
6433 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
6437 /* ${#var} doesn't have any of the other parameter expansions on it. */
6438 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
6439 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
6441 #if defined (CASEMOD_EXPANSIONS)
6442 /* To enable case-toggling expansions using the `~' operator character
6443 change the 1 to 0. */
6444 # if defined (CASEMOD_CAPCASE)
6445 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
6447 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
6448 # endif /* CASEMOD_CAPCASE */
6450 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
6451 #endif /* CASEMOD_EXPANSIONS */
6456 /* If the name really consists of a special variable, then make sure
6457 that we have the entire name. We don't allow indirect references
6458 to special variables except `#', `?', `@' and `*'. */
6459 if ((sindex
== t_index
&&
6460 (string
[t_index
] == '-' ||
6461 string
[t_index
] == '?' ||
6462 string
[t_index
] == '#')) ||
6463 (sindex
== t_index
- 1 && string
[sindex
] == '!' &&
6464 (string
[t_index
] == '#' ||
6465 string
[t_index
] == '?' ||
6466 string
[t_index
] == '@' ||
6467 string
[t_index
] == '*')))
6471 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
6472 name
= (char *)xmalloc (3 + (strlen (temp1
)));
6473 *name
= string
[sindex
];
6474 if (string
[sindex
] == '!')
6476 /* indirect reference of $#, $?, $@, or $* */
6477 name
[1] = string
[sindex
+ 1];
6478 strcpy (name
+ 2, temp1
);
6481 strcpy (name
+ 1, temp1
);
6486 /* Find out what character ended the variable name. Then
6487 do the appropriate thing. */
6488 if (c
= string
[sindex
])
6491 /* If c is followed by one of the valid parameter expansion
6492 characters, move past it as normal. If not, assume that
6493 a substring specification is being given, and do not move
6495 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
6498 if (c
= string
[sindex
])
6501 else if (c
== ':' && string
[sindex
] != RBRACE
)
6503 else if (c
== '/' && string
[sindex
] != RBRACE
)
6505 #if defined (CASEMOD_EXPANSIONS)
6506 else if (c
== '^' || c
== ',' || c
== '~')
6513 /* Catch the valid and invalid brace expressions that made it through the
6515 /* ${#-} is a valid expansion and means to take the length of $-.
6516 Similarly for ${#?} and ${##}... */
6517 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6518 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
6520 name
= (char *)xrealloc (name
, 3);
6523 c
= string
[sindex
++];
6526 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
6527 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
6528 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
6530 temp
= (char *)NULL
;
6531 goto bad_substitution
;
6534 /* Indirect expansion begins with a `!'. A valid indirect expansion is
6535 either a variable name, one of the positional parameters or a special
6536 variable that expands to one of the positional parameters. */
6537 want_indir
= *name
== '!' &&
6538 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
6539 || VALID_INDIR_PARAM (name
[1]));
6541 /* Determine the value of this variable. */
6543 /* Check for special variables, directly referenced. */
6544 if (SPECIAL_VAR (name
, want_indir
))
6547 /* Check for special expansion things, like the length of a parameter */
6548 if (*name
== '#' && name
[1])
6550 /* If we are not pointing at the character just after the
6551 closing brace, then we haven't gotten all of the name.
6552 Since it begins with a special character, this is a bad
6553 substitution. Also check NAME for validity before trying
6555 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
6557 temp
= (char *)NULL
;
6558 goto bad_substitution
;
6561 number
= parameter_brace_expand_length (name
);
6566 return (&expand_wdesc_error
);
6569 ret
= alloc_word_desc ();
6570 ret
->word
= itos (number
);
6575 /* ${@} is identical to $@. */
6576 if (name
[0] == '@' && name
[1] == '\0')
6578 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6579 *quoted_dollar_atp
= 1;
6581 if (contains_dollar_at
)
6582 *contains_dollar_at
= 1;
6585 /* Process ${!PREFIX*} expansion. */
6586 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6587 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
6588 legal_variable_starter ((unsigned char) name
[1]))
6593 temp1
= savestring (name
+ 1);
6594 number
= strlen (temp1
);
6595 temp1
[number
- 1] = '\0';
6596 x
= all_variables_matching_prefix (temp1
);
6597 xlist
= strvec_to_word_list (x
, 0, 0);
6598 if (string
[sindex
- 2] == '*')
6599 temp
= string_list_dollar_star (xlist
);
6602 temp
= string_list_dollar_at (xlist
, quoted
);
6603 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6604 *quoted_dollar_atp
= 1;
6605 if (contains_dollar_at
)
6606 *contains_dollar_at
= 1;
6609 dispose_words (xlist
);
6613 ret
= alloc_word_desc ();
6618 #if defined (ARRAY_VARS)
6619 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
6620 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
6621 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
6625 temp1
= savestring (name
+ 1);
6626 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
6628 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
6630 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
6633 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6634 *quoted_dollar_atp
= 1;
6635 if (contains_dollar_at
)
6636 *contains_dollar_at
= 1;
6642 ret
= alloc_word_desc ();
6649 #endif /* ARRAY_VARS */
6651 /* Make sure that NAME is valid before trying to go on. */
6652 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
6653 var_is_special
) == 0)
6655 temp
= (char *)NULL
;
6656 goto bad_substitution
;
6660 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6662 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
);
6667 tflag
= tdesc
->flags
;
6668 dispose_word_desc (tdesc
);
6673 #if defined (ARRAY_VARS)
6674 if (valid_array_reference (name
))
6675 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
6678 var_is_set
= temp
!= (char *)0;
6679 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
6681 /* Get the rest of the stuff inside the braces. */
6682 if (c
&& c
!= RBRACE
)
6684 /* Extract the contents of the ${ ... } expansion
6685 according to the Posix.2 rules. */
6686 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, 0);
6687 if (string
[sindex
] == RBRACE
)
6690 goto bad_substitution
;
6693 value
= (char *)NULL
;
6697 /* If this is a substring spec, process it and add the result. */
6700 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
6705 if (temp1
== &expand_param_error
)
6706 return (&expand_wdesc_error
);
6707 else if (temp1
== &expand_param_fatal
)
6708 return (&expand_wdesc_fatal
);
6710 ret
= alloc_word_desc ();
6712 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6713 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6716 else if (want_patsub
)
6718 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
6723 if (temp1
== &expand_param_error
)
6724 return (&expand_wdesc_error
);
6725 else if (temp1
== &expand_param_fatal
)
6726 return (&expand_wdesc_fatal
);
6728 ret
= alloc_word_desc ();
6730 ret
= alloc_word_desc ();
6732 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6733 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6736 #if defined (CASEMOD_EXPANSIONS)
6737 else if (want_casemod
)
6739 temp1
= parameter_brace_casemod (name
, temp
, modspec
, value
, quoted
);
6744 if (temp1
== &expand_param_error
)
6745 return (&expand_wdesc_error
);
6746 else if (temp1
== &expand_param_fatal
)
6747 return (&expand_wdesc_fatal
);
6749 ret
= alloc_word_desc ();
6751 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6752 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6757 /* Do the right thing based on which character ended the variable name. */
6763 report_error (_("%s: bad substitution"), string
? string
: "??");
6767 return &expand_wdesc_error
;
6770 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
6772 last_command_exit_value
= EXECUTION_FAILURE
;
6773 err_unboundvar (name
);
6777 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6781 case '#': /* ${param#[#]pattern} */
6782 case '%': /* ${param%[%]pattern} */
6783 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
6788 temp1
= parameter_brace_remove_pattern (name
, temp
, value
, c
, quoted
);
6792 ret
= alloc_word_desc ();
6794 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6795 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
6802 if (var_is_set
&& var_is_null
== 0)
6804 /* If the operator is `+', we don't want the value of the named
6805 variable for anything, just the value of the right hand side. */
6809 /* XXX -- if we're double-quoted and the named variable is "$@",
6810 we want to turn off any special handling of "$@" --
6811 we're not using it, so whatever is on the rhs applies. */
6812 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6813 *quoted_dollar_atp
= 0;
6814 if (contains_dollar_at
)
6815 *contains_dollar_at
= 0;
6820 ret
= parameter_brace_expand_rhs (name
, value
, c
,
6823 contains_dollar_at
);
6824 /* XXX - fix up later, esp. noting presence of
6825 W_HASQUOTEDNULL in ret->flags */
6829 temp
= (char *)NULL
;
6835 /* Otherwise do nothing; just use the value in TEMP. */
6837 else /* VAR not set or VAR is NULL. */
6840 temp
= (char *)NULL
;
6841 if (c
== '=' && var_is_special
)
6843 report_error (_("$%s: cannot assign in this way"), name
);
6846 return &expand_wdesc_error
;
6850 parameter_brace_expand_error (name
, value
);
6851 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6855 /* XXX -- if we're double-quoted and the named variable is "$@",
6856 we want to turn off any special handling of "$@" --
6857 we're not using it, so whatever is on the rhs applies. */
6858 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
6859 *quoted_dollar_atp
= 0;
6860 if (contains_dollar_at
)
6861 *contains_dollar_at
= 0;
6863 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
6865 contains_dollar_at
);
6866 /* XXX - fix up later, esp. noting presence of
6867 W_HASQUOTEDNULL in tdesc->flags */
6878 ret
= alloc_word_desc ();
6885 /* Expand a single ${xxx} expansion. The braces are optional. When
6886 the braces are used, parameter_brace_expand() does the work,
6887 possibly calling param_expand recursively. */
6889 param_expand (string
, sindex
, quoted
, expanded_something
,
6890 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
6893 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
6894 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
6896 char *temp
, *temp1
, uerror
[3];
6897 int zindex
, t_index
, expok
;
6902 WORD_DESC
*tdesc
, *ret
;
6906 c
= string
[++zindex
];
6908 temp
= (char *)NULL
;
6909 ret
= tdesc
= (WORD_DESC
*)NULL
;
6912 /* Do simple cases first. Switch on what follows '$'. */
6926 temp1
= dollar_vars
[TODIGIT (c
)];
6927 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
6932 err_unboundvar (uerror
);
6933 last_command_exit_value
= EXECUTION_FAILURE
;
6934 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6937 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
6938 ? quote_string (temp1
)
6939 : quote_escapes (temp1
);
6941 temp
= (char *)NULL
;
6945 /* $$ -- pid of the invoking shell. */
6947 temp
= itos (dollar_dollar_pid
);
6950 /* $# -- number of positional parameters. */
6952 temp
= itos (number_of_args ());
6955 /* $? -- return value of the last synchronous command. */
6957 temp
= itos (last_command_exit_value
);
6960 /* $- -- flags supplied to the shell on invocation or by `set'. */
6962 temp
= which_set_flags ();
6965 /* $! -- Pid of the last asynchronous command. */
6967 /* If no asynchronous pids have been created, expand to nothing.
6968 If `set -u' has been executed, and no async processes have
6969 been created, this is an expansion error. */
6970 if (last_asynchronous_pid
== NO_PID
)
6972 if (expanded_something
)
6973 *expanded_something
= 0;
6974 temp
= (char *)NULL
;
6975 if (unbound_vars_is_error
)
6980 err_unboundvar (uerror
);
6981 last_command_exit_value
= EXECUTION_FAILURE
;
6982 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
6986 temp
= itos (last_asynchronous_pid
);
6989 /* The only difference between this and $@ is when the arg is quoted. */
6990 case '*': /* `$*' */
6991 list
= list_rest_of_args ();
6994 /* According to austin-group posix proposal by Geoff Clare in
6995 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
6997 "The shell shall write a message to standard error and
6998 immediately exit when it tries to expand an unset parameter
6999 other than the '@' and '*' special parameters."
7002 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7007 last_command_exit_value
= EXECUTION_FAILURE
;
7008 err_unboundvar (uerror
);
7009 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7013 /* If there are no command-line arguments, this should just
7014 disappear if there are other characters in the expansion,
7015 even if it's quoted. */
7016 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7017 temp
= (char *)NULL
;
7018 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7020 /* If we have "$*" we want to make a string of the positional
7021 parameters, separated by the first character of $IFS, and
7022 quote the whole string, including the separators. If IFS
7023 is unset, the parameters are separated by ' '; if $IFS is
7024 null, the parameters are concatenated. */
7025 temp
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (list
) : string_list (list
);
7026 temp1
= quote_string (temp
);
7028 tflag
|= W_HASQUOTEDNULL
;
7034 /* We check whether or not we're eventually going to split $* here,
7035 for example when IFS is empty and we are processing the rhs of
7036 an assignment statement. In that case, we don't separate the
7037 arguments at all. Otherwise, if the $* is not quoted it is
7040 # if defined (HANDLE_MULTIBYTE)
7041 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7043 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7045 temp
= string_list_dollar_star (list
);
7047 temp
= string_list_dollar_at (list
, quoted
);
7049 temp
= string_list_dollar_at (list
, quoted
);
7051 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7052 *contains_dollar_at
= 1;
7055 dispose_words (list
);
7058 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7059 means that we have to turn quoting off after we split into
7060 the individually quoted arguments so that the final split
7061 on the first character of $IFS is still done. */
7062 case '@': /* `$@' */
7063 list
= list_rest_of_args ();
7066 /* According to austin-group posix proposal by Geoff Clare in
7067 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7069 "The shell shall write a message to standard error and
7070 immediately exit when it tries to expand an unset parameter
7071 other than the '@' and '*' special parameters."
7074 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7079 last_command_exit_value
= EXECUTION_FAILURE
;
7080 err_unboundvar (uerror
);
7081 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7085 /* We want to flag the fact that we saw this. We can't turn
7086 off quoting entirely, because other characters in the
7087 string might need it (consider "\"$@\""), but we need some
7088 way to signal that the final split on the first character
7089 of $IFS should be done, even though QUOTED is 1. */
7090 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7091 *quoted_dollar_at_p
= 1;
7092 if (contains_dollar_at
)
7093 *contains_dollar_at
= 1;
7095 /* We want to separate the positional parameters with the first
7096 character of $IFS in case $IFS is something other than a space.
7097 We also want to make sure that splitting is done no matter what --
7098 according to POSIX.2, this expands to a list of the positional
7099 parameters no matter what IFS is set to. */
7100 temp
= string_list_dollar_at (list
, quoted
);
7102 dispose_words (list
);
7106 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
7108 contains_dollar_at
);
7110 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7112 temp
= tdesc
? tdesc
->word
: (char *)0;
7115 /* Quoted nulls should be removed if there is anything else
7117 /* Note that we saw the quoted null so we can add one back at
7118 the end of this function if there are no other characters
7119 in the string, discard TEMP, and go on. The exception to
7120 this is when we have "${@}" and $1 is '', since $@ needs
7121 special handling. */
7122 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7124 if (had_quoted_null_p
)
7125 *had_quoted_null_p
= 1;
7126 if (*quoted_dollar_at_p
== 0)
7129 tdesc
->word
= temp
= (char *)NULL
;
7137 /* Do command or arithmetic substitution. */
7139 /* We have to extract the contents of this paren substitution. */
7140 t_index
= zindex
+ 1;
7141 temp
= extract_command_subst (string
, &t_index
, 0);
7144 /* For Posix.2-style `$(( ))' arithmetic substitution,
7145 extract the expression and pass it to the evaluator. */
7146 if (temp
&& *temp
== LPAREN
)
7150 temp2
= savestring (temp1
);
7151 t_index
= strlen (temp2
) - 1;
7153 if (temp2
[t_index
] != RPAREN
)
7159 /* Cut off ending `)' */
7160 temp2
[t_index
] = '\0';
7162 if (chk_arithsub (temp2
, t_index
) == 0)
7168 /* Expand variables found inside the expression. */
7169 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7173 /* No error messages. */
7174 this_command_name
= (char *)NULL
;
7175 number
= evalexp (temp1
, &expok
);
7180 if (interactive_shell
== 0 && posixly_correct
)
7182 last_command_exit_value
= EXECUTION_FAILURE
;
7183 return (&expand_wdesc_fatal
);
7186 return (&expand_wdesc_error
);
7188 temp
= itos (number
);
7193 if (pflags
& PF_NOCOMSUB
)
7194 /* we need zindex+1 because string[zindex] == RPAREN */
7195 temp1
= substring (string
, *sindex
, zindex
+1);
7198 tdesc
= command_substitute (temp
, quoted
);
7199 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7201 dispose_word_desc (tdesc
);
7207 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7208 away in a future bash release. */
7210 /* Extract the contents of this arithmetic substitution. */
7211 t_index
= zindex
+ 1;
7212 temp
= extract_arithmetic_subst (string
, &t_index
);
7216 temp
= savestring (string
);
7217 if (expanded_something
)
7218 *expanded_something
= 0;
7222 /* Do initial variable expansion. */
7223 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7228 /* Find the variable in VARIABLE_LIST. */
7229 temp
= (char *)NULL
;
7231 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7233 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7235 /* If this isn't a variable name, then just output the `$'. */
7236 if (temp1
== 0 || *temp1
== '\0')
7239 temp
= (char *)xmalloc (2);
7242 if (expanded_something
)
7243 *expanded_something
= 0;
7247 /* If the variable exists, return its value cell. */
7248 var
= find_variable (temp1
);
7250 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7252 #if defined (ARRAY_VARS)
7253 if (assoc_p (var
) || array_p (var
))
7255 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7256 : assoc_reference (assoc_cell (var
), "0");
7258 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7259 ? quote_string (temp
)
7260 : quote_escapes (temp
);
7261 else if (unbound_vars_is_error
)
7262 goto unbound_variable
;
7267 temp
= value_cell (var
);
7269 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7270 ? quote_string (temp
)
7271 : quote_escapes (temp
);
7279 temp
= (char *)NULL
;
7282 if (unbound_vars_is_error
)
7283 err_unboundvar (temp1
);
7291 last_command_exit_value
= EXECUTION_FAILURE
;
7292 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7293 ? &expand_wdesc_fatal
7294 : &expand_wdesc_error
);
7305 ret
= alloc_word_desc ();
7306 ret
->flags
= tflag
; /* XXX */
7312 /* Make a word list which is the result of parameter and variable
7313 expansion, command substitution, arithmetic substitution, and
7314 quote removal of WORD. Return a pointer to a WORD_LIST which is
7315 the result of the expansion. If WORD contains a null word, the
7316 word list returned is also null.
7318 QUOTED contains flag values defined in shell.h.
7320 ISEXP is used to tell expand_word_internal that the word should be
7321 treated as the result of an expansion. This has implications for
7322 how IFS characters in the word are treated.
7324 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7325 they point to an integer value which receives information about expansion.
7326 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7327 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7330 This only does word splitting in the case of $@ expansion. In that
7331 case, we split on ' '. */
7333 /* Values for the local variable quoted_state. */
7335 #define PARTIALLY_QUOTED 1
7336 #define WHOLLY_QUOTED 2
7339 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7342 int *contains_dollar_at
;
7343 int *expanded_something
;
7348 /* The intermediate string that we build while expanding. */
7351 /* The current size of the above object. */
7354 /* Index into ISTRING. */
7357 /* Temporary string storage. */
7360 /* The text of WORD. */
7361 register char *string
;
7363 /* The size of STRING. */
7366 /* The index into STRING. */
7369 /* This gets 1 if we see a $@ while quoted. */
7370 int quoted_dollar_at
;
7372 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7373 whether WORD contains no quoting characters, a partially quoted
7374 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7378 int had_quoted_null
;
7382 int assignoff
; /* If assignment, offset of `=' */
7384 register unsigned char c
; /* Current character. */
7385 int t_index
; /* For calls to string_extract_xxx. */
7391 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
7392 istring
[istring_index
= 0] = '\0';
7393 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
7394 quoted_state
= UNQUOTED
;
7396 string
= word
->word
;
7398 goto finished_with_string
;
7399 /* Don't need the string length for the SADD... and COPY_ macros unless
7400 multibyte characters are possible. */
7401 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
7403 if (contains_dollar_at
)
7404 *contains_dollar_at
= 0;
7408 /* Begin the expansion. */
7414 /* Case on toplevel character. */
7418 goto finished_with_string
;
7422 #if HANDLE_MULTIBYTE
7423 if (MB_CUR_MAX
> 1 && string
[sindex
])
7425 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7430 temp
= (char *)xmalloc (3);
7432 temp
[1] = c
= string
[sindex
];
7443 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
7449 #if defined (PROCESS_SUBSTITUTION)
7450 /* Process substitution. */
7454 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
7456 sindex
--; /* add_character: label increments sindex */
7460 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
7462 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
7465 /* If the process substitution specification is `<()', we want to
7466 open the pipe for writing in the child and produce output; if
7467 it is `>()', we want to open the pipe for reading in the child
7468 and consume input. */
7469 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
7473 goto dollar_add_string
;
7475 #endif /* PROCESS_SUBSTITUTION */
7478 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7479 which are not assignment statements are not expanded. If the
7480 shell isn't in posix mode, though, we perform tilde expansion
7481 on `likely candidate' unquoted assignment statements (flags
7482 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7483 contains an unquoted :~ or =~. Something to think about: we
7484 now have a flag that says to perform tilde expansion on arguments
7485 to `assignment builtins' like declare and export that look like
7486 assignment statements. We now do tilde expansion on such words
7487 even in POSIX mode. */
7488 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
7490 if (isexp
== 0 && isifs (c
))
7491 goto add_ifs_character
;
7495 /* If we're not in posix mode or forcing assignment-statement tilde
7496 expansion, note where the `=' appears in the word and prepare to
7497 do tilde expansion following the first `='. */
7498 if ((word
->flags
& W_ASSIGNMENT
) &&
7499 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7500 assignoff
== -1 && sindex
> 0)
7502 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
7503 word
->flags
|= W_ITILDE
;
7505 else if ((word
->flags
& W_ASSIGNMENT
) &&
7506 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7507 string
[sindex
+1] == '~')
7508 word
->flags
|= W_ITILDE
;
7510 if (isexp
== 0 && isifs (c
))
7511 goto add_ifs_character
;
7516 if (word
->flags
& W_NOTILDE
)
7518 if (isexp
== 0 && isifs (c
))
7519 goto add_ifs_character
;
7524 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
7525 string
[sindex
+1] == '~')
7526 word
->flags
|= W_ITILDE
;
7528 if (isexp
== 0 && isifs (c
))
7529 goto add_ifs_character
;
7534 /* If the word isn't supposed to be tilde expanded, or we're not
7535 at the start of a word or after an unquoted : or = in an
7536 assignment statement, we don't do tilde expansion. */
7537 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
7538 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
7539 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7541 word
->flags
&= ~W_ITILDE
;
7542 if (isexp
== 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
7543 goto add_ifs_character
;
7548 if (word
->flags
& W_ASSIGNRHS
)
7550 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
7555 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
7557 word
->flags
&= ~W_ITILDE
;
7559 if (temp
&& *temp
&& t_index
> 0)
7561 temp1
= bash_tilde_expand (temp
, tflag
);
7562 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
7566 goto add_character
; /* tilde expansion failed */
7571 goto add_quoted_string
; /* XXX was add_string */
7580 if (expanded_something
)
7581 *expanded_something
= 1;
7584 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
7585 &has_dollar_at
, "ed_dollar_at
,
7587 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
7589 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
7593 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
7594 : &expand_word_fatal
);
7596 if (contains_dollar_at
&& has_dollar_at
)
7597 *contains_dollar_at
= 1;
7599 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
7600 had_quoted_null
= 1;
7603 dispose_word_desc (tword
);
7608 case '`': /* Backquoted command substitution. */
7612 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
7613 /* The test of sindex against t_index is to allow bare instances of
7614 ` to pass through, for backwards compatibility. */
7615 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
7617 if (sindex
- 1 == t_index
)
7622 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
7625 return ((temp
== &extract_string_error
) ? &expand_word_error
7626 : &expand_word_fatal
);
7629 if (expanded_something
)
7630 *expanded_something
= 1;
7632 if (word
->flags
& W_NOCOMSUB
)
7633 /* sindex + 1 because string[sindex] == '`' */
7634 temp1
= substring (string
, t_index
, sindex
+ 1);
7637 de_backslash (temp
);
7638 tword
= command_substitute (temp
, quoted
);
7639 temp1
= tword
? tword
->word
: (char *)NULL
;
7641 dispose_word_desc (tword
);
7645 goto dollar_add_string
;
7649 if (string
[sindex
+ 1] == '\n')
7655 c
= string
[++sindex
];
7657 if (quoted
& Q_HERE_DOCUMENT
)
7659 else if (quoted
& Q_DOUBLE_QUOTES
)
7664 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7666 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7671 sindex
--; /* add_character: label increments sindex */
7676 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7681 /* BEFORE jumping here, we need to increment sindex if appropriate */
7682 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7683 DEFAULT_ARRAY_SIZE
);
7684 istring
[istring_index
++] = twochars
[0];
7685 istring
[istring_index
++] = twochars
[1];
7686 istring
[istring_index
] = '\0';
7692 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7694 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7699 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7701 /* If the quotes surrounded the entire string, then the
7702 whole word was quoted. */
7703 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7709 tword
= alloc_word_desc ();
7712 temp
= (char *)NULL
;
7715 /* Need to get W_HASQUOTEDNULL flag through this function. */
7716 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7718 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7722 /* expand_word_internal has already freed temp_word->word
7723 for us because of the way it prints error messages. */
7724 tword
->word
= (char *)NULL
;
7725 dispose_word (tword
);
7729 dispose_word (tword
);
7731 /* "$@" (a double-quoted dollar-at) expands into nothing,
7732 not even a NULL word, when there are no positional
7734 if (list
== 0 && has_dollar_at
)
7740 /* If we get "$@", we know we have expanded something, so we
7741 need to remember it for the final split on $IFS. This is
7742 a special case; it's the only case where a quoted string
7743 can expand into more than one word. It's going to come back
7744 from the above call to expand_word_internal as a list with
7745 a single word, in which all characters are quoted and
7746 separated by blanks. What we want to do is to turn it back
7747 into a list for the next piece of code. */
7749 dequote_list (list
);
7751 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7752 had_quoted_null
= 1;
7757 if (contains_dollar_at
)
7758 *contains_dollar_at
= 1;
7759 if (expanded_something
)
7760 *expanded_something
= 1;
7765 /* What we have is "". This is a minor optimization. */
7767 list
= (WORD_LIST
*)NULL
;
7770 /* The code above *might* return a list (consider the case of "$@",
7771 where it returns "$1", "$2", etc.). We can't throw away the
7772 rest of the list, and we have to make sure each word gets added
7773 as quoted. We test on tresult->next: if it is non-NULL, we
7774 quote the whole list, save it to a string with string_list, and
7775 add that string. We don't need to quote the results of this
7776 (and it would be wrong, since that would quote the separators
7777 as well), so we go directly to add_string. */
7782 /* Testing quoted_dollar_at makes sure that "$@" is
7783 split correctly when $IFS does not contain a space. */
7784 temp
= quoted_dollar_at
7785 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7786 : string_list (quote_list (list
));
7787 dispose_words (list
);
7792 temp
= savestring (list
->word
->word
);
7793 tflag
= list
->word
->flags
;
7794 dispose_words (list
);
7796 /* If the string is not a quoted null string, we want
7797 to remove any embedded unquoted CTLNUL characters.
7798 We do not want to turn quoted null strings back into
7799 the empty string, though. We do this because we
7800 want to remove any quoted nulls from expansions that
7801 contain other characters. For example, if we have
7802 x"$*"y or "x$*y" and there are no positional parameters,
7803 the $* should expand into nothing. */
7804 /* We use the W_HASQUOTEDNULL flag to differentiate the
7805 cases: a quoted null character as above and when
7806 CTLNUL is contained in the (non-null) expansion
7807 of some variable. We use the had_quoted_null flag to
7808 pass the value through this function to its caller. */
7809 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7810 remove_quoted_nulls (temp
); /* XXX */
7814 temp
= (char *)NULL
;
7816 /* We do not want to add quoted nulls to strings that are only
7817 partially quoted; we can throw them away. */
7818 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7826 temp
= quote_string (temp
);
7834 sindex
--; /* add_character: label increments sindex */
7842 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7844 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7849 temp
= string_extract_single_quoted (string
, &sindex
);
7851 /* If the entire STRING was surrounded by single quotes,
7852 then the string is wholly quoted. */
7853 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7857 /* If all we had was '', it is a null expansion. */
7861 temp
= (char *)NULL
;
7864 remove_quoted_escapes (temp
); /* ??? */
7866 /* We do not want to add quoted nulls to strings that are only
7867 partially quoted; such nulls are discarded. */
7868 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7871 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7875 sindex
--; /* add_character: label increments sindex */
7879 goto add_quoted_string
;
7884 /* This is the fix for " $@ " */
7886 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7888 if (string
[sindex
]) /* from old goto dollar_add_string */
7897 #if HANDLE_MULTIBYTE
7903 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7908 twochars
[0] = CTLESC
;
7915 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7918 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7919 DEFAULT_ARRAY_SIZE
);
7920 istring
[istring_index
++] = c
;
7921 istring
[istring_index
] = '\0';
7923 /* Next character. */
7928 finished_with_string
:
7929 /* OK, we're ready to return. If we have a quoted string, and
7930 quoted_dollar_at is not set, we do no splitting at all; otherwise
7931 we split on ' '. The routines that call this will handle what to
7932 do if nothing has been expanded. */
7934 /* Partially and wholly quoted strings which expand to the empty
7935 string are retained as an empty arguments. Unquoted strings
7936 which expand to the empty string are discarded. The single
7937 exception is the case of expanding "$@" when there are no
7938 positional parameters. In that case, we discard the expansion. */
7940 /* Because of how the code that handles "" and '' in partially
7941 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7942 if we saw quoting characters, but the expansion was empty.
7943 "" and '' are tossed away before we get to this point when
7944 processing partially quoted strings. This makes "" and $xxx""
7945 equivalent when xxx is unset. We also look to see whether we
7946 saw a quoted null from a ${} expansion and add one back if we
7949 /* If we expand to nothing and there were no single or double quotes
7950 in the word, we throw it away. Otherwise, we return a NULL word.
7951 The single exception is for $@ surrounded by double quotes when
7952 there are no positional parameters. In that case, we also throw
7955 if (*istring
== '\0')
7957 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7959 istring
[0] = CTLNUL
;
7961 tword
= make_bare_word (istring
);
7962 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7963 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7964 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7965 tword
->flags
|= W_QUOTED
;
7967 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7968 and a double-quoted "$@" appears anywhere in it, then the entire
7970 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
7971 list
= (WORD_LIST
*)NULL
;
7975 tword
= make_bare_word (istring
);
7976 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7977 tword
->flags
|= W_QUOTED
;
7978 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7982 list
= (WORD_LIST
*)NULL
;
7985 else if (word
->flags
& W_NOSPLIT
)
7987 tword
= make_bare_word (istring
);
7988 if (word
->flags
& W_ASSIGNMENT
)
7989 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
7990 if (word
->flags
& W_COMPASSIGN
)
7991 tword
->flags
|= W_COMPASSIGN
; /* XXX */
7992 if (word
->flags
& W_NOGLOB
)
7993 tword
->flags
|= W_NOGLOB
; /* XXX */
7994 if (word
->flags
& W_NOEXPAND
)
7995 tword
->flags
|= W_NOEXPAND
; /* XXX */
7996 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7997 tword
->flags
|= W_QUOTED
;
7998 if (had_quoted_null
)
7999 tword
->flags
|= W_HASQUOTEDNULL
;
8000 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8006 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8008 /* If we have $@, we need to split the results no matter what. If
8009 IFS is unset or NULL, string_list_dollar_at has separated the
8010 positional parameters with a space, so we split on space (we have
8011 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8012 string_list_dollar_at has separated the positional parameters
8013 with the first character of $IFS, so we split on $IFS. */
8014 if (has_dollar_at
&& ifs_chars
)
8015 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8018 tword
= make_bare_word (istring
);
8019 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8020 tword
->flags
|= W_QUOTED
;
8021 if (word
->flags
& W_ASSIGNMENT
)
8022 tword
->flags
|= W_ASSIGNMENT
;
8023 if (word
->flags
& W_COMPASSIGN
)
8024 tword
->flags
|= W_COMPASSIGN
;
8025 if (word
->flags
& W_NOGLOB
)
8026 tword
->flags
|= W_NOGLOB
;
8027 if (word
->flags
& W_NOEXPAND
)
8028 tword
->flags
|= W_NOEXPAND
;
8029 if (had_quoted_null
)
8030 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8031 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8039 /* **************************************************************** */
8041 /* Functions for Quote Removal */
8043 /* **************************************************************** */
8045 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8046 backslash quoting rules for within double quotes or a here document. */
8048 string_quote_removal (string
, quoted
)
8053 char *r
, *result_string
, *temp
, *send
;
8054 int sindex
, tindex
, dquote
;
8058 /* The result can be no longer than the original string. */
8059 slen
= strlen (string
);
8060 send
= string
+ slen
;
8062 r
= result_string
= (char *)xmalloc (slen
+ 1);
8064 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8069 c
= string
[++sindex
];
8075 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8080 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8084 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8090 tindex
= sindex
+ 1;
8091 temp
= string_extract_single_quoted (string
, &tindex
);
8102 dquote
= 1 - dquote
;
8108 return (result_string
);
8113 /* Perform quote removal on word WORD. This allocates and returns a new
8116 word_quote_removal (word
, quoted
)
8123 t
= string_quote_removal (word
->word
, quoted
);
8124 w
= alloc_word_desc ();
8125 w
->word
= t
? t
: savestring ("");
8129 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8130 the members of the list are treated as if they are surrounded by
8131 double quotes. Return a new list, or NULL if LIST is NULL. */
8133 word_list_quote_removal (list
, quoted
)
8137 WORD_LIST
*result
, *t
, *tresult
, *e
;
8139 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8141 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8143 result
= (WORD_LIST
*) list_append (result
, tresult
);
8146 result
= e
= tresult
;
8159 /*******************************************
8161 * Functions to perform word splitting *
8163 *******************************************/
8173 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8175 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8176 handle multibyte chars in IFS */
8177 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8178 for (t
= ifs_value
; t
&& *t
; t
++)
8184 #if defined (HANDLE_MULTIBYTE)
8187 ifs_firstc
[0] = '\0';
8193 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8194 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8195 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8197 ifs_firstc
[0] = ifs_value
[0];
8198 ifs_firstc
[1] = '\0';
8202 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8205 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8215 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8216 is not quoted. list_string () performs quote removal for us, even if we
8217 don't do any splitting. */
8219 word_split (w
, ifs_chars
)
8229 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8230 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8233 result
= (WORD_LIST
*)NULL
;
8238 /* Perform word splitting on LIST and return the RESULT. It is possible
8239 to return (WORD_LIST *)NULL. */
8241 word_list_split (list
)
8244 WORD_LIST
*result
, *t
, *tresult
, *e
;
8246 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8248 tresult
= word_split (t
->word
, ifs_value
);
8250 result
= e
= tresult
;
8261 /**************************************************
8263 * Functions to expand an entire WORD_LIST *
8265 **************************************************/
8267 /* Do any word-expansion-specific cleanup and jump to top_level */
8269 exp_jump_to_top_level (v
)
8272 set_pipestatus_from_exit (last_command_exit_value
);
8274 /* Cleanup code goes here. */
8275 expand_no_split_dollar_star
= 0; /* XXX */
8276 expanding_redir
= 0;
8277 assigning_in_environment
= 0;
8279 if (parse_and_execute_level
== 0)
8280 top_level_cleanup (); /* from sig.c */
8282 jump_to_top_level (v
);
8285 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8286 ELIST, and set ELIST to the new list. */
8287 #define PREPEND_LIST(nlist, elist) \
8288 do { nlist->next = elist; elist = nlist; } while (0)
8290 /* Separate out any initial variable assignments from TLIST. If set -k has
8291 been executed, remove all assignment statements from TLIST. Initial
8292 variable assignments and other environment assignments are placed
8293 on SUBST_ASSIGN_VARLIST. */
8295 separate_out_assignments (tlist
)
8298 register WORD_LIST
*vp
, *lp
;
8301 return ((WORD_LIST
*)NULL
);
8303 if (subst_assign_varlist
)
8304 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8306 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8309 /* Separate out variable assignments at the start of the command.
8310 Loop invariant: vp->next == lp
8312 lp = list of words left after assignment statements skipped
8313 tlist = original list of words
8315 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8321 /* If lp != tlist, we have some initial assignment statements.
8322 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8323 words and TLIST point to the remaining words. */
8326 subst_assign_varlist
= tlist
;
8327 /* ASSERT(vp->next == lp); */
8328 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8329 tlist
= lp
; /* remainder of word list */
8332 /* vp == end of variable list */
8333 /* tlist == remainder of original word list without variable assignments */
8335 /* All the words in tlist were assignment statements */
8336 return ((WORD_LIST
*)NULL
);
8338 /* ASSERT(tlist != NULL); */
8339 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8341 /* If the -k option is in effect, we need to go through the remaining
8342 words, separate out the assignment words, and place them on
8343 SUBST_ASSIGN_VARLIST. */
8344 if (place_keywords_in_env
)
8346 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8351 /* Loop Invariant: tp->next == lp */
8352 /* Loop postcondition: tlist == word list without assignment statements */
8355 if (lp
->word
->flags
& W_ASSIGNMENT
)
8357 /* Found an assignment statement, add this word to end of
8358 subst_assign_varlist (vp). */
8359 if (!subst_assign_varlist
)
8360 subst_assign_varlist
= vp
= lp
;
8367 /* Remove the word pointed to by LP from TLIST. */
8368 tp
->next
= lp
->next
;
8369 /* ASSERT(vp == lp); */
8370 lp
->next
= (WORD_LIST
*)NULL
;
8383 #define WEXP_VARASSIGN 0x001
8384 #define WEXP_BRACEEXP 0x002
8385 #define WEXP_TILDEEXP 0x004
8386 #define WEXP_PARAMEXP 0x008
8387 #define WEXP_PATHEXP 0x010
8389 /* All of the expansions, including variable assignments at the start of
8391 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8393 /* All of the expansions except variable assignments at the start of
8395 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8397 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8398 expansion, command substitution, arithmetic expansion, word splitting, and
8400 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8402 /* Take the list of words in LIST and do the various substitutions. Return
8403 a new list of words which is the expanded list, and without things like
8404 variable assignments. */
8410 return (expand_word_list_internal (list
, WEXP_ALL
));
8413 /* Same as expand_words (), but doesn't hack variable or environment
8416 expand_words_no_vars (list
)
8419 return (expand_word_list_internal (list
, WEXP_NOVARS
));
8423 expand_words_shellexp (list
)
8426 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
8430 glob_expand_word_list (tlist
, eflags
)
8434 char **glob_array
, *temp_string
;
8435 register int glob_index
;
8436 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
8439 output_list
= disposables
= (WORD_LIST
*)NULL
;
8440 glob_array
= (char **)NULL
;
8443 /* For each word, either globbing is attempted or the word is
8444 added to orig_list. If globbing succeeds, the results are
8445 added to orig_list and the word (tlist) is added to the list
8446 of disposable words. If globbing fails and failed glob
8447 expansions are left unchanged (the shell default), the
8448 original word is added to orig_list. If globbing fails and
8449 failed glob expansions are removed, the original word is
8450 added to the list of disposable words. orig_list ends up
8451 in reverse order and requires a call to REVERSE_LIST to
8452 be set right. After all words are examined, the disposable
8456 /* If the word isn't an assignment and contains an unquoted
8457 pattern matching character, then glob it. */
8458 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
8459 unquoted_glob_pattern_p (tlist
->word
->word
))
8461 glob_array
= shell_glob_filename (tlist
->word
->word
);
8463 /* Handle error cases.
8464 I don't think we should report errors like "No such file
8465 or directory". However, I would like to report errors
8466 like "Read failed". */
8468 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
8470 glob_array
= (char **)xmalloc (sizeof (char *));
8471 glob_array
[0] = (char *)NULL
;
8474 /* Dequote the current word in case we have to use it. */
8475 if (glob_array
[0] == NULL
)
8477 temp_string
= dequote_string (tlist
->word
->word
);
8478 free (tlist
->word
->word
);
8479 tlist
->word
->word
= temp_string
;
8482 /* Make the array into a word list. */
8483 glob_list
= (WORD_LIST
*)NULL
;
8484 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
8486 tword
= make_bare_word (glob_array
[glob_index
]);
8487 tword
->flags
|= W_GLOBEXP
; /* XXX */
8488 glob_list
= make_word_list (tword
, glob_list
);
8493 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
8494 PREPEND_LIST (tlist
, disposables
);
8496 else if (fail_glob_expansion
!= 0)
8498 report_error (_("no match: %s"), tlist
->word
->word
);
8499 exp_jump_to_top_level (DISCARD
);
8501 else if (allow_null_glob_expansion
== 0)
8503 /* Failed glob expressions are left unchanged. */
8504 PREPEND_LIST (tlist
, output_list
);
8508 /* Failed glob expressions are removed. */
8509 PREPEND_LIST (tlist
, disposables
);
8514 /* Dequote the string. */
8515 temp_string
= dequote_string (tlist
->word
->word
);
8516 free (tlist
->word
->word
);
8517 tlist
->word
->word
= temp_string
;
8518 PREPEND_LIST (tlist
, output_list
);
8521 strvec_dispose (glob_array
);
8522 glob_array
= (char **)NULL
;
8528 dispose_words (disposables
);
8531 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8533 return (output_list
);
8536 #if defined (BRACE_EXPANSION)
8538 brace_expand_word_list (tlist
, eflags
)
8542 register char **expansions
;
8544 WORD_LIST
*disposables
, *output_list
, *next
;
8548 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
8552 /* Only do brace expansion if the word has a brace character. If
8553 not, just add the word list element to BRACES and continue. In
8554 the common case, at least when running shell scripts, this will
8555 degenerate to a bunch of calls to `xstrchr', and then what is
8556 basically a reversal of TLIST into BRACES, which is corrected
8557 by a call to REVERSE_LIST () on BRACES when the end of TLIST
8559 if (xstrchr (tlist
->word
->word
, LBRACE
))
8561 expansions
= brace_expand (tlist
->word
->word
);
8563 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
8565 w
= make_word (temp_string
);
8566 /* If brace expansion didn't change the word, preserve
8567 the flags. We may want to preserve the flags
8568 unconditionally someday -- XXX */
8569 if (STREQ (temp_string
, tlist
->word
->word
))
8570 w
->flags
= tlist
->word
->flags
;
8571 output_list
= make_word_list (w
, output_list
);
8572 free (expansions
[eindex
]);
8576 /* Add TLIST to the list of words to be freed after brace
8577 expansion has been performed. */
8578 PREPEND_LIST (tlist
, disposables
);
8581 PREPEND_LIST (tlist
, output_list
);
8585 dispose_words (disposables
);
8588 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8590 return (output_list
);
8594 #if defined (ARRAY_VARS)
8595 /* Take WORD, a compound associative array assignment, and internally run
8596 'declare -A w', where W is the variable name portion of WORD. */
8598 make_internal_declare (word
, option
)
8606 w
= make_word (word
);
8608 t
= assignment (w
->word
, 0);
8611 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
8612 wl
= make_word_list (make_word (option
), wl
);
8614 return (declare_builtin (wl
));
8619 shell_expand_word_list (tlist
, eflags
)
8623 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
8624 int expanded_something
, has_dollar_at
;
8627 /* We do tilde expansion all the time. This is what 1003.2 says. */
8628 new_list
= (WORD_LIST
*)NULL
;
8629 for (orig_list
= tlist
; tlist
; tlist
= next
)
8631 temp_string
= tlist
->word
->word
;
8635 #if defined (ARRAY_VARS)
8636 /* If this is a compound array assignment to a builtin that accepts
8637 such assignments (e.g., `declare'), take the assignment and perform
8638 it separately, handling the semantics of declarations inside shell
8639 functions. This avoids the double-evaluation of such arguments,
8640 because `declare' does some evaluation of compound assignments on
8642 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8646 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
8647 make_internal_declare (tlist
->word
->word
, "-A");
8649 t
= do_word_assignment (tlist
->word
);
8652 last_command_exit_value
= EXECUTION_FAILURE
;
8653 exp_jump_to_top_level (DISCARD
);
8656 /* Now transform the word as ksh93 appears to do and go on */
8657 t
= assignment (tlist
->word
->word
, 0);
8658 tlist
->word
->word
[t
] = '\0';
8659 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
8663 expanded_something
= 0;
8664 expanded
= expand_word_internal
8665 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
8667 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
8669 /* By convention, each time this error is returned,
8670 tlist->word->word has already been freed. */
8671 tlist
->word
->word
= (char *)NULL
;
8673 /* Dispose our copy of the original list. */
8674 dispose_words (orig_list
);
8675 /* Dispose the new list we're building. */
8676 dispose_words (new_list
);
8678 last_command_exit_value
= EXECUTION_FAILURE
;
8679 if (expanded
== &expand_word_error
)
8680 exp_jump_to_top_level (DISCARD
);
8682 exp_jump_to_top_level (FORCE_EOF
);
8685 /* Don't split words marked W_NOSPLIT. */
8686 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
8688 temp_list
= word_list_split (expanded
);
8689 dispose_words (expanded
);
8693 /* If no parameter expansion, command substitution, process
8694 substitution, or arithmetic substitution took place, then
8695 do not do word splitting. We still have to remove quoted
8696 null characters from the result. */
8697 word_list_remove_quoted_nulls (expanded
);
8698 temp_list
= expanded
;
8701 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8702 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8706 dispose_words (orig_list
);
8709 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8714 /* The workhorse for expand_words () and expand_words_no_vars ().
8715 First arg is LIST, a WORD_LIST of words.
8716 Second arg EFLAGS is a flags word controlling which expansions are
8719 This does all of the substitutions: brace expansion, tilde expansion,
8720 parameter expansion, command substitution, arithmetic expansion,
8721 process substitution, word splitting, and pathname expansion, according
8722 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8723 set, or for which no expansion is done, do not undergo word splitting.
8724 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8726 expand_word_list_internal (list
, eflags
)
8730 WORD_LIST
*new_list
, *temp_list
;
8734 return ((WORD_LIST
*)NULL
);
8736 garglist
= new_list
= copy_word_list (list
);
8737 if (eflags
& WEXP_VARASSIGN
)
8739 garglist
= new_list
= separate_out_assignments (new_list
);
8742 if (subst_assign_varlist
)
8744 /* All the words were variable assignments, so they are placed
8745 into the shell's environment. */
8746 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8748 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8749 tint
= do_word_assignment (temp_list
->word
);
8750 /* Variable assignment errors in non-interactive shells
8751 running in Posix.2 mode cause the shell to exit. */
8754 last_command_exit_value
= EXECUTION_FAILURE
;
8755 if (interactive_shell
== 0 && posixly_correct
)
8756 exp_jump_to_top_level (FORCE_EOF
);
8758 exp_jump_to_top_level (DISCARD
);
8761 dispose_words (subst_assign_varlist
);
8762 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8764 return ((WORD_LIST
*)NULL
);
8768 /* Begin expanding the words that remain. The expansions take place on
8769 things that aren't really variable assignments. */
8771 #if defined (BRACE_EXPANSION)
8772 /* Do brace expansion on this word if there are any brace characters
8774 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8775 new_list
= brace_expand_word_list (new_list
, eflags
);
8776 #endif /* BRACE_EXPANSION */
8778 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8779 variable substitution, command substitution, arithmetic expansion,
8780 and word splitting. */
8781 new_list
= shell_expand_word_list (new_list
, eflags
);
8783 /* Okay, we're almost done. Now let's just do some filename
8787 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8788 /* Glob expand the word list unless globbing has been disabled. */
8789 new_list
= glob_expand_word_list (new_list
, eflags
);
8791 /* Dequote the words, because we're not performing globbing. */
8792 new_list
= dequote_list (new_list
);
8795 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8797 sh_wassign_func_t
*assign_func
;
8799 /* If the remainder of the words expand to nothing, Posix.2 requires
8800 that the variable and environment assignments affect the shell's
8802 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8803 tempenv_assign_error
= 0;
8805 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8807 this_command_name
= (char *)NULL
;
8808 assigning_in_environment
= (assign_func
== assign_in_env
);
8809 tint
= (*assign_func
) (temp_list
->word
);
8810 assigning_in_environment
= 0;
8811 /* Variable assignment errors in non-interactive shells running
8812 in Posix.2 mode cause the shell to exit. */
8815 if (assign_func
== do_word_assignment
)
8817 last_command_exit_value
= EXECUTION_FAILURE
;
8818 if (interactive_shell
== 0 && posixly_correct
)
8819 exp_jump_to_top_level (FORCE_EOF
);
8821 exp_jump_to_top_level (DISCARD
);
8824 tempenv_assign_error
++;
8828 dispose_words (subst_assign_varlist
);
8829 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8833 tint
= list_length (new_list
) + 1;
8834 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8835 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8836 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8837 glob_argv_flags
[tint
] = '\0';