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;
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
)
6772 err_unboundvar (name
);
6776 last_command_exit_value
= EXECUTION_FAILURE
;
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 ();
6993 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
6998 err_unboundvar (uerror
);
6999 last_command_exit_value
= EXECUTION_FAILURE
;
7000 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7003 /* If there are no command-line arguments, this should just
7004 disappear if there are other characters in the expansion,
7005 even if it's quoted. */
7006 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7007 temp
= (char *)NULL
;
7008 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7010 /* If we have "$*" we want to make a string of the positional
7011 parameters, separated by the first character of $IFS, and
7012 quote the whole string, including the separators. If IFS
7013 is unset, the parameters are separated by ' '; if $IFS is
7014 null, the parameters are concatenated. */
7015 temp
= (quoted
& Q_DOUBLE_QUOTES
) ? string_list_dollar_star (list
) : string_list (list
);
7016 temp1
= quote_string (temp
);
7018 tflag
|= W_HASQUOTEDNULL
;
7024 /* We check whether or not we're eventually going to split $* here,
7025 for example when IFS is empty and we are processing the rhs of
7026 an assignment statement. In that case, we don't separate the
7027 arguments at all. Otherwise, if the $* is not quoted it is
7030 # if defined (HANDLE_MULTIBYTE)
7031 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7033 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7035 temp
= string_list_dollar_star (list
);
7037 temp
= string_list_dollar_at (list
, quoted
);
7039 temp
= string_list_dollar_at (list
, quoted
);
7041 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7042 *contains_dollar_at
= 1;
7045 dispose_words (list
);
7048 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7049 means that we have to turn quoting off after we split into
7050 the individually quoted arguments so that the final split
7051 on the first character of $IFS is still done. */
7052 case '@': /* `$@' */
7053 list
= list_rest_of_args ();
7055 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7060 err_unboundvar (uerror
);
7061 last_command_exit_value
= EXECUTION_FAILURE
;
7062 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7065 /* We want to flag the fact that we saw this. We can't turn
7066 off quoting entirely, because other characters in the
7067 string might need it (consider "\"$@\""), but we need some
7068 way to signal that the final split on the first character
7069 of $IFS should be done, even though QUOTED is 1. */
7070 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7071 *quoted_dollar_at_p
= 1;
7072 if (contains_dollar_at
)
7073 *contains_dollar_at
= 1;
7075 /* We want to separate the positional parameters with the first
7076 character of $IFS in case $IFS is something other than a space.
7077 We also want to make sure that splitting is done no matter what --
7078 according to POSIX.2, this expands to a list of the positional
7079 parameters no matter what IFS is set to. */
7080 temp
= string_list_dollar_at (list
, quoted
);
7082 dispose_words (list
);
7086 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
,
7088 contains_dollar_at
);
7090 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7092 temp
= tdesc
? tdesc
->word
: (char *)0;
7095 /* Quoted nulls should be removed if there is anything else
7097 /* Note that we saw the quoted null so we can add one back at
7098 the end of this function if there are no other characters
7099 in the string, discard TEMP, and go on. The exception to
7100 this is when we have "${@}" and $1 is '', since $@ needs
7101 special handling. */
7102 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7104 if (had_quoted_null_p
)
7105 *had_quoted_null_p
= 1;
7106 if (*quoted_dollar_at_p
== 0)
7109 tdesc
->word
= temp
= (char *)NULL
;
7117 /* Do command or arithmetic substitution. */
7119 /* We have to extract the contents of this paren substitution. */
7120 t_index
= zindex
+ 1;
7121 temp
= extract_command_subst (string
, &t_index
, 0);
7124 /* For Posix.2-style `$(( ))' arithmetic substitution,
7125 extract the expression and pass it to the evaluator. */
7126 if (temp
&& *temp
== LPAREN
)
7130 temp2
= savestring (temp1
);
7131 t_index
= strlen (temp2
) - 1;
7133 if (temp2
[t_index
] != RPAREN
)
7139 /* Cut off ending `)' */
7140 temp2
[t_index
] = '\0';
7142 if (chk_arithsub (temp2
, t_index
) == 0)
7148 /* Expand variables found inside the expression. */
7149 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7153 /* No error messages. */
7154 this_command_name
= (char *)NULL
;
7155 number
= evalexp (temp1
, &expok
);
7160 if (interactive_shell
== 0 && posixly_correct
)
7162 last_command_exit_value
= EXECUTION_FAILURE
;
7163 return (&expand_wdesc_fatal
);
7166 return (&expand_wdesc_error
);
7168 temp
= itos (number
);
7173 if (pflags
& PF_NOCOMSUB
)
7174 /* we need zindex+1 because string[zindex] == RPAREN */
7175 temp1
= substring (string
, *sindex
, zindex
+1);
7178 tdesc
= command_substitute (temp
, quoted
);
7179 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7181 dispose_word_desc (tdesc
);
7187 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7188 away in a future bash release. */
7190 /* Extract the contents of this arithmetic substitution. */
7191 t_index
= zindex
+ 1;
7192 temp
= extract_arithmetic_subst (string
, &t_index
);
7196 temp
= savestring (string
);
7197 if (expanded_something
)
7198 *expanded_something
= 0;
7202 /* Do initial variable expansion. */
7203 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7208 /* Find the variable in VARIABLE_LIST. */
7209 temp
= (char *)NULL
;
7211 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7213 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7215 /* If this isn't a variable name, then just output the `$'. */
7216 if (temp1
== 0 || *temp1
== '\0')
7219 temp
= (char *)xmalloc (2);
7222 if (expanded_something
)
7223 *expanded_something
= 0;
7227 /* If the variable exists, return its value cell. */
7228 var
= find_variable (temp1
);
7230 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7232 #if defined (ARRAY_VARS)
7233 if (assoc_p (var
) || array_p (var
))
7235 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7236 : assoc_reference (assoc_cell (var
), "0");
7238 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7239 ? quote_string (temp
)
7240 : quote_escapes (temp
);
7241 else if (unbound_vars_is_error
)
7242 goto unbound_variable
;
7247 temp
= value_cell (var
);
7249 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7250 ? quote_string (temp
)
7251 : quote_escapes (temp
);
7259 temp
= (char *)NULL
;
7262 if (unbound_vars_is_error
)
7263 err_unboundvar (temp1
);
7271 last_command_exit_value
= EXECUTION_FAILURE
;
7272 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7273 ? &expand_wdesc_fatal
7274 : &expand_wdesc_error
);
7285 ret
= alloc_word_desc ();
7286 ret
->flags
= tflag
; /* XXX */
7292 /* Make a word list which is the result of parameter and variable
7293 expansion, command substitution, arithmetic substitution, and
7294 quote removal of WORD. Return a pointer to a WORD_LIST which is
7295 the result of the expansion. If WORD contains a null word, the
7296 word list returned is also null.
7298 QUOTED contains flag values defined in shell.h.
7300 ISEXP is used to tell expand_word_internal that the word should be
7301 treated as the result of an expansion. This has implications for
7302 how IFS characters in the word are treated.
7304 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7305 they point to an integer value which receives information about expansion.
7306 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7307 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7310 This only does word splitting in the case of $@ expansion. In that
7311 case, we split on ' '. */
7313 /* Values for the local variable quoted_state. */
7315 #define PARTIALLY_QUOTED 1
7316 #define WHOLLY_QUOTED 2
7319 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7322 int *contains_dollar_at
;
7323 int *expanded_something
;
7328 /* The intermediate string that we build while expanding. */
7331 /* The current size of the above object. */
7334 /* Index into ISTRING. */
7337 /* Temporary string storage. */
7340 /* The text of WORD. */
7341 register char *string
;
7343 /* The size of STRING. */
7346 /* The index into STRING. */
7349 /* This gets 1 if we see a $@ while quoted. */
7350 int quoted_dollar_at
;
7352 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7353 whether WORD contains no quoting characters, a partially quoted
7354 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7358 int had_quoted_null
;
7362 int assignoff
; /* If assignment, offset of `=' */
7364 register unsigned char c
; /* Current character. */
7365 int t_index
; /* For calls to string_extract_xxx. */
7371 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
7372 istring
[istring_index
= 0] = '\0';
7373 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
7374 quoted_state
= UNQUOTED
;
7376 string
= word
->word
;
7378 goto finished_with_string
;
7379 /* Don't need the string length for the SADD... and COPY_ macros unless
7380 multibyte characters are possible. */
7381 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
7383 if (contains_dollar_at
)
7384 *contains_dollar_at
= 0;
7388 /* Begin the expansion. */
7394 /* Case on toplevel character. */
7398 goto finished_with_string
;
7402 #if HANDLE_MULTIBYTE
7403 if (MB_CUR_MAX
> 1 && string
[sindex
])
7405 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7410 temp
= (char *)xmalloc (3);
7412 temp
[1] = c
= string
[sindex
];
7423 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
7429 #if defined (PROCESS_SUBSTITUTION)
7430 /* Process substitution. */
7434 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
7436 sindex
--; /* add_character: label increments sindex */
7440 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
7442 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
7445 /* If the process substitution specification is `<()', we want to
7446 open the pipe for writing in the child and produce output; if
7447 it is `>()', we want to open the pipe for reading in the child
7448 and consume input. */
7449 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
7453 goto dollar_add_string
;
7455 #endif /* PROCESS_SUBSTITUTION */
7458 /* Posix.2 section 3.6.1 says that tildes following `=' in words
7459 which are not assignment statements are not expanded. If the
7460 shell isn't in posix mode, though, we perform tilde expansion
7461 on `likely candidate' unquoted assignment statements (flags
7462 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
7463 contains an unquoted :~ or =~. Something to think about: we
7464 now have a flag that says to perform tilde expansion on arguments
7465 to `assignment builtins' like declare and export that look like
7466 assignment statements. We now do tilde expansion on such words
7467 even in POSIX mode. */
7468 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
7470 if (isexp
== 0 && isifs (c
))
7471 goto add_ifs_character
;
7475 /* If we're not in posix mode or forcing assignment-statement tilde
7476 expansion, note where the `=' appears in the word and prepare to
7477 do tilde expansion following the first `='. */
7478 if ((word
->flags
& W_ASSIGNMENT
) &&
7479 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7480 assignoff
== -1 && sindex
> 0)
7482 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
7483 word
->flags
|= W_ITILDE
;
7485 else if ((word
->flags
& W_ASSIGNMENT
) &&
7486 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
7487 string
[sindex
+1] == '~')
7488 word
->flags
|= W_ITILDE
;
7490 if (isexp
== 0 && isifs (c
))
7491 goto add_ifs_character
;
7496 if (word
->flags
& W_NOTILDE
)
7498 if (isexp
== 0 && isifs (c
))
7499 goto add_ifs_character
;
7504 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
7505 string
[sindex
+1] == '~')
7506 word
->flags
|= W_ITILDE
;
7508 if (isexp
== 0 && isifs (c
))
7509 goto add_ifs_character
;
7514 /* If the word isn't supposed to be tilde expanded, or we're not
7515 at the start of a word or after an unquoted : or = in an
7516 assignment statement, we don't do tilde expansion. */
7517 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
7518 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
7519 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7521 word
->flags
&= ~W_ITILDE
;
7522 if (isexp
== 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
7523 goto add_ifs_character
;
7528 if (word
->flags
& W_ASSIGNRHS
)
7530 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
7535 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
7537 word
->flags
&= ~W_ITILDE
;
7539 if (temp
&& *temp
&& t_index
> 0)
7541 temp1
= bash_tilde_expand (temp
, tflag
);
7542 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
7546 goto add_character
; /* tilde expansion failed */
7551 goto add_quoted_string
; /* XXX was add_string */
7560 if (expanded_something
)
7561 *expanded_something
= 1;
7564 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
7565 &has_dollar_at
, "ed_dollar_at
,
7567 (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0);
7569 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
7573 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
7574 : &expand_word_fatal
);
7576 if (contains_dollar_at
&& has_dollar_at
)
7577 *contains_dollar_at
= 1;
7579 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
7580 had_quoted_null
= 1;
7583 dispose_word_desc (tword
);
7588 case '`': /* Backquoted command substitution. */
7592 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
7593 /* The test of sindex against t_index is to allow bare instances of
7594 ` to pass through, for backwards compatibility. */
7595 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
7597 if (sindex
- 1 == t_index
)
7602 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
7605 return ((temp
== &extract_string_error
) ? &expand_word_error
7606 : &expand_word_fatal
);
7609 if (expanded_something
)
7610 *expanded_something
= 1;
7612 if (word
->flags
& W_NOCOMSUB
)
7613 /* sindex + 1 because string[sindex] == '`' */
7614 temp1
= substring (string
, t_index
, sindex
+ 1);
7617 de_backslash (temp
);
7618 tword
= command_substitute (temp
, quoted
);
7619 temp1
= tword
? tword
->word
: (char *)NULL
;
7621 dispose_word_desc (tword
);
7625 goto dollar_add_string
;
7629 if (string
[sindex
+ 1] == '\n')
7635 c
= string
[++sindex
];
7637 if (quoted
& Q_HERE_DOCUMENT
)
7639 else if (quoted
& Q_DOUBLE_QUOTES
)
7644 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
7646 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
7651 sindex
--; /* add_character: label increments sindex */
7656 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
7661 /* BEFORE jumping here, we need to increment sindex if appropriate */
7662 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
7663 DEFAULT_ARRAY_SIZE
);
7664 istring
[istring_index
++] = twochars
[0];
7665 istring
[istring_index
++] = twochars
[1];
7666 istring
[istring_index
] = '\0';
7672 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7674 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7679 temp
= string_extract_double_quoted (string
, &sindex
, 0);
7681 /* If the quotes surrounded the entire string, then the
7682 whole word was quoted. */
7683 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7689 tword
= alloc_word_desc ();
7692 temp
= (char *)NULL
;
7695 /* Need to get W_HASQUOTEDNULL flag through this function. */
7696 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &has_dollar_at
, (int *)NULL
);
7698 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
7702 /* expand_word_internal has already freed temp_word->word
7703 for us because of the way it prints error messages. */
7704 tword
->word
= (char *)NULL
;
7705 dispose_word (tword
);
7709 dispose_word (tword
);
7711 /* "$@" (a double-quoted dollar-at) expands into nothing,
7712 not even a NULL word, when there are no positional
7714 if (list
== 0 && has_dollar_at
)
7720 /* If we get "$@", we know we have expanded something, so we
7721 need to remember it for the final split on $IFS. This is
7722 a special case; it's the only case where a quoted string
7723 can expand into more than one word. It's going to come back
7724 from the above call to expand_word_internal as a list with
7725 a single word, in which all characters are quoted and
7726 separated by blanks. What we want to do is to turn it back
7727 into a list for the next piece of code. */
7729 dequote_list (list
);
7731 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
7732 had_quoted_null
= 1;
7737 if (contains_dollar_at
)
7738 *contains_dollar_at
= 1;
7739 if (expanded_something
)
7740 *expanded_something
= 1;
7745 /* What we have is "". This is a minor optimization. */
7747 list
= (WORD_LIST
*)NULL
;
7750 /* The code above *might* return a list (consider the case of "$@",
7751 where it returns "$1", "$2", etc.). We can't throw away the
7752 rest of the list, and we have to make sure each word gets added
7753 as quoted. We test on tresult->next: if it is non-NULL, we
7754 quote the whole list, save it to a string with string_list, and
7755 add that string. We don't need to quote the results of this
7756 (and it would be wrong, since that would quote the separators
7757 as well), so we go directly to add_string. */
7762 /* Testing quoted_dollar_at makes sure that "$@" is
7763 split correctly when $IFS does not contain a space. */
7764 temp
= quoted_dollar_at
7765 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
7766 : string_list (quote_list (list
));
7767 dispose_words (list
);
7772 temp
= savestring (list
->word
->word
);
7773 tflag
= list
->word
->flags
;
7774 dispose_words (list
);
7776 /* If the string is not a quoted null string, we want
7777 to remove any embedded unquoted CTLNUL characters.
7778 We do not want to turn quoted null strings back into
7779 the empty string, though. We do this because we
7780 want to remove any quoted nulls from expansions that
7781 contain other characters. For example, if we have
7782 x"$*"y or "x$*y" and there are no positional parameters,
7783 the $* should expand into nothing. */
7784 /* We use the W_HASQUOTEDNULL flag to differentiate the
7785 cases: a quoted null character as above and when
7786 CTLNUL is contained in the (non-null) expansion
7787 of some variable. We use the had_quoted_null flag to
7788 pass the value through this function to its caller. */
7789 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
7790 remove_quoted_nulls (temp
); /* XXX */
7794 temp
= (char *)NULL
;
7796 /* We do not want to add quoted nulls to strings that are only
7797 partially quoted; we can throw them away. */
7798 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
7806 temp
= quote_string (temp
);
7814 sindex
--; /* add_character: label increments sindex */
7822 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
7824 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
7829 temp
= string_extract_single_quoted (string
, &sindex
);
7831 /* If the entire STRING was surrounded by single quotes,
7832 then the string is wholly quoted. */
7833 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
7837 /* If all we had was '', it is a null expansion. */
7841 temp
= (char *)NULL
;
7844 remove_quoted_escapes (temp
); /* ??? */
7846 /* We do not want to add quoted nulls to strings that are only
7847 partially quoted; such nulls are discarded. */
7848 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
7851 /* If we have a quoted null expansion, add a quoted NULL to istring. */
7855 sindex
--; /* add_character: label increments sindex */
7859 goto add_quoted_string
;
7864 /* This is the fix for " $@ " */
7866 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
7868 if (string
[sindex
]) /* from old goto dollar_add_string */
7877 #if HANDLE_MULTIBYTE
7883 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
7888 twochars
[0] = CTLESC
;
7895 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
7898 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
7899 DEFAULT_ARRAY_SIZE
);
7900 istring
[istring_index
++] = c
;
7901 istring
[istring_index
] = '\0';
7903 /* Next character. */
7908 finished_with_string
:
7909 /* OK, we're ready to return. If we have a quoted string, and
7910 quoted_dollar_at is not set, we do no splitting at all; otherwise
7911 we split on ' '. The routines that call this will handle what to
7912 do if nothing has been expanded. */
7914 /* Partially and wholly quoted strings which expand to the empty
7915 string are retained as an empty arguments. Unquoted strings
7916 which expand to the empty string are discarded. The single
7917 exception is the case of expanding "$@" when there are no
7918 positional parameters. In that case, we discard the expansion. */
7920 /* Because of how the code that handles "" and '' in partially
7921 quoted strings works, we need to make ISTRING into a QUOTED_NULL
7922 if we saw quoting characters, but the expansion was empty.
7923 "" and '' are tossed away before we get to this point when
7924 processing partially quoted strings. This makes "" and $xxx""
7925 equivalent when xxx is unset. We also look to see whether we
7926 saw a quoted null from a ${} expansion and add one back if we
7929 /* If we expand to nothing and there were no single or double quotes
7930 in the word, we throw it away. Otherwise, we return a NULL word.
7931 The single exception is for $@ surrounded by double quotes when
7932 there are no positional parameters. In that case, we also throw
7935 if (*istring
== '\0')
7937 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
7939 istring
[0] = CTLNUL
;
7941 tword
= make_bare_word (istring
);
7942 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
7943 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7944 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7945 tword
->flags
|= W_QUOTED
;
7947 /* According to sh, ksh, and Posix.2, if a word expands into nothing
7948 and a double-quoted "$@" appears anywhere in it, then the entire
7950 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
7951 list
= (WORD_LIST
*)NULL
;
7955 tword
= make_bare_word (istring
);
7956 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7957 tword
->flags
|= W_QUOTED
;
7958 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7962 list
= (WORD_LIST
*)NULL
;
7965 else if (word
->flags
& W_NOSPLIT
)
7967 tword
= make_bare_word (istring
);
7968 if (word
->flags
& W_ASSIGNMENT
)
7969 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
7970 if (word
->flags
& W_COMPASSIGN
)
7971 tword
->flags
|= W_COMPASSIGN
; /* XXX */
7972 if (word
->flags
& W_NOGLOB
)
7973 tword
->flags
|= W_NOGLOB
; /* XXX */
7974 if (word
->flags
& W_NOEXPAND
)
7975 tword
->flags
|= W_NOEXPAND
; /* XXX */
7976 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7977 tword
->flags
|= W_QUOTED
;
7978 if (had_quoted_null
)
7979 tword
->flags
|= W_HASQUOTEDNULL
;
7980 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
7986 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
7988 /* If we have $@, we need to split the results no matter what. If
7989 IFS is unset or NULL, string_list_dollar_at has separated the
7990 positional parameters with a space, so we split on space (we have
7991 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
7992 string_list_dollar_at has separated the positional parameters
7993 with the first character of $IFS, so we split on $IFS. */
7994 if (has_dollar_at
&& ifs_chars
)
7995 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
7998 tword
= make_bare_word (istring
);
7999 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8000 tword
->flags
|= W_QUOTED
;
8001 if (word
->flags
& W_ASSIGNMENT
)
8002 tword
->flags
|= W_ASSIGNMENT
;
8003 if (word
->flags
& W_COMPASSIGN
)
8004 tword
->flags
|= W_COMPASSIGN
;
8005 if (word
->flags
& W_NOGLOB
)
8006 tword
->flags
|= W_NOGLOB
;
8007 if (word
->flags
& W_NOEXPAND
)
8008 tword
->flags
|= W_NOEXPAND
;
8009 if (had_quoted_null
)
8010 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8011 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8019 /* **************************************************************** */
8021 /* Functions for Quote Removal */
8023 /* **************************************************************** */
8025 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8026 backslash quoting rules for within double quotes or a here document. */
8028 string_quote_removal (string
, quoted
)
8033 char *r
, *result_string
, *temp
, *send
;
8034 int sindex
, tindex
, dquote
;
8038 /* The result can be no longer than the original string. */
8039 slen
= strlen (string
);
8040 send
= string
+ slen
;
8042 r
= result_string
= (char *)xmalloc (slen
+ 1);
8044 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8049 c
= string
[++sindex
];
8055 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8060 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8064 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8070 tindex
= sindex
+ 1;
8071 temp
= string_extract_single_quoted (string
, &tindex
);
8082 dquote
= 1 - dquote
;
8088 return (result_string
);
8093 /* Perform quote removal on word WORD. This allocates and returns a new
8096 word_quote_removal (word
, quoted
)
8103 t
= string_quote_removal (word
->word
, quoted
);
8104 w
= alloc_word_desc ();
8105 w
->word
= t
? t
: savestring ("");
8109 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8110 the members of the list are treated as if they are surrounded by
8111 double quotes. Return a new list, or NULL if LIST is NULL. */
8113 word_list_quote_removal (list
, quoted
)
8117 WORD_LIST
*result
, *t
, *tresult
, *e
;
8119 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8121 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8123 result
= (WORD_LIST
*) list_append (result
, tresult
);
8126 result
= e
= tresult
;
8139 /*******************************************
8141 * Functions to perform word splitting *
8143 *******************************************/
8153 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8155 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8156 handle multibyte chars in IFS */
8157 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8158 for (t
= ifs_value
; t
&& *t
; t
++)
8164 #if defined (HANDLE_MULTIBYTE)
8167 ifs_firstc
[0] = '\0';
8173 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8174 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8175 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8177 ifs_firstc
[0] = ifs_value
[0];
8178 ifs_firstc
[1] = '\0';
8182 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8185 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8195 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8196 is not quoted. list_string () performs quote removal for us, even if we
8197 don't do any splitting. */
8199 word_split (w
, ifs_chars
)
8209 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8210 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8213 result
= (WORD_LIST
*)NULL
;
8218 /* Perform word splitting on LIST and return the RESULT. It is possible
8219 to return (WORD_LIST *)NULL. */
8221 word_list_split (list
)
8224 WORD_LIST
*result
, *t
, *tresult
, *e
;
8226 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8228 tresult
= word_split (t
->word
, ifs_value
);
8230 result
= e
= tresult
;
8241 /**************************************************
8243 * Functions to expand an entire WORD_LIST *
8245 **************************************************/
8247 /* Do any word-expansion-specific cleanup and jump to top_level */
8249 exp_jump_to_top_level (v
)
8252 set_pipestatus_from_exit (last_command_exit_value
);
8254 /* Cleanup code goes here. */
8255 expand_no_split_dollar_star
= 0; /* XXX */
8256 expanding_redir
= 0;
8257 assigning_in_environment
= 0;
8259 if (parse_and_execute_level
== 0)
8260 top_level_cleanup (); /* from sig.c */
8262 jump_to_top_level (v
);
8265 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8266 ELIST, and set ELIST to the new list. */
8267 #define PREPEND_LIST(nlist, elist) \
8268 do { nlist->next = elist; elist = nlist; } while (0)
8270 /* Separate out any initial variable assignments from TLIST. If set -k has
8271 been executed, remove all assignment statements from TLIST. Initial
8272 variable assignments and other environment assignments are placed
8273 on SUBST_ASSIGN_VARLIST. */
8275 separate_out_assignments (tlist
)
8278 register WORD_LIST
*vp
, *lp
;
8281 return ((WORD_LIST
*)NULL
);
8283 if (subst_assign_varlist
)
8284 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8286 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8289 /* Separate out variable assignments at the start of the command.
8290 Loop invariant: vp->next == lp
8292 lp = list of words left after assignment statements skipped
8293 tlist = original list of words
8295 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8301 /* If lp != tlist, we have some initial assignment statements.
8302 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8303 words and TLIST point to the remaining words. */
8306 subst_assign_varlist
= tlist
;
8307 /* ASSERT(vp->next == lp); */
8308 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8309 tlist
= lp
; /* remainder of word list */
8312 /* vp == end of variable list */
8313 /* tlist == remainder of original word list without variable assignments */
8315 /* All the words in tlist were assignment statements */
8316 return ((WORD_LIST
*)NULL
);
8318 /* ASSERT(tlist != NULL); */
8319 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8321 /* If the -k option is in effect, we need to go through the remaining
8322 words, separate out the assignment words, and place them on
8323 SUBST_ASSIGN_VARLIST. */
8324 if (place_keywords_in_env
)
8326 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8331 /* Loop Invariant: tp->next == lp */
8332 /* Loop postcondition: tlist == word list without assignment statements */
8335 if (lp
->word
->flags
& W_ASSIGNMENT
)
8337 /* Found an assignment statement, add this word to end of
8338 subst_assign_varlist (vp). */
8339 if (!subst_assign_varlist
)
8340 subst_assign_varlist
= vp
= lp
;
8347 /* Remove the word pointed to by LP from TLIST. */
8348 tp
->next
= lp
->next
;
8349 /* ASSERT(vp == lp); */
8350 lp
->next
= (WORD_LIST
*)NULL
;
8363 #define WEXP_VARASSIGN 0x001
8364 #define WEXP_BRACEEXP 0x002
8365 #define WEXP_TILDEEXP 0x004
8366 #define WEXP_PARAMEXP 0x008
8367 #define WEXP_PATHEXP 0x010
8369 /* All of the expansions, including variable assignments at the start of
8371 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8373 /* All of the expansions except variable assignments at the start of
8375 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
8377 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
8378 expansion, command substitution, arithmetic expansion, word splitting, and
8380 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
8382 /* Take the list of words in LIST and do the various substitutions. Return
8383 a new list of words which is the expanded list, and without things like
8384 variable assignments. */
8390 return (expand_word_list_internal (list
, WEXP_ALL
));
8393 /* Same as expand_words (), but doesn't hack variable or environment
8396 expand_words_no_vars (list
)
8399 return (expand_word_list_internal (list
, WEXP_NOVARS
));
8403 expand_words_shellexp (list
)
8406 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
8410 glob_expand_word_list (tlist
, eflags
)
8414 char **glob_array
, *temp_string
;
8415 register int glob_index
;
8416 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
8419 output_list
= disposables
= (WORD_LIST
*)NULL
;
8420 glob_array
= (char **)NULL
;
8423 /* For each word, either globbing is attempted or the word is
8424 added to orig_list. If globbing succeeds, the results are
8425 added to orig_list and the word (tlist) is added to the list
8426 of disposable words. If globbing fails and failed glob
8427 expansions are left unchanged (the shell default), the
8428 original word is added to orig_list. If globbing fails and
8429 failed glob expansions are removed, the original word is
8430 added to the list of disposable words. orig_list ends up
8431 in reverse order and requires a call to REVERSE_LIST to
8432 be set right. After all words are examined, the disposable
8436 /* If the word isn't an assignment and contains an unquoted
8437 pattern matching character, then glob it. */
8438 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
8439 unquoted_glob_pattern_p (tlist
->word
->word
))
8441 glob_array
= shell_glob_filename (tlist
->word
->word
);
8443 /* Handle error cases.
8444 I don't think we should report errors like "No such file
8445 or directory". However, I would like to report errors
8446 like "Read failed". */
8448 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
8450 glob_array
= (char **)xmalloc (sizeof (char *));
8451 glob_array
[0] = (char *)NULL
;
8454 /* Dequote the current word in case we have to use it. */
8455 if (glob_array
[0] == NULL
)
8457 temp_string
= dequote_string (tlist
->word
->word
);
8458 free (tlist
->word
->word
);
8459 tlist
->word
->word
= temp_string
;
8462 /* Make the array into a word list. */
8463 glob_list
= (WORD_LIST
*)NULL
;
8464 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
8466 tword
= make_bare_word (glob_array
[glob_index
]);
8467 tword
->flags
|= W_GLOBEXP
; /* XXX */
8468 glob_list
= make_word_list (tword
, glob_list
);
8473 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
8474 PREPEND_LIST (tlist
, disposables
);
8476 else if (fail_glob_expansion
!= 0)
8478 report_error (_("no match: %s"), tlist
->word
->word
);
8479 exp_jump_to_top_level (DISCARD
);
8481 else if (allow_null_glob_expansion
== 0)
8483 /* Failed glob expressions are left unchanged. */
8484 PREPEND_LIST (tlist
, output_list
);
8488 /* Failed glob expressions are removed. */
8489 PREPEND_LIST (tlist
, disposables
);
8494 /* Dequote the string. */
8495 temp_string
= dequote_string (tlist
->word
->word
);
8496 free (tlist
->word
->word
);
8497 tlist
->word
->word
= temp_string
;
8498 PREPEND_LIST (tlist
, output_list
);
8501 strvec_dispose (glob_array
);
8502 glob_array
= (char **)NULL
;
8508 dispose_words (disposables
);
8511 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8513 return (output_list
);
8516 #if defined (BRACE_EXPANSION)
8518 brace_expand_word_list (tlist
, eflags
)
8522 register char **expansions
;
8524 WORD_LIST
*disposables
, *output_list
, *next
;
8528 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
8532 /* Only do brace expansion if the word has a brace character. If
8533 not, just add the word list element to BRACES and continue. In
8534 the common case, at least when running shell scripts, this will
8535 degenerate to a bunch of calls to `xstrchr', and then what is
8536 basically a reversal of TLIST into BRACES, which is corrected
8537 by a call to REVERSE_LIST () on BRACES when the end of TLIST
8539 if (xstrchr (tlist
->word
->word
, LBRACE
))
8541 expansions
= brace_expand (tlist
->word
->word
);
8543 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
8545 w
= make_word (temp_string
);
8546 /* If brace expansion didn't change the word, preserve
8547 the flags. We may want to preserve the flags
8548 unconditionally someday -- XXX */
8549 if (STREQ (temp_string
, tlist
->word
->word
))
8550 w
->flags
= tlist
->word
->flags
;
8551 output_list
= make_word_list (w
, output_list
);
8552 free (expansions
[eindex
]);
8556 /* Add TLIST to the list of words to be freed after brace
8557 expansion has been performed. */
8558 PREPEND_LIST (tlist
, disposables
);
8561 PREPEND_LIST (tlist
, output_list
);
8565 dispose_words (disposables
);
8568 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
8570 return (output_list
);
8574 #if defined (ARRAY_VARS)
8575 /* Take WORD, a compound associative array assignment, and internally run
8576 'declare -A w', where W is the variable name portion of WORD. */
8578 make_internal_declare (word
, option
)
8586 w
= make_word (word
);
8588 t
= assignment (w
->word
, 0);
8591 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
8592 wl
= make_word_list (make_word (option
), wl
);
8594 return (declare_builtin (wl
));
8599 shell_expand_word_list (tlist
, eflags
)
8603 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
8604 int expanded_something
, has_dollar_at
;
8607 /* We do tilde expansion all the time. This is what 1003.2 says. */
8608 new_list
= (WORD_LIST
*)NULL
;
8609 for (orig_list
= tlist
; tlist
; tlist
= next
)
8611 temp_string
= tlist
->word
->word
;
8615 #if defined (ARRAY_VARS)
8616 /* If this is a compound array assignment to a builtin that accepts
8617 such assignments (e.g., `declare'), take the assignment and perform
8618 it separately, handling the semantics of declarations inside shell
8619 functions. This avoids the double-evaluation of such arguments,
8620 because `declare' does some evaluation of compound assignments on
8622 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
8626 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
8627 make_internal_declare (tlist
->word
->word
, "-A");
8629 t
= do_word_assignment (tlist
->word
);
8632 last_command_exit_value
= EXECUTION_FAILURE
;
8633 exp_jump_to_top_level (DISCARD
);
8636 /* Now transform the word as ksh93 appears to do and go on */
8637 t
= assignment (tlist
->word
->word
, 0);
8638 tlist
->word
->word
[t
] = '\0';
8639 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
8643 expanded_something
= 0;
8644 expanded
= expand_word_internal
8645 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
8647 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
8649 /* By convention, each time this error is returned,
8650 tlist->word->word has already been freed. */
8651 tlist
->word
->word
= (char *)NULL
;
8653 /* Dispose our copy of the original list. */
8654 dispose_words (orig_list
);
8655 /* Dispose the new list we're building. */
8656 dispose_words (new_list
);
8658 last_command_exit_value
= EXECUTION_FAILURE
;
8659 if (expanded
== &expand_word_error
)
8660 exp_jump_to_top_level (DISCARD
);
8662 exp_jump_to_top_level (FORCE_EOF
);
8665 /* Don't split words marked W_NOSPLIT. */
8666 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
8668 temp_list
= word_list_split (expanded
);
8669 dispose_words (expanded
);
8673 /* If no parameter expansion, command substitution, process
8674 substitution, or arithmetic substitution took place, then
8675 do not do word splitting. We still have to remove quoted
8676 null characters from the result. */
8677 word_list_remove_quoted_nulls (expanded
);
8678 temp_list
= expanded
;
8681 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
8682 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
8686 dispose_words (orig_list
);
8689 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
8694 /* The workhorse for expand_words () and expand_words_no_vars ().
8695 First arg is LIST, a WORD_LIST of words.
8696 Second arg EFLAGS is a flags word controlling which expansions are
8699 This does all of the substitutions: brace expansion, tilde expansion,
8700 parameter expansion, command substitution, arithmetic expansion,
8701 process substitution, word splitting, and pathname expansion, according
8702 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
8703 set, or for which no expansion is done, do not undergo word splitting.
8704 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
8706 expand_word_list_internal (list
, eflags
)
8710 WORD_LIST
*new_list
, *temp_list
;
8714 return ((WORD_LIST
*)NULL
);
8716 garglist
= new_list
= copy_word_list (list
);
8717 if (eflags
& WEXP_VARASSIGN
)
8719 garglist
= new_list
= separate_out_assignments (new_list
);
8722 if (subst_assign_varlist
)
8724 /* All the words were variable assignments, so they are placed
8725 into the shell's environment. */
8726 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8728 this_command_name
= (char *)NULL
; /* no arithmetic errors */
8729 tint
= do_word_assignment (temp_list
->word
);
8730 /* Variable assignment errors in non-interactive shells
8731 running in Posix.2 mode cause the shell to exit. */
8734 last_command_exit_value
= EXECUTION_FAILURE
;
8735 if (interactive_shell
== 0 && posixly_correct
)
8736 exp_jump_to_top_level (FORCE_EOF
);
8738 exp_jump_to_top_level (DISCARD
);
8741 dispose_words (subst_assign_varlist
);
8742 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8744 return ((WORD_LIST
*)NULL
);
8748 /* Begin expanding the words that remain. The expansions take place on
8749 things that aren't really variable assignments. */
8751 #if defined (BRACE_EXPANSION)
8752 /* Do brace expansion on this word if there are any brace characters
8754 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
8755 new_list
= brace_expand_word_list (new_list
, eflags
);
8756 #endif /* BRACE_EXPANSION */
8758 /* Perform the `normal' shell expansions: tilde expansion, parameter and
8759 variable substitution, command substitution, arithmetic expansion,
8760 and word splitting. */
8761 new_list
= shell_expand_word_list (new_list
, eflags
);
8763 /* Okay, we're almost done. Now let's just do some filename
8767 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
8768 /* Glob expand the word list unless globbing has been disabled. */
8769 new_list
= glob_expand_word_list (new_list
, eflags
);
8771 /* Dequote the words, because we're not performing globbing. */
8772 new_list
= dequote_list (new_list
);
8775 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
8777 sh_wassign_func_t
*assign_func
;
8779 /* If the remainder of the words expand to nothing, Posix.2 requires
8780 that the variable and environment assignments affect the shell's
8782 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
8783 tempenv_assign_error
= 0;
8785 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
8787 this_command_name
= (char *)NULL
;
8788 assigning_in_environment
= (assign_func
== assign_in_env
);
8789 tint
= (*assign_func
) (temp_list
->word
);
8790 assigning_in_environment
= 0;
8791 /* Variable assignment errors in non-interactive shells running
8792 in Posix.2 mode cause the shell to exit. */
8795 if (assign_func
== do_word_assignment
)
8797 last_command_exit_value
= EXECUTION_FAILURE
;
8798 if (interactive_shell
== 0 && posixly_correct
)
8799 exp_jump_to_top_level (FORCE_EOF
);
8801 exp_jump_to_top_level (DISCARD
);
8804 tempenv_assign_error
++;
8808 dispose_words (subst_assign_varlist
);
8809 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8813 tint
= list_length (new_list
) + 1;
8814 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
8815 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
8816 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
8817 glob_argv_flags
[tint
] = '\0';