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-2012 Free Software Foundation, Inc.
9 This file is part of GNU Bash, the Bourne Again SHell.
11 Bash is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 Bash is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with Bash. If not, see <http://www.gnu.org/licenses/>.
27 #include "bashtypes.h"
29 #include "chartypes.h"
30 #if defined (HAVE_PWD_H)
36 #if defined (HAVE_UNISTD_H)
41 #include "posixstat.h"
48 #include "execute_cmd.h"
52 #include "mailcheck.h"
57 #include "builtins/getopt.h"
58 #include "builtins/common.h"
60 #include "builtins/builtext.h"
62 #include <tilde/tilde.h>
63 #include <glob/strmatch.h>
69 /* The size that strings change by. */
70 #define DEFAULT_INITIAL_ARRAY_SIZE 112
71 #define DEFAULT_ARRAY_SIZE 128
77 #define VT_ARRAYMEMBER 3
80 #define VT_STARSUB 128 /* $* or ${array[*]} -- used to split */
82 /* Flags for quoted_strchr */
83 #define ST_BACKSL 0x01
84 #define ST_CTLESC 0x02
85 #define ST_SQUOTE 0x04 /* unused yet */
86 #define ST_DQUOTE 0x08 /* unused yet */
88 /* Flags for the `pflags' argument to param_expand() */
89 #define PF_NOCOMSUB 0x01 /* Do not perform command substitution */
90 #define PF_IGNUNBOUND 0x02 /* ignore unbound vars even if -u set */
91 #define PF_NOSPLIT2 0x04 /* same as W_NOSPLIT2 */
92 #define PF_ASSIGNRHS 0x08 /* same as W_ASSIGNRHS */
94 /* These defs make it easier to use the editor. */
100 #if defined (HANDLE_MULTIBYTE)
105 /* Evaluates to 1 if C is one of the shell's special parameters whose length
106 can be taken, but is also one of the special expansion characters. */
107 #define VALID_SPECIAL_LENGTH_PARAM(c) \
108 ((c) == '-' || (c) == '?' || (c) == '#')
110 /* Evaluates to 1 if C is one of the shell's special parameters for which an
111 indirect variable reference may be made. */
112 #define VALID_INDIR_PARAM(c) \
113 ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')
115 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
116 in ${parameter[:]OPword}. */
117 #define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)
119 /* Evaluates to 1 if this is one of the shell's special variables. */
120 #define SPECIAL_VAR(name, wi) \
121 ((DIGIT (*name) && all_digits (name)) || \
122 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
123 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
125 /* An expansion function that takes a string and a quoted flag and returns
126 a WORD_LIST *. Used as the type of the third argument to
127 expand_string_if_necessary(). */
128 typedef WORD_LIST
*EXPFUNC
__P((char *, int));
130 /* Process ID of the last command executed within command substitution. */
131 pid_t last_command_subst_pid
= NO_PID
;
132 pid_t current_command_subst_pid
= NO_PID
;
134 /* Variables used to keep track of the characters in IFS. */
137 unsigned char ifs_cmap
[UCHAR_MAX
+ 1];
139 #if defined (HANDLE_MULTIBYTE)
140 unsigned char ifs_firstc
[MB_LEN_MAX
];
141 size_t ifs_firstc_len
;
143 unsigned char ifs_firstc
;
146 /* Sentinel to tell when we are performing variable assignments preceding a
147 command name and putting them into the environment. Used to make sure
148 we use the temporary environment when looking up variable values. */
149 int assigning_in_environment
;
151 /* Used to hold a list of variable assignments preceding a command. Global
152 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
153 SIGCHLD trap and so it can be saved and restored by the trap handlers. */
154 WORD_LIST
*subst_assign_varlist
= (WORD_LIST
*)NULL
;
156 /* Extern functions and variables from different files. */
157 extern int last_command_exit_value
, last_command_exit_signal
;
158 extern int subshell_environment
, line_number
;
159 extern int subshell_level
, parse_and_execute_level
, sourcelevel
;
160 extern int eof_encountered
;
161 extern int return_catch_flag
, return_catch_value
;
162 extern pid_t dollar_dollar_pid
;
163 extern int posixly_correct
;
164 extern char *this_command_name
;
165 extern struct fd_bitmap
*current_fds_to_close
;
166 extern int wordexp_only
;
167 extern int expanding_redir
;
168 extern int tempenv_assign_error
;
170 #if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)
171 extern wchar_t *wcsdup
__P((const wchar_t *));
174 /* Non-zero means to allow unmatched globbed filenames to expand to
176 int allow_null_glob_expansion
;
178 /* Non-zero means to throw an error when globbing fails to match anything. */
179 int fail_glob_expansion
;
182 /* Variables to keep track of which words in an expanded word list (the
183 output of expand_word_list_internal) are the result of globbing
184 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
185 (CURRENTLY UNUSED). */
186 char *glob_argv_flags
;
187 static int glob_argv_flags_size
;
190 static WORD_LIST expand_word_error
, expand_word_fatal
;
191 static WORD_DESC expand_wdesc_error
, expand_wdesc_fatal
;
192 static char expand_param_error
, expand_param_fatal
;
193 static char extract_string_error
, extract_string_fatal
;
195 /* Tell the expansion functions to not longjmp back to top_level on fatal
196 errors. Enabled when doing completion and prompt string expansion. */
197 static int no_longjmp_on_fatal_error
= 0;
199 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
200 $* on $IFS, primarily when doing assignment statements. */
201 static int expand_no_split_dollar_star
= 0;
203 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
204 without any leading variable assignments. */
205 static WORD_LIST
*garglist
= (WORD_LIST
*)NULL
;
207 static char *quoted_substring
__P((char *, int, int));
208 static int quoted_strlen
__P((char *));
209 static char *quoted_strchr
__P((char *, int, int));
211 static char *expand_string_if_necessary
__P((char *, int, EXPFUNC
*));
212 static inline char *expand_string_to_string_internal
__P((char *, int, EXPFUNC
*));
213 static WORD_LIST
*call_expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
214 static WORD_LIST
*expand_string_internal
__P((char *, int));
215 static WORD_LIST
*expand_string_leave_quoted
__P((char *, int));
216 static WORD_LIST
*expand_string_for_rhs
__P((char *, int, int *, int *));
218 static WORD_LIST
*list_quote_escapes
__P((WORD_LIST
*));
219 static char *make_quoted_char
__P((int));
220 static WORD_LIST
*quote_list
__P((WORD_LIST
*));
222 static int unquoted_substring
__P((char *, char *));
223 static int unquoted_member
__P((int, char *));
225 #if defined (ARRAY_VARS)
226 static SHELL_VAR
*do_compound_assignment
__P((char *, char *, int));
228 static int do_assignment_internal
__P((const WORD_DESC
*, int));
230 static char *string_extract_verbatim
__P((char *, size_t, int *, char *, int));
231 static char *string_extract
__P((char *, int *, char *, int));
232 static char *string_extract_double_quoted
__P((char *, int *, int));
233 static inline char *string_extract_single_quoted
__P((char *, int *));
234 static inline int skip_single_quoted
__P((const char *, size_t, int));
235 static int skip_double_quoted
__P((char *, size_t, int));
236 static char *extract_delimited_string
__P((char *, int *, char *, char *, char *, int));
237 static char *extract_dollar_brace_string
__P((char *, int *, int, int));
238 static int skip_matched_pair
__P((const char *, int, int, int, int));
240 static char *pos_params
__P((char *, int, int, int));
242 static unsigned char *mb_getcharlens
__P((char *, int));
244 static char *remove_upattern
__P((char *, char *, int));
245 #if defined (HANDLE_MULTIBYTE)
246 static wchar_t *remove_wpattern
__P((wchar_t *, size_t, wchar_t *, int));
248 static char *remove_pattern
__P((char *, char *, int));
250 static int match_upattern
__P((char *, char *, int, char **, char **));
251 #if defined (HANDLE_MULTIBYTE)
252 static int match_wpattern
__P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));
254 static int match_pattern
__P((char *, char *, int, char **, char **));
255 static int getpatspec
__P((int, char *));
256 static char *getpattern
__P((char *, int, int));
257 static char *variable_remove_pattern
__P((char *, char *, int, int));
258 static char *list_remove_pattern
__P((WORD_LIST
*, char *, int, int, int));
259 static char *parameter_list_remove_pattern
__P((int, char *, int, int));
261 static char *array_remove_pattern
__P((SHELL_VAR
*, char *, int, char *, int));
263 static char *parameter_brace_remove_pattern
__P((char *, char *, int, char *, int, int, int));
265 static char *process_substitute
__P((char *, int));
267 static char *read_comsub
__P((int, int, int *));
270 static arrayind_t array_length_reference
__P((char *));
273 static int valid_brace_expansion_word
__P((char *, int));
274 static int chk_atstar
__P((char *, int, int *, int *));
275 static int chk_arithsub
__P((const char *, int));
277 static WORD_DESC
*parameter_brace_expand_word
__P((char *, int, int, int, arrayind_t
*));
278 static WORD_DESC
*parameter_brace_expand_indir
__P((char *, int, int, int *, int *));
279 static WORD_DESC
*parameter_brace_expand_rhs
__P((char *, char *, int, int, int *, int *));
280 static void parameter_brace_expand_error
__P((char *, char *));
282 static int valid_length_expression
__P((char *));
283 static intmax_t parameter_brace_expand_length
__P((char *));
285 static char *skiparith
__P((char *, int));
286 static int verify_substring_values
__P((SHELL_VAR
*, char *, char *, int, intmax_t *, intmax_t *));
287 static int get_var_and_type
__P((char *, char *, arrayind_t
, int, int, SHELL_VAR
**, char **));
288 static char *mb_substring
__P((char *, int, int));
289 static char *parameter_brace_substring
__P((char *, char *, int, char *, int, int));
291 static int shouldexp_replacement
__P((char *));
293 static char *pos_params_pat_subst
__P((char *, char *, char *, int));
295 static char *parameter_brace_patsub
__P((char *, char *, int, char *, int, int));
297 static char *pos_params_casemod
__P((char *, char *, int, int));
298 static char *parameter_brace_casemod
__P((char *, char *, int, int, char *, int, int));
300 static WORD_DESC
*parameter_brace_expand
__P((char *, int *, int, int, int *, int *));
301 static WORD_DESC
*param_expand
__P((char *, int *, int, int *, int *, int *, int *, int));
303 static WORD_LIST
*expand_word_internal
__P((WORD_DESC
*, int, int, int *, int *));
305 static WORD_LIST
*word_list_split
__P((WORD_LIST
*));
307 static void exp_jump_to_top_level
__P((int));
309 static WORD_LIST
*separate_out_assignments
__P((WORD_LIST
*));
310 static WORD_LIST
*glob_expand_word_list
__P((WORD_LIST
*, int));
311 #ifdef BRACE_EXPANSION
312 static WORD_LIST
*brace_expand_word_list
__P((WORD_LIST
*, int));
314 #if defined (ARRAY_VARS)
315 static int make_internal_declare
__P((char *, char *));
317 static WORD_LIST
*shell_expand_word_list
__P((WORD_LIST
*, int));
318 static WORD_LIST
*expand_word_list_internal
__P((WORD_LIST
*, int));
320 /* **************************************************************** */
322 /* Utility Functions */
324 /* **************************************************************** */
328 dump_word_flags (flags
)
334 fprintf (stderr
, "%d -> ", f
);
335 if (f
& W_ASSIGNASSOC
)
338 fprintf (stderr
, "W_ASSIGNASSOC%s", f
? "|" : "");
343 fprintf (stderr
, "W_HASCTLESC%s", f
? "|" : "");
348 fprintf (stderr
, "W_NOPROCSUB%s", f
? "|" : "");
353 fprintf (stderr
, "W_DQUOTE%s", f
? "|" : "");
355 if (f
& W_HASQUOTEDNULL
)
357 f
&= ~W_HASQUOTEDNULL
;
358 fprintf (stderr
, "W_HASQUOTEDNULL%s", f
? "|" : "");
363 fprintf (stderr
, "W_ASSIGNARG%s", f
? "|" : "");
368 fprintf (stderr
, "W_ASSNBLTIN%s", f
? "|" : "");
370 if (f
& W_ASSNGLOBAL
)
373 fprintf (stderr
, "W_ASSNGLOBAL%s", f
? "|" : "");
375 if (f
& W_COMPASSIGN
)
378 fprintf (stderr
, "W_COMPASSIGN%s", f
? "|" : "");
383 fprintf (stderr
, "W_NOEXPAND%s", f
? "|" : "");
388 fprintf (stderr
, "W_ITILDE%s", f
? "|" : "");
393 fprintf (stderr
, "W_NOTILDE%s", f
? "|" : "");
398 fprintf (stderr
, "W_ASSIGNRHS%s", f
? "|" : "");
403 fprintf (stderr
, "W_NOCOMSUB%s", f
? "|" : "");
405 if (f
& W_DOLLARSTAR
)
408 fprintf (stderr
, "W_DOLLARSTAR%s", f
? "|" : "");
413 fprintf (stderr
, "W_DOLLARAT%s", f
? "|" : "");
418 fprintf (stderr
, "W_TILDEEXP%s", f
? "|" : "");
423 fprintf (stderr
, "W_NOSPLIT2%s", f
? "|" : "");
428 fprintf (stderr
, "W_NOSPLIT%s", f
? "|" : "");
433 fprintf (stderr
, "W_NOBRACE%s", f
? "|" : "");
438 fprintf (stderr
, "W_NOGLOB%s", f
? "|" : "");
443 fprintf (stderr
, "W_GLOBEXP%s", f
? "|" : "");
445 if (f
& W_ASSIGNMENT
)
448 fprintf (stderr
, "W_ASSIGNMENT%s", f
? "|" : "");
453 fprintf (stderr
, "W_QUOTED%s", f
? "|" : "");
458 fprintf (stderr
, "W_HASDOLLAR%s", f
? "|" : "");
460 fprintf (stderr
, "\n");
465 #ifdef INCLUDE_UNUSED
467 quoted_substring (string
, start
, end
)
472 register char *result
, *s
, *r
;
476 /* Move to string[start], skipping quoted characters. */
477 for (s
= string
, l
= 0; *s
&& l
< start
; )
489 r
= result
= (char *)xmalloc (2*len
+ 1); /* save room for quotes */
491 /* Copy LEN characters, including quote characters. */
493 for (l
= 0; l
< len
; s
++)
507 #ifdef INCLUDE_UNUSED
508 /* Return the length of S, skipping over quoted characters */
532 /* Find the first occurrence of character C in string S, obeying shell
533 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
534 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
535 escaped with CTLESC are skipped. */
537 quoted_strchr (s
, c
, flags
)
545 if (((flags
& ST_BACKSL
) && *p
== '\\')
546 || ((flags
& ST_CTLESC
) && *p
== CTLESC
))
550 return ((char *)NULL
);
556 return ((char *)NULL
);
559 /* Return 1 if CHARACTER appears in an unquoted portion of
560 STRING. Return 0 otherwise. CHARACTER must be a single-byte character. */
562 unquoted_member (character
, string
)
570 slen
= strlen (string
);
572 while (c
= string
[sindex
])
580 ADVANCE_CHAR (string
, slen
, sindex
);
586 ADVANCE_CHAR (string
, slen
, sindex
);
590 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
594 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
601 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
603 unquoted_substring (substr
, string
)
604 char *substr
, *string
;
607 int sindex
, c
, sublen
;
610 if (substr
== 0 || *substr
== '\0')
613 slen
= strlen (string
);
614 sublen
= strlen (substr
);
615 for (sindex
= 0; c
= string
[sindex
]; )
617 if (STREQN (string
+ sindex
, substr
, sublen
))
625 ADVANCE_CHAR (string
, slen
, sindex
);
629 sindex
= skip_single_quoted (string
, slen
, ++sindex
);
633 sindex
= skip_double_quoted (string
, slen
, ++sindex
);
637 ADVANCE_CHAR (string
, slen
, sindex
);
644 /* Most of the substitutions must be done in parallel. In order
645 to avoid using tons of unclear goto's, I have some functions
646 for manipulating malloc'ed strings. They all take INDX, a
647 pointer to an integer which is the offset into the string
648 where manipulation is taking place. They also take SIZE, a
649 pointer to an integer which is the current length of the
650 character array for this string. */
652 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
653 of space allocated to TARGET. SOURCE can be NULL, in which
654 case nothing happens. Gets rid of SOURCE by freeing it.
655 Returns TARGET in case the location has changed. */
657 sub_append_string (source
, target
, indx
, size
)
658 char *source
, *target
;
665 srclen
= STRLEN (source
);
666 if (srclen
>= (int)(*size
- *indx
))
669 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
670 target
= (char *)xrealloc (target
, (*size
= n
));
673 FASTCOPY (source
, target
+ *indx
, srclen
);
675 target
[*indx
] = '\0';
684 /* Append the textual representation of NUMBER to TARGET.
685 INDX and SIZE are as in SUB_APPEND_STRING. */
687 sub_append_number (number
, target
, indx
, size
)
694 temp
= itos (number
);
695 return (sub_append_string (temp
, target
, indx
, size
));
699 /* Extract a substring from STRING, starting at SINDEX and ending with
700 one of the characters in CHARLIST. Don't make the ending character
701 part of the string. Leave SINDEX pointing at the ending character.
702 Understand about backslashes in the string. If (flags & SX_VARNAME)
703 is non-zero, and array variables have been compiled into the shell,
704 everything between a `[' and a corresponding `]' is skipped over.
705 If (flags & SX_NOALLOC) is non-zero, don't return the substring, just
706 update SINDEX. If (flags & SX_REQMATCH) is non-zero, the string must
707 contain a closing character from CHARLIST. */
709 string_extract (string
, sindex
, charlist
, flags
)
721 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
724 while (c
= string
[i
])
733 #if defined (ARRAY_VARS)
734 else if ((flags
& SX_VARNAME
) && c
== '[')
737 /* If this is an array subscript, skip over it and continue. */
738 ni
= skipsubscript (string
, i
, 0);
739 if (string
[ni
] == ']')
743 else if (MEMBER (c
, charlist
))
749 ADVANCE_CHAR (string
, slen
, i
);
752 /* If we had to have a matching delimiter and didn't find one, return an
753 error and let the caller deal with it. */
754 if ((flags
& SX_REQMATCH
) && found
== 0)
757 return (&extract_string_error
);
760 temp
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
766 /* Extract the contents of STRING as if it is enclosed in double quotes.
767 SINDEX, when passed in, is the offset of the character immediately
768 following the opening double quote; on exit, SINDEX is left pointing after
769 the closing double quote. If STRIPDQ is non-zero, unquoted double
770 quotes are stripped and the string is terminated by a null byte.
771 Backslashes between the embedded double quotes are processed. If STRIPDQ
772 is zero, an unquoted `"' terminates the string. */
774 string_extract_double_quoted (string
, sindex
, stripdq
)
776 int *sindex
, stripdq
;
782 char *temp
, *ret
; /* The new string we return. */
783 int pass_next
, backquote
, si
; /* State variables for the machine. */
787 slen
= strlen (string
+ *sindex
) + *sindex
;
788 send
= string
+ slen
;
790 pass_next
= backquote
= dquote
= 0;
791 temp
= (char *)xmalloc (1 + slen
- *sindex
);
795 while (c
= string
[i
])
797 /* Process a character that was quoted by a backslash. */
800 /* XXX - take another look at this in light of Interp 221 */
803 ``The backslash shall retain its special meaning as an escape
804 character only when followed by one of the characters:
807 If STRIPDQ is zero, we handle the double quotes here and let
808 expand_word_internal handle the rest. If STRIPDQ is non-zero,
809 we have already been through one round of backslash stripping,
810 and want to strip these backslashes only if DQUOTE is non-zero,
811 indicating that we are inside an embedded double-quoted string. */
813 /* If we are in an embedded quoted string, then don't strip
814 backslashes before characters for which the backslash
815 retains its special meaning, but remove backslashes in
816 front of other characters. If we are not in an
817 embedded quoted string, don't strip backslashes at all.
818 This mess is necessary because the string was already
819 surrounded by double quotes (and sh has some really weird
821 The returned string will be run through expansion as if
822 it were double-quoted. */
823 if ((stripdq
== 0 && c
!= '"') ||
824 (stripdq
&& ((dquote
&& (sh_syntaxtab
[c
] & CBSDQUOTE
)) || dquote
== 0)))
829 COPY_CHAR_I (temp
, j
, string
, send
, i
);
833 /* A backslash protects the next character. The code just above
834 handles preserving the backslash in front of any character but
843 /* Inside backquotes, ``the portion of the quoted string from the
844 initial backquote and the characters up to the next backquote
845 that is not preceded by a backslash, having escape characters
846 removed, defines that command''. */
864 /* Pass everything between `$(' and the matching `)' or a quoted
865 ${ ... } pair through according to the Posix.2 specification. */
866 if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
871 if (string
[i
+ 1] == LPAREN
)
872 ret
= extract_command_subst (string
, &si
, 0);
874 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, 0);
877 temp
[j
++] = string
[i
+ 1];
879 /* Just paranoia; ret will not be 0 unless no_longjmp_on_fatal_error
881 if (ret
== 0 && no_longjmp_on_fatal_error
)
884 ret
= string
+ i
+ 2;
887 for (t
= 0; ret
[t
]; t
++, j
++)
889 temp
[j
] = string
[si
];
904 /* Add any character but a double quote to the quoted string we're
907 goto add_one_character
;
921 /* Point to after the closing quote. */
929 /* This should really be another option to string_extract_double_quoted. */
931 skip_double_quoted (string
, slen
, sind
)
938 int pass_next
, backquote
, si
;
941 pass_next
= backquote
= 0;
943 while (c
= string
[i
])
948 ADVANCE_CHAR (string
, slen
, i
);
961 ADVANCE_CHAR (string
, slen
, i
);
970 else if (c
== '$' && ((string
[i
+ 1] == LPAREN
) || (string
[i
+ 1] == LBRACE
)))
973 if (string
[i
+ 1] == LPAREN
)
974 ret
= extract_command_subst (string
, &si
, SX_NOALLOC
);
976 ret
= extract_dollar_brace_string (string
, &si
, Q_DOUBLE_QUOTES
, SX_NOALLOC
);
983 ADVANCE_CHAR (string
, slen
, i
);
996 /* Extract the contents of STRING as if it is enclosed in single quotes.
997 SINDEX, when passed in, is the offset of the character immediately
998 following the opening single quote; on exit, SINDEX is left pointing after
999 the closing single quote. */
1000 static inline char *
1001 string_extract_single_quoted (string
, sindex
)
1010 /* Don't need slen for ADVANCE_CHAR unless multibyte chars possible. */
1011 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 0;
1013 while (string
[i
] && string
[i
] != '\'')
1014 ADVANCE_CHAR (string
, slen
, i
);
1016 t
= substring (string
, *sindex
, i
);
1026 skip_single_quoted (string
, slen
, sind
)
1035 while (string
[c
] && string
[c
] != '\'')
1036 ADVANCE_CHAR (string
, slen
, c
);
1043 /* Just like string_extract, but doesn't hack backslashes or any of
1044 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
1046 string_extract_verbatim (string
, slen
, sindex
, charlist
, flags
)
1054 #if defined (HANDLE_MULTIBYTE)
1062 if (charlist
[0] == '\'' && charlist
[1] == '\0')
1064 temp
= string_extract_single_quoted (string
, sindex
);
1065 --*sindex
; /* leave *sindex at separator character */
1071 /* See how the MBLEN and ADVANCE_CHAR macros work to understand why we need
1072 this only if MB_CUR_MAX > 1. */
1073 slen
= (MB_CUR_MAX
> 1) ? strlen (string
+ *sindex
) + *sindex
: 1;
1075 #if defined (HANDLE_MULTIBYTE)
1076 clen
= strlen (charlist
);
1079 while (c
= string
[i
])
1081 #if defined (HANDLE_MULTIBYTE)
1084 if ((flags
& SX_NOCTLESC
) == 0 && c
== CTLESC
)
1089 /* Even if flags contains SX_NOCTLESC, we let CTLESC quoting CTLNUL
1090 through, to protect the CTLNULs from later calls to
1091 remove_quoted_nulls. */
1092 else if ((flags
& SX_NOESCCTLNUL
) == 0 && c
== CTLESC
&& string
[i
+1] == CTLNUL
)
1098 #if defined (HANDLE_MULTIBYTE)
1099 mblength
= MBLEN (string
+ i
, slen
- i
);
1103 mblength
= mbtowc (&wc
, string
+ i
, slen
- i
);
1104 if (MB_INVALIDCH (mblength
))
1106 if (MEMBER (c
, charlist
))
1114 len
= mbstowcs (wcharlist
, charlist
, 0);
1117 wcharlist
= (wchar_t *)xmalloc (sizeof (wchar_t) * (len
+ 1));
1118 mbstowcs (wcharlist
, charlist
, len
+ 1);
1121 if (wcschr (wcharlist
, wc
))
1127 if (MEMBER (c
, charlist
))
1130 ADVANCE_CHAR (string
, slen
, i
);
1133 #if defined (HANDLE_MULTIBYTE)
1137 temp
= substring (string
, *sindex
, i
);
1143 /* Extract the $( construct in STRING, and return a new string.
1144 Start extracting at (SINDEX) as if we had just seen "$(".
1145 Make (SINDEX) get the position of the matching ")". )
1146 XFLAGS is additional flags to pass to other extraction functions. */
1148 extract_command_subst (string
, sindex
, xflags
)
1153 if (string
[*sindex
] == LPAREN
)
1154 return (extract_delimited_string (string
, sindex
, "$(", "(", ")", xflags
|SX_COMMAND
)); /*)*/
1157 xflags
|= (no_longjmp_on_fatal_error
? SX_NOLONGJMP
: 0);
1158 return (xparse_dolparen (string
, string
+*sindex
, sindex
, xflags
));
1162 /* Extract the $[ construct in STRING, and return a new string. (])
1163 Start extracting at (SINDEX) as if we had just seen "$[".
1164 Make (SINDEX) get the position of the matching "]". */
1166 extract_arithmetic_subst (string
, sindex
)
1170 return (extract_delimited_string (string
, sindex
, "$[", "[", "]", 0)); /*]*/
1173 #if defined (PROCESS_SUBSTITUTION)
1174 /* Extract the <( or >( construct in STRING, and return a new string.
1175 Start extracting at (SINDEX) as if we had just seen "<(".
1176 Make (SINDEX) get the position of the matching ")". */ /*))*/
1178 extract_process_subst (string
, starter
, sindex
)
1183 return (extract_delimited_string (string
, sindex
, starter
, "(", ")", SX_COMMAND
));
1185 #endif /* PROCESS_SUBSTITUTION */
1187 #if defined (ARRAY_VARS)
1188 /* This can be fooled by unquoted right parens in the passed string. If
1189 each caller verifies that the last character in STRING is a right paren,
1190 we don't even need to call extract_delimited_string. */
1192 extract_array_assignment_list (string
, sindex
)
1199 slen
= strlen (string
); /* ( */
1200 if (string
[slen
- 1] == ')')
1202 ret
= substring (string
, *sindex
, slen
- 1);
1210 /* Extract and create a new string from the contents of STRING, a
1211 character string delimited with OPENER and CLOSER. SINDEX is
1212 the address of an int describing the current offset in STRING;
1213 it should point to just after the first OPENER found. On exit,
1214 SINDEX gets the position of the last character of the matching CLOSER.
1215 If OPENER is more than a single character, ALT_OPENER, if non-null,
1216 contains a character string that can also match CLOSER and thus
1217 needs to be skipped. */
1219 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
, flags
)
1222 char *opener
, *alt_opener
, *closer
;
1228 int pass_character
, nesting_level
, in_comment
;
1229 int len_closer
, len_opener
, len_alt_opener
;
1232 slen
= strlen (string
+ *sindex
) + *sindex
;
1233 len_opener
= STRLEN (opener
);
1234 len_alt_opener
= STRLEN (alt_opener
);
1235 len_closer
= STRLEN (closer
);
1237 pass_character
= in_comment
= 0;
1242 while (nesting_level
)
1253 ADVANCE_CHAR (string
, slen
, i
);
1257 if (pass_character
) /* previous char was backslash */
1260 ADVANCE_CHAR (string
, slen
, i
);
1264 /* Not exactly right yet; should handle shell metacharacters and
1265 multibyte characters, too. See COMMENT_BEGIN define in parse.y */
1266 if ((flags
& SX_COMMAND
) && c
== '#' && (i
== 0 || string
[i
- 1] == '\n' || shellblank (string
[i
- 1])))
1269 ADVANCE_CHAR (string
, slen
, i
);
1273 if (c
== CTLESC
|| c
== '\\')
1280 /* Process a nested command substitution, but only if we're parsing an
1281 arithmetic substitution. */
1282 if ((flags
& SX_COMMAND
) && string
[i
] == '$' && string
[i
+1] == LPAREN
)
1285 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1290 /* Process a nested OPENER. */
1291 if (STREQN (string
+ i
, opener
, len_opener
))
1293 si
= i
+ len_opener
;
1294 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1299 /* Process a nested ALT_OPENER */
1300 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
1302 si
= i
+ len_alt_opener
;
1303 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
, flags
|SX_NOALLOC
);
1308 /* If the current substring terminates the delimited string, decrement
1309 the nesting level. */
1310 if (STREQN (string
+ i
, closer
, len_closer
))
1312 i
+= len_closer
- 1; /* move to last byte of the closer */
1314 if (nesting_level
== 0)
1318 /* Pass old-style command substitution through verbatim. */
1322 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1327 /* Pass single-quoted and double-quoted strings through verbatim. */
1328 if (c
== '\'' || c
== '"')
1331 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1332 : skip_double_quoted (string
, slen
, si
);
1336 /* move past this character, which was not special. */
1337 ADVANCE_CHAR (string
, slen
, i
);
1340 if (c
== 0 && nesting_level
)
1342 if (no_longjmp_on_fatal_error
== 0)
1344 last_command_exit_value
= EXECUTION_FAILURE
;
1345 report_error (_("bad substitution: no closing `%s' in %s"), closer
, string
);
1346 exp_jump_to_top_level (DISCARD
);
1351 return (char *)NULL
;
1355 si
= i
- *sindex
- len_closer
+ 1;
1356 if (flags
& SX_NOALLOC
)
1357 result
= (char *)NULL
;
1360 result
= (char *)xmalloc (1 + si
);
1361 strncpy (result
, string
+ *sindex
, si
);
1369 /* Extract a parameter expansion expression within ${ and } from STRING.
1370 Obey the Posix.2 rules for finding the ending `}': count braces while
1371 skipping over enclosed quoted strings and command substitutions.
1372 SINDEX is the address of an int describing the current offset in STRING;
1373 it should point to just after the first `{' found. On exit, SINDEX
1374 gets the position of the matching `}'. QUOTED is non-zero if this
1375 occurs inside double quotes. */
1376 /* XXX -- this is very similar to extract_delimited_string -- XXX */
1378 extract_dollar_brace_string (string
, sindex
, quoted
, flags
)
1380 int *sindex
, quoted
, flags
;
1384 int pass_character
, nesting_level
, si
, dolbrace_state
;
1390 slen
= strlen (string
+ *sindex
) + *sindex
;
1392 /* The handling of dolbrace_state needs to agree with the code in parse.y:
1393 parse_matched_pair(). The different initial value is to handle the
1394 case where this function is called to parse the word in
1395 ${param op word} (SX_WORD). */
1396 dolbrace_state
= (flags
& SX_WORD
) ? DOLBRACE_WORD
: DOLBRACE_PARAM
;
1397 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && (flags
& SX_POSIXEXP
))
1398 dolbrace_state
= DOLBRACE_QUOTE
;
1401 while (c
= string
[i
])
1406 ADVANCE_CHAR (string
, slen
, i
);
1410 /* CTLESCs and backslashes quote the next character. */
1411 if (c
== CTLESC
|| c
== '\\')
1418 if (string
[i
] == '$' && string
[i
+1] == LBRACE
)
1428 if (nesting_level
== 0)
1434 /* Pass the contents of old-style command substitutions through
1439 t
= string_extract (string
, &si
, "`", flags
|SX_NOALLOC
);
1444 /* Pass the contents of new-style command substitutions and
1445 arithmetic substitutions through verbatim. */
1446 if (string
[i
] == '$' && string
[i
+1] == LPAREN
)
1449 t
= extract_command_subst (string
, &si
, flags
|SX_NOALLOC
);
1455 /* Pass the contents of single-quoted and double-quoted strings
1456 through verbatim. */
1457 if (c
== '\'' || c
== '"')
1460 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, si
)
1461 : skip_double_quoted (string
, slen
, si
);
1462 /* skip_XXX_quoted leaves index one past close quote */
1465 #else /* XXX - bash-4.2 */
1466 /* Pass the contents of double-quoted strings through verbatim. */
1470 i
= skip_double_quoted (string
, slen
, si
);
1471 /* skip_XXX_quoted leaves index one past close quote */
1477 /*itrace("extract_dollar_brace_string: c == single quote flags = %d quoted = %d dolbrace_state = %d", flags, quoted, dolbrace_state);*/
1478 if (posixly_correct
&& shell_compatibility_level
> 41 && dolbrace_state
!= DOLBRACE_QUOTE
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
1479 ADVANCE_CHAR (string
, slen
, i
);
1483 i
= skip_single_quoted (string
, slen
, si
);
1490 /* move past this character, which was not special. */
1491 ADVANCE_CHAR (string
, slen
, i
);
1493 /* This logic must agree with parse.y:parse_matched_pair, since they
1494 share the same defines. */
1495 if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '%' && (i
- *sindex
) > 1)
1496 dolbrace_state
= DOLBRACE_QUOTE
;
1497 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '#' && (i
- *sindex
) > 1)
1498 dolbrace_state
= DOLBRACE_QUOTE
;
1499 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '/' && (i
- *sindex
) > 1)
1500 dolbrace_state
= DOLBRACE_QUOTE
;
1501 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== '^' && (i
- *sindex
) > 1)
1502 dolbrace_state
= DOLBRACE_QUOTE
;
1503 else if (dolbrace_state
== DOLBRACE_PARAM
&& c
== ',' && (i
- *sindex
) > 1)
1504 dolbrace_state
= DOLBRACE_QUOTE
;
1505 else if (dolbrace_state
== DOLBRACE_PARAM
&& strchr ("#%^,~:-=?+/", c
) != 0)
1506 dolbrace_state
= DOLBRACE_OP
;
1507 else if (dolbrace_state
== DOLBRACE_OP
&& strchr ("#%^,~:-=?+/", c
) == 0)
1508 dolbrace_state
= DOLBRACE_WORD
;
1511 if (c
== 0 && nesting_level
)
1513 if (no_longjmp_on_fatal_error
== 0)
1515 last_command_exit_value
= EXECUTION_FAILURE
;
1516 report_error (_("bad substitution: no closing `%s' in %s"), "}", string
);
1517 exp_jump_to_top_level (DISCARD
);
1522 return ((char *)NULL
);
1526 result
= (flags
& SX_NOALLOC
) ? (char *)NULL
: substring (string
, *sindex
, i
);
1532 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1533 STRING, and returns a pointer to it. */
1535 de_backslash (string
)
1538 register size_t slen
;
1539 register int i
, j
, prev_i
;
1542 slen
= strlen (string
);
1545 /* Loop copying string[i] to string[j], i >= j. */
1548 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
1549 string
[i
+ 1] == '$'))
1552 ADVANCE_CHAR (string
, slen
, i
);
1554 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
1565 /* Replace instances of \! in a string with !. */
1567 unquote_bang (string
)
1571 register char *temp
;
1573 temp
= (char *)xmalloc (1 + strlen (string
));
1575 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
1577 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
1583 strcpy (string
, temp
);
1588 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1590 /* This function assumes s[i] == open; returns with s[ret] == close; used to
1591 parse array subscripts. FLAGS & 1 means to not attempt to skip over
1592 matched pairs of quotes or backquotes, or skip word expansions; it is
1593 intended to be used after expansion has been performed and during final
1594 assignment parsing (see arrayfunc.c:assign_compound_array_list()). */
1596 skip_matched_pair (string
, start
, open
, close
, flags
)
1598 int start
, open
, close
, flags
;
1600 int i
, pass_next
, backq
, si
, c
, count
;
1605 slen
= strlen (string
+ start
) + start
;
1606 no_longjmp_on_fatal_error
= 1;
1608 i
= start
+ 1; /* skip over leading bracket */
1610 pass_next
= backq
= 0;
1611 ss
= (char *)string
;
1612 while (c
= string
[i
])
1619 ADVANCE_CHAR (string
, slen
, i
);
1632 ADVANCE_CHAR (string
, slen
, i
);
1635 else if ((flags
& 1) == 0 && c
== '`')
1641 else if ((flags
& 1) == 0 && c
== open
)
1647 else if (c
== close
)
1655 else if ((flags
& 1) == 0 && (c
== '\'' || c
== '"'))
1657 i
= (c
== '\'') ? skip_single_quoted (ss
, slen
, ++i
)
1658 : skip_double_quoted (ss
, slen
, ++i
);
1659 /* no increment, the skip functions increment past the closing quote. */
1661 else if ((flags
&1) == 0 && c
== '$' && (string
[i
+1] == LPAREN
|| string
[i
+1] == LBRACE
))
1664 if (string
[si
] == '\0')
1667 if (string
[i
+1] == LPAREN
)
1668 temp
= extract_delimited_string (ss
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1670 temp
= extract_dollar_brace_string (ss
, &si
, 0, SX_NOALLOC
);
1672 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1678 ADVANCE_CHAR (string
, slen
, i
);
1684 #if defined (ARRAY_VARS)
1686 skipsubscript (string
, start
, flags
)
1690 return (skip_matched_pair (string
, start
, '[', ']', flags
));
1694 /* Skip characters in STRING until we find a character in DELIMS, and return
1695 the index of that character. START is the index into string at which we
1696 begin. This is similar in spirit to strpbrk, but it returns an index into
1697 STRING and takes a starting index. This little piece of code knows quite
1698 a lot of shell syntax. It's very similar to skip_double_quoted and other
1699 functions of that ilk. */
1701 skip_to_delim (string
, start
, delims
, flags
)
1707 int i
, pass_next
, backq
, si
, c
, invert
, skipquote
, skipcmd
;
1709 char *temp
, open
[3];
1712 slen
= strlen (string
+ start
) + start
;
1713 if (flags
& SD_NOJMP
)
1714 no_longjmp_on_fatal_error
= 1;
1715 invert
= (flags
& SD_INVERT
);
1716 skipcmd
= (flags
& SD_NOSKIPCMD
) == 0;
1719 pass_next
= backq
= 0;
1720 while (c
= string
[i
])
1722 /* If this is non-zero, we should not let quote characters be delimiters
1723 and the current character is a single or double quote. We should not
1724 test whether or not it's a delimiter until after we skip single- or
1725 double-quoted strings. */
1726 skipquote
= ((flags
& SD_NOQUOTEDELIM
) && (c
== '\'' || c
=='"'));
1732 ADVANCE_CHAR (string
, slen
, i
);
1745 ADVANCE_CHAR (string
, slen
, i
);
1754 else if (skipquote
== 0 && invert
== 0 && member (c
, delims
))
1756 else if (c
== '\'' || c
== '"')
1758 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1759 : skip_double_quoted (string
, slen
, ++i
);
1760 /* no increment, the skip functions increment past the closing quote. */
1762 else if (c
== '$' && ((skipcmd
&& string
[i
+1] == LPAREN
) || string
[i
+1] == LBRACE
))
1765 if (string
[si
] == '\0')
1768 if (string
[i
+1] == LPAREN
)
1769 temp
= extract_delimited_string (string
, &si
, "$(", "(", ")", SX_NOALLOC
|SX_COMMAND
); /* ) */
1771 temp
= extract_dollar_brace_string (string
, &si
, 0, SX_NOALLOC
);
1773 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1778 #if defined (PROCESS_SUBSTITUTION)
1779 else if (skipcmd
&& (c
== '<' || c
== '>') && string
[i
+1] == LPAREN
)
1782 if (string
[si
] == '\0')
1784 temp
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &si
);
1785 free (temp
); /* no SX_ALLOC here */
1787 if (string
[i
] == '\0')
1792 #endif /* PROCESS_SUBSTITUTION */
1793 #if defined (EXTENDED_GLOB)
1794 else if ((flags
& SD_EXTGLOB
) && extended_glob
&& string
[i
+1] == LPAREN
&& member (c
, "?*+!@"))
1797 if (string
[si
] == '\0')
1803 temp
= extract_delimited_string (string
, &si
, open
, "(", ")", SX_NOALLOC
); /* ) */
1806 if (string
[i
] == '\0') /* don't increment i past EOS in loop */
1812 else if ((skipquote
|| invert
) && (member (c
, delims
) == 0))
1815 ADVANCE_CHAR (string
, slen
, i
);
1821 #if defined (READLINE)
1822 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1823 an unclosed quoted string), or if the character at EINDEX is quoted
1824 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1825 single and double-quoted string parsing functions should not return an
1826 error if there are unclosed quotes or braces. The characters that this
1827 recognizes need to be the same as the contents of
1828 rl_completer_quote_characters. */
1831 char_is_quoted (string
, eindex
)
1835 int i
, pass_next
, c
;
1839 slen
= strlen (string
);
1840 no_longjmp_on_fatal_error
= 1;
1849 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1851 ADVANCE_CHAR (string
, slen
, i
);
1860 else if (c
== '\'' || c
== '"')
1862 i
= (c
== '\'') ? skip_single_quoted (string
, slen
, ++i
)
1863 : skip_double_quoted (string
, slen
, ++i
);
1866 /* no increment, the skip_xxx functions go one past end */
1869 ADVANCE_CHAR (string
, slen
, i
);
1876 unclosed_pair (string
, eindex
, openstr
)
1881 int i
, pass_next
, openc
, olen
;
1885 slen
= strlen (string
);
1886 olen
= strlen (openstr
);
1887 i
= pass_next
= openc
= 0;
1893 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1895 ADVANCE_CHAR (string
, slen
, i
);
1898 else if (string
[i
] == '\\')
1904 else if (STREQN (string
+ i
, openstr
, olen
))
1909 else if (string
[i
] == '\'' || string
[i
] == '"')
1911 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, slen
, i
)
1912 : skip_double_quoted (string
, slen
, i
);
1917 ADVANCE_CHAR (string
, slen
, i
);
1922 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1923 individual words. If DELIMS is NULL, the current value of $IFS is used
1924 to split the string, and the function follows the shell field splitting
1925 rules. SENTINEL is an index to look for. NWP, if non-NULL,
1926 gets the number of words in the returned list. CWP, if non-NULL, gets
1927 the index of the word containing SENTINEL. Non-whitespace chars in
1928 DELIMS delimit separate fields. */
1930 split_at_delims (string
, slen
, delims
, sentinel
, flags
, nwp
, cwp
)
1934 int sentinel
, flags
;
1937 int ts
, te
, i
, nw
, cw
, ifs_split
, dflags
;
1938 char *token
, *d
, *d2
;
1939 WORD_LIST
*ret
, *tl
;
1941 if (string
== 0 || *string
== '\0')
1947 return ((WORD_LIST
*)NULL
);
1950 d
= (delims
== 0) ? ifs_value
: delims
;
1951 ifs_split
= delims
== 0;
1953 /* Make d2 the non-whitespace characters in delims */
1958 #if defined (HANDLE_MULTIBYTE)
1959 size_t mblength
= 1;
1963 slength
= strlen (delims
);
1964 d2
= (char *)xmalloc (slength
+ 1);
1968 #if defined (HANDLE_MULTIBYTE)
1969 mbstate_t state_bak
;
1971 mblength
= MBRLEN (delims
+ i
, slength
, &state
);
1972 if (MB_INVALIDCH (mblength
))
1974 else if (mblength
> 1)
1976 memcpy (d2
+ ts
, delims
+ i
, mblength
);
1979 slength
-= mblength
;
1983 if (whitespace (delims
[i
]) == 0)
1984 d2
[ts
++] = delims
[i
];
1992 ret
= (WORD_LIST
*)NULL
;
1994 /* Remove sequences of whitespace characters at the start of the string, as
1995 long as those characters are delimiters. */
1996 for (i
= 0; member (string
[i
], d
) && spctabnl (string
[i
]); i
++)
1998 if (string
[i
] == '\0')
2004 dflags
= flags
|SD_NOJMP
;
2007 te
= skip_to_delim (string
, ts
, d
, dflags
);
2009 /* If we have a non-whitespace delimiter character, use it to make a
2010 separate field. This is just about what $IFS splitting does and
2011 is closer to the behavior of the shell parser. */
2012 if (ts
== te
&& d2
&& member (string
[ts
], d2
))
2015 /* If we're using IFS splitting, the non-whitespace delimiter char
2016 and any additional IFS whitespace delimits a field. */
2018 while (member (string
[te
], d
) && spctabnl (string
[te
]))
2021 while (member (string
[te
], d2
))
2025 token
= substring (string
, ts
, te
);
2027 ret
= add_string_to_list (token
, ret
);
2031 if (sentinel
>= ts
&& sentinel
<= te
)
2034 /* If the cursor is at whitespace just before word start, set the
2035 sentinel word to the current word. */
2036 if (cwp
&& cw
== -1 && sentinel
== ts
-1)
2039 /* If the cursor is at whitespace between two words, make a new, empty
2040 word, add it before (well, after, since the list is in reverse order)
2041 the word we just added, and set the current word to that one. */
2042 if (cwp
&& cw
== -1 && sentinel
< ts
)
2044 tl
= make_word_list (make_word (""), ret
->next
);
2050 if (string
[te
] == 0)
2054 while (member (string
[i
], d
) && (ifs_split
|| spctabnl(string
[i
])))
2063 /* Special case for SENTINEL at the end of STRING. If we haven't found
2064 the word containing SENTINEL yet, and the index we're looking for is at
2065 the end of STRING (or past the end of the previously-found token,
2066 possible if the end of the line is composed solely of IFS whitespace)
2067 add an additional null argument and set the current word pointer to that. */
2068 if (cwp
&& cw
== -1 && (sentinel
>= slen
|| sentinel
>= te
))
2070 if (whitespace (string
[sentinel
- 1]))
2073 ret
= add_string_to_list (token
, ret
);
2086 return (REVERSE_LIST (ret
, WORD_LIST
*));
2088 #endif /* READLINE */
2092 /* Extract the name of the variable to bind to from the assignment string. */
2094 assignment_name (string
)
2100 offset
= assignment (string
, 0);
2102 return (char *)NULL
;
2103 temp
= substring (string
, 0, offset
);
2108 /* **************************************************************** */
2110 /* Functions to convert strings to WORD_LISTs and vice versa */
2112 /* **************************************************************** */
2114 /* Return a single string of all the words in LIST. SEP is the separator
2115 to put between individual elements of LIST in the output string. */
2117 string_list_internal (list
, sep
)
2121 register WORD_LIST
*t
;
2123 int word_len
, sep_len
, result_size
;
2126 return ((char *)NULL
);
2128 /* Short-circuit quickly if we don't need to separate anything. */
2129 if (list
->next
== 0)
2130 return (savestring (list
->word
->word
));
2132 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
2133 sep_len
= STRLEN (sep
);
2136 for (t
= list
; t
; t
= t
->next
)
2139 result_size
+= sep_len
;
2140 result_size
+= strlen (t
->word
->word
);
2143 r
= result
= (char *)xmalloc (result_size
+ 1);
2145 for (t
= list
; t
; t
= t
->next
)
2147 if (t
!= list
&& sep_len
)
2151 FASTCOPY (sep
, r
, sep_len
);
2158 word_len
= strlen (t
->word
->word
);
2159 FASTCOPY (t
->word
->word
, r
, word_len
);
2167 /* Return a single string of all the words present in LIST, separating
2168 each word with a space. */
2173 return (string_list_internal (list
, " "));
2176 /* An external interface that can be used by the rest of the shell to
2177 obtain a string containing the first character in $IFS. Handles all
2178 the multibyte complications. If LENP is non-null, it is set to the
2179 length of the returned string. */
2181 ifs_firstchar (lenp
)
2187 ret
= xmalloc (MB_LEN_MAX
+ 1);
2188 #if defined (HANDLE_MULTIBYTE)
2189 if (ifs_firstc_len
== 1)
2191 ret
[0] = ifs_firstc
[0];
2193 len
= ret
[0] ? 1 : 0;
2197 memcpy (ret
, ifs_firstc
, ifs_firstc_len
);
2198 ret
[len
= ifs_firstc_len
] = '\0';
2201 ret
[0] = ifs_firstc
;
2203 len
= ret
[0] ? 0 : 1;
2212 /* Return a single string of all the words present in LIST, obeying the
2213 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
2214 expansion [of $*] appears within a double quoted string, it expands
2215 to a single field with the value of each parameter separated by the
2216 first character of the IFS variable, or by a <space> if IFS is unset." */
2218 string_list_dollar_star (list
)
2222 #if defined (HANDLE_MULTIBYTE)
2223 # if defined (__GNUC__)
2224 char sep
[MB_CUR_MAX
+ 1];
2232 #if defined (HANDLE_MULTIBYTE)
2233 # if !defined (__GNUC__)
2234 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2235 # endif /* !__GNUC__ */
2236 if (ifs_firstc_len
== 1)
2238 sep
[0] = ifs_firstc
[0];
2243 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2244 sep
[ifs_firstc_len
] = '\0';
2247 sep
[0] = ifs_firstc
;
2251 ret
= string_list_internal (list
, sep
);
2252 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2258 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
2259 is non-zero, the $@ appears within double quotes, and we should quote
2260 the list before converting it into a string. If IFS is unset, and the
2261 word is not quoted, we just need to quote CTLESC and CTLNUL characters
2262 in the words in the list, because the default value of $IFS is
2263 <space><tab><newline>, IFS characters in the words in the list should
2264 also be split. If IFS is null, and the word is not quoted, we need
2265 to quote the words in the list to preserve the positional parameters
2268 string_list_dollar_at (list
, quoted
)
2273 #if defined (HANDLE_MULTIBYTE)
2274 # if defined (__GNUC__)
2275 char sep
[MB_CUR_MAX
+ 1];
2278 # endif /* !__GNUC__ */
2284 /* XXX this could just be ifs = ifs_value; */
2285 ifs
= ifs_var
? value_cell (ifs_var
) : (char *)0;
2287 #if defined (HANDLE_MULTIBYTE)
2288 # if !defined (__GNUC__)
2289 sep
= (char *)xmalloc (MB_CUR_MAX
+ 1);
2290 # endif /* !__GNUC__ */
2293 if (ifs_firstc_len
== 1)
2295 sep
[0] = ifs_firstc
[0];
2300 memcpy (sep
, ifs_firstc
, ifs_firstc_len
);
2301 sep
[ifs_firstc_len
] = '\0';
2310 sep
[0] = (ifs
== 0 || *ifs
== 0) ? ' ' : *ifs
;
2314 /* XXX -- why call quote_list if ifs == 0? we can get away without doing
2315 it now that quote_escapes quotes spaces */
2316 tlist
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
2318 : list_quote_escapes (list
);
2320 ret
= string_list_internal (tlist
, sep
);
2321 #if defined (HANDLE_MULTIBYTE) && !defined (__GNUC__)
2327 /* Turn the positional paramters into a string, understanding quoting and
2328 the various subtleties of using the first character of $IFS as the
2329 separator. Calls string_list_dollar_at, string_list_dollar_star, and
2330 string_list as appropriate. */
2332 string_list_pos_params (pchar
, list
, quoted
)
2340 if (pchar
== '*' && (quoted
& Q_DOUBLE_QUOTES
))
2342 tlist
= quote_list (list
);
2343 word_list_remove_quoted_nulls (tlist
);
2344 ret
= string_list_dollar_star (tlist
);
2346 else if (pchar
== '*' && (quoted
& Q_HERE_DOCUMENT
))
2348 tlist
= quote_list (list
);
2349 word_list_remove_quoted_nulls (tlist
);
2350 ret
= string_list (tlist
);
2352 else if (pchar
== '*')
2354 /* Even when unquoted, string_list_dollar_star does the right thing
2355 making sure that the first character of $IFS is used as the
2357 ret
= string_list_dollar_star (list
);
2359 else if (pchar
== '@' && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
2360 /* We use string_list_dollar_at, but only if the string is quoted, since
2361 that quotes the escapes if it's not, which we don't want. We could
2362 use string_list (the old code did), but that doesn't do the right
2363 thing if the first character of $IFS is not a space. We use
2364 string_list_dollar_star if the string is unquoted so we make sure that
2365 the elements of $@ are separated by the first character of $IFS for
2367 ret
= string_list_dollar_at (list
, quoted
);
2368 else if (pchar
== '@')
2369 ret
= string_list_dollar_star (list
);
2371 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (list
) : list
);
2376 /* Return the list of words present in STRING. Separate the string into
2377 words at any of the characters found in SEPARATORS. If QUOTED is
2378 non-zero then word in the list will have its quoted flag set, otherwise
2379 the quoted flag is left as make_word () deemed fit.
2381 This obeys the P1003.2 word splitting semantics. If `separators' is
2382 exactly <space><tab><newline>, then the splitting algorithm is that of
2383 the Bourne shell, which treats any sequence of characters from `separators'
2384 as a delimiter. If IFS is unset, which results in `separators' being set
2385 to "", no splitting occurs. If separators has some other value, the
2386 following rules are applied (`IFS white space' means zero or more
2387 occurrences of <space>, <tab>, or <newline>, as long as those characters
2388 are in `separators'):
2390 1) IFS white space is ignored at the start and the end of the
2392 2) Each occurrence of a character in `separators' that is not
2393 IFS white space, along with any adjacent occurrences of
2394 IFS white space delimits a field.
2395 3) Any nonzero-length sequence of IFS white space delimits a field.
2398 /* BEWARE! list_string strips null arguments. Don't call it twice and
2399 expect to have "" preserved! */
2401 /* This performs word splitting and quoted null character removal on
2404 (((separators)[0]) ? ((separators)[1] ? isifs(c) \
2405 : (c) == (separators)[0]) \
2409 list_string (string
, separators
, quoted
)
2410 register char *string
, *separators
;
2415 char *current_word
, *s
;
2416 int sindex
, sh_style_split
, whitesep
, xflags
;
2419 if (!string
|| !*string
)
2420 return ((WORD_LIST
*)NULL
);
2422 sh_style_split
= separators
&& separators
[0] == ' ' &&
2423 separators
[1] == '\t' &&
2424 separators
[2] == '\n' &&
2425 separators
[3] == '\0';
2426 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2428 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2429 else if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2433 /* Remove sequences of whitespace at the beginning of STRING, as
2434 long as those characters appear in IFS. Do not do this if
2435 STRING is quoted or if there are no separator characters. */
2436 if (!quoted
|| !separators
|| !*separators
)
2438 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
2441 return ((WORD_LIST
*)NULL
);
2446 /* OK, now STRING points to a word that does not begin with white space.
2447 The splitting algorithm is:
2448 extract a word, stopping at a separator
2449 skip sequences of spc, tab, or nl as long as they are separators
2450 This obeys the field splitting rules in Posix.2. */
2451 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
2452 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
2454 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2455 unless multibyte chars are possible. */
2456 current_word
= string_extract_verbatim (string
, slen
, &sindex
, separators
, xflags
);
2457 if (current_word
== 0)
2460 /* If we have a quoted empty string, add a quoted null argument. We
2461 want to preserve the quoted null character iff this is a quoted
2462 empty string; otherwise the quoted null characters are removed
2464 if (QUOTED_NULL (current_word
))
2466 t
= alloc_word_desc ();
2467 t
->word
= make_quoted_char ('\0');
2468 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2469 result
= make_word_list (t
, result
);
2471 else if (current_word
[0] != '\0')
2473 /* If we have something, then add it regardless. However,
2474 perform quoted null character removal on the current word. */
2475 remove_quoted_nulls (current_word
);
2476 result
= add_string_to_list (current_word
, result
);
2477 result
->word
->flags
&= ~W_HASQUOTEDNULL
; /* just to be sure */
2478 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
2479 result
->word
->flags
|= W_QUOTED
;
2482 /* If we're not doing sequences of separators in the traditional
2483 Bourne shell style, then add a quoted null argument. */
2484 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
2486 t
= alloc_word_desc ();
2487 t
->word
= make_quoted_char ('\0');
2488 t
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
2489 result
= make_word_list (t
, result
);
2492 free (current_word
);
2494 /* Note whether or not the separator is IFS whitespace, used later. */
2495 whitesep
= string
[sindex
] && spctabnl (string
[sindex
]);
2497 /* Move past the current separator character. */
2501 ADVANCE_CHAR (string
, slen
, sindex
);
2504 /* Now skip sequences of space, tab, or newline characters if they are
2505 in the list of separators. */
2506 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
2509 /* If the first separator was IFS whitespace and the current character
2510 is a non-whitespace IFS character, it should be part of the current
2511 field delimiter, not a separate delimiter that would result in an
2512 empty field. Look at POSIX.2, 3.6.5, (3)(b). */
2513 if (string
[sindex
] && whitesep
&& issep (string
[sindex
]) && !spctabnl (string
[sindex
]))
2516 /* An IFS character that is not IFS white space, along with any
2517 adjacent IFS white space, shall delimit a field. (SUSv3) */
2518 while (string
[sindex
] && spctabnl (string
[sindex
]) && isifs (string
[sindex
]))
2522 return (REVERSE_LIST (result
, WORD_LIST
*));
2525 /* Parse a single word from STRING, using SEPARATORS to separate fields.
2526 ENDPTR is set to the first character after the word. This is used by
2527 the `read' builtin. This is never called with SEPARATORS != $IFS;
2528 it should be simplified.
2530 XXX - this function is very similar to list_string; they should be
2533 get_word_from_string (stringp
, separators
, endptr
)
2534 char **stringp
, *separators
, **endptr
;
2538 int sindex
, sh_style_split
, whitesep
, xflags
;
2541 if (!stringp
|| !*stringp
|| !**stringp
)
2542 return ((char *)NULL
);
2544 sh_style_split
= separators
&& separators
[0] == ' ' &&
2545 separators
[1] == '\t' &&
2546 separators
[2] == '\n' &&
2547 separators
[3] == '\0';
2548 for (xflags
= 0, s
= ifs_value
; s
&& *s
; s
++)
2550 if (*s
== CTLESC
) xflags
|= SX_NOCTLESC
;
2551 if (*s
== CTLNUL
) xflags
|= SX_NOESCCTLNUL
;
2557 /* Remove sequences of whitespace at the beginning of STRING, as
2558 long as those characters appear in IFS. */
2559 if (sh_style_split
|| !separators
|| !*separators
)
2561 for (; *s
&& spctabnl (*s
) && isifs (*s
); s
++);
2563 /* If the string is nothing but whitespace, update it and return. */
2569 return ((char *)NULL
);
2573 /* OK, S points to a word that does not begin with white space.
2574 Now extract a word, stopping at a separator, save a pointer to
2575 the first character after the word, then skip sequences of spc,
2576 tab, or nl as long as they are separators.
2578 This obeys the field splitting rules in Posix.2. */
2580 /* Don't need string length in ADVANCE_CHAR or string_extract_verbatim
2581 unless multibyte chars are possible. */
2582 slen
= (MB_CUR_MAX
> 1) ? strlen (s
) : 1;
2583 current_word
= string_extract_verbatim (s
, slen
, &sindex
, separators
, xflags
);
2585 /* Set ENDPTR to the first character after the end of the word. */
2587 *endptr
= s
+ sindex
;
2589 /* Note whether or not the separator is IFS whitespace, used later. */
2590 whitesep
= s
[sindex
] && spctabnl (s
[sindex
]);
2592 /* Move past the current separator character. */
2596 ADVANCE_CHAR (s
, slen
, sindex
);
2599 /* Now skip sequences of space, tab, or newline characters if they are
2600 in the list of separators. */
2601 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2604 /* If the first separator was IFS whitespace and the current character is
2605 a non-whitespace IFS character, it should be part of the current field
2606 delimiter, not a separate delimiter that would result in an empty field.
2607 Look at POSIX.2, 3.6.5, (3)(b). */
2608 if (s
[sindex
] && whitesep
&& isifs (s
[sindex
]) && !spctabnl (s
[sindex
]))
2611 /* An IFS character that is not IFS white space, along with any adjacent
2612 IFS white space, shall delimit a field. */
2613 while (s
[sindex
] && spctabnl (s
[sindex
]) && isifs (s
[sindex
]))
2617 /* Update STRING to point to the next field. */
2618 *stringp
= s
+ sindex
;
2619 return (current_word
);
2622 /* Remove IFS white space at the end of STRING. Start at the end
2623 of the string and walk backwards until the beginning of the string
2624 or we find a character that's not IFS white space and not CTLESC.
2625 Only let CTLESC escape a white space character if SAW_ESCAPE is
2628 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
2629 char *string
, *separators
;
2634 s
= string
+ STRLEN (string
) - 1;
2635 while (s
> string
&& ((spctabnl (*s
) && isifs (*s
)) ||
2636 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
2644 /* Split STRING into words at whitespace. Obeys shell-style quoting with
2645 backslashes, single and double quotes. */
2647 list_string_with_quotes (string
)
2653 int c
, i
, tokstart
, len
;
2655 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
2657 if (s
== 0 || *s
== 0)
2658 return ((WORD_LIST
*)NULL
);
2662 list
= (WORD_LIST
*)NULL
;
2673 i
= skip_single_quoted (s
, s_len
, ++i
);
2675 i
= skip_double_quoted (s
, s_len
, ++i
);
2676 else if (c
== 0 || spctabnl (c
))
2678 /* We have found the end of a token. Make a word out of it and
2679 add it to the word list. */
2680 token
= substring (s
, tokstart
, i
);
2681 list
= add_string_to_list (token
, list
);
2683 while (spctabnl (s
[i
]))
2691 i
++; /* normal character */
2693 return (REVERSE_LIST (list
, WORD_LIST
*));
2697 /********************************************************/
2699 /* Functions to perform assignment statements */
2701 /********************************************************/
2703 #if defined (ARRAY_VARS)
2705 do_compound_assignment (name
, value
, flags
)
2710 int mklocal
, mkassoc
;
2713 mklocal
= flags
& ASS_MKLOCAL
;
2714 mkassoc
= flags
& ASS_MKASSOC
;
2716 if (mklocal
&& variable_context
)
2718 v
= find_variable (name
);
2719 list
= expand_compound_array_assignment (v
, value
, flags
);
2721 v
= make_local_assoc_variable (name
);
2722 else if (v
== 0 || (array_p (v
) == 0 && assoc_p (v
) == 0) || v
->context
!= variable_context
)
2723 v
= make_local_array_variable (name
, 0);
2724 assign_compound_array_list (v
, list
, flags
);
2727 v
= assign_array_from_string (name
, value
, flags
);
2733 /* Given STRING, an assignment string, get the value of the right side
2734 of the `=', and bind it to the left side. If EXPAND is true, then
2735 perform parameter expansion, command substitution, and arithmetic
2736 expansion on the right-hand side. Perform tilde expansion in any
2737 case. Do not perform word splitting on the result of expansion. */
2739 do_assignment_internal (word
, expand
)
2740 const WORD_DESC
*word
;
2743 int offset
, appendop
, assign_list
, aflags
, retval
;
2744 char *name
, *value
, *temp
;
2746 #if defined (ARRAY_VARS)
2752 if (word
== 0 || word
->word
== 0)
2755 appendop
= assign_list
= aflags
= 0;
2756 string
= word
->word
;
2757 offset
= assignment (string
, 0);
2758 name
= savestring (string
);
2759 value
= (char *)NULL
;
2761 if (name
[offset
] == '=')
2763 if (name
[offset
- 1] == '+')
2766 name
[offset
- 1] = '\0';
2769 name
[offset
] = 0; /* might need this set later */
2770 temp
= name
+ offset
+ 1;
2772 #if defined (ARRAY_VARS)
2773 if (expand
&& (word
->flags
& W_COMPASSIGN
))
2775 assign_list
= ni
= 1;
2776 value
= extract_array_assignment_list (temp
, &ni
);
2780 if (expand
&& temp
[0])
2781 value
= expand_string_if_necessary (temp
, 0, expand_string_assignment
);
2783 value
= savestring (temp
);
2788 value
= (char *)xmalloc (1);
2792 if (echo_command_at_execute
)
2795 name
[offset
- 1] = '+';
2796 xtrace_print_assignment (name
, value
, assign_list
, 1);
2798 name
[offset
- 1] = '\0';
2801 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
2804 aflags
|= ASS_APPEND
;
2806 #if defined (ARRAY_VARS)
2807 if (t
= mbschr (name
, '[')) /*]*/
2811 report_error (_("%s: cannot assign list to array member"), name
);
2814 entry
= assign_array_element (name
, value
, aflags
);
2818 else if (assign_list
)
2820 if ((word
->flags
& W_ASSIGNARG
) && (word
->flags
& W_ASSNGLOBAL
) == 0)
2821 aflags
|= ASS_MKLOCAL
;
2822 if (word
->flags
& W_ASSIGNASSOC
)
2823 aflags
|= ASS_MKASSOC
;
2824 entry
= do_compound_assignment (name
, value
, aflags
);
2827 #endif /* ARRAY_VARS */
2828 entry
= bind_variable (name
, value
, aflags
);
2830 stupidly_hack_special_variables (name
);
2832 /* Return 1 if the assignment seems to have been performed correctly. */
2833 if (entry
== 0 || readonly_p (entry
))
2834 retval
= 0; /* assignment failure */
2835 else if (noassign_p (entry
))
2837 last_command_exit_value
= EXECUTION_FAILURE
;
2838 retval
= 1; /* error status, but not assignment failure */
2843 if (entry
&& retval
!= 0 && noassign_p (entry
) == 0)
2844 VUNSETATTR (entry
, att_invisible
);
2846 ASSIGN_RETURN (retval
);
2849 /* Perform the assignment statement in STRING, and expand the
2850 right side by doing tilde, command and parameter expansion. */
2852 do_assignment (string
)
2857 td
.flags
= W_ASSIGNMENT
;
2860 return do_assignment_internal (&td
, 1);
2864 do_word_assignment (word
, flags
)
2868 return do_assignment_internal (word
, 1);
2871 /* Given STRING, an assignment string, get the value of the right side
2872 of the `=', and bind it to the left side. Do not perform any word
2873 expansions on the right hand side. */
2875 do_assignment_no_expand (string
)
2880 td
.flags
= W_ASSIGNMENT
;
2883 return (do_assignment_internal (&td
, 0));
2886 /***************************************************
2888 * Functions to manage the positional parameters *
2890 ***************************************************/
2892 /* Return the word list that corresponds to `$*'. */
2894 list_rest_of_args ()
2896 register WORD_LIST
*list
, *args
;
2899 /* Break out of the loop as soon as one of the dollar variables is null. */
2900 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
2901 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
2903 for (args
= rest_of_args
; args
; args
= args
->next
)
2904 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
2906 return (REVERSE_LIST (list
, WORD_LIST
*));
2912 register WORD_LIST
*list
;
2915 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
2917 for (list
= rest_of_args
; list
; list
= list
->next
)
2922 /* Return the value of a positional parameter. This handles values > 10. */
2924 get_dollar_var_value (ind
)
2931 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2932 else /* We want something like ${11} */
2935 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2937 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2942 /* Make a single large string out of the dollar digit variables,
2943 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
2944 case of "$*" with respect to IFS. */
2946 string_rest_of_args (dollar_star
)
2949 register WORD_LIST
*list
;
2952 list
= list_rest_of_args ();
2953 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
2954 dispose_words (list
);
2958 /* Return a string containing the positional parameters from START to
2959 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
2960 which only makes a difference if QUOTED is non-zero. If QUOTED includes
2961 Q_HERE_DOCUMENT or Q_DOUBLE_QUOTES, this returns a quoted list, otherwise
2962 no quoting chars are added. */
2964 pos_params (string
, start
, end
, quoted
)
2966 int start
, end
, quoted
;
2968 WORD_LIST
*save
, *params
, *h
, *t
;
2972 /* see if we can short-circuit. if start == end, we want 0 parameters. */
2974 return ((char *)NULL
);
2976 save
= params
= list_rest_of_args ();
2978 return ((char *)NULL
);
2980 if (start
== 0) /* handle ${@:0[:x]} specially */
2982 t
= make_word_list (make_word (dollar_vars
[0]), params
);
2986 for (i
= start
? 1 : 0; params
&& i
< start
; i
++)
2987 params
= params
->next
;
2989 return ((char *)NULL
);
2990 for (h
= t
= params
; params
&& i
< end
; i
++)
2993 params
= params
->next
;
2996 t
->next
= (WORD_LIST
*)NULL
;
2998 ret
= string_list_pos_params (string
[0], h
, quoted
);
3003 dispose_words (save
);
3007 /******************************************************************/
3009 /* Functions to expand strings to strings or WORD_LISTs */
3011 /******************************************************************/
3013 #if defined (PROCESS_SUBSTITUTION)
3014 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC || s == '~')
3016 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC || s == '~')
3019 /* If there are any characters in STRING that require full expansion,
3020 then call FUNC to expand STRING; otherwise just perform quote
3021 removal if necessary. This returns a new string. */
3023 expand_string_if_necessary (string
, quoted
, func
)
3034 /* Don't need string length for ADVANCE_CHAR unless multibyte chars possible. */
3035 slen
= (MB_CUR_MAX
> 1) ? strlen (string
) : 0;
3039 if (EXP_CHAR (string
[i
]))
3041 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
3043 ADVANCE_CHAR (string
, slen
, i
);
3048 list
= (*func
) (string
, quoted
);
3051 ret
= string_list (list
);
3052 dispose_words (list
);
3057 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
3058 ret
= string_quote_removal (string
, quoted
);
3060 ret
= savestring (string
);
3065 static inline char *
3066 expand_string_to_string_internal (string
, quoted
, func
)
3074 if (string
== 0 || *string
== '\0')
3075 return ((char *)NULL
);
3077 list
= (*func
) (string
, quoted
);
3080 ret
= string_list (list
);
3081 dispose_words (list
);
3090 expand_string_to_string (string
, quoted
)
3094 return (expand_string_to_string_internal (string
, quoted
, expand_string
));
3098 expand_string_unsplit_to_string (string
, quoted
)
3102 return (expand_string_to_string_internal (string
, quoted
, expand_string_unsplit
));
3106 expand_assignment_string_to_string (string
, quoted
)
3110 return (expand_string_to_string_internal (string
, quoted
, expand_string_assignment
));
3114 expand_arith_string (string
, quoted
)
3118 return (expand_string_if_necessary (string
, quoted
, expand_string
));
3121 #if defined (COND_COMMAND)
3122 /* Just remove backslashes in STRING. Returns a new string. */
3124 remove_backslashes (string
)
3129 r
= ret
= (char *)xmalloc (strlen (string
) + 1);
3130 for (s
= string
; s
&& *s
; )
3142 /* This needs better error handling. */
3143 /* Expand W for use as an argument to a unary or binary operator in a
3144 [[...]] expression. If SPECIAL is 1, this is the rhs argument
3145 to the != or == operator, and should be treated as a pattern. In
3146 this case, we quote the string specially for the globbing code. If
3147 SPECIAL is 2, this is an rhs argument for the =~ operator, and should
3148 be quoted appropriately for regcomp/regexec. The caller is responsible
3149 for removing the backslashes if the unquoted word is needed later. */
3151 cond_expand_word (w
, special
)
3159 if (w
->word
== 0 || w
->word
[0] == '\0')
3160 return ((char *)NULL
);
3162 w
->flags
|= W_NOSPLIT2
;
3163 l
= call_expand_word_internal (w
, 0, 0, (int *)0, (int *)0);
3169 r
= string_list (l
);
3173 qflags
= QGLOB_CVTNULL
;
3175 qflags
|= QGLOB_REGEXP
;
3176 p
= string_list (l
);
3177 r
= quote_string_for_globbing (p
, qflags
);
3189 /* Call expand_word_internal to expand W and handle error returns.
3190 A convenience function for functions that don't want to handle
3191 any errors or free any memory before aborting. */
3193 call_expand_word_internal (w
, q
, i
, c
, e
)
3199 result
= expand_word_internal (w
, q
, i
, c
, e
);
3200 if (result
== &expand_word_error
|| result
== &expand_word_fatal
)
3202 /* By convention, each time this error is returned, w->word has
3203 already been freed (it sometimes may not be in the fatal case,
3204 but that doesn't result in a memory leak because we're going
3205 to exit in most cases). */
3206 w
->word
= (char *)NULL
;
3207 last_command_exit_value
= EXECUTION_FAILURE
;
3208 exp_jump_to_top_level ((result
== &expand_word_error
) ? DISCARD
: FORCE_EOF
);
3215 /* Perform parameter expansion, command substitution, and arithmetic
3216 expansion on STRING, as if it were a word. Leave the result quoted.
3217 Since this does not perform word splitting, it leaves quoted nulls
3220 expand_string_internal (string
, quoted
)
3227 if (string
== 0 || *string
== 0)
3228 return ((WORD_LIST
*)NULL
);
3231 td
.word
= savestring (string
);
3233 tresult
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3239 /* Expand STRING by performing parameter expansion, command substitution,
3240 and arithmetic expansion. Dequote the resulting WORD_LIST before
3241 returning it, but do not perform word splitting. The call to
3242 remove_quoted_nulls () is in here because word splitting normally
3243 takes care of quote removal. */
3245 expand_string_unsplit (string
, quoted
)
3251 if (string
== 0 || *string
== '\0')
3252 return ((WORD_LIST
*)NULL
);
3254 expand_no_split_dollar_star
= 1;
3255 value
= expand_string_internal (string
, quoted
);
3256 expand_no_split_dollar_star
= 0;
3262 remove_quoted_nulls (value
->word
->word
);
3263 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3265 dequote_list (value
);
3270 /* Expand the rhs of an assignment statement */
3272 expand_string_assignment (string
, quoted
)
3279 if (string
== 0 || *string
== '\0')
3280 return ((WORD_LIST
*)NULL
);
3282 expand_no_split_dollar_star
= 1;
3284 td
.flags
= W_ASSIGNRHS
;
3285 td
.word
= savestring (string
);
3286 value
= call_expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3289 expand_no_split_dollar_star
= 0;
3295 remove_quoted_nulls (value
->word
->word
);
3296 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3298 dequote_list (value
);
3304 /* Expand one of the PS? prompt strings. This is a sort of combination of
3305 expand_string_unsplit and expand_string_internal, but returns the
3306 passed string when an error occurs. Might want to trap other calls
3307 to jump_to_top_level here so we don't endlessly loop. */
3309 expand_prompt_string (string
, quoted
, wflags
)
3317 if (string
== 0 || *string
== 0)
3318 return ((WORD_LIST
*)NULL
);
3321 td
.word
= savestring (string
);
3323 no_longjmp_on_fatal_error
= 1;
3324 value
= expand_word_internal (&td
, quoted
, 0, (int *)NULL
, (int *)NULL
);
3325 no_longjmp_on_fatal_error
= 0;
3327 if (value
== &expand_word_error
|| value
== &expand_word_fatal
)
3329 value
= make_word_list (make_bare_word (string
), (WORD_LIST
*)NULL
);
3337 remove_quoted_nulls (value
->word
->word
);
3338 value
->word
->flags
&= ~W_HASQUOTEDNULL
;
3340 dequote_list (value
);
3345 /* Expand STRING just as if you were expanding a word, but do not dequote
3346 the resultant WORD_LIST. This is called only from within this file,
3347 and is used to correctly preserve quoted characters when expanding
3348 things like ${1+"$@"}. This does parameter expansion, command
3349 substitution, arithmetic expansion, and word splitting. */
3351 expand_string_leave_quoted (string
, quoted
)
3358 if (string
== 0 || *string
== '\0')
3359 return ((WORD_LIST
*)NULL
);
3361 tlist
= expand_string_internal (string
, quoted
);
3365 tresult
= word_list_split (tlist
);
3366 dispose_words (tlist
);
3369 return ((WORD_LIST
*)NULL
);
3372 /* This does not perform word splitting or dequote the WORD_LIST
3375 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
3377 int quoted
, *dollar_at_p
, *has_dollar_at
;
3382 if (string
== 0 || *string
== '\0')
3383 return (WORD_LIST
*)NULL
;
3385 td
.flags
= W_NOSPLIT2
; /* no splitting, remove "" and '' */
3387 tresult
= call_expand_word_internal (&td
, quoted
, 1, dollar_at_p
, has_dollar_at
);
3391 /* Expand STRING just as if you were expanding a word. This also returns
3392 a list of words. Note that filename globbing is *NOT* done for word
3393 or string expansion, just when the shell is expanding a command. This
3394 does parameter expansion, command substitution, arithmetic expansion,
3395 and word splitting. Dequote the resultant WORD_LIST before returning. */
3397 expand_string (string
, quoted
)
3403 if (string
== 0 || *string
== '\0')
3404 return ((WORD_LIST
*)NULL
);
3406 result
= expand_string_leave_quoted (string
, quoted
);
3407 return (result
? dequote_list (result
) : result
);
3410 /***************************************************
3412 * Functions to handle quoting chars *
3414 ***************************************************/
3418 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
3419 The parser passes CTLNUL as CTLESC CTLNUL. */
3421 /* Quote escape characters in string s, but no other characters. This is
3422 used to protect CTLESC and CTLNUL in variable values from the rest of
3423 the word expansion process after the variable is expanded (word splitting
3424 and filename generation). If IFS is null, we quote spaces as well, just
3425 in case we split on spaces later (in the case of unquoted $@, we will
3426 eventually attempt to split the entire word on spaces). Corresponding
3427 code exists in dequote_escapes. Even if we don't end up splitting on
3428 spaces, quoting spaces is not a problem. This should never be called on
3429 a string that is quoted with single or double quotes or part of a here
3430 document (effectively double-quoted). */
3432 quote_escapes (string
)
3435 register char *s
, *t
;
3437 char *result
, *send
;
3438 int quote_spaces
, skip_ctlesc
, skip_ctlnul
;
3441 slen
= strlen (string
);
3442 send
= string
+ slen
;
3444 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3446 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
3447 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
3449 t
= result
= (char *)xmalloc ((slen
* 2) + 1);
3454 if ((skip_ctlesc
== 0 && *s
== CTLESC
) || (skip_ctlnul
== 0 && *s
== CTLNUL
) || (quote_spaces
&& *s
== ' '))
3456 COPY_CHAR_P (t
, s
, send
);
3463 list_quote_escapes (list
)
3466 register WORD_LIST
*w
;
3469 for (w
= list
; w
; w
= w
->next
)
3472 w
->word
->word
= quote_escapes (t
);
3478 /* Inverse of quote_escapes; remove CTLESC protecting CTLESC or CTLNUL.
3480 The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
3481 This is necessary to make unquoted CTLESC and CTLNUL characters in the
3482 data stream pass through properly.
3484 We need to remove doubled CTLESC characters inside quoted strings before
3485 quoting the entire string, so we do not double the number of CTLESC
3488 Also used by parts of the pattern substitution code. */
3490 dequote_escapes (string
)
3493 register char *s
, *t
, *s1
;
3495 char *result
, *send
;
3502 slen
= strlen (string
);
3503 send
= string
+ slen
;
3505 t
= result
= (char *)xmalloc (slen
+ 1);
3507 if (strchr (string
, CTLESC
) == 0)
3508 return (strcpy (result
, string
));
3510 quote_spaces
= (ifs_value
&& *ifs_value
== 0);
3515 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
|| (quote_spaces
&& s
[1] == ' ')))
3521 COPY_CHAR_P (t
, s
, send
);
3527 /* Return a new string with the quoted representation of character C.
3528 This turns "" into QUOTED_NULL, so the W_HASQUOTEDNULL flag needs to be
3529 set in any resultant WORD_DESC where this value is the word. */
3531 make_quoted_char (c
)
3536 temp
= (char *)xmalloc (3);
3551 /* Quote STRING, returning a new string. This turns "" into QUOTED_NULL, so
3552 the W_HASQUOTEDNULL flag needs to be set in any resultant WORD_DESC where
3553 this value is the word. */
3555 quote_string (string
)
3560 char *result
, *send
;
3564 result
= (char *)xmalloc (2);
3572 slen
= strlen (string
);
3573 send
= string
+ slen
;
3575 result
= (char *)xmalloc ((slen
* 2) + 1);
3577 for (t
= result
; string
< send
; )
3580 COPY_CHAR_P (t
, string
, send
);
3587 /* De-quote quoted characters in STRING. */
3589 dequote_string (string
)
3592 register char *s
, *t
;
3594 char *result
, *send
;
3597 slen
= strlen (string
);
3599 t
= result
= (char *)xmalloc (slen
+ 1);
3601 if (QUOTED_NULL (string
))
3607 /* If no character in the string can be quoted, don't bother examining
3608 each character. Just return a copy of the string passed to us. */
3609 if (strchr (string
, CTLESC
) == NULL
)
3610 return (strcpy (result
, string
));
3612 send
= string
+ slen
;
3622 COPY_CHAR_P (t
, s
, send
);
3629 /* Quote the entire WORD_LIST list. */
3634 register WORD_LIST
*w
;
3637 for (w
= list
; w
; w
= w
->next
)
3640 w
->word
->word
= quote_string (t
);
3642 w
->word
->flags
|= W_HASQUOTEDNULL
; /* XXX - turn on W_HASQUOTEDNULL here? */
3643 w
->word
->flags
|= W_QUOTED
;
3649 /* De-quote quoted characters in each word in LIST. */
3655 register WORD_LIST
*tlist
;
3657 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
3659 s
= dequote_string (tlist
->word
->word
);
3660 if (QUOTED_NULL (tlist
->word
->word
))
3661 tlist
->word
->flags
&= ~W_HASQUOTEDNULL
;
3662 free (tlist
->word
->word
);
3663 tlist
->word
->word
= s
;
3668 /* Remove CTLESC protecting a CTLESC or CTLNUL in place. Return the passed
3671 remove_quoted_escapes (string
)
3678 t
= dequote_escapes (string
);
3686 /* Perform quoted null character removal on STRING. We don't allow any
3687 quoted null characters in the middle or at the ends of strings because
3688 of how expand_word_internal works. remove_quoted_nulls () turns
3689 STRING into an empty string iff it only consists of a quoted null,
3690 and removes all unquoted CTLNUL characters. */
3692 remove_quoted_nulls (string
)
3695 register size_t slen
;
3696 register int i
, j
, prev_i
;
3699 if (strchr (string
, CTLNUL
) == 0) /* XXX */
3700 return string
; /* XXX */
3702 slen
= strlen (string
);
3707 if (string
[i
] == CTLESC
)
3709 /* Old code had j++, but we cannot assume that i == j at this
3710 point -- what if a CTLNUL has already been removed from the
3711 string? We don't want to drop the CTLESC or recopy characters
3712 that we've already copied down. */
3713 i
++; string
[j
++] = CTLESC
;
3717 else if (string
[i
] == CTLNUL
)
3724 ADVANCE_CHAR (string
, slen
, i
);
3727 do string
[j
++] = string
[prev_i
++]; while (prev_i
< i
);
3737 /* Perform quoted null character removal on each element of LIST.
3738 This modifies LIST. */
3740 word_list_remove_quoted_nulls (list
)
3743 register WORD_LIST
*t
;
3745 for (t
= list
; t
; t
= t
->next
)
3747 remove_quoted_nulls (t
->word
->word
);
3748 t
->word
->flags
&= ~W_HASQUOTEDNULL
;
3752 /* **************************************************************** */
3754 /* Functions for Matching and Removing Patterns */
3756 /* **************************************************************** */
3758 #if defined (HANDLE_MULTIBYTE)
3759 #if 0 /* Currently unused */
3760 static unsigned char *
3761 mb_getcharlens (string
, len
)
3765 int i
, offset
, last
;
3772 ret
= (unsigned char *)xmalloc (len
);
3773 memset (ret
, 0, len
);
3774 while (string
[last
])
3776 ADVANCE_CHAR (string
, len
, offset
);
3777 ret
[last
] = offset
- last
;
3785 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
3786 can have one of 4 values:
3787 RP_LONG_LEFT remove longest matching portion at start of PARAM
3788 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
3789 RP_LONG_RIGHT remove longest matching portion at end of PARAM
3790 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
3793 #define RP_LONG_LEFT 1
3794 #define RP_SHORT_LEFT 2
3795 #define RP_LONG_RIGHT 3
3796 #define RP_SHORT_RIGHT 4
3798 /* Returns its first argument if nothing matched; new memory otherwise */
3800 remove_upattern (param
, pattern
, op
)
3801 char *param
, *pattern
;
3806 register char *p
, *ret
, c
;
3808 len
= STRLEN (param
);
3813 case RP_LONG_LEFT
: /* remove longest match at start */
3814 for (p
= end
; p
>= param
; p
--)
3817 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3820 return (savestring (p
));
3827 case RP_SHORT_LEFT
: /* remove shortest match at start */
3828 for (p
= param
; p
<= end
; p
++)
3831 if (strmatch (pattern
, param
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3834 return (savestring (p
));
3840 case RP_LONG_RIGHT
: /* remove longest match at end */
3841 for (p
= param
; p
<= end
; p
++)
3843 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3846 ret
= savestring (param
);
3853 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3854 for (p
= end
; p
>= param
; p
--)
3856 if (strmatch (pattern
, p
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3859 ret
= savestring (param
);
3867 return (param
); /* no match, return original string */
3870 #if defined (HANDLE_MULTIBYTE)
3871 /* Returns its first argument if nothing matched; new memory otherwise */
3873 remove_wpattern (wparam
, wstrlen
, wpattern
, op
)
3884 case RP_LONG_LEFT
: /* remove longest match at start */
3885 for (n
= wstrlen
; n
>= 0; n
--)
3887 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3888 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3891 return (wcsdup (wparam
+ n
));
3897 case RP_SHORT_LEFT
: /* remove shortest match at start */
3898 for (n
= 0; n
<= wstrlen
; n
++)
3900 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3901 if (wcsmatch (wpattern
, wparam
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3904 return (wcsdup (wparam
+ n
));
3910 case RP_LONG_RIGHT
: /* remove longest match at end */
3911 for (n
= 0; n
<= wstrlen
; n
++)
3913 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3915 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3916 ret
= wcsdup (wparam
);
3923 case RP_SHORT_RIGHT
: /* remove shortest match at end */
3924 for (n
= wstrlen
; n
>= 0; n
--)
3926 if (wcsmatch (wpattern
, wparam
+ n
, FNMATCH_EXTFLAG
) != FNM_NOMATCH
)
3928 wc
= wparam
[n
]; wparam
[n
] = L
'\0';
3929 ret
= wcsdup (wparam
);
3937 return (wparam
); /* no match, return original string */
3939 #endif /* HANDLE_MULTIBYTE */
3942 remove_pattern (param
, pattern
, op
)
3943 char *param
, *pattern
;
3950 if (*param
== '\0' || pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
3951 return (savestring (param
));
3953 #if defined (HANDLE_MULTIBYTE)
3956 wchar_t *ret
, *oret
;
3958 wchar_t *wparam
, *wpattern
;
3961 n
= xdupmbstowcs (&wpattern
, NULL
, pattern
);
3962 if (n
== (size_t)-1)
3964 xret
= remove_upattern (param
, pattern
, op
);
3965 return ((xret
== param
) ? savestring (param
) : xret
);
3967 n
= xdupmbstowcs (&wparam
, NULL
, param
);
3968 if (n
== (size_t)-1)
3971 xret
= remove_upattern (param
, pattern
, op
);
3972 return ((xret
== param
) ? savestring (param
) : xret
);
3974 oret
= ret
= remove_wpattern (wparam
, n
, wpattern
, op
);
3975 /* Don't bother to convert wparam back to multibyte string if nothing
3976 matched; just return copy of original string */
3981 return (savestring (param
));
3988 xret
= (char *)xmalloc (n
+ 1);
3989 memset (&ps
, '\0', sizeof (mbstate_t));
3990 n
= wcsrtombs (xret
, (const wchar_t **)&ret
, n
, &ps
);
3991 xret
[n
] = '\0'; /* just to make sure */
3998 xret
= remove_upattern (param
, pattern
, op
);
3999 return ((xret
== param
) ? savestring (param
) : xret
);
4003 /* Match PAT anywhere in STRING and return the match boundaries.
4004 This returns 1 in case of a successful match, 0 otherwise. SP
4005 and EP are pointers into the string where the match begins and
4006 ends, respectively. MTYPE controls what kind of match is attempted.
4007 MATCH_BEG and MATCH_END anchor the match at the beginning and end
4008 of the string, respectively. The longest match is returned. */
4010 match_upattern (string
, pat
, mtype
, sp
, ep
)
4016 register char *p
, *p1
, *npat
;
4020 /* If the pattern doesn't match anywhere in the string, go ahead and
4021 short-circuit right away. A minor optimization, saves a bunch of
4022 unnecessary calls to strmatch (up to N calls for a string of N
4023 characters) if the match is unsuccessful. To preserve the semantics
4024 of the substring matches below, we make sure that the pattern has
4025 `*' as first and last character, making a new pattern if necessary. */
4026 /* XXX - check this later if I ever implement `**' with special meaning,
4027 since this will potentially result in `**' at the beginning or end */
4029 if (pat
[0] != '*' || (pat
[0] == '*' && pat
[1] == LPAREN
&& extended_glob
) || pat
[len
- 1] != '*')
4031 p
= npat
= (char *)xmalloc (len
+ 3);
4033 if (*p1
!= '*' || (*p1
== '*' && p1
[1] == LPAREN
&& extended_glob
))
4037 if (p1
[-1] != '*' || p
[-2] == '\\')
4043 c
= strmatch (npat
, string
, FNMATCH_EXTFLAG
);
4046 if (c
== FNM_NOMATCH
)
4049 len
= STRLEN (string
);
4052 mlen
= umatchlen (pat
, len
);
4057 for (p
= string
; p
<= end
; p
++)
4059 if (match_pattern_char (pat
, p
))
4062 for (p1
= end
; p1
>= p
; p1
--)
4064 p1
= (mlen
== -1) ? end
: p
+ mlen
;
4065 /* p1 - p = length of portion of string to be considered
4066 p = current position in string
4067 mlen = number of characters consumed by match (-1 for entire string)
4069 we want to break immediately if the potential match len
4070 is greater than the number of characters remaining in the
4075 for ( ; p1
>= p
; p1
--)
4078 c
= *p1
; *p1
= '\0';
4079 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4088 /* If MLEN != -1, we have a fixed length pattern. */
4099 if (match_pattern_char (pat
, string
) == 0)
4103 for (p
= end
; p
>= string
; p
--)
4105 for (p
= (mlen
== -1) ? end
: string
+ mlen
; p
>= string
; p
--)
4109 if (strmatch (pat
, string
, FNMATCH_EXTFLAG
) == 0)
4118 /* If MLEN != -1, we have a fixed length pattern. */
4128 for (p
= string
; p
<= end
; p
++)
4130 for (p
= end
- ((mlen
== -1) ? len
: mlen
); p
<= end
; p
++)
4133 if (strmatch (pat
, p
, FNMATCH_EXTFLAG
) == 0)
4140 /* If MLEN != -1, we have a fixed length pattern. */
4152 #if defined (HANDLE_MULTIBYTE)
4153 /* Match WPAT anywhere in WSTRING and return the match boundaries.
4154 This returns 1 in case of a successful match, 0 otherwise. Wide
4155 character version. */
4157 match_wpattern (wstring
, indices
, wstrlen
, wpat
, mtype
, sp
, ep
)
4165 wchar_t wc
, *wp
, *nwpat
, *wp1
;
4168 int n
, n1
, n2
, simple
;
4170 simple
= (wpat
[0] != L
'\\' && wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'[');
4171 #if defined (EXTENDED_GLOB)
4173 simple
&= (wpat
[1] != L
'(' || (wpat
[0] != L
'*' && wpat
[0] != L
'?' && wpat
[0] != L
'+' && wpat
[0] != L
'!' && wpat
[0] != L
'@')); /*)*/
4176 /* If the pattern doesn't match anywhere in the string, go ahead and
4177 short-circuit right away. A minor optimization, saves a bunch of
4178 unnecessary calls to strmatch (up to N calls for a string of N
4179 characters) if the match is unsuccessful. To preserve the semantics
4180 of the substring matches below, we make sure that the pattern has
4181 `*' as first and last character, making a new pattern if necessary. */
4182 len
= wcslen (wpat
);
4183 if (wpat
[0] != L
'*' || (wpat
[0] == L
'*' && wpat
[1] == WLPAREN
&& extended_glob
) || wpat
[len
- 1] != L
'*')
4185 wp
= nwpat
= (wchar_t *)xmalloc ((len
+ 3) * sizeof (wchar_t));
4187 if (*wp1
!= L
'*' || (*wp1
== '*' && wp1
[1] == WLPAREN
&& extended_glob
))
4189 while (*wp1
!= L
'\0')
4191 if (wp1
[-1] != L
'*' || wp1
[-2] == L
'\\')
4197 len
= wcsmatch (nwpat
, wstring
, FNMATCH_EXTFLAG
);
4200 if (len
== FNM_NOMATCH
)
4203 mlen
= wmatchlen (wpat
, wstrlen
);
4205 /* itrace("wmatchlen (%ls) -> %d", wpat, mlen); */
4209 for (n
= 0; n
<= wstrlen
; n
++)
4212 n2
= simple
? (*wpat
== wstring
[n
]) : match_pattern_wchar (wpat
, wstring
+ n
);
4214 n2
= match_pattern_wchar (wpat
, wstring
+ n
);
4219 for (n1
= wstrlen
; n1
>= n
; n1
--)
4221 n1
= (mlen
== -1) ? wstrlen
: n
+ mlen
;
4225 for ( ; n1
>= n
; n1
--)
4228 wc
= wstring
[n1
]; wstring
[n1
] = L
'\0';
4229 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4238 /* If MLEN != -1, we have a fixed length pattern. */
4249 if (match_pattern_wchar (wpat
, wstring
) == 0)
4253 for (n
= wstrlen
; n
>= 0; n
--)
4255 for (n
= (mlen
== -1) ? wstrlen
: mlen
; n
>= 0; n
--)
4258 wc
= wstring
[n
]; wstring
[n
] = L
'\0';
4259 if (wcsmatch (wpat
, wstring
, FNMATCH_EXTFLAG
) == 0)
4268 /* If MLEN != -1, we have a fixed length pattern. */
4278 for (n
= 0; n
<= wstrlen
; n
++)
4280 for (n
= wstrlen
- ((mlen
== -1) ? wstrlen
: mlen
); n
<= wstrlen
; n
++)
4283 if (wcsmatch (wpat
, wstring
+ n
, FNMATCH_EXTFLAG
) == 0)
4286 *ep
= indices
[wstrlen
];
4290 /* If MLEN != -1, we have a fixed length pattern. */
4301 #endif /* HANDLE_MULTIBYTE */
4304 match_pattern (string
, pat
, mtype
, sp
, ep
)
4309 #if defined (HANDLE_MULTIBYTE)
4312 wchar_t *wstring
, *wpat
;
4314 size_t slen
, plen
, mslen
, mplen
;
4317 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
4320 #if defined (HANDLE_MULTIBYTE)
4324 slen
= STRLEN (string
);
4325 mslen
= MBSLEN (string
);
4326 plen
= STRLEN (pat
);
4327 mplen
= MBSLEN (pat
);
4328 if (slen
== mslen
&& plen
== mplen
)
4330 if (mbsmbchar (string
) == 0 && mbsmbchar (pat
) == 0)
4332 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4334 n
= xdupmbstowcs (&wpat
, NULL
, pat
);
4335 if (n
== (size_t)-1)
4336 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4337 n
= xdupmbstowcs (&wstring
, &indices
, string
);
4338 if (n
== (size_t)-1)
4341 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4343 ret
= match_wpattern (wstring
, indices
, n
, wpat
, mtype
, sp
, ep
);
4353 return (match_upattern (string
, pat
, mtype
, sp
, ep
));
4357 getpatspec (c
, value
)
4362 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
4364 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
4367 /* Posix.2 says that the WORD should be run through tilde expansion,
4368 parameter expansion, command substitution and arithmetic expansion.
4369 This leaves the result quoted, so quote_string_for_globbing () has
4370 to be called to fix it up for strmatch (). If QUOTED is non-zero,
4371 it means that the entire expression was enclosed in double quotes.
4372 This means that quoting characters in the pattern do not make any
4373 special pattern characters quoted. For example, the `*' in the
4374 following retains its special meaning: "${foo#'*'}". */
4376 getpattern (value
, quoted
, expandpat
)
4378 int quoted
, expandpat
;
4385 /* There is a problem here: how to handle single or double quotes in the
4386 pattern string when the whole expression is between double quotes?
4387 POSIX.2 says that enclosing double quotes do not cause the pattern to
4388 be quoted, but does that leave us a problem with @ and array[@] and their
4389 expansions inside a pattern? */
4391 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
4394 pat
= string_extract_double_quoted (tword
, &i
, 1);
4400 /* expand_string_for_rhs () leaves WORD quoted and does not perform
4402 l
= *value
? expand_string_for_rhs (value
,
4403 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_PATQUOTE
: quoted
,
4404 (int *)NULL
, (int *)NULL
)
4406 pat
= string_list (l
);
4410 tword
= quote_string_for_globbing (pat
, QGLOB_CVTNULL
);
4418 /* Handle removing a pattern from a string as a result of ${name%[%]value}
4419 or ${name#[#]value}. */
4421 variable_remove_pattern (value
, pattern
, patspec
, quoted
)
4422 char *value
, *pattern
;
4423 int patspec
, quoted
;
4427 tword
= remove_pattern (value
, pattern
, patspec
);
4434 list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
)
4437 int patspec
, itype
, quoted
;
4443 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
4445 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
4446 w
= alloc_word_desc ();
4447 w
->word
= tword
? tword
: savestring ("");
4448 new = make_word_list (w
, new);
4451 l
= REVERSE_LIST (new, WORD_LIST
*);
4452 tword
= string_list_pos_params (itype
, l
, quoted
);
4459 parameter_list_remove_pattern (itype
, pattern
, patspec
, quoted
)
4462 int patspec
, quoted
;
4467 list
= list_rest_of_args ();
4469 return ((char *)NULL
);
4470 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4471 dispose_words (list
);
4475 #if defined (ARRAY_VARS)
4477 array_remove_pattern (var
, pattern
, patspec
, varname
, quoted
)
4481 char *varname
; /* so we can figure out how it's indexed */
4491 /* compute itype from varname here */
4492 v
= array_variable_part (varname
, &ret
, 0);
4495 a
= (v
&& array_p (v
)) ? array_cell (v
) : 0;
4496 h
= (v
&& assoc_p (v
)) ? assoc_cell (v
) : 0;
4498 list
= a
? array_to_word_list (a
) : (h
? assoc_to_word_list (h
) : 0);
4500 return ((char *)NULL
);
4501 ret
= list_remove_pattern (list
, pattern
, patspec
, itype
, quoted
);
4502 dispose_words (list
);
4506 #endif /* ARRAY_VARS */
4509 parameter_brace_remove_pattern (varname
, value
, ind
, patstr
, rtype
, quoted
, flags
)
4510 char *varname
, *value
;
4513 int rtype
, quoted
, flags
;
4515 int vtype
, patspec
, starsub
;
4516 char *temp1
, *val
, *pattern
;
4520 return ((char *)NULL
);
4522 this_command_name
= varname
;
4524 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
4526 return ((char *)NULL
);
4528 starsub
= vtype
& VT_STARSUB
;
4529 vtype
&= ~VT_STARSUB
;
4531 patspec
= getpatspec (rtype
, patstr
);
4532 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
4535 /* Need to pass getpattern newly-allocated memory in case of expansion --
4536 the expansion code will free the passed string on an error. */
4537 temp1
= savestring (patstr
);
4538 pattern
= getpattern (temp1
, quoted
, 1);
4541 temp1
= (char *)NULL
; /* shut up gcc */
4545 case VT_ARRAYMEMBER
:
4546 temp1
= remove_pattern (val
, pattern
, patspec
);
4547 if (vtype
== VT_VARIABLE
)
4551 val
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4552 ? quote_string (temp1
)
4553 : quote_escapes (temp1
);
4558 #if defined (ARRAY_VARS)
4560 temp1
= array_remove_pattern (v
, pattern
, patspec
, varname
, quoted
);
4561 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4563 val
= quote_escapes (temp1
);
4570 temp1
= parameter_list_remove_pattern (varname
[0], pattern
, patspec
, quoted
);
4571 if (temp1
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
4573 val
= quote_escapes (temp1
);
4584 /*******************************************
4586 * Functions to expand WORD_DESCs *
4588 *******************************************/
4590 /* Expand WORD, performing word splitting on the result. This does
4591 parameter expansion, command substitution, arithmetic expansion,
4592 word splitting, and quote removal. */
4595 expand_word (word
, quoted
)
4599 WORD_LIST
*result
, *tresult
;
4601 tresult
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4602 result
= word_list_split (tresult
);
4603 dispose_words (tresult
);
4604 return (result
? dequote_list (result
) : result
);
4607 /* Expand WORD, but do not perform word splitting on the result. This
4608 does parameter expansion, command substitution, arithmetic expansion,
4609 and quote removal. */
4611 expand_word_unsplit (word
, quoted
)
4617 expand_no_split_dollar_star
= 1;
4618 #if defined (HANDLE_MULTIBYTE)
4619 if (ifs_firstc
[0] == 0)
4621 if (ifs_firstc
== 0)
4623 word
->flags
|= W_NOSPLIT
;
4624 word
->flags
|= W_NOSPLIT2
;
4625 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4626 expand_no_split_dollar_star
= 0;
4628 return (result
? dequote_list (result
) : result
);
4631 /* Perform shell expansions on WORD, but do not perform word splitting or
4632 quote removal on the result. Virtually identical to expand_word_unsplit;
4633 could be combined if implementations don't diverge. */
4635 expand_word_leave_quoted (word
, quoted
)
4641 expand_no_split_dollar_star
= 1;
4642 #if defined (HANDLE_MULTIBYTE)
4643 if (ifs_firstc
[0] == 0)
4645 if (ifs_firstc
== 0)
4647 word
->flags
|= W_NOSPLIT
;
4648 word
->flags
|= W_NOSPLIT2
;
4649 result
= call_expand_word_internal (word
, quoted
, 0, (int *)NULL
, (int *)NULL
);
4650 expand_no_split_dollar_star
= 0;
4655 #if defined (PROCESS_SUBSTITUTION)
4657 /*****************************************************************/
4659 /* Hacking Process Substitution */
4661 /*****************************************************************/
4663 #if !defined (HAVE_DEV_FD)
4664 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
4665 of FIFOs the shell has open. unlink_fifo_list will walk the list and
4666 unlink all of them. add_fifo_list adds the name of an open FIFO to the
4667 list. NFIFO is a count of the number of FIFOs in the list. */
4668 #define FIFO_INCR 20
4675 static struct temp_fifo
*fifo_list
= (struct temp_fifo
*)NULL
;
4677 static int fifo_list_size
;
4680 copy_fifo_list (sizep
)
4685 return (char *)NULL
;
4689 add_fifo_list (pathname
)
4692 if (nfifo
>= fifo_list_size
- 1)
4694 fifo_list_size
+= FIFO_INCR
;
4695 fifo_list
= (struct temp_fifo
*)xrealloc (fifo_list
,
4696 fifo_list_size
* sizeof (struct temp_fifo
));
4699 fifo_list
[nfifo
].file
= savestring (pathname
);
4707 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4709 unlink (fifo_list
[i
].file
);
4710 free (fifo_list
[i
].file
);
4711 fifo_list
[i
].file
= (char *)NULL
;
4712 fifo_list
[i
].proc
= -1;
4724 for (i
= saved
= 0; i
< nfifo
; i
++)
4726 if ((fifo_list
[i
].proc
== -1) || (kill(fifo_list
[i
].proc
, 0) == -1))
4728 unlink (fifo_list
[i
].file
);
4729 free (fifo_list
[i
].file
);
4730 fifo_list
[i
].file
= (char *)NULL
;
4731 fifo_list
[i
].proc
= -1;
4737 /* If we didn't remove some of the FIFOs, compact the list. */
4740 for (i
= j
= 0; i
< nfifo
; i
++)
4741 if (fifo_list
[i
].file
)
4743 fifo_list
[j
].file
= fifo_list
[i
].file
;
4744 fifo_list
[j
].proc
= fifo_list
[i
].proc
;
4753 /* Take LIST, which is a bitmap denoting active FIFOs in fifo_list
4754 from some point in the past, and close all open FIFOs in fifo_list
4755 that are not marked as active in LIST. If LIST is NULL, close
4756 everything in fifo_list. LSIZE is the number of elements in LIST, in
4757 case it's larger than fifo_list_size (size of fifo_list). */
4759 close_new_fifos (list
, lsize
)
4767 unlink_fifo_list ();
4771 for (i
= 0; i
< lsize
; i
++)
4772 if (list
[i
] == 0 && i
< fifo_list_size
&& fifo_list
[i
].proc
!= -1)
4775 for (i
= lsize
; i
< fifo_list_size
; i
++)
4796 tname
= sh_mktmpname ("sh-np", MT_USERANDOM
|MT_USETMPDIR
);
4797 if (mkfifo (tname
, 0600) < 0)
4800 return ((char *)NULL
);
4803 add_fifo_list (tname
);
4807 #else /* HAVE_DEV_FD */
4809 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
4810 has open to children. NFDS is a count of the number of bits currently
4811 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
4813 static char *dev_fd_list
= (char *)NULL
;
4815 static int totfds
; /* The highest possible number of open files. */
4818 copy_fifo_list (sizep
)
4823 if (nfds
== 0 || totfds
== 0)
4827 return (char *)NULL
;
4832 ret
= (char *)xmalloc (totfds
);
4833 return (memcpy (ret
, dev_fd_list
, totfds
));
4840 if (dev_fd_list
== 0 || fd
>= totfds
)
4845 totfds
= getdtablesize ();
4846 if (totfds
< 0 || totfds
> 256)
4851 dev_fd_list
= (char *)xrealloc (dev_fd_list
, totfds
);
4852 memset (dev_fd_list
+ ofds
, '\0', totfds
- ofds
);
4855 dev_fd_list
[fd
] = 1;
4862 return 0; /* used for cleanup; not needed with /dev/fd */
4875 if (dev_fd_list
[fd
])
4878 dev_fd_list
[fd
] = 0;
4891 for (i
= 0; nfds
&& i
< totfds
; i
++)
4897 /* Take LIST, which is a snapshot copy of dev_fd_list from some point in
4898 the past, and close all open fds in dev_fd_list that are not marked
4899 as open in LIST. If LIST is NULL, close everything in dev_fd_list.
4900 LSIZE is the number of elements in LIST, in case it's larger than
4901 totfds (size of dev_fd_list). */
4903 close_new_fifos (list
, lsize
)
4911 unlink_fifo_list ();
4915 for (i
= 0; i
< lsize
; i
++)
4916 if (list
[i
] == 0 && i
< totfds
&& dev_fd_list
[i
])
4919 for (i
= lsize
; i
< totfds
; i
++)
4923 #if defined (NOTDEF)
4924 print_dev_fd_list ()
4928 fprintf (stderr
, "pid %ld: dev_fd_list:", (long)getpid ());
4931 for (i
= 0; i
< totfds
; i
++)
4934 fprintf (stderr
, " %d", i
);
4936 fprintf (stderr
, "\n");
4941 make_dev_fd_filename (fd
)
4944 char *ret
, intbuf
[INT_STRLEN_BOUND (int) + 1], *p
;
4946 ret
= (char *)xmalloc (sizeof (DEV_FD_PREFIX
) + 8);
4948 strcpy (ret
, DEV_FD_PREFIX
);
4949 p
= inttostr (fd
, intbuf
, sizeof (intbuf
));
4950 strcpy (ret
+ sizeof (DEV_FD_PREFIX
) - 1, p
);
4956 #endif /* HAVE_DEV_FD */
4958 /* Return a filename that will open a connection to the process defined by
4959 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
4960 a filename in /dev/fd corresponding to a descriptor that is one of the
4961 ends of the pipe. If not defined, we use named pipes on systems that have
4962 them. Systems without /dev/fd and named pipes are out of luck.
4964 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
4965 use the read end of the pipe and dup that file descriptor to fd 0 in
4966 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
4967 writing or use the write end of the pipe in the child, and dup that
4968 file descriptor to fd 1 in the child. The parent does the opposite. */
4971 process_substitute (string
, open_for_read_in_child
)
4973 int open_for_read_in_child
;
4978 #if defined (HAVE_DEV_FD)
4979 int parent_pipe_fd
, child_pipe_fd
;
4981 #endif /* HAVE_DEV_FD */
4982 #if defined (JOB_CONTROL)
4983 pid_t old_pipeline_pgrp
;
4986 if (!string
|| !*string
|| wordexp_only
)
4987 return ((char *)NULL
);
4989 #if !defined (HAVE_DEV_FD)
4990 pathname
= make_named_pipe ();
4991 #else /* HAVE_DEV_FD */
4992 if (pipe (fildes
) < 0)
4994 sys_error (_("cannot make pipe for process substitution"));
4995 return ((char *)NULL
);
4997 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
4998 the pipe in the parent, otherwise the read end. */
4999 parent_pipe_fd
= fildes
[open_for_read_in_child
];
5000 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
5001 /* Move the parent end of the pipe to some high file descriptor, to
5002 avoid clashes with FDs used by the script. */
5003 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
5005 pathname
= make_dev_fd_filename (parent_pipe_fd
);
5006 #endif /* HAVE_DEV_FD */
5010 sys_error (_("cannot make pipe for process substitution"));
5011 return ((char *)NULL
);
5014 old_pid
= last_made_pid
;
5016 #if defined (JOB_CONTROL)
5017 old_pipeline_pgrp
= pipeline_pgrp
;
5018 pipeline_pgrp
= shell_pgrp
;
5020 #endif /* JOB_CONTROL */
5022 pid
= make_child ((char *)NULL
, 1);
5025 reset_terminating_signals (); /* XXX */
5026 free_pushed_string_input ();
5027 /* Cancel traps, in trap.c. */
5028 restore_original_signals (); /* XXX - what about special builtins? bash-4.2 */
5029 setup_async_signals ();
5030 subshell_environment
|= SUBSHELL_COMSUB
|SUBSHELL_PROCSUB
;
5033 #if defined (JOB_CONTROL)
5034 set_sigchld_handler ();
5035 stop_making_children ();
5036 /* XXX - should we only do this in the parent? (as in command subst) */
5037 pipeline_pgrp
= old_pipeline_pgrp
;
5038 #endif /* JOB_CONTROL */
5042 sys_error (_("cannot make child for process substitution"));
5044 #if defined (HAVE_DEV_FD)
5045 close (parent_pipe_fd
);
5046 close (child_pipe_fd
);
5047 #endif /* HAVE_DEV_FD */
5048 return ((char *)NULL
);
5053 #if defined (JOB_CONTROL)
5054 restore_pipeline (1);
5057 #if !defined (HAVE_DEV_FD)
5058 fifo_list
[nfifo
-1].proc
= pid
;
5061 last_made_pid
= old_pid
;
5063 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5065 #endif /* JOB_CONTROL && PGRP_PIPE */
5067 #if defined (HAVE_DEV_FD)
5068 close (child_pipe_fd
);
5069 #endif /* HAVE_DEV_FD */
5074 set_sigint_handler ();
5076 #if defined (JOB_CONTROL)
5077 set_job_control (0);
5078 #endif /* JOB_CONTROL */
5080 #if !defined (HAVE_DEV_FD)
5081 /* Open the named pipe in the child. */
5082 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
5085 /* Two separate strings for ease of translation. */
5086 if (open_for_read_in_child
)
5087 sys_error (_("cannot open named pipe %s for reading"), pathname
);
5089 sys_error (_("cannot open named pipe %s for writing"), pathname
);
5093 if (open_for_read_in_child
)
5095 if (sh_unset_nodelay_mode (fd
) < 0)
5097 sys_error (_("cannot reset nodelay mode for fd %d"), fd
);
5101 #else /* HAVE_DEV_FD */
5103 #endif /* HAVE_DEV_FD */
5105 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
5107 sys_error (_("cannot duplicate named pipe %s as fd %d"), pathname
,
5108 open_for_read_in_child
? 0 : 1);
5112 if (fd
!= (open_for_read_in_child
? 0 : 1))
5115 /* Need to close any files that this process has open to pipes inherited
5117 if (current_fds_to_close
)
5119 close_fd_bitmap (current_fds_to_close
);
5120 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
5123 #if defined (HAVE_DEV_FD)
5124 /* Make sure we close the parent's end of the pipe and clear the slot
5125 in the fd list so it is not closed later, if reallocated by, for
5126 instance, pipe(2). */
5127 close (parent_pipe_fd
);
5128 dev_fd_list
[parent_pipe_fd
] = 0;
5129 #endif /* HAVE_DEV_FD */
5131 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
5133 #if !defined (HAVE_DEV_FD)
5134 /* Make sure we close the named pipe in the child before we exit. */
5135 close (open_for_read_in_child
? 0 : 1);
5136 #endif /* !HAVE_DEV_FD */
5141 #endif /* PROCESS_SUBSTITUTION */
5143 /***********************************/
5145 /* Command Substitution */
5147 /***********************************/
5150 read_comsub (fd
, quoted
, rflag
)
5154 char *istring
, buf
[128], *bufp
, *s
;
5155 int istring_index
, istring_size
, c
, tflag
, skip_ctlesc
, skip_ctlnul
;
5158 istring
= (char *)NULL
;
5159 istring_index
= istring_size
= bufn
= tflag
= 0;
5161 for (skip_ctlesc
= skip_ctlnul
= 0, s
= ifs_value
; s
&& *s
; s
++)
5162 skip_ctlesc
|= *s
== CTLESC
, skip_ctlnul
|= *s
== CTLNUL
;
5164 /* Read the output of the command through the pipe. This may need to be
5165 changed to understand multibyte characters in the future. */
5172 bufn
= zread (fd
, buf
, sizeof (buf
));
5182 internal_warning ("read_comsub: ignored null byte in input");
5187 /* Add the character to ISTRING, possibly after resizing it. */
5188 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
5190 /* This is essentially quote_string inline */
5191 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) /* || c == CTLESC || c == CTLNUL */)
5192 istring
[istring_index
++] = CTLESC
;
5193 /* Escape CTLESC and CTLNUL in the output to protect those characters
5194 from the rest of the word expansions (word splitting and globbing.)
5195 This is essentially quote_escapes inline. */
5196 else if (skip_ctlesc
== 0 && c
== CTLESC
)
5198 tflag
|= W_HASCTLESC
;
5199 istring
[istring_index
++] = CTLESC
;
5201 else if ((skip_ctlnul
== 0 && c
== CTLNUL
) || (c
== ' ' && (ifs_value
&& *ifs_value
== 0)))
5202 istring
[istring_index
++] = CTLESC
;
5204 istring
[istring_index
++] = c
;
5207 #if defined (__CYGWIN__)
5208 if (c
== '\n' && istring_index
> 1 && istring
[istring_index
- 2] == '\r')
5211 istring
[istring_index
- 1] = '\n';
5218 istring
[istring_index
] = '\0';
5220 /* If we read no output, just return now and save ourselves some
5222 if (istring_index
== 0)
5227 return (char *)NULL
;
5230 /* Strip trailing newlines from the output of the command. */
5231 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
5233 while (istring_index
> 0)
5235 if (istring
[istring_index
- 1] == '\n')
5239 /* If the newline was quoted, remove the quoting char. */
5240 if (istring
[istring_index
- 1] == CTLESC
)
5246 istring
[istring_index
] = '\0';
5249 strip_trailing (istring
, istring_index
- 1, 1);
5256 /* Perform command substitution on STRING. This returns a WORD_DESC * with the
5257 contained string possibly quoted. */
5259 command_substitute (string
, quoted
)
5263 pid_t pid
, old_pid
, old_pipeline_pgrp
, old_async_pid
;
5265 int result
, fildes
[2], function_value
, pflags
, rc
, tflag
;
5268 istring
= (char *)NULL
;
5270 /* Don't fork () if there is no need to. In the case of no command to
5271 run, just return NULL. */
5272 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
5273 return ((WORD_DESC
*)NULL
);
5275 if (wordexp_only
&& read_but_dont_execute
)
5277 last_command_exit_value
= EX_WEXPCOMSUB
;
5278 jump_to_top_level (EXITPROG
);
5281 /* We're making the assumption here that the command substitution will
5282 eventually run a command from the file system. Since we'll run
5283 maybe_make_export_env in this subshell before executing that command,
5284 the parent shell and any other shells it starts will have to remake
5285 the environment. If we make it before we fork, other shells won't
5286 have to. Don't bother if we have any temporary variable assignments,
5287 though, because the export environment will be remade after this
5288 command completes anyway, but do it if all the words to be expanded
5289 are variable assignments. */
5290 if (subst_assign_varlist
== 0 || garglist
== 0)
5291 maybe_make_export_env (); /* XXX */
5293 /* Flags to pass to parse_and_execute() */
5294 pflags
= (interactive
&& sourcelevel
== 0) ? SEVAL_RESETLINE
: 0;
5296 /* Pipe the output of executing STRING into the current shell. */
5297 if (pipe (fildes
) < 0)
5299 sys_error (_("cannot make pipe for command substitution"));
5303 old_pid
= last_made_pid
;
5304 #if defined (JOB_CONTROL)
5305 old_pipeline_pgrp
= pipeline_pgrp
;
5306 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
5307 if ((subshell_environment
& SUBSHELL_PIPE
) == 0)
5308 pipeline_pgrp
= shell_pgrp
;
5309 cleanup_the_pipeline ();
5310 #endif /* JOB_CONTROL */
5312 old_async_pid
= last_asynchronous_pid
;
5313 pid
= make_child ((char *)NULL
, subshell_environment
&SUBSHELL_ASYNC
);
5314 last_asynchronous_pid
= old_async_pid
;
5318 /* Reset the signal handlers in the child, but don't free the
5319 trap strings. Set a flag noting that we have to free the
5320 trap strings if we run trap to change a signal disposition. */
5321 reset_signal_handlers ();
5322 subshell_environment
|= SUBSHELL_RESETTRAP
;
5325 #if defined (JOB_CONTROL)
5326 /* XXX DO THIS ONLY IN PARENT ? XXX */
5327 set_sigchld_handler ();
5328 stop_making_children ();
5330 pipeline_pgrp
= old_pipeline_pgrp
;
5332 stop_making_children ();
5333 #endif /* JOB_CONTROL */
5337 sys_error (_("cannot make child for command substitution"));
5340 last_made_pid
= old_pid
;
5345 return ((WORD_DESC
*)NULL
);
5350 set_sigint_handler (); /* XXX */
5352 free_pushed_string_input ();
5354 if (dup2 (fildes
[1], 1) < 0)
5356 sys_error (_("command_substitute: cannot duplicate pipe as fd 1"));
5357 exit (EXECUTION_FAILURE
);
5360 /* If standard output is closed in the parent shell
5361 (such as after `exec >&-'), file descriptor 1 will be
5362 the lowest available file descriptor, and end up in
5363 fildes[0]. This can happen for stdin and stderr as well,
5364 but stdout is more important -- it will cause no output
5365 to be generated from this command. */
5366 if ((fildes
[1] != fileno (stdin
)) &&
5367 (fildes
[1] != fileno (stdout
)) &&
5368 (fildes
[1] != fileno (stderr
)))
5371 if ((fildes
[0] != fileno (stdin
)) &&
5372 (fildes
[0] != fileno (stdout
)) &&
5373 (fildes
[0] != fileno (stderr
)))
5377 /* Let stdio know the fd may have changed from text to binary mode, and
5378 make sure to preserve stdout line buffering. */
5379 freopen (NULL
, "w", stdout
);
5380 sh_setlinebuf (stdout
);
5381 #endif /* __CYGWIN__ */
5383 /* The currently executing shell is not interactive. */
5386 /* This is a subshell environment. */
5387 subshell_environment
|= SUBSHELL_COMSUB
;
5389 /* When not in POSIX mode, command substitution does not inherit
5391 if (posixly_correct
== 0)
5392 exit_immediately_on_error
= 0;
5394 remove_quoted_escapes (string
);
5396 startup_state
= 2; /* see if we can avoid a fork */
5397 /* Give command substitution a place to jump back to on failure,
5398 so we don't go back up to main (). */
5399 result
= setjmp (top_level
);
5401 /* If we're running a command substitution inside a shell function,
5402 trap `return' so we don't return from the function in the subshell
5403 and go off to never-never land. */
5404 if (result
== 0 && return_catch_flag
)
5405 function_value
= setjmp (return_catch
);
5409 if (result
== ERREXIT
)
5410 rc
= last_command_exit_value
;
5411 else if (result
== EXITPROG
)
5412 rc
= last_command_exit_value
;
5414 rc
= EXECUTION_FAILURE
;
5415 else if (function_value
)
5416 rc
= return_catch_value
;
5420 rc
= parse_and_execute (string
, "command substitution", pflags
|SEVAL_NOHIST
);
5424 last_command_exit_value
= rc
;
5425 rc
= run_exit_trap ();
5426 #if defined (PROCESS_SUBSTITUTION)
5427 unlink_fifo_list ();
5433 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
5435 #endif /* JOB_CONTROL && PGRP_PIPE */
5440 istring
= read_comsub (fildes
[0], quoted
, &tflag
);
5444 current_command_subst_pid
= pid
;
5445 last_command_exit_value
= wait_for (pid
);
5446 last_command_subst_pid
= pid
;
5447 last_made_pid
= old_pid
;
5449 #if defined (JOB_CONTROL)
5450 /* If last_command_exit_value > 128, then the substituted command
5451 was terminated by a signal. If that signal was SIGINT, then send
5452 SIGINT to ourselves. This will break out of loops, for instance. */
5453 if (last_command_exit_value
== (128 + SIGINT
) && last_command_exit_signal
== SIGINT
)
5454 kill (getpid (), SIGINT
);
5456 /* wait_for gives the terminal back to shell_pgrp. If some other
5457 process group should have it, give it away to that group here.
5458 pipeline_pgrp is non-zero only while we are constructing a
5459 pipline, so what we are concerned about is whether or not that
5460 pipeline was started in the background. A pipeline started in
5461 the background should never get the tty back here. */
5462 if (interactive
&& pipeline_pgrp
!= (pid_t
)0 && (subshell_environment
& SUBSHELL_ASYNC
) == 0)
5463 give_terminal_to (pipeline_pgrp
, 0);
5464 #endif /* JOB_CONTROL */
5466 ret
= alloc_word_desc ();
5467 ret
->word
= istring
;
5474 /********************************************************
5476 * Utility functions for parameter expansion *
5478 ********************************************************/
5480 #if defined (ARRAY_VARS)
5483 array_length_reference (s
)
5494 var
= array_variable_part (s
, &t
, &len
);
5496 /* If unbound variables should generate an error, report one and return
5498 if ((var
== 0 || (assoc_p (var
) == 0 && array_p (var
) == 0)) && unbound_vars_is_error
)
5502 last_command_exit_value
= EXECUTION_FAILURE
;
5510 /* We support a couple of expansions for variables that are not arrays.
5511 We'll return the length of the value for v[0], and 1 for v[@] or
5512 v[*]. Return 0 for everything else. */
5514 array
= array_p (var
) ? array_cell (var
) : (ARRAY
*)NULL
;
5515 h
= assoc_p (var
) ? assoc_cell (var
) : (HASH_TABLE
*)NULL
;
5517 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
5520 return (h
? assoc_num_elements (h
) : 0);
5521 else if (array_p (var
))
5522 return (array
? array_num_elements (array
) : 0);
5524 return (var_isset (var
) ? 1 : 0);
5530 akey
= expand_assignment_string_to_string (t
, 0); /* [ */
5532 if (akey
== 0 || *akey
== 0)
5534 err_badarraysub (t
);
5538 t
= assoc_reference (assoc_cell (var
), akey
);
5543 ind
= array_expand_index (var
, t
, len
);
5544 /* negative subscripts to indexed arrays count back from end */
5545 if (var
&& array_p (var
) && ind
< 0)
5546 ind
= array_max_index (array_cell (var
)) + 1 + ind
;
5549 err_badarraysub (t
);
5553 t
= array_reference (array
, ind
);
5555 t
= (ind
== 0) ? value_cell (var
) : (char *)NULL
;
5558 len
= MB_STRLEN (t
);
5561 #endif /* ARRAY_VARS */
5564 valid_brace_expansion_word (name
, var_is_special
)
5568 if (DIGIT (*name
) && all_digits (name
))
5570 else if (var_is_special
)
5572 #if defined (ARRAY_VARS)
5573 else if (valid_array_reference (name
))
5575 #endif /* ARRAY_VARS */
5576 else if (legal_identifier (name
))
5583 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5586 int *quoted_dollar_atp
, *contains_dollar_at
;
5592 if (quoted_dollar_atp
)
5593 *quoted_dollar_atp
= 0;
5594 if (contains_dollar_at
)
5595 *contains_dollar_at
= 0;
5599 /* check for $@ and $* */
5600 if (name
[0] == '@' && name
[1] == 0)
5602 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5603 *quoted_dollar_atp
= 1;
5604 if (contains_dollar_at
)
5605 *contains_dollar_at
= 1;
5608 else if (name
[0] == '*' && name
[1] == '\0' && quoted
== 0)
5610 if (contains_dollar_at
)
5611 *contains_dollar_at
= 1;
5615 /* Now check for ${array[@]} and ${array[*]} */
5616 #if defined (ARRAY_VARS)
5617 else if (valid_array_reference (name
))
5619 temp1
= mbschr (name
, '[');
5620 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
5622 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
5623 *quoted_dollar_atp
= 1;
5624 if (contains_dollar_at
)
5625 *contains_dollar_at
= 1;
5628 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
5629 which should result in separate words even when IFS is unset. */
5630 if (temp1
&& temp1
[1] == '*' && temp1
[2] == ']' && quoted
== 0)
5632 if (contains_dollar_at
)
5633 *contains_dollar_at
= 1;
5641 /* Parameter expand NAME, and return a new string which is the expansion,
5642 or NULL if there was no expansion.
5643 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
5644 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
5645 NAME was found inside of a double-quoted expression. */
5647 parameter_brace_expand_word (name
, var_is_special
, quoted
, pflags
, indp
)
5649 int var_is_special
, quoted
, pflags
;
5666 /* Handle multiple digit arguments, as in ${11}. */
5667 if (legal_number (name
, &arg_index
))
5669 tt
= get_dollar_var_value (arg_index
);
5671 temp
= (*tt
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5673 : quote_escapes (tt
);
5675 temp
= (char *)NULL
;
5678 else if (var_is_special
) /* ${@} */
5681 tt
= (char *)xmalloc (2 + strlen (name
));
5682 tt
[sindex
= 0] = '$';
5683 strcpy (tt
+ 1, name
);
5685 ret
= param_expand (tt
, &sindex
, quoted
, (int *)NULL
, (int *)NULL
,
5686 (int *)NULL
, (int *)NULL
, pflags
);
5689 #if defined (ARRAY_VARS)
5690 else if (valid_array_reference (name
))
5693 /* XXX - does this leak if name[@] or name[*]? */
5694 temp
= array_value (name
, quoted
, 0, &atype
, &ind
);
5695 if (atype
== 0 && temp
)
5697 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5698 ? quote_string (temp
)
5699 : quote_escapes (temp
);
5700 rflags
|= W_ARRAYIND
;
5704 else if (atype
== 1 && temp
&& QUOTED_NULL (temp
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5705 rflags
|= W_HASQUOTEDNULL
;
5708 else if (var
= find_variable (name
))
5710 if (var_isset (var
) && invisible_p (var
) == 0)
5712 #if defined (ARRAY_VARS)
5714 temp
= assoc_reference (assoc_cell (var
), "0");
5715 else if (array_p (var
))
5716 temp
= array_reference (array_cell (var
), 0);
5718 temp
= value_cell (var
);
5720 temp
= value_cell (var
);
5724 temp
= (*temp
&& (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
5725 ? quote_string (temp
)
5726 : quote_escapes (temp
);
5729 temp
= (char *)NULL
;
5731 #if defined (ARRAY_VARS)
5732 /* Handle expanding nameref whose value is x[n] */
5733 else if (var
= find_variable_last_nameref (name
))
5735 temp
= nameref_cell (var
);
5736 if (temp
&& *temp
&& valid_array_reference (temp
))
5739 goto expand_arrayref
;
5741 temp
= (char *)NULL
;
5745 temp
= (char *)NULL
;
5749 ret
= alloc_word_desc ();
5751 ret
->flags
|= rflags
;
5756 /* Expand an indirect reference to a variable: ${!NAME} expands to the
5757 value of the variable whose name is the value of NAME. */
5759 parameter_brace_expand_indir (name
, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
5761 int var_is_special
, quoted
;
5762 int *quoted_dollar_atp
, *contains_dollar_at
;
5768 /* See if it's a nameref first, behave in ksh93-compatible fashion.
5769 There is at least one incompatibility: given ${!foo[0]} where foo=bar,
5770 bash performs an indirect lookup on foo[0] and expands the result;
5771 ksh93 expands bar[0]. We could do that here -- there are enough usable
5772 primitives to do that -- but do not at this point. */
5773 if (var_is_special
== 0 && (v
= find_variable_last_nameref (name
)))
5775 if (nameref_p (v
) && (t
= nameref_cell (v
)) && *t
)
5777 w
= alloc_word_desc ();
5778 w
->word
= savestring (t
);
5784 w
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
, 0);
5786 /* Have to dequote here if necessary */
5789 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
5790 ? dequote_string (t
)
5791 : dequote_escapes (t
);
5795 dispose_word_desc (w
);
5797 chk_atstar (t
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
5799 return (WORD_DESC
*)NULL
;
5801 w
= parameter_brace_expand_word (t
, SPECIAL_VAR(t
, 0), quoted
, 0, 0);
5807 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
5808 depending on the value of C, the separating character. C can be one of
5809 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
5810 between double quotes. */
5812 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
5814 int c
, quoted
, *qdollaratp
, *hasdollarat
;
5818 char *t
, *t1
, *temp
;
5821 /* If the entire expression is between double quotes, we want to treat
5822 the value as a double-quoted string, with the exception that we strip
5823 embedded unescaped double quotes (for sh backwards compatibility). */
5824 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *value
)
5827 temp
= string_extract_double_quoted (value
, &hasdol
, 1);
5832 w
= alloc_word_desc ();
5834 /* XXX was 0 not quoted */
5835 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
5838 *hasdollarat
= hasdol
|| (l
&& l
->next
);
5843 /* The expansion of TEMP returned something. We need to treat things
5844 slightly differently if HASDOL is non-zero. If we have "$@", the
5845 individual words have already been quoted. We need to turn them
5846 into a string with the words separated by the first character of
5847 $IFS without any additional quoting, so string_list_dollar_at won't
5848 do the right thing. We use string_list_dollar_star instead. */
5849 temp
= (hasdol
|| l
->next
) ? string_list_dollar_star (l
) : string_list (l
);
5851 /* If l->next is not null, we know that TEMP contained "$@", since that
5852 is the only expansion that creates more than one word. */
5853 if (qdollaratp
&& ((hasdol
&& quoted
) || l
->next
))
5855 /* If we have a quoted null result (QUOTED_NULL(temp)) and the word is
5856 a quoted null (l->next == 0 && QUOTED_NULL(l->word->word)), the
5857 flags indicate it (l->word->flags & W_HASQUOTEDNULL), and the
5858 expansion is quoted (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5859 (which is more paranoia than anything else), we need to return the
5860 quoted null string and set the flags to indicate it. */
5861 if (l
->next
== 0 && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && QUOTED_NULL (temp
) && QUOTED_NULL (l
->word
->word
) && (l
->word
->flags
& W_HASQUOTEDNULL
))
5863 w
->flags
|= W_HASQUOTEDNULL
;
5867 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
5869 /* The brace expansion occurred between double quotes and there was
5870 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
5871 it does not expand to anything. In this case, we want to return
5872 a quoted empty string. */
5873 temp
= make_quoted_char ('\0');
5874 w
->flags
|= W_HASQUOTEDNULL
;
5877 temp
= (char *)NULL
;
5879 if (c
== '-' || c
== '+')
5886 t
= temp
? savestring (temp
) : savestring ("");
5887 t1
= dequote_string (t
);
5889 #if defined (ARRAY_VARS)
5890 if (valid_array_reference (name
))
5891 assign_array_element (name
, t1
, 0);
5893 #endif /* ARRAY_VARS */
5894 bind_variable (name
, t1
, 0);
5896 /* From Posix group discussion Feb-March 2010. Issue 7 0000221 */
5903 /* Deal with the right hand side of a ${name:?value} expansion in the case
5904 that NAME is null or not set. If VALUE is non-null it is expanded and
5905 used as the error message to print, otherwise a standard message is
5908 parameter_brace_expand_error (name
, value
)
5914 last_command_exit_value
= EXECUTION_FAILURE
; /* ensure it's non-zero */
5915 if (value
&& *value
)
5917 l
= expand_string (value
, 0);
5918 temp
= string_list (l
);
5919 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
5924 report_error (_("%s: parameter null or not set"), name
);
5926 /* Free the data we have allocated during this expansion, since we
5927 are about to longjmp out. */
5932 /* Return 1 if NAME is something for which parameter_brace_expand_length is
5935 valid_length_expression (name
)
5938 return (name
[1] == '\0' || /* ${#} */
5939 ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0') || /* special param */
5940 (DIGIT (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
5941 #if defined (ARRAY_VARS)
5942 valid_array_reference (name
+ 1) || /* ${#a[7]} */
5944 legal_identifier (name
+ 1)); /* ${#PS1} */
5947 /* Handle the parameter brace expansion that requires us to return the
5948 length of a parameter. */
5950 parameter_brace_expand_length (name
)
5954 intmax_t number
, arg_index
;
5956 #if defined (ARRAY_VARS)
5960 if (name
[1] == '\0') /* ${#} */
5961 number
= number_of_args ();
5962 else if ((name
[1] == '@' || name
[1] == '*') && name
[2] == '\0') /* ${#@}, ${#*} */
5963 number
= number_of_args ();
5964 else if ((sh_syntaxtab
[(unsigned char) name
[1]] & CSPECVAR
) && name
[2] == '\0')
5966 /* Take the lengths of some of the shell's special parameters. */
5970 t
= which_set_flags ();
5973 t
= itos (last_command_exit_value
);
5976 t
= itos (dollar_dollar_pid
);
5979 if (last_asynchronous_pid
== NO_PID
)
5980 t
= (char *)NULL
; /* XXX - error if set -u set? */
5982 t
= itos (last_asynchronous_pid
);
5985 t
= itos (number_of_args ());
5988 number
= STRLEN (t
);
5991 #if defined (ARRAY_VARS)
5992 else if (valid_array_reference (name
+ 1))
5993 number
= array_length_reference (name
+ 1);
5994 #endif /* ARRAY_VARS */
5999 if (legal_number (name
+ 1, &arg_index
)) /* ${#1} */
6001 t
= get_dollar_var_value (arg_index
);
6002 if (t
== 0 && unbound_vars_is_error
)
6004 number
= MB_STRLEN (t
);
6007 #if defined (ARRAY_VARS)
6008 else if ((var
= find_variable (name
+ 1)) && (invisible_p (var
) == 0) && (array_p (var
) || assoc_p (var
)))
6011 t
= assoc_reference (assoc_cell (var
), "0");
6013 t
= array_reference (array_cell (var
), 0);
6014 if (t
== 0 && unbound_vars_is_error
)
6016 number
= MB_STRLEN (t
);
6021 newname
= savestring (name
);
6023 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
6024 t
= list
? string_list (list
) : (char *)NULL
;
6027 dispose_words (list
);
6029 number
= t
? MB_STRLEN (t
) : 0;
6037 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
6038 so we do some ad-hoc parsing of an arithmetic expression to find
6039 the first DELIM, instead of using strchr(3). Two rules:
6040 1. If the substring contains a `(', read until closing `)'.
6041 2. If the substring contains a `?', read past one `:' for each `?'.
6045 skiparith (substr
, delim
)
6050 int skipcol
, pcount
, i
;
6053 sublen
= strlen (substr
);
6054 i
= skipcol
= pcount
= 0;
6057 /* Balance parens */
6058 if (substr
[i
] == LPAREN
)
6064 if (substr
[i
] == RPAREN
&& pcount
)
6072 ADVANCE_CHAR (substr
, sublen
, i
);
6076 /* Skip one `:' for each `?' */
6077 if (substr
[i
] == ':' && skipcol
)
6083 if (substr
[i
] == delim
)
6085 if (substr
[i
] == '?')
6091 ADVANCE_CHAR (substr
, sublen
, i
);
6094 return (substr
+ i
);
6097 /* Verify and limit the start and end of the desired substring. If
6098 VTYPE == 0, a regular shell variable is being used; if it is 1,
6099 then the positional parameters are being used; if it is 2, then
6100 VALUE is really a pointer to an array variable that should be used.
6101 Return value is 1 if both values were OK, 0 if there was a problem
6102 with an invalid expression, or -1 if the values were out of range. */
6104 verify_substring_values (v
, value
, substr
, vtype
, e1p
, e2p
)
6106 char *value
, *substr
;
6108 intmax_t *e1p
, *e2p
;
6110 char *t
, *temp1
, *temp2
;
6113 #if defined (ARRAY_VARS)
6118 /* duplicate behavior of strchr(3) */
6119 t
= skiparith (substr
, ':');
6120 if (*t
&& *t
== ':')
6125 temp1
= expand_arith_string (substr
, Q_DOUBLE_QUOTES
);
6126 *e1p
= evalexp (temp1
, &expok
);
6131 len
= -1; /* paranoia */
6135 case VT_ARRAYMEMBER
:
6136 len
= MB_STRLEN (value
);
6139 len
= number_of_args () + 1;
6141 len
++; /* add one arg if counting from $0 */
6143 #if defined (ARRAY_VARS)
6145 /* For arrays, the first value deals with array indices. Negative
6146 offsets count from one past the array's maximum index. Associative
6147 arrays treat the number of elements as the maximum index. */
6151 len
= assoc_num_elements (h
) + (*e1p
< 0);
6156 len
= array_max_index (a
) + (*e1p
< 0); /* arrays index from 0 to n - 1 */
6162 if (len
== -1) /* paranoia */
6165 if (*e1p
< 0) /* negative offsets count from end */
6168 if (*e1p
> len
|| *e1p
< 0)
6171 #if defined (ARRAY_VARS)
6172 /* For arrays, the second offset deals with the number of elements. */
6173 if (vtype
== VT_ARRAYVAR
)
6174 len
= assoc_p (v
) ? assoc_num_elements (h
) : array_num_elements (a
);
6180 temp2
= savestring (t
);
6181 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
6184 *e2p
= evalexp (temp1
, &expok
);
6189 if ((vtype
== VT_ARRAYVAR
|| vtype
== VT_POSPARMS
) && *e2p
< 0)
6191 /* bash-4.3: allow positional parameter length < 0 to count backwards
6192 from end of positional parameters */
6193 if (vtype
== VT_ARRAYVAR
&& *e2p
< 0)
6196 internal_error (_("%s: substring expression < 0"), t
);
6199 #if defined (ARRAY_VARS)
6200 /* In order to deal with sparse arrays, push the intelligence about how
6201 to deal with the number of elements desired down to the array-
6202 specific functions. */
6203 if (vtype
!= VT_ARRAYVAR
)
6209 if (*e2p
< 0 || *e2p
< *e1p
)
6211 internal_error (_("%s: substring expression < 0"), t
);
6216 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
6227 /* Return the type of variable specified by VARNAME (simple variable,
6228 positional param, or array variable). Also return the value specified
6229 by VARNAME (value of a variable or a reference to an array element).
6230 QUOTED is the standard description of quoting state, using Q_* defines.
6231 FLAGS is currently a set of flags to pass to array_value. If IND is
6232 non-null and not INTMAX_MIN, and FLAGS includes AV_USEIND, IND is
6233 passed to array_value so the array index is not computed again.
6234 If this returns VT_VARIABLE, the caller assumes that CTLESC and CTLNUL
6235 characters in the value are quoted with CTLESC and takes appropriate
6236 steps. For convenience, *VALP is set to the dequoted VALUE. */
6238 get_var_and_type (varname
, value
, ind
, quoted
, flags
, varp
, valp
)
6239 char *varname
, *value
;
6247 #if defined (ARRAY_VARS)
6252 /* This sets vtype to VT_VARIABLE or VT_POSPARMS */
6253 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0';
6254 if (vtype
== VT_POSPARMS
&& varname
[0] == '*')
6255 vtype
|= VT_STARSUB
;
6256 *varp
= (SHELL_VAR
*)NULL
;
6258 #if defined (ARRAY_VARS)
6259 if (valid_array_reference (varname
))
6261 v
= array_variable_part (varname
, &temp
, (int *)0);
6262 /* If we want to signal array_value to use an already-computed index,
6263 set LIND to that index */
6264 lind
= (ind
!= INTMAX_MIN
&& (flags
& AV_USEIND
)) ? ind
: 0;
6265 if (v
&& (array_p (v
) || assoc_p (v
)))
6267 if (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']')
6269 /* Callers have to differentiate betwen indexed and associative */
6270 vtype
= VT_ARRAYVAR
;
6272 vtype
|= VT_STARSUB
;
6273 *valp
= array_p (v
) ? (char *)array_cell (v
) : (char *)assoc_cell (v
);
6277 vtype
= VT_ARRAYMEMBER
;
6278 *valp
= array_value (varname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6282 else if (v
&& (ALL_ELEMENT_SUB (temp
[0]) && temp
[1] == ']'))
6284 vtype
= VT_VARIABLE
;
6286 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6287 *valp
= dequote_string (value
);
6289 *valp
= dequote_escapes (value
);
6293 vtype
= VT_ARRAYMEMBER
;
6295 *valp
= array_value (varname
, Q_DOUBLE_QUOTES
, flags
, (int *)NULL
, &lind
);
6298 else if ((v
= find_variable (varname
)) && (invisible_p (v
) == 0) && (assoc_p (v
) || array_p (v
)))
6300 vtype
= VT_ARRAYMEMBER
;
6302 *valp
= assoc_p (v
) ? assoc_reference (assoc_cell (v
), "0") : array_reference (array_cell (v
), 0);
6307 if (value
&& vtype
== VT_VARIABLE
)
6309 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6310 *valp
= dequote_string (value
);
6312 *valp
= dequote_escapes (value
);
6321 /******************************************************/
6323 /* Functions to extract substrings of variable values */
6325 /******************************************************/
6327 #if defined (HANDLE_MULTIBYTE)
6328 /* Character-oriented rather than strictly byte-oriented substrings. S and
6329 E, rather being strict indices into STRING, indicate character (possibly
6330 multibyte character) positions that require calculation.
6331 Used by the ${param:offset[:length]} expansion. */
6333 mb_substring (string
, s
, e
)
6338 int start
, stop
, i
, slen
;
6342 /* Don't need string length in ADVANCE_CHAR unless multibyte chars possible. */
6343 slen
= (MB_CUR_MAX
> 1) ? STRLEN (string
) : 0;
6346 while (string
[start
] && i
--)
6347 ADVANCE_CHAR (string
, slen
, start
);
6350 while (string
[stop
] && i
--)
6351 ADVANCE_CHAR (string
, slen
, stop
);
6352 tt
= substring (string
, start
, stop
);
6357 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
6358 is `@', use the positional parameters; otherwise, use the value of
6359 VARNAME. If VARNAME is an array variable, use the array elements. */
6362 parameter_brace_substring (varname
, value
, ind
, substr
, quoted
, flags
)
6363 char *varname
, *value
;
6369 int vtype
, r
, starsub
;
6370 char *temp
, *val
, *tt
, *oname
;
6374 return ((char *)NULL
);
6376 oname
= this_command_name
;
6377 this_command_name
= varname
;
6379 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6382 this_command_name
= oname
;
6383 return ((char *)NULL
);
6386 starsub
= vtype
& VT_STARSUB
;
6387 vtype
&= ~VT_STARSUB
;
6389 r
= verify_substring_values (v
, val
, substr
, vtype
, &e1
, &e2
);
6390 this_command_name
= oname
;
6393 if (vtype
== VT_VARIABLE
)
6395 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
6401 case VT_ARRAYMEMBER
:
6402 #if defined (HANDLE_MULTIBYTE)
6404 tt
= mb_substring (val
, e1
, e2
);
6407 tt
= substring (val
, e1
, e2
);
6409 if (vtype
== VT_VARIABLE
)
6411 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
6412 temp
= quote_string (tt
);
6414 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6418 tt
= pos_params (varname
, e1
, e2
, quoted
);
6419 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
6421 temp
= tt
? quote_escapes (tt
) : (char *)NULL
;
6427 #if defined (ARRAY_VARS)
6430 /* we convert to list and take first e2 elements starting at e1th
6431 element -- officially undefined for now */
6432 temp
= assoc_subrange (assoc_cell (v
), e1
, e2
, starsub
, quoted
);
6434 /* We want E2 to be the number of elements desired (arrays can be sparse,
6435 so verify_substring_values just returns the numbers specified and we
6436 rely on array_subrange to understand how to deal with them). */
6437 temp
= array_subrange (array_cell (v
), e1
, e2
, starsub
, quoted
);
6438 /* array_subrange now calls array_quote_escapes as appropriate, so the
6439 caller no longer needs to. */
6443 temp
= (char *)NULL
;
6449 /****************************************************************/
6451 /* Functions to perform pattern substitution on variable values */
6453 /****************************************************************/
6456 shouldexp_replacement (s
)
6461 for (p
= s
; p
&& *p
; p
++)
6472 pat_subst (string
, pat
, rep
, mflags
)
6473 char *string
, *pat
, *rep
;
6476 char *ret
, *s
, *e
, *str
, *rstr
, *mstr
;
6477 int rsize
, rptr
, l
, replen
, mtype
, rxpand
, rslen
, mlen
;
6480 return (savestring (""));
6482 mtype
= mflags
& MATCH_TYPEMASK
;
6484 #if 0 /* bash-4.2 ? */
6485 rxpand
= (rep
&& *rep
) ? shouldexp_replacement (rep
) : 0;
6491 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
6492 * with REP and return the result.
6493 * 2. A null pattern with mtype == MATCH_END means to append REP to
6494 * STRING and return the result.
6495 * These don't understand or process `&' in the replacement string.
6497 if ((pat
== 0 || *pat
== 0) && (mtype
== MATCH_BEG
|| mtype
== MATCH_END
))
6499 replen
= STRLEN (rep
);
6500 l
= STRLEN (string
);
6501 ret
= (char *)xmalloc (replen
+ l
+ 2);
6503 strcpy (ret
, string
);
6504 else if (mtype
== MATCH_BEG
)
6507 strcpy (ret
+ replen
, string
);
6511 strcpy (ret
, string
);
6512 strcpy (ret
+ l
, rep
);
6517 ret
= (char *)xmalloc (rsize
= 64);
6520 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
6522 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
6530 mstr
= xmalloc (mlen
+ 1);
6531 for (x
= 0; x
< mlen
; x
++)
6534 rstr
= strcreplace (rep
, '&', mstr
, 0);
6535 rslen
= strlen (rstr
);
6543 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ rslen
), rsize
, 64);
6545 /* OK, now copy the leading unmatched portion of the string (from
6546 str to s) to ret starting at rptr (the current offset). Then copy
6547 the replacement string at ret + rptr + (s - str). Increment
6548 rptr (if necessary) and str and go on. */
6551 strncpy (ret
+ rptr
, str
, l
);
6556 strncpy (ret
+ rptr
, rstr
, rslen
);
6559 str
= e
; /* e == end of match */
6564 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
6569 /* On a zero-length match, make sure we copy one character, since
6570 we increment one character to avoid infinite recursion. */
6571 RESIZE_MALLOCED_BUFFER (ret
, rptr
, 1, rsize
, 64);
6572 ret
[rptr
++] = *str
++;
6573 e
++; /* avoid infinite recursion on zero-length match */
6577 /* Now copy the unmatched portion of the input string */
6580 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
6581 strcpy (ret
+ rptr
, str
);
6589 /* Do pattern match and replacement on the positional parameters. */
6591 pos_params_pat_subst (string
, pat
, rep
, mflags
)
6592 char *string
, *pat
, *rep
;
6595 WORD_LIST
*save
, *params
;
6600 save
= params
= list_rest_of_args ();
6602 return ((char *)NULL
);
6604 for ( ; params
; params
= params
->next
)
6606 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
6607 w
= alloc_word_desc ();
6608 w
->word
= ret
? ret
: savestring ("");
6609 dispose_word (params
->word
);
6613 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6614 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6617 if ((mflags
& (MATCH_QUOTED
|MATCH_STARSUB
)) == (MATCH_QUOTED
|MATCH_STARSUB
))
6618 ret
= string_list_dollar_star (quote_list (save
));
6619 else if ((mflags
& MATCH_STARSUB
) == MATCH_STARSUB
)
6620 ret
= string_list_dollar_star (save
);
6621 else if ((mflags
& MATCH_QUOTED
) == MATCH_QUOTED
)
6622 ret
= string_list_dollar_at (save
, qflags
);
6624 ret
= string_list_dollar_star (save
);
6626 ret
= string_list_pos_params (pchar
, save
, qflags
);
6629 dispose_words (save
);
6634 /* Perform pattern substitution on VALUE, which is the expansion of
6635 VARNAME. PATSUB is an expression supplying the pattern to match
6636 and the string to substitute. QUOTED is a flags word containing
6637 the type of quoting currently in effect. */
6639 parameter_brace_patsub (varname
, value
, ind
, patsub
, quoted
, flags
)
6640 char *varname
, *value
;
6645 int vtype
, mflags
, starsub
, delim
;
6646 char *val
, *temp
, *pat
, *rep
, *p
, *lpatsub
, *tt
;
6650 return ((char *)NULL
);
6652 this_command_name
= varname
;
6654 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6656 return ((char *)NULL
);
6658 starsub
= vtype
& VT_STARSUB
;
6659 vtype
&= ~VT_STARSUB
;
6662 /* PATSUB is never NULL when this is called. */
6665 mflags
|= MATCH_GLOBREP
;
6669 /* Malloc this because expand_string_if_necessary or one of the expansion
6670 functions in its call chain may free it on a substitution error. */
6671 lpatsub
= savestring (patsub
);
6673 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6674 mflags
|= MATCH_QUOTED
;
6677 mflags
|= MATCH_STARSUB
;
6679 /* If the pattern starts with a `/', make sure we skip over it when looking
6680 for the replacement delimiter. */
6681 delim
= skip_to_delim (lpatsub
, ((*patsub
== '/') ? 1 : 0), "/", 0);
6682 if (lpatsub
[delim
] == '/')
6685 rep
= lpatsub
+ delim
+ 1;
6690 if (rep
&& *rep
== '\0')
6693 /* Perform the same expansions on the pattern as performed by the
6694 pattern removal expansions. */
6695 pat
= getpattern (lpatsub
, quoted
, 1);
6698 /* We want to perform quote removal on the expanded replacement even if
6699 the entire expansion is double-quoted because the parser and string
6700 extraction functions treated quotes in the replacement string as
6702 rep
= expand_string_if_necessary (rep
, quoted
& ~(Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
), expand_string_unsplit
);
6704 /* ksh93 doesn't allow the match specifier to be a part of the expanded
6705 pattern. This is an extension. Make sure we don't anchor the pattern
6706 at the beginning or end of the string if we're doing global replacement,
6709 if (mflags
& MATCH_GLOBREP
)
6710 mflags
|= MATCH_ANY
;
6711 else if (pat
&& pat
[0] == '#')
6713 mflags
|= MATCH_BEG
;
6716 else if (pat
&& pat
[0] == '%')
6718 mflags
|= MATCH_END
;
6722 mflags
|= MATCH_ANY
;
6724 /* OK, we now want to substitute REP for PAT in VAL. If
6725 flags & MATCH_GLOBREP is non-zero, the substitution is done
6726 everywhere, otherwise only the first occurrence of PAT is
6727 replaced. The pattern matching code doesn't understand
6728 CTLESC quoting CTLESC and CTLNUL so we use the dequoted variable
6729 values passed in (VT_VARIABLE) so the pattern substitution
6730 code works right. We need to requote special chars after
6731 we're done for VT_VARIABLE and VT_ARRAYMEMBER, and for the
6732 other cases if QUOTED == 0, since the posparams and arrays
6733 indexed by * or @ do special things when QUOTED != 0. */
6738 case VT_ARRAYMEMBER
:
6739 temp
= pat_subst (val
, p
, rep
, mflags
);
6740 if (vtype
== VT_VARIABLE
)
6744 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6750 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
6751 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6753 tt
= quote_escapes (temp
);
6758 #if defined (ARRAY_VARS)
6760 temp
= assoc_p (v
) ? assoc_patsub (assoc_cell (v
), p
, rep
, mflags
)
6761 : array_patsub (array_cell (v
), p
, rep
, mflags
);
6762 /* Don't call quote_escapes anymore; array_patsub calls
6763 array_quote_escapes as appropriate before adding the
6764 space separators; ditto for assoc_patsub. */
6776 /****************************************************************/
6778 /* Functions to perform case modification on variable values */
6780 /****************************************************************/
6782 /* Do case modification on the positional parameters. */
6785 pos_params_modcase (string
, pat
, modop
, mflags
)
6790 WORD_LIST
*save
, *params
;
6795 save
= params
= list_rest_of_args ();
6797 return ((char *)NULL
);
6799 for ( ; params
; params
= params
->next
)
6801 ret
= sh_modcase (params
->word
->word
, pat
, modop
);
6802 w
= alloc_word_desc ();
6803 w
->word
= ret
? ret
: savestring ("");
6804 dispose_word (params
->word
);
6808 pchar
= (mflags
& MATCH_STARSUB
) == MATCH_STARSUB
? '*' : '@';
6809 qflags
= (mflags
& MATCH_QUOTED
) == MATCH_QUOTED
? Q_DOUBLE_QUOTES
: 0;
6811 ret
= string_list_pos_params (pchar
, save
, qflags
);
6812 dispose_words (save
);
6817 /* Perform case modification on VALUE, which is the expansion of
6818 VARNAME. MODSPEC is an expression supplying the type of modification
6819 to perform. QUOTED is a flags word containing the type of quoting
6820 currently in effect. */
6822 parameter_brace_casemod (varname
, value
, ind
, modspec
, patspec
, quoted
, flags
)
6823 char *varname
, *value
;
6828 int vtype
, starsub
, modop
, mflags
, x
;
6829 char *val
, *temp
, *pat
, *p
, *lpat
, *tt
;
6833 return ((char *)NULL
);
6835 this_command_name
= varname
;
6837 vtype
= get_var_and_type (varname
, value
, ind
, quoted
, flags
, &v
, &val
);
6839 return ((char *)NULL
);
6841 starsub
= vtype
& VT_STARSUB
;
6842 vtype
&= ~VT_STARSUB
;
6846 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
6847 mflags
|= MATCH_QUOTED
;
6849 mflags
|= MATCH_STARSUB
;
6854 x
= p
&& p
[0] == modspec
;
6855 modop
= x
? CASE_UPPER
: CASE_UPFIRST
;
6858 else if (modspec
== ',')
6860 x
= p
&& p
[0] == modspec
;
6861 modop
= x
? CASE_LOWER
: CASE_LOWFIRST
;
6864 else if (modspec
== '~')
6866 x
= p
&& p
[0] == modspec
;
6867 modop
= x
? CASE_TOGGLEALL
: CASE_TOGGLE
;
6871 lpat
= p
? savestring (p
) : 0;
6872 /* Perform the same expansions on the pattern as performed by the
6873 pattern removal expansions. FOR LATER */
6874 pat
= lpat
? getpattern (lpat
, quoted
, 1) : 0;
6876 /* OK, now we do the case modification. */
6880 case VT_ARRAYMEMBER
:
6881 temp
= sh_modcase (val
, pat
, modop
);
6882 if (vtype
== VT_VARIABLE
)
6886 tt
= (mflags
& MATCH_QUOTED
) ? quote_string (temp
) : quote_escapes (temp
);
6893 temp
= pos_params_modcase (val
, pat
, modop
, mflags
);
6894 if (temp
&& (mflags
& MATCH_QUOTED
) == 0)
6896 tt
= quote_escapes (temp
);
6902 #if defined (ARRAY_VARS)
6904 temp
= assoc_p (v
) ? assoc_modcase (assoc_cell (v
), pat
, modop
, mflags
)
6905 : array_modcase (array_cell (v
), pat
, modop
, mflags
);
6906 /* Don't call quote_escapes; array_modcase calls array_quote_escapes
6907 as appropriate before adding the space separators; ditto for
6919 /* Check for unbalanced parens in S, which is the contents of $(( ... )). If
6920 any occur, this must be a nested command substitution, so return 0.
6921 Otherwise, return 1. A valid arithmetic expression must always have a
6922 ( before a matching ), so any cases where there are more right parens
6923 means that this must not be an arithmetic expression, though the parser
6924 will not accept it without a balanced total number of parens. */
6926 chk_arithsub (s
, len
)
6938 else if (s
[i
] == RPAREN
)
6948 ADVANCE_CHAR (s
, len
, i
);
6954 ADVANCE_CHAR (s
, len
, i
);
6958 i
= skip_single_quoted (s
, len
, ++i
);
6962 i
= skip_double_quoted ((char *)s
, len
, ++i
);
6967 return (count
== 0);
6970 /****************************************************************/
6972 /* Functions to perform parameter expansion on a string */
6974 /****************************************************************/
6976 /* ${[#][!]name[[:][^[^]][,[,]]#[#]%[%]-=?+[word][:e1[:e2]]]} */
6978 parameter_brace_expand (string
, indexp
, quoted
, pflags
, quoted_dollar_atp
, contains_dollar_at
)
6980 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
, pflags
;
6982 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
6983 int want_substring
, want_indir
, want_patsub
, want_casemod
;
6984 char *name
, *value
, *temp
, *temp1
;
6985 WORD_DESC
*tdesc
, *ret
;
6986 int t_index
, sindex
, c
, tflag
, modspec
;
6990 temp
= temp1
= value
= (char *)NULL
;
6991 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
6992 want_substring
= want_indir
= want_patsub
= want_casemod
= 0;
6996 /* ${#var} doesn't have any of the other parameter expansions on it. */
6997 if (string
[t_index
] == '#' && legal_variable_starter (string
[t_index
+1])) /* {{ */
6998 name
= string_extract (string
, &t_index
, "}", SX_VARNAME
);
7000 #if defined (CASEMOD_EXPANSIONS)
7001 /* To enable case-toggling expansions using the `~' operator character
7002 change the 1 to 0. */
7003 # if defined (CASEMOD_CAPCASE)
7004 name
= string_extract (string
, &t_index
, "#%^,~:-=?+/}", SX_VARNAME
);
7006 name
= string_extract (string
, &t_index
, "#%^,:-=?+/}", SX_VARNAME
);
7007 # endif /* CASEMOD_CAPCASE */
7009 name
= string_extract (string
, &t_index
, "#%:-=?+/}", SX_VARNAME
);
7010 #endif /* CASEMOD_EXPANSIONS */
7017 /* If the name really consists of a special variable, then make sure
7018 that we have the entire name. We don't allow indirect references
7019 to special variables except `#', `?', `@' and `*'. */
7020 if ((sindex
== t_index
&& VALID_SPECIAL_LENGTH_PARAM (string
[t_index
])) ||
7021 (sindex
== t_index
- 1 && string
[sindex
] == '!' && VALID_INDIR_PARAM (string
[t_index
])))
7024 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
7025 name
= (char *)xrealloc (name
, 3 + (strlen (temp1
)));
7026 *name
= string
[sindex
];
7027 if (string
[sindex
] == '!')
7029 /* indirect reference of $#, $?, $@, or $* */
7030 name
[1] = string
[sindex
+ 1];
7031 strcpy (name
+ 2, temp1
);
7034 strcpy (name
+ 1, temp1
);
7039 /* Find out what character ended the variable name. Then
7040 do the appropriate thing. */
7041 if (c
= string
[sindex
])
7044 /* If c is followed by one of the valid parameter expansion
7045 characters, move past it as normal. If not, assume that
7046 a substring specification is being given, and do not move
7048 if (c
== ':' && VALID_PARAM_EXPAND_CHAR (string
[sindex
]))
7051 if (c
= string
[sindex
])
7054 else if (c
== ':' && string
[sindex
] != RBRACE
)
7056 else if (c
== '/' /* && string[sindex] != RBRACE */) /* XXX */
7058 #if defined (CASEMOD_EXPANSIONS)
7059 else if (c
== '^' || c
== ',' || c
== '~')
7066 /* Catch the valid and invalid brace expressions that made it through the
7068 /* ${#-} is a valid expansion and means to take the length of $-.
7069 Similarly for ${#?} and ${##}... */
7070 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7071 VALID_SPECIAL_LENGTH_PARAM (c
) && string
[sindex
] == RBRACE
)
7073 name
= (char *)xrealloc (name
, 3);
7076 c
= string
[sindex
++];
7079 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
7080 if (name
[0] == '#' && name
[1] == '\0' && check_nullness
== 0 &&
7081 member (c
, "%:=+/") && string
[sindex
] == RBRACE
)
7083 temp
= (char *)NULL
;
7084 goto bad_substitution
;
7087 /* Indirect expansion begins with a `!'. A valid indirect expansion is
7088 either a variable name, one of the positional parameters or a special
7089 variable that expands to one of the positional parameters. */
7090 want_indir
= *name
== '!' &&
7091 (legal_variable_starter ((unsigned char)name
[1]) || DIGIT (name
[1])
7092 || VALID_INDIR_PARAM (name
[1]));
7094 /* Determine the value of this variable. */
7096 /* Check for special variables, directly referenced. */
7097 if (SPECIAL_VAR (name
, want_indir
))
7100 /* Check for special expansion things, like the length of a parameter */
7101 if (*name
== '#' && name
[1])
7103 /* If we are not pointing at the character just after the
7104 closing brace, then we haven't gotten all of the name.
7105 Since it begins with a special character, this is a bad
7106 substitution. Also check NAME for validity before trying
7108 if (string
[sindex
- 1] != RBRACE
|| (valid_length_expression (name
) == 0))
7110 temp
= (char *)NULL
;
7111 goto bad_substitution
;
7114 number
= parameter_brace_expand_length (name
);
7115 if (number
== INTMAX_MIN
&& unbound_vars_is_error
)
7117 last_command_exit_value
= EXECUTION_FAILURE
;
7118 err_unboundvar (name
+1);
7120 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7126 return (&expand_wdesc_error
);
7129 ret
= alloc_word_desc ();
7130 ret
->word
= itos (number
);
7135 /* ${@} is identical to $@. */
7136 if (name
[0] == '@' && name
[1] == '\0')
7138 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7139 *quoted_dollar_atp
= 1;
7141 if (contains_dollar_at
)
7142 *contains_dollar_at
= 1;
7144 tflag
|= W_DOLLARAT
;
7147 /* Process ${!PREFIX*} expansion. */
7148 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7149 (string
[sindex
- 2] == '*' || string
[sindex
- 2] == '@') &&
7150 legal_variable_starter ((unsigned char) name
[1]))
7155 temp1
= savestring (name
+ 1);
7156 number
= strlen (temp1
);
7157 temp1
[number
- 1] = '\0';
7158 x
= all_variables_matching_prefix (temp1
);
7159 xlist
= strvec_to_word_list (x
, 0, 0);
7160 if (string
[sindex
- 2] == '*')
7161 temp
= string_list_dollar_star (xlist
);
7164 temp
= string_list_dollar_at (xlist
, quoted
);
7165 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7166 *quoted_dollar_atp
= 1;
7167 if (contains_dollar_at
)
7168 *contains_dollar_at
= 1;
7170 tflag
|= W_DOLLARAT
;
7173 dispose_words (xlist
);
7179 ret
= alloc_word_desc ();
7181 ret
->flags
= tflag
; /* XXX */
7185 #if defined (ARRAY_VARS)
7186 /* Process ${!ARRAY[@]} and ${!ARRAY[*]} expansion. */ /* [ */
7187 if (want_indir
&& string
[sindex
- 1] == RBRACE
&&
7188 string
[sindex
- 2] == ']' && valid_array_reference (name
+1))
7192 temp1
= savestring (name
+ 1);
7193 x
= array_variable_name (temp1
, &x1
, (int *)0); /* [ */
7195 if (ALL_ELEMENT_SUB (x1
[0]) && x1
[1] == ']')
7197 temp
= array_keys (temp1
, quoted
); /* handles assoc vars too */
7200 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7201 *quoted_dollar_atp
= 1;
7202 if (contains_dollar_at
)
7203 *contains_dollar_at
= 1;
7205 tflag
|= W_DOLLARAT
;
7211 ret
= alloc_word_desc ();
7213 ret
->flags
= tflag
; /* XXX */
7219 #endif /* ARRAY_VARS */
7221 /* Make sure that NAME is valid before trying to go on. */
7222 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
7223 var_is_special
) == 0)
7225 temp
= (char *)NULL
;
7226 goto bad_substitution
;
7230 tdesc
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7232 tdesc
= parameter_brace_expand_word (name
, var_is_special
, quoted
, PF_IGNUNBOUND
|(pflags
&PF_NOSPLIT2
), &ind
);
7237 tflag
= tdesc
->flags
;
7238 dispose_word_desc (tdesc
);
7243 #if defined (ARRAY_VARS)
7244 if (valid_array_reference (name
))
7245 chk_atstar (name
, quoted
, quoted_dollar_atp
, contains_dollar_at
);
7248 var_is_set
= temp
!= (char *)0;
7249 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
7251 /* Get the rest of the stuff inside the braces. */
7252 if (c
&& c
!= RBRACE
)
7254 /* Extract the contents of the ${ ... } expansion
7255 according to the Posix.2 rules. */
7256 value
= extract_dollar_brace_string (string
, &sindex
, quoted
, (c
== '%' || c
== '#' || c
=='/' || c
== '^' || c
== ',' || c
==':') ? SX_POSIXEXP
|SX_WORD
: SX_WORD
);
7257 if (string
[sindex
] == RBRACE
)
7260 goto bad_substitution
;
7263 value
= (char *)NULL
;
7267 /* All the cases where an expansion can possibly generate an unbound
7269 if (want_substring
|| want_patsub
|| want_casemod
|| c
== '#' || c
== '%' || c
== RBRACE
)
7271 if (var_is_set
== 0 && unbound_vars_is_error
&& ((name
[0] != '@' && name
[0] != '*') || name
[1]))
7273 last_command_exit_value
= EXECUTION_FAILURE
;
7274 err_unboundvar (name
);
7278 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7282 /* If this is a substring spec, process it and add the result. */
7285 temp1
= parameter_brace_substring (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7290 if (temp1
== &expand_param_error
)
7291 return (&expand_wdesc_error
);
7292 else if (temp1
== &expand_param_fatal
)
7293 return (&expand_wdesc_fatal
);
7295 ret
= alloc_word_desc ();
7297 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7298 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7301 else if (want_patsub
)
7303 temp1
= parameter_brace_patsub (name
, temp
, ind
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7308 if (temp1
== &expand_param_error
)
7309 return (&expand_wdesc_error
);
7310 else if (temp1
== &expand_param_fatal
)
7311 return (&expand_wdesc_fatal
);
7313 ret
= alloc_word_desc ();
7315 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7316 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7319 #if defined (CASEMOD_EXPANSIONS)
7320 else if (want_casemod
)
7322 temp1
= parameter_brace_casemod (name
, temp
, ind
, modspec
, value
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7327 if (temp1
== &expand_param_error
)
7328 return (&expand_wdesc_error
);
7329 else if (temp1
== &expand_param_fatal
)
7330 return (&expand_wdesc_fatal
);
7332 ret
= alloc_word_desc ();
7334 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7335 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7340 /* Do the right thing based on which character ended the variable name. */
7346 last_command_exit_value
= EXECUTION_FAILURE
;
7347 report_error (_("%s: bad substitution"), string
? string
: "??");
7351 return &expand_wdesc_error
;
7356 case '#': /* ${param#[#]pattern} */
7357 case '%': /* ${param%[%]pattern} */
7358 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
7363 temp1
= parameter_brace_remove_pattern (name
, temp
, ind
, value
, c
, quoted
, (tflag
& W_ARRAYIND
) ? AV_USEIND
: 0);
7368 ret
= alloc_word_desc ();
7370 if (temp1
&& QUOTED_NULL (temp1
) && (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7371 ret
->flags
|= W_QUOTED
|W_HASQUOTEDNULL
;
7378 if (var_is_set
&& var_is_null
== 0)
7380 /* If the operator is `+', we don't want the value of the named
7381 variable for anything, just the value of the right hand side. */
7384 /* XXX -- if we're double-quoted and the named variable is "$@",
7385 we want to turn off any special handling of "$@" --
7386 we're not using it, so whatever is on the rhs applies. */
7387 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7388 *quoted_dollar_atp
= 0;
7389 if (contains_dollar_at
)
7390 *contains_dollar_at
= 0;
7395 /* From Posix discussion on austin-group list. Issue 221
7396 requires that backslashes escaping `}' inside
7397 double-quoted ${...} be removed. */
7398 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7399 quoted
|= Q_DOLBRACE
;
7400 ret
= parameter_brace_expand_rhs (name
, value
, c
,
7403 contains_dollar_at
);
7404 /* XXX - fix up later, esp. noting presence of
7405 W_HASQUOTEDNULL in ret->flags */
7409 temp
= (char *)NULL
;
7415 /* Otherwise do nothing; just use the value in TEMP. */
7417 else /* VAR not set or VAR is NULL. */
7420 temp
= (char *)NULL
;
7421 if (c
== '=' && var_is_special
)
7423 last_command_exit_value
= EXECUTION_FAILURE
;
7424 report_error (_("$%s: cannot assign in this way"), name
);
7427 return &expand_wdesc_error
;
7431 parameter_brace_expand_error (name
, value
);
7432 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7436 /* XXX -- if we're double-quoted and the named variable is "$@",
7437 we want to turn off any special handling of "$@" --
7438 we're not using it, so whatever is on the rhs applies. */
7439 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
7440 *quoted_dollar_atp
= 0;
7441 if (contains_dollar_at
)
7442 *contains_dollar_at
= 0;
7444 /* From Posix discussion on austin-group list. Issue 221 requires
7445 that backslashes escaping `}' inside double-quoted ${...} be
7447 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
7448 quoted
|= Q_DOLBRACE
;
7449 ret
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
7451 contains_dollar_at
);
7452 /* XXX - fix up later, esp. noting presence of
7453 W_HASQUOTEDNULL in tdesc->flags */
7464 ret
= alloc_word_desc ();
7471 /* Expand a single ${xxx} expansion. The braces are optional. When
7472 the braces are used, parameter_brace_expand() does the work,
7473 possibly calling param_expand recursively. */
7475 param_expand (string
, sindex
, quoted
, expanded_something
,
7476 contains_dollar_at
, quoted_dollar_at_p
, had_quoted_null_p
,
7479 int *sindex
, quoted
, *expanded_something
, *contains_dollar_at
;
7480 int *quoted_dollar_at_p
, *had_quoted_null_p
, pflags
;
7482 char *temp
, *temp1
, uerror
[3];
7483 int zindex
, t_index
, expok
;
7488 WORD_DESC
*tdesc
, *ret
;
7492 c
= string
[++zindex
];
7494 temp
= (char *)NULL
;
7495 ret
= tdesc
= (WORD_DESC
*)NULL
;
7498 /* Do simple cases first. Switch on what follows '$'. */
7512 temp1
= dollar_vars
[TODIGIT (c
)];
7513 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
7518 last_command_exit_value
= EXECUTION_FAILURE
;
7519 err_unboundvar (uerror
);
7520 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7523 temp
= (*temp1
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7524 ? quote_string (temp1
)
7525 : quote_escapes (temp1
);
7527 temp
= (char *)NULL
;
7531 /* $$ -- pid of the invoking shell. */
7533 temp
= itos (dollar_dollar_pid
);
7536 /* $# -- number of positional parameters. */
7538 temp
= itos (number_of_args ());
7541 /* $? -- return value of the last synchronous command. */
7543 temp
= itos (last_command_exit_value
);
7546 /* $- -- flags supplied to the shell on invocation or by `set'. */
7548 temp
= which_set_flags ();
7551 /* $! -- Pid of the last asynchronous command. */
7553 /* If no asynchronous pids have been created, expand to nothing.
7554 If `set -u' has been executed, and no async processes have
7555 been created, this is an expansion error. */
7556 if (last_asynchronous_pid
== NO_PID
)
7558 if (expanded_something
)
7559 *expanded_something
= 0;
7560 temp
= (char *)NULL
;
7561 if (unbound_vars_is_error
)
7566 last_command_exit_value
= EXECUTION_FAILURE
;
7567 err_unboundvar (uerror
);
7568 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7572 temp
= itos (last_asynchronous_pid
);
7575 /* The only difference between this and $@ is when the arg is quoted. */
7576 case '*': /* `$*' */
7577 list
= list_rest_of_args ();
7580 /* According to austin-group posix proposal by Geoff Clare in
7581 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7583 "The shell shall write a message to standard error and
7584 immediately exit when it tries to expand an unset parameter
7585 other than the '@' and '*' special parameters."
7588 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7593 last_command_exit_value
= EXECUTION_FAILURE
;
7594 err_unboundvar (uerror
);
7595 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7599 /* If there are no command-line arguments, this should just
7600 disappear if there are other characters in the expansion,
7601 even if it's quoted. */
7602 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
== 0)
7603 temp
= (char *)NULL
;
7604 else if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
|Q_PATQUOTE
))
7606 /* If we have "$*" we want to make a string of the positional
7607 parameters, separated by the first character of $IFS, and
7608 quote the whole string, including the separators. If IFS
7609 is unset, the parameters are separated by ' '; if $IFS is
7610 null, the parameters are concatenated. */
7611 temp
= (quoted
& (Q_DOUBLE_QUOTES
|Q_PATQUOTE
)) ? string_list_dollar_star (list
) : string_list (list
);
7614 temp1
= quote_string (temp
);
7616 tflag
|= W_HASQUOTEDNULL
;
7623 /* We check whether or not we're eventually going to split $* here,
7624 for example when IFS is empty and we are processing the rhs of
7625 an assignment statement. In that case, we don't separate the
7626 arguments at all. Otherwise, if the $* is not quoted it is
7629 # if defined (HANDLE_MULTIBYTE)
7630 if (expand_no_split_dollar_star
&& ifs_firstc
[0] == 0)
7632 if (expand_no_split_dollar_star
&& ifs_firstc
== 0)
7634 temp
= string_list_dollar_star (list
);
7636 temp
= string_list_dollar_at (list
, quoted
);
7638 temp
= string_list_dollar_at (list
, quoted
);
7640 if (expand_no_split_dollar_star
== 0 && contains_dollar_at
)
7641 *contains_dollar_at
= 1;
7644 dispose_words (list
);
7647 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
7648 means that we have to turn quoting off after we split into
7649 the individually quoted arguments so that the final split
7650 on the first character of $IFS is still done. */
7651 case '@': /* `$@' */
7652 list
= list_rest_of_args ();
7655 /* According to austin-group posix proposal by Geoff Clare in
7656 <20090505091501.GA10097@squonk.masqnet> of 5 May 2009:
7658 "The shell shall write a message to standard error and
7659 immediately exit when it tries to expand an unset parameter
7660 other than the '@' and '*' special parameters."
7663 if (list
== 0 && unbound_vars_is_error
&& (pflags
& PF_IGNUNBOUND
) == 0)
7668 last_command_exit_value
= EXECUTION_FAILURE
;
7669 err_unboundvar (uerror
);
7670 return (interactive_shell
? &expand_wdesc_error
: &expand_wdesc_fatal
);
7674 /* We want to flag the fact that we saw this. We can't turn
7675 off quoting entirely, because other characters in the
7676 string might need it (consider "\"$@\""), but we need some
7677 way to signal that the final split on the first character
7678 of $IFS should be done, even though QUOTED is 1. */
7679 /* XXX - should this test include Q_PATQUOTE? */
7680 if (quoted_dollar_at_p
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7681 *quoted_dollar_at_p
= 1;
7682 if (contains_dollar_at
)
7683 *contains_dollar_at
= 1;
7685 /* We want to separate the positional parameters with the first
7686 character of $IFS in case $IFS is something other than a space.
7687 We also want to make sure that splitting is done no matter what --
7688 according to POSIX.2, this expands to a list of the positional
7689 parameters no matter what IFS is set to. */
7690 temp
= string_list_dollar_at (list
, (pflags
& PF_ASSIGNRHS
) ? (quoted
|Q_DOUBLE_QUOTES
) : quoted
);
7692 tflag
|= W_DOLLARAT
;
7693 dispose_words (list
);
7697 tdesc
= parameter_brace_expand (string
, &zindex
, quoted
, pflags
,
7699 contains_dollar_at
);
7701 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7703 temp
= tdesc
? tdesc
->word
: (char *)0;
7706 /* Quoted nulls should be removed if there is anything else
7708 /* Note that we saw the quoted null so we can add one back at
7709 the end of this function if there are no other characters
7710 in the string, discard TEMP, and go on. The exception to
7711 this is when we have "${@}" and $1 is '', since $@ needs
7712 special handling. */
7713 if (tdesc
&& tdesc
->word
&& (tdesc
->flags
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
))
7715 if (had_quoted_null_p
)
7716 *had_quoted_null_p
= 1;
7717 if (*quoted_dollar_at_p
== 0)
7720 tdesc
->word
= temp
= (char *)NULL
;
7728 /* Do command or arithmetic substitution. */
7730 /* We have to extract the contents of this paren substitution. */
7731 t_index
= zindex
+ 1;
7732 temp
= extract_command_subst (string
, &t_index
, 0);
7735 /* For Posix.2-style `$(( ))' arithmetic substitution,
7736 extract the expression and pass it to the evaluator. */
7737 if (temp
&& *temp
== LPAREN
)
7741 temp2
= savestring (temp1
);
7742 t_index
= strlen (temp2
) - 1;
7744 if (temp2
[t_index
] != RPAREN
)
7750 /* Cut off ending `)' */
7751 temp2
[t_index
] = '\0';
7753 if (chk_arithsub (temp2
, t_index
) == 0)
7757 internal_warning (_("future versions of the shell will force evaluation as an arithmetic substitution"));
7762 /* Expand variables found inside the expression. */
7763 temp1
= expand_arith_string (temp2
, Q_DOUBLE_QUOTES
);
7767 /* No error messages. */
7768 this_command_name
= (char *)NULL
;
7769 number
= evalexp (temp1
, &expok
);
7774 if (interactive_shell
== 0 && posixly_correct
)
7776 last_command_exit_value
= EXECUTION_FAILURE
;
7777 return (&expand_wdesc_fatal
);
7780 return (&expand_wdesc_error
);
7782 temp
= itos (number
);
7787 if (pflags
& PF_NOCOMSUB
)
7788 /* we need zindex+1 because string[zindex] == RPAREN */
7789 temp1
= substring (string
, *sindex
, zindex
+1);
7792 tdesc
= command_substitute (temp
, quoted
);
7793 temp1
= tdesc
? tdesc
->word
: (char *)NULL
;
7795 dispose_word_desc (tdesc
);
7801 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
7802 away in a future bash release. */
7804 /* Extract the contents of this arithmetic substitution. */
7805 t_index
= zindex
+ 1;
7806 temp
= extract_arithmetic_subst (string
, &t_index
);
7810 temp
= savestring (string
);
7811 if (expanded_something
)
7812 *expanded_something
= 0;
7816 /* Do initial variable expansion. */
7817 temp1
= expand_arith_string (temp
, Q_DOUBLE_QUOTES
);
7822 /* Find the variable in VARIABLE_LIST. */
7823 temp
= (char *)NULL
;
7825 for (t_index
= zindex
; (c
= string
[zindex
]) && legal_variable_char (c
); zindex
++)
7827 temp1
= (zindex
> t_index
) ? substring (string
, t_index
, zindex
) : (char *)NULL
;
7829 /* If this isn't a variable name, then just output the `$'. */
7830 if (temp1
== 0 || *temp1
== '\0')
7833 temp
= (char *)xmalloc (2);
7836 if (expanded_something
)
7837 *expanded_something
= 0;
7841 /* If the variable exists, return its value cell. */
7842 var
= find_variable (temp1
);
7844 if (var
&& invisible_p (var
) == 0 && var_isset (var
))
7846 #if defined (ARRAY_VARS)
7847 if (assoc_p (var
) || array_p (var
))
7849 temp
= array_p (var
) ? array_reference (array_cell (var
), 0)
7850 : assoc_reference (assoc_cell (var
), "0");
7852 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7853 ? quote_string (temp
)
7854 : quote_escapes (temp
);
7855 else if (unbound_vars_is_error
)
7856 goto unbound_variable
;
7861 temp
= value_cell (var
);
7863 temp
= (*temp
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)))
7864 ? quote_string (temp
)
7865 : quote_escapes (temp
);
7872 #if defined (ARRAY_VARS)
7873 else if (var
= find_variable_last_nameref (temp1
))
7875 temp
= nameref_cell (var
);
7876 if (temp
&& *temp
&& valid_array_reference (temp
))
7878 tdesc
= parameter_brace_expand_word (temp
, SPECIAL_VAR (temp
, 0), quoted
, pflags
, (arrayind_t
*)NULL
);
7879 if (tdesc
== &expand_wdesc_error
|| tdesc
== &expand_wdesc_fatal
)
7885 temp
= (char *)NULL
;
7889 temp
= (char *)NULL
;
7892 if (unbound_vars_is_error
)
7894 last_command_exit_value
= EXECUTION_FAILURE
;
7895 err_unboundvar (temp1
);
7904 last_command_exit_value
= EXECUTION_FAILURE
;
7905 return ((unbound_vars_is_error
&& interactive_shell
== 0)
7906 ? &expand_wdesc_fatal
7907 : &expand_wdesc_error
);
7918 ret
= alloc_word_desc ();
7919 ret
->flags
= tflag
; /* XXX */
7925 /* Make a word list which is the result of parameter and variable
7926 expansion, command substitution, arithmetic substitution, and
7927 quote removal of WORD. Return a pointer to a WORD_LIST which is
7928 the result of the expansion. If WORD contains a null word, the
7929 word list returned is also null.
7931 QUOTED contains flag values defined in shell.h.
7933 ISEXP is used to tell expand_word_internal that the word should be
7934 treated as the result of an expansion. This has implications for
7935 how IFS characters in the word are treated.
7937 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
7938 they point to an integer value which receives information about expansion.
7939 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
7940 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
7943 This only does word splitting in the case of $@ expansion. In that
7944 case, we split on ' '. */
7946 /* Values for the local variable quoted_state. */
7948 #define PARTIALLY_QUOTED 1
7949 #define WHOLLY_QUOTED 2
7952 expand_word_internal (word
, quoted
, isexp
, contains_dollar_at
, expanded_something
)
7955 int *contains_dollar_at
;
7956 int *expanded_something
;
7961 /* The intermediate string that we build while expanding. */
7964 /* The current size of the above object. */
7967 /* Index into ISTRING. */
7970 /* Temporary string storage. */
7973 /* The text of WORD. */
7974 register char *string
;
7976 /* The size of STRING. */
7979 /* The index into STRING. */
7982 /* This gets 1 if we see a $@ while quoted. */
7983 int quoted_dollar_at
;
7985 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
7986 whether WORD contains no quoting characters, a partially quoted
7987 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
7991 int had_quoted_null
;
7992 int has_dollar_at
, temp_has_dollar_at
;
7994 int pflags
; /* flags passed to param_expand */
7996 int assignoff
; /* If assignment, offset of `=' */
7998 register unsigned char c
; /* Current character. */
7999 int t_index
; /* For calls to string_extract_xxx. */
8005 istring
= (char *)xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
8006 istring
[istring_index
= 0] = '\0';
8007 quoted_dollar_at
= had_quoted_null
= has_dollar_at
= 0;
8008 quoted_state
= UNQUOTED
;
8010 string
= word
->word
;
8012 goto finished_with_string
;
8013 /* Don't need the string length for the SADD... and COPY_ macros unless
8014 multibyte characters are possible. */
8015 string_size
= (MB_CUR_MAX
> 1) ? strlen (string
) : 1;
8017 if (contains_dollar_at
)
8018 *contains_dollar_at
= 0;
8022 /* Begin the expansion. */
8028 /* Case on toplevel character. */
8032 goto finished_with_string
;
8036 #if HANDLE_MULTIBYTE
8037 if (MB_CUR_MAX
> 1 && string
[sindex
])
8039 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8044 temp
= (char *)xmalloc (3);
8046 temp
[1] = c
= string
[sindex
];
8057 istring
= sub_append_string (temp
, istring
, &istring_index
, &istring_size
);
8063 #if defined (PROCESS_SUBSTITUTION)
8064 /* Process substitution. */
8068 if (string
[++sindex
] != LPAREN
|| (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (word
->flags
& (W_DQUOTE
|W_NOPROCSUB
)) || posixly_correct
)
8070 sindex
--; /* add_character: label increments sindex */
8074 t_index
= sindex
+ 1; /* skip past both '<' and LPAREN */
8076 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
); /*))*/
8079 /* If the process substitution specification is `<()', we want to
8080 open the pipe for writing in the child and produce output; if
8081 it is `>()', we want to open the pipe for reading in the child
8082 and consume input. */
8083 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
8087 goto dollar_add_string
;
8089 #endif /* PROCESS_SUBSTITUTION */
8092 /* Posix.2 section 3.6.1 says that tildes following `=' in words
8093 which are not assignment statements are not expanded. If the
8094 shell isn't in posix mode, though, we perform tilde expansion
8095 on `likely candidate' unquoted assignment statements (flags
8096 include W_ASSIGNMENT but not W_QUOTED). A likely candidate
8097 contains an unquoted :~ or =~. Something to think about: we
8098 now have a flag that says to perform tilde expansion on arguments
8099 to `assignment builtins' like declare and export that look like
8100 assignment statements. We now do tilde expansion on such words
8101 even in POSIX mode. */
8102 if (word
->flags
& (W_ASSIGNRHS
|W_NOTILDE
))
8104 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8105 goto add_ifs_character
;
8109 /* If we're not in posix mode or forcing assignment-statement tilde
8110 expansion, note where the `=' appears in the word and prepare to
8111 do tilde expansion following the first `='. */
8112 if ((word
->flags
& W_ASSIGNMENT
) &&
8113 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8114 assignoff
== -1 && sindex
> 0)
8116 if (sindex
== assignoff
&& string
[sindex
+1] == '~') /* XXX */
8117 word
->flags
|= W_ITILDE
;
8119 else if ((word
->flags
& W_ASSIGNMENT
) &&
8120 (posixly_correct
== 0 || (word
->flags
& W_TILDEEXP
)) &&
8121 string
[sindex
+1] == '~')
8122 word
->flags
|= W_ITILDE
;
8124 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8125 goto add_ifs_character
;
8130 if (word
->flags
& W_NOTILDE
)
8132 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8133 goto add_ifs_character
;
8138 if ((word
->flags
& (W_ASSIGNMENT
|W_ASSIGNRHS
|W_TILDEEXP
)) &&
8139 string
[sindex
+1] == '~')
8140 word
->flags
|= W_ITILDE
;
8142 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
))
8143 goto add_ifs_character
;
8148 /* If the word isn't supposed to be tilde expanded, or we're not
8149 at the start of a word or after an unquoted : or = in an
8150 assignment statement, we don't do tilde expansion. */
8151 if ((word
->flags
& (W_NOTILDE
|W_DQUOTE
)) ||
8152 (sindex
> 0 && ((word
->flags
& W_ITILDE
) == 0)) ||
8153 (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8155 word
->flags
&= ~W_ITILDE
;
8156 if (isexp
== 0 && (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)) == 0 && isifs (c
) && (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) == 0)
8157 goto add_ifs_character
;
8162 if (word
->flags
& W_ASSIGNRHS
)
8164 else if (word
->flags
& (W_ASSIGNMENT
|W_TILDEEXP
))
8169 temp
= bash_tilde_find_word (string
+ sindex
, tflag
, &t_index
);
8171 word
->flags
&= ~W_ITILDE
;
8173 if (temp
&& *temp
&& t_index
> 0)
8175 temp1
= bash_tilde_expand (temp
, tflag
);
8176 if (temp1
&& *temp1
== '~' && STREQ (temp
, temp1
))
8180 goto add_character
; /* tilde expansion failed */
8185 goto add_quoted_string
; /* XXX was add_string */
8194 if (expanded_something
)
8195 *expanded_something
= 1;
8197 temp_has_dollar_at
= 0;
8198 pflags
= (word
->flags
& W_NOCOMSUB
) ? PF_NOCOMSUB
: 0;
8199 if (word
->flags
& W_NOSPLIT2
)
8200 pflags
|= PF_NOSPLIT2
;
8201 if (word
->flags
& W_ASSIGNRHS
)
8202 pflags
|= PF_ASSIGNRHS
;
8203 tword
= param_expand (string
, &sindex
, quoted
, expanded_something
,
8204 &temp_has_dollar_at
, "ed_dollar_at
,
8205 &had_quoted_null
, pflags
);
8206 has_dollar_at
+= temp_has_dollar_at
;
8208 if (tword
== &expand_wdesc_error
|| tword
== &expand_wdesc_fatal
)
8212 return ((tword
== &expand_wdesc_error
) ? &expand_word_error
8213 : &expand_word_fatal
);
8215 if (contains_dollar_at
&& has_dollar_at
)
8216 *contains_dollar_at
= 1;
8218 if (tword
&& (tword
->flags
& W_HASQUOTEDNULL
))
8219 had_quoted_null
= 1;
8221 temp
= tword
? tword
->word
: (char *)NULL
;
8222 dispose_word_desc (tword
);
8224 /* Kill quoted nulls; we will add them back at the end of
8225 expand_word_internal if nothing else in the string */
8226 if (had_quoted_null
&& temp
&& QUOTED_NULL (temp
))
8229 temp
= (char *)NULL
;
8235 case '`': /* Backquoted command substitution. */
8239 temp
= string_extract (string
, &sindex
, "`", SX_REQMATCH
);
8240 /* The test of sindex against t_index is to allow bare instances of
8241 ` to pass through, for backwards compatibility. */
8242 if (temp
== &extract_string_error
|| temp
== &extract_string_fatal
)
8244 if (sindex
- 1 == t_index
)
8249 last_command_exit_value
= EXECUTION_FAILURE
;
8250 report_error (_("bad substitution: no closing \"`\" in %s") , string
+t_index
);
8253 return ((temp
== &extract_string_error
) ? &expand_word_error
8254 : &expand_word_fatal
);
8257 if (expanded_something
)
8258 *expanded_something
= 1;
8260 if (word
->flags
& W_NOCOMSUB
)
8261 /* sindex + 1 because string[sindex] == '`' */
8262 temp1
= substring (string
, t_index
, sindex
+ 1);
8265 de_backslash (temp
);
8266 tword
= command_substitute (temp
, quoted
);
8267 temp1
= tword
? tword
->word
: (char *)NULL
;
8269 dispose_word_desc (tword
);
8273 goto dollar_add_string
;
8277 if (string
[sindex
+ 1] == '\n')
8283 c
= string
[++sindex
];
8285 if (quoted
& Q_HERE_DOCUMENT
)
8287 else if (quoted
& Q_DOUBLE_QUOTES
)
8292 /* From Posix discussion on austin-group list: Backslash escaping
8293 a } in ${...} is removed. Issue 0000221 */
8294 if ((quoted
& Q_DOLBRACE
) && c
== RBRACE
)
8296 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8298 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && ((sh_syntaxtab
[c
] & tflag
) == 0))
8300 SCOPY_CHAR_I (twochars
, '\\', c
, string
, sindex
, string_size
);
8305 sindex
--; /* add_character: label increments sindex */
8310 SCOPY_CHAR_I (twochars
, CTLESC
, c
, string
, sindex
, string_size
);
8315 /* BEFORE jumping here, we need to increment sindex if appropriate */
8316 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
,
8317 DEFAULT_ARRAY_SIZE
);
8318 istring
[istring_index
++] = twochars
[0];
8319 istring
[istring_index
++] = twochars
[1];
8320 istring
[istring_index
] = '\0';
8326 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
8328 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8333 temp
= string_extract_double_quoted (string
, &sindex
, 0);
8335 /* If the quotes surrounded the entire string, then the
8336 whole word was quoted. */
8337 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8343 tword
= alloc_word_desc ();
8346 temp
= (char *)NULL
;
8348 temp_has_dollar_at
= 0; /* XXX */
8349 /* Need to get W_HASQUOTEDNULL flag through this function. */
8350 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, 0, &temp_has_dollar_at
, (int *)NULL
);
8351 has_dollar_at
+= temp_has_dollar_at
;
8353 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
8357 /* expand_word_internal has already freed temp_word->word
8358 for us because of the way it prints error messages. */
8359 tword
->word
= (char *)NULL
;
8360 dispose_word (tword
);
8364 dispose_word (tword
);
8366 /* "$@" (a double-quoted dollar-at) expands into nothing,
8367 not even a NULL word, when there are no positional
8369 if (list
== 0 && has_dollar_at
)
8375 /* If we get "$@", we know we have expanded something, so we
8376 need to remember it for the final split on $IFS. This is
8377 a special case; it's the only case where a quoted string
8378 can expand into more than one word. It's going to come back
8379 from the above call to expand_word_internal as a list with
8380 a single word, in which all characters are quoted and
8381 separated by blanks. What we want to do is to turn it back
8382 into a list for the next piece of code. */
8384 dequote_list (list
);
8386 if (list
&& list
->word
&& (list
->word
->flags
& W_HASQUOTEDNULL
))
8387 had_quoted_null
= 1; /* XXX */
8392 if (contains_dollar_at
)
8393 *contains_dollar_at
= 1;
8394 if (expanded_something
)
8395 *expanded_something
= 1;
8400 /* What we have is "". This is a minor optimization. */
8402 list
= (WORD_LIST
*)NULL
;
8405 /* The code above *might* return a list (consider the case of "$@",
8406 where it returns "$1", "$2", etc.). We can't throw away the
8407 rest of the list, and we have to make sure each word gets added
8408 as quoted. We test on tresult->next: if it is non-NULL, we
8409 quote the whole list, save it to a string with string_list, and
8410 add that string. We don't need to quote the results of this
8411 (and it would be wrong, since that would quote the separators
8412 as well), so we go directly to add_string. */
8418 if (quoted_dollar_at
&& (word
->flags
& W_NOSPLIT2
))
8419 temp
= string_list_internal (quote_list (list
), " ");
8422 /* Testing quoted_dollar_at makes sure that "$@" is
8423 split correctly when $IFS does not contain a space. */
8424 temp
= quoted_dollar_at
8425 ? string_list_dollar_at (list
, Q_DOUBLE_QUOTES
)
8426 : string_list (quote_list (list
));
8427 dispose_words (list
);
8432 temp
= savestring (list
->word
->word
);
8433 tflag
= list
->word
->flags
;
8434 dispose_words (list
);
8436 /* If the string is not a quoted null string, we want
8437 to remove any embedded unquoted CTLNUL characters.
8438 We do not want to turn quoted null strings back into
8439 the empty string, though. We do this because we
8440 want to remove any quoted nulls from expansions that
8441 contain other characters. For example, if we have
8442 x"$*"y or "x$*y" and there are no positional parameters,
8443 the $* should expand into nothing. */
8444 /* We use the W_HASQUOTEDNULL flag to differentiate the
8445 cases: a quoted null character as above and when
8446 CTLNUL is contained in the (non-null) expansion
8447 of some variable. We use the had_quoted_null flag to
8448 pass the value through this function to its caller. */
8449 if ((tflag
& W_HASQUOTEDNULL
) && QUOTED_NULL (temp
) == 0)
8450 remove_quoted_nulls (temp
); /* XXX */
8454 temp
= (char *)NULL
;
8456 /* We do not want to add quoted nulls to strings that are only
8457 partially quoted; we can throw them away. The exception to
8458 this is when we are going to be performing word splitting,
8459 since we have to preserve a null argument if the next character
8460 will cause word splitting. */
8461 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
&& (word
->flags
& (W_NOSPLIT
|W_NOSPLIT2
)))
8469 temp
= quote_string (temp
);
8477 sindex
--; /* add_character: label increments sindex */
8485 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (word
->flags
& W_DQUOTE
))
8487 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)))
8492 temp
= string_extract_single_quoted (string
, &sindex
);
8494 /* If the entire STRING was surrounded by single quotes,
8495 then the string is wholly quoted. */
8496 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
8500 /* If all we had was '', it is a null expansion. */
8504 temp
= (char *)NULL
;
8507 remove_quoted_escapes (temp
); /* ??? */
8509 /* We do not want to add quoted nulls to strings that are only
8510 partially quoted; such nulls are discarded. */
8511 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
8514 /* If we have a quoted null expansion, add a quoted NULL to istring. */
8518 sindex
--; /* add_character: label increments sindex */
8522 goto add_quoted_string
;
8527 /* This is the fix for " $@ " */
8529 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || (isexp
== 0 && isifs (c
)))
8531 if (string
[sindex
]) /* from old goto dollar_add_string */
8540 #if HANDLE_MULTIBYTE
8546 SADD_MBQCHAR_BODY(temp
, string
, sindex
, string_size
);
8551 twochars
[0] = CTLESC
;
8558 SADD_MBCHAR (temp
, string
, sindex
, string_size
);
8561 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
8562 DEFAULT_ARRAY_SIZE
);
8563 istring
[istring_index
++] = c
;
8564 istring
[istring_index
] = '\0';
8566 /* Next character. */
8571 finished_with_string
:
8572 /* OK, we're ready to return. If we have a quoted string, and
8573 quoted_dollar_at is not set, we do no splitting at all; otherwise
8574 we split on ' '. The routines that call this will handle what to
8575 do if nothing has been expanded. */
8577 /* Partially and wholly quoted strings which expand to the empty
8578 string are retained as an empty arguments. Unquoted strings
8579 which expand to the empty string are discarded. The single
8580 exception is the case of expanding "$@" when there are no
8581 positional parameters. In that case, we discard the expansion. */
8583 /* Because of how the code that handles "" and '' in partially
8584 quoted strings works, we need to make ISTRING into a QUOTED_NULL
8585 if we saw quoting characters, but the expansion was empty.
8586 "" and '' are tossed away before we get to this point when
8587 processing partially quoted strings. This makes "" and $xxx""
8588 equivalent when xxx is unset. We also look to see whether we
8589 saw a quoted null from a ${} expansion and add one back if we
8592 /* If we expand to nothing and there were no single or double quotes
8593 in the word, we throw it away. Otherwise, we return a NULL word.
8594 The single exception is for $@ surrounded by double quotes when
8595 there are no positional parameters. In that case, we also throw
8598 if (*istring
== '\0')
8600 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
8602 istring
[0] = CTLNUL
;
8604 tword
= make_bare_word (istring
);
8605 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8606 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8607 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8608 tword
->flags
|= W_QUOTED
;
8610 /* According to sh, ksh, and Posix.2, if a word expands into nothing
8611 and a double-quoted "$@" appears anywhere in it, then the entire
8613 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
8614 list
= (WORD_LIST
*)NULL
;
8618 tword
= make_bare_word (istring
);
8619 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8620 tword
->flags
|= W_QUOTED
;
8621 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8625 list
= (WORD_LIST
*)NULL
;
8628 else if (word
->flags
& W_NOSPLIT
)
8630 tword
= make_bare_word (istring
);
8631 if (word
->flags
& W_ASSIGNMENT
)
8632 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
8633 if (word
->flags
& W_COMPASSIGN
)
8634 tword
->flags
|= W_COMPASSIGN
; /* XXX */
8635 if (word
->flags
& W_NOGLOB
)
8636 tword
->flags
|= W_NOGLOB
; /* XXX */
8637 if (word
->flags
& W_NOBRACE
)
8638 tword
->flags
|= W_NOBRACE
; /* XXX */
8639 if (word
->flags
& W_NOEXPAND
)
8640 tword
->flags
|= W_NOEXPAND
; /* XXX */
8641 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
8642 tword
->flags
|= W_QUOTED
;
8643 if (had_quoted_null
&& QUOTED_NULL (istring
))
8644 tword
->flags
|= W_HASQUOTEDNULL
;
8645 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8651 ifs_chars
= (quoted_dollar_at
|| has_dollar_at
) ? ifs_value
: (char *)NULL
;
8653 /* If we have $@, we need to split the results no matter what. If
8654 IFS is unset or NULL, string_list_dollar_at has separated the
8655 positional parameters with a space, so we split on space (we have
8656 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
8657 string_list_dollar_at has separated the positional parameters
8658 with the first character of $IFS, so we split on $IFS. */
8659 if (has_dollar_at
&& ifs_chars
)
8660 list
= list_string (istring
, *ifs_chars
? ifs_chars
: " ", 1);
8663 tword
= make_bare_word (istring
);
8664 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
8665 tword
->flags
|= W_QUOTED
;
8666 if (word
->flags
& W_ASSIGNMENT
)
8667 tword
->flags
|= W_ASSIGNMENT
;
8668 if (word
->flags
& W_COMPASSIGN
)
8669 tword
->flags
|= W_COMPASSIGN
;
8670 if (word
->flags
& W_NOGLOB
)
8671 tword
->flags
|= W_NOGLOB
;
8672 if (word
->flags
& W_NOBRACE
)
8673 tword
->flags
|= W_NOBRACE
;
8674 if (word
->flags
& W_NOEXPAND
)
8675 tword
->flags
|= W_NOEXPAND
;
8676 if (had_quoted_null
&& QUOTED_NULL (istring
))
8677 tword
->flags
|= W_HASQUOTEDNULL
; /* XXX */
8678 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
8686 /* **************************************************************** */
8688 /* Functions for Quote Removal */
8690 /* **************************************************************** */
8692 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
8693 backslash quoting rules for within double quotes or a here document. */
8695 string_quote_removal (string
, quoted
)
8700 char *r
, *result_string
, *temp
, *send
;
8701 int sindex
, tindex
, dquote
;
8705 /* The result can be no longer than the original string. */
8706 slen
= strlen (string
);
8707 send
= string
+ slen
;
8709 r
= result_string
= (char *)xmalloc (slen
+ 1);
8711 for (dquote
= sindex
= 0; c
= string
[sindex
];)
8716 c
= string
[++sindex
];
8722 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && (sh_syntaxtab
[c
] & CBSDQUOTE
) == 0)
8727 SCOPY_CHAR_M (r
, string
, send
, sindex
);
8731 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
8737 tindex
= sindex
+ 1;
8738 temp
= string_extract_single_quoted (string
, &tindex
);
8749 dquote
= 1 - dquote
;
8755 return (result_string
);
8760 /* Perform quote removal on word WORD. This allocates and returns a new
8763 word_quote_removal (word
, quoted
)
8770 t
= string_quote_removal (word
->word
, quoted
);
8771 w
= alloc_word_desc ();
8772 w
->word
= t
? t
: savestring ("");
8776 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
8777 the members of the list are treated as if they are surrounded by
8778 double quotes. Return a new list, or NULL if LIST is NULL. */
8780 word_list_quote_removal (list
, quoted
)
8784 WORD_LIST
*result
, *t
, *tresult
, *e
;
8786 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8788 tresult
= make_word_list (word_quote_removal (t
->word
, quoted
), (WORD_LIST
*)NULL
);
8790 result
= (WORD_LIST
*) list_append (result
, tresult
);
8793 result
= e
= tresult
;
8806 /*******************************************
8808 * Functions to perform word splitting *
8810 *******************************************/
8820 ifs_value
= (v
&& value_cell (v
)) ? value_cell (v
) : " \t\n";
8822 /* Should really merge ifs_cmap with sh_syntaxtab. XXX - doesn't yet
8823 handle multibyte chars in IFS */
8824 memset (ifs_cmap
, '\0', sizeof (ifs_cmap
));
8825 for (t
= ifs_value
; t
&& *t
; t
++)
8831 #if defined (HANDLE_MULTIBYTE)
8834 ifs_firstc
[0] = '\0';
8840 ifs_len
= strnlen (ifs_value
, MB_CUR_MAX
);
8841 ifs_firstc_len
= MBLEN (ifs_value
, ifs_len
);
8842 if (ifs_firstc_len
== 1 || ifs_firstc_len
== 0 || MB_INVALIDCH (ifs_firstc_len
))
8844 ifs_firstc
[0] = ifs_value
[0];
8845 ifs_firstc
[1] = '\0';
8849 memcpy (ifs_firstc
, ifs_value
, ifs_firstc_len
);
8852 ifs_firstc
= ifs_value
? *ifs_value
: 0;
8862 /* This splits a single word into a WORD LIST on $IFS, but only if the word
8863 is not quoted. list_string () performs quote removal for us, even if we
8864 don't do any splitting. */
8866 word_split (w
, ifs_chars
)
8876 xifs
= ((w
->flags
& W_QUOTED
) || ifs_chars
== 0) ? "" : ifs_chars
;
8877 result
= list_string (w
->word
, xifs
, w
->flags
& W_QUOTED
);
8880 result
= (WORD_LIST
*)NULL
;
8885 /* Perform word splitting on LIST and return the RESULT. It is possible
8886 to return (WORD_LIST *)NULL. */
8888 word_list_split (list
)
8891 WORD_LIST
*result
, *t
, *tresult
, *e
;
8893 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
8895 tresult
= word_split (t
->word
, ifs_value
);
8897 result
= e
= tresult
;
8908 /**************************************************
8910 * Functions to expand an entire WORD_LIST *
8912 **************************************************/
8914 /* Do any word-expansion-specific cleanup and jump to top_level */
8916 exp_jump_to_top_level (v
)
8919 set_pipestatus_from_exit (last_command_exit_value
);
8921 /* Cleanup code goes here. */
8922 expand_no_split_dollar_star
= 0; /* XXX */
8923 expanding_redir
= 0;
8924 assigning_in_environment
= 0;
8926 if (parse_and_execute_level
== 0)
8927 top_level_cleanup (); /* from sig.c */
8929 jump_to_top_level (v
);
8932 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
8933 ELIST, and set ELIST to the new list. */
8934 #define PREPEND_LIST(nlist, elist) \
8935 do { nlist->next = elist; elist = nlist; } while (0)
8937 /* Separate out any initial variable assignments from TLIST. If set -k has
8938 been executed, remove all assignment statements from TLIST. Initial
8939 variable assignments and other environment assignments are placed
8940 on SUBST_ASSIGN_VARLIST. */
8942 separate_out_assignments (tlist
)
8945 register WORD_LIST
*vp
, *lp
;
8948 return ((WORD_LIST
*)NULL
);
8950 if (subst_assign_varlist
)
8951 dispose_words (subst_assign_varlist
); /* Clean up after previous error */
8953 subst_assign_varlist
= (WORD_LIST
*)NULL
;
8956 /* Separate out variable assignments at the start of the command.
8957 Loop invariant: vp->next == lp
8959 lp = list of words left after assignment statements skipped
8960 tlist = original list of words
8962 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
8968 /* If lp != tlist, we have some initial assignment statements.
8969 We make SUBST_ASSIGN_VARLIST point to the list of assignment
8970 words and TLIST point to the remaining words. */
8973 subst_assign_varlist
= tlist
;
8974 /* ASSERT(vp->next == lp); */
8975 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
8976 tlist
= lp
; /* remainder of word list */
8979 /* vp == end of variable list */
8980 /* tlist == remainder of original word list without variable assignments */
8982 /* All the words in tlist were assignment statements */
8983 return ((WORD_LIST
*)NULL
);
8985 /* ASSERT(tlist != NULL); */
8986 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
8988 /* If the -k option is in effect, we need to go through the remaining
8989 words, separate out the assignment words, and place them on
8990 SUBST_ASSIGN_VARLIST. */
8991 if (place_keywords_in_env
)
8993 WORD_LIST
*tp
; /* tp == running pointer into tlist */
8998 /* Loop Invariant: tp->next == lp */
8999 /* Loop postcondition: tlist == word list without assignment statements */
9002 if (lp
->word
->flags
& W_ASSIGNMENT
)
9004 /* Found an assignment statement, add this word to end of
9005 subst_assign_varlist (vp). */
9006 if (!subst_assign_varlist
)
9007 subst_assign_varlist
= vp
= lp
;
9014 /* Remove the word pointed to by LP from TLIST. */
9015 tp
->next
= lp
->next
;
9016 /* ASSERT(vp == lp); */
9017 lp
->next
= (WORD_LIST
*)NULL
;
9030 #define WEXP_VARASSIGN 0x001
9031 #define WEXP_BRACEEXP 0x002
9032 #define WEXP_TILDEEXP 0x004
9033 #define WEXP_PARAMEXP 0x008
9034 #define WEXP_PATHEXP 0x010
9036 /* All of the expansions, including variable assignments at the start of
9038 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9040 /* All of the expansions except variable assignments at the start of
9042 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
9044 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
9045 expansion, command substitution, arithmetic expansion, word splitting, and
9047 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
9049 /* Take the list of words in LIST and do the various substitutions. Return
9050 a new list of words which is the expanded list, and without things like
9051 variable assignments. */
9057 return (expand_word_list_internal (list
, WEXP_ALL
));
9060 /* Same as expand_words (), but doesn't hack variable or environment
9063 expand_words_no_vars (list
)
9066 return (expand_word_list_internal (list
, WEXP_NOVARS
));
9070 expand_words_shellexp (list
)
9073 return (expand_word_list_internal (list
, WEXP_SHELLEXP
));
9077 glob_expand_word_list (tlist
, eflags
)
9081 char **glob_array
, *temp_string
;
9082 register int glob_index
;
9083 WORD_LIST
*glob_list
, *output_list
, *disposables
, *next
;
9086 output_list
= disposables
= (WORD_LIST
*)NULL
;
9087 glob_array
= (char **)NULL
;
9090 /* For each word, either globbing is attempted or the word is
9091 added to orig_list. If globbing succeeds, the results are
9092 added to orig_list and the word (tlist) is added to the list
9093 of disposable words. If globbing fails and failed glob
9094 expansions are left unchanged (the shell default), the
9095 original word is added to orig_list. If globbing fails and
9096 failed glob expansions are removed, the original word is
9097 added to the list of disposable words. orig_list ends up
9098 in reverse order and requires a call to REVERSE_LIST to
9099 be set right. After all words are examined, the disposable
9103 /* If the word isn't an assignment and contains an unquoted
9104 pattern matching character, then glob it. */
9105 if ((tlist
->word
->flags
& W_NOGLOB
) == 0 &&
9106 unquoted_glob_pattern_p (tlist
->word
->word
))
9108 glob_array
= shell_glob_filename (tlist
->word
->word
);
9110 /* Handle error cases.
9111 I don't think we should report errors like "No such file
9112 or directory". However, I would like to report errors
9113 like "Read failed". */
9115 if (glob_array
== 0 || GLOB_FAILED (glob_array
))
9117 glob_array
= (char **)xmalloc (sizeof (char *));
9118 glob_array
[0] = (char *)NULL
;
9121 /* Dequote the current word in case we have to use it. */
9122 if (glob_array
[0] == NULL
)
9124 temp_string
= dequote_string (tlist
->word
->word
);
9125 free (tlist
->word
->word
);
9126 tlist
->word
->word
= temp_string
;
9129 /* Make the array into a word list. */
9130 glob_list
= (WORD_LIST
*)NULL
;
9131 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
9133 tword
= make_bare_word (glob_array
[glob_index
]);
9134 tword
->flags
|= W_GLOBEXP
; /* XXX */
9135 glob_list
= make_word_list (tword
, glob_list
);
9140 output_list
= (WORD_LIST
*)list_append (glob_list
, output_list
);
9141 PREPEND_LIST (tlist
, disposables
);
9143 else if (fail_glob_expansion
!= 0)
9145 last_command_exit_value
= EXECUTION_FAILURE
;
9146 report_error (_("no match: %s"), tlist
->word
->word
);
9147 exp_jump_to_top_level (DISCARD
);
9149 else if (allow_null_glob_expansion
== 0)
9151 /* Failed glob expressions are left unchanged. */
9152 PREPEND_LIST (tlist
, output_list
);
9156 /* Failed glob expressions are removed. */
9157 PREPEND_LIST (tlist
, disposables
);
9162 /* Dequote the string. */
9163 temp_string
= dequote_string (tlist
->word
->word
);
9164 free (tlist
->word
->word
);
9165 tlist
->word
->word
= temp_string
;
9166 PREPEND_LIST (tlist
, output_list
);
9169 strvec_dispose (glob_array
);
9170 glob_array
= (char **)NULL
;
9176 dispose_words (disposables
);
9179 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9181 return (output_list
);
9184 #if defined (BRACE_EXPANSION)
9186 brace_expand_word_list (tlist
, eflags
)
9190 register char **expansions
;
9192 WORD_LIST
*disposables
, *output_list
, *next
;
9196 for (disposables
= output_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
9200 if (tlist
->word
->flags
& W_NOBRACE
)
9202 itrace("brace_expand_word_list: %s: W_NOBRACE", tlist
->word
->word
);
9203 PREPEND_LIST (tlist
, output_list
);
9207 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9209 /*itrace("brace_expand_word_list: %s: W_COMPASSIGN|W_ASSIGNARG", tlist->word->word);*/
9210 PREPEND_LIST (tlist
, output_list
);
9214 /* Only do brace expansion if the word has a brace character. If
9215 not, just add the word list element to BRACES and continue. In
9216 the common case, at least when running shell scripts, this will
9217 degenerate to a bunch of calls to `mbschr', and then what is
9218 basically a reversal of TLIST into BRACES, which is corrected
9219 by a call to REVERSE_LIST () on BRACES when the end of TLIST
9221 if (mbschr (tlist
->word
->word
, LBRACE
))
9223 expansions
= brace_expand (tlist
->word
->word
);
9225 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
9227 w
= alloc_word_desc ();
9228 w
->word
= temp_string
;
9230 /* If brace expansion didn't change the word, preserve
9231 the flags. We may want to preserve the flags
9232 unconditionally someday -- XXX */
9233 if (STREQ (temp_string
, tlist
->word
->word
))
9234 w
->flags
= tlist
->word
->flags
;
9236 w
= make_word_flags (w
, temp_string
);
9238 output_list
= make_word_list (w
, output_list
);
9242 /* Add TLIST to the list of words to be freed after brace
9243 expansion has been performed. */
9244 PREPEND_LIST (tlist
, disposables
);
9247 PREPEND_LIST (tlist
, output_list
);
9251 dispose_words (disposables
);
9254 output_list
= REVERSE_LIST (output_list
, WORD_LIST
*);
9256 return (output_list
);
9260 #if defined (ARRAY_VARS)
9261 /* Take WORD, a compound associative array assignment, and internally run
9262 'declare -A w', where W is the variable name portion of WORD. */
9264 make_internal_declare (word
, option
)
9272 w
= make_word (word
);
9274 t
= assignment (w
->word
, 0);
9277 wl
= make_word_list (w
, (WORD_LIST
*)NULL
);
9278 wl
= make_word_list (make_word (option
), wl
);
9280 return (declare_builtin (wl
));
9285 shell_expand_word_list (tlist
, eflags
)
9289 WORD_LIST
*expanded
, *orig_list
, *new_list
, *next
, *temp_list
;
9290 int expanded_something
, has_dollar_at
;
9293 /* We do tilde expansion all the time. This is what 1003.2 says. */
9294 new_list
= (WORD_LIST
*)NULL
;
9295 for (orig_list
= tlist
; tlist
; tlist
= next
)
9297 temp_string
= tlist
->word
->word
;
9301 #if defined (ARRAY_VARS)
9302 /* If this is a compound array assignment to a builtin that accepts
9303 such assignments (e.g., `declare'), take the assignment and perform
9304 it separately, handling the semantics of declarations inside shell
9305 functions. This avoids the double-evaluation of such arguments,
9306 because `declare' does some evaluation of compound assignments on
9308 if ((tlist
->word
->flags
& (W_COMPASSIGN
|W_ASSIGNARG
)) == (W_COMPASSIGN
|W_ASSIGNARG
))
9312 if (tlist
->word
->flags
& W_ASSIGNASSOC
)
9313 make_internal_declare (tlist
->word
->word
, "-A");
9315 t
= do_word_assignment (tlist
->word
, 0);
9318 last_command_exit_value
= EXECUTION_FAILURE
;
9319 exp_jump_to_top_level (DISCARD
);
9322 /* Now transform the word as ksh93 appears to do and go on */
9323 t
= assignment (tlist
->word
->word
, 0);
9324 tlist
->word
->word
[t
] = '\0';
9325 tlist
->word
->flags
&= ~(W_ASSIGNMENT
|W_NOSPLIT
|W_COMPASSIGN
|W_ASSIGNARG
|W_ASSIGNASSOC
);
9329 expanded_something
= 0;
9330 expanded
= expand_word_internal
9331 (tlist
->word
, 0, 0, &has_dollar_at
, &expanded_something
);
9333 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
9335 /* By convention, each time this error is returned,
9336 tlist->word->word has already been freed. */
9337 tlist
->word
->word
= (char *)NULL
;
9339 /* Dispose our copy of the original list. */
9340 dispose_words (orig_list
);
9341 /* Dispose the new list we're building. */
9342 dispose_words (new_list
);
9344 last_command_exit_value
= EXECUTION_FAILURE
;
9345 if (expanded
== &expand_word_error
)
9346 exp_jump_to_top_level (DISCARD
);
9348 exp_jump_to_top_level (FORCE_EOF
);
9351 /* Don't split words marked W_NOSPLIT. */
9352 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
9354 temp_list
= word_list_split (expanded
);
9355 dispose_words (expanded
);
9359 /* If no parameter expansion, command substitution, process
9360 substitution, or arithmetic substitution took place, then
9361 do not do word splitting. We still have to remove quoted
9362 null characters from the result. */
9363 word_list_remove_quoted_nulls (expanded
);
9364 temp_list
= expanded
;
9367 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
9368 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
9372 dispose_words (orig_list
);
9375 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
9380 /* The workhorse for expand_words () and expand_words_no_vars ().
9381 First arg is LIST, a WORD_LIST of words.
9382 Second arg EFLAGS is a flags word controlling which expansions are
9385 This does all of the substitutions: brace expansion, tilde expansion,
9386 parameter expansion, command substitution, arithmetic expansion,
9387 process substitution, word splitting, and pathname expansion, according
9388 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
9389 set, or for which no expansion is done, do not undergo word splitting.
9390 Words with the W_NOGLOB bit set do not undergo pathname expansion; words
9391 with W_NOBRACE set do not undergo brace expansion (see
9392 brace_expand_word_list above). */
9394 expand_word_list_internal (list
, eflags
)
9398 WORD_LIST
*new_list
, *temp_list
;
9402 return ((WORD_LIST
*)NULL
);
9404 garglist
= new_list
= copy_word_list (list
);
9405 if (eflags
& WEXP_VARASSIGN
)
9407 garglist
= new_list
= separate_out_assignments (new_list
);
9410 if (subst_assign_varlist
)
9412 /* All the words were variable assignments, so they are placed
9413 into the shell's environment. */
9414 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9416 this_command_name
= (char *)NULL
; /* no arithmetic errors */
9417 tint
= do_word_assignment (temp_list
->word
, 0);
9418 /* Variable assignment errors in non-interactive shells
9419 running in Posix.2 mode cause the shell to exit. */
9422 last_command_exit_value
= EXECUTION_FAILURE
;
9423 if (interactive_shell
== 0 && posixly_correct
)
9424 exp_jump_to_top_level (FORCE_EOF
);
9426 exp_jump_to_top_level (DISCARD
);
9429 dispose_words (subst_assign_varlist
);
9430 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9432 return ((WORD_LIST
*)NULL
);
9436 /* Begin expanding the words that remain. The expansions take place on
9437 things that aren't really variable assignments. */
9439 #if defined (BRACE_EXPANSION)
9440 /* Do brace expansion on this word if there are any brace characters
9442 if ((eflags
& WEXP_BRACEEXP
) && brace_expansion
&& new_list
)
9443 new_list
= brace_expand_word_list (new_list
, eflags
);
9444 #endif /* BRACE_EXPANSION */
9446 /* Perform the `normal' shell expansions: tilde expansion, parameter and
9447 variable substitution, command substitution, arithmetic expansion,
9448 and word splitting. */
9449 new_list
= shell_expand_word_list (new_list
, eflags
);
9451 /* Okay, we're almost done. Now let's just do some filename
9455 if ((eflags
& WEXP_PATHEXP
) && disallow_filename_globbing
== 0)
9456 /* Glob expand the word list unless globbing has been disabled. */
9457 new_list
= glob_expand_word_list (new_list
, eflags
);
9459 /* Dequote the words, because we're not performing globbing. */
9460 new_list
= dequote_list (new_list
);
9463 if ((eflags
& WEXP_VARASSIGN
) && subst_assign_varlist
)
9465 sh_wassign_func_t
*assign_func
;
9466 int is_special_builtin
, is_builtin_or_func
;
9468 /* If the remainder of the words expand to nothing, Posix.2 requires
9469 that the variable and environment assignments affect the shell's
9471 assign_func
= new_list
? assign_in_env
: do_word_assignment
;
9472 tempenv_assign_error
= 0;
9474 is_builtin_or_func
= (new_list
&& new_list
->word
&& (find_shell_builtin (new_list
->word
->word
) || find_function (new_list
->word
->word
)));
9475 /* Posix says that special builtins exit if a variable assignment error
9476 occurs in an assignment preceding it. */
9477 is_special_builtin
= (posixly_correct
&& new_list
&& new_list
->word
&& find_special_builtin (new_list
->word
->word
));
9479 for (temp_list
= subst_assign_varlist
; temp_list
; temp_list
= temp_list
->next
)
9481 this_command_name
= (char *)NULL
;
9482 assigning_in_environment
= (assign_func
== assign_in_env
);
9483 tint
= (*assign_func
) (temp_list
->word
, is_builtin_or_func
);
9484 assigning_in_environment
= 0;
9485 /* Variable assignment errors in non-interactive shells running
9486 in Posix.2 mode cause the shell to exit. */
9489 if (assign_func
== do_word_assignment
)
9491 last_command_exit_value
= EXECUTION_FAILURE
;
9492 if (interactive_shell
== 0 && posixly_correct
&& is_special_builtin
)
9493 exp_jump_to_top_level (FORCE_EOF
);
9495 exp_jump_to_top_level (DISCARD
);
9498 tempenv_assign_error
++;
9502 dispose_words (subst_assign_varlist
);
9503 subst_assign_varlist
= (WORD_LIST
*)NULL
;
9507 tint
= list_length (new_list
) + 1;
9508 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
9509 for (tint
= 0, temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
9510 glob_argv_flags
[tint
++] = (temp_list
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
9511 glob_argv_flags
[tint
] = '\0';