1 /* subst.c -- The part of the shell that does parameter, command, and
2 globbing substitutions. */
4 /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 #include "bashtypes.h"
30 #if defined (HAVE_UNISTD_H)
35 #include "posixstat.h"
40 #include "execute_cmd.h"
44 #include "mailcheck.h"
46 #if !defined (HAVE_RESTARTABLE_SYSCALLS) /* for getc_with_restart */
50 #include "builtins/getopt.h"
51 #include "builtins/common.h"
53 #include <tilde/tilde.h>
54 #include <glob/fnmatch.h>
60 /* The size that strings change by. */
61 #define DEFAULT_INITIAL_ARRAY_SIZE 112
62 #define DEFAULT_ARRAY_SIZE 128
68 #define VT_ARRAYMEMBER 3
70 /* Flags for quoted_strchr */
71 #define ST_BACKSL 0x01
72 #define ST_CTLESC 0x02
74 /* These defs make it easier to use the editor. */
80 /* Process ID of the last command executed within command substitution. */
81 pid_t last_command_subst_pid = NO_PID;
83 /* Extern functions and variables from different files. */
84 extern int last_command_exit_value, interactive, interactive_shell;
85 extern int subshell_environment, startup_state;
86 extern int dollar_dollar_pid;
87 extern int posixly_correct;
88 extern char *this_command_name;
89 extern struct fd_bitmap *current_fds_to_close;
90 extern int wordexp_only;
92 extern void getopts_reset ();
94 /* Non-zero means to allow unmatched globbed filenames to expand to
96 int allow_null_glob_expansion;
98 /* Variables to keep track of which words in an expanded word list (the
99 output of expand_word_list_internal) are the result of globbing
100 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c. */
101 char *glob_argv_flags;
102 static int glob_argv_flags_size;
104 static WORD_LIST expand_word_error, expand_word_fatal;
105 static char expand_param_error, expand_param_fatal;
107 static char *make_quoted_char ();
108 static void remove_quoted_nulls ();
109 static char *param_expand ();
110 static char *maybe_expand_string ();
111 static WORD_LIST *call_expand_word_internal ();
112 static WORD_LIST *expand_string_internal ();
113 static WORD_LIST *expand_word_internal (), *expand_word_list_internal ();
114 static WORD_LIST *expand_string_leave_quoted ();
115 static WORD_LIST *expand_string_for_rhs ();
116 static WORD_LIST *word_list_split ();
117 static WORD_LIST *quote_list (), *dequote_list ();
118 static char *quote_escapes ();
119 static WORD_LIST *list_quote_escapes ();
120 static int unquoted_substring (), unquoted_member ();
121 static int do_assignment_internal ();
122 static char *string_extract_verbatim (), *string_extract ();
123 static char *string_extract_double_quoted (), *string_extract_single_quoted ();
124 static char *string_list_dollar_at (), *string_list_dollar_star ();
125 static inline int skip_single_quoted (), skip_double_quoted ();
126 static char *extract_delimited_string ();
127 static char *extract_dollar_brace_string ();
129 /* **************************************************************** */
131 /* Utility Functions */
133 /* **************************************************************** */
135 /* Cons a new string from STRING starting at START and ending at END,
136 not including END. */
138 substring (string, start, end)
143 register char *result;
146 result = xmalloc (len + 1);
147 strncpy (result, string + start, len);
153 quoted_substring (string, start, end)
158 register char *result, *s, *r;
162 /* Move to string[start], skipping quoted characters. */
163 for (s = string, l = 0; *s && l < start; )
175 r = result = xmalloc (2*len + 1); /* save room for quotes */
177 /* Copy LEN characters, including quote characters. */
179 for (l = 0; l < len; s++)
192 /* Find the first occurrence of character C in string S, obeying shell
193 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
194 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
195 escaped with CTLESC are skipped. */
197 quoted_strchr (s, c, flags)
205 if (((flags & ST_BACKSL) && *p == '\\')
206 || ((flags & ST_CTLESC) && *p == CTLESC))
210 return ((char *)NULL);
216 return ((char *)NULL);
219 /* Return 1 if CHARACTER appears in an unquoted portion of
220 STRING. Return 0 otherwise. */
222 unquoted_member (character, string)
228 for (sindex = 0; c = string[sindex]; )
246 sindex = skip_single_quoted (string, ++sindex);
250 sindex = skip_double_quoted (string, ++sindex);
257 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
259 unquoted_substring (substr, string)
260 char *substr, *string;
262 int sindex, c, sublen;
264 if (substr == 0 || *substr == '\0')
267 sublen = strlen (substr);
268 for (sindex = 0; c = string[sindex]; )
270 if (STREQN (string + sindex, substr, sublen))
283 sindex = skip_single_quoted (string, ++sindex);
287 sindex = skip_double_quoted (string, ++sindex);
298 /* Most of the substitutions must be done in parallel. In order
299 to avoid using tons of unclear goto's, I have some functions
300 for manipulating malloc'ed strings. They all take INDX, a
301 pointer to an integer which is the offset into the string
302 where manipulation is taking place. They also take SIZE, a
303 pointer to an integer which is the current length of the
304 character array for this string. */
306 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
307 of space allocated to TARGET. SOURCE can be NULL, in which
308 case nothing happens. Gets rid of SOURCE by freeing it.
309 Returns TARGET in case the location has changed. */
311 sub_append_string (source, target, indx, size)
312 char *source, *target;
319 srclen = STRLEN (source);
320 if (srclen >= (int)(*size - *indx))
323 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
324 target = xrealloc (target, (*size = n));
327 FASTCOPY (source, target + *indx, srclen);
329 target[*indx] = '\0';
338 /* Append the textual representation of NUMBER to TARGET.
339 INDX and SIZE are as in SUB_APPEND_STRING. */
341 sub_append_number (number, target, indx, size)
342 int number, *indx, *size;
347 temp = itos (number);
348 return (sub_append_string (temp, target, indx, size));
352 /* Extract a substring from STRING, starting at SINDEX and ending with
353 one of the characters in CHARLIST. Don't make the ending character
354 part of the string. Leave SINDEX pointing at the ending character.
355 Understand about backslashes in the string. If VARNAME is non-zero,
356 and array variables have been compiled into the shell, everything
357 between a `[' and a corresponding `]' is skipped over. */
359 string_extract (string, sindex, charlist, varname)
360 char *string, *charlist;
361 int *sindex, varname;
366 for (i = *sindex; c = string[i]; i++)
373 #if defined (ARRAY_VARS)
374 else if (varname && c == '[')
377 /* If this is an array subscript, skip over it and continue. */
378 ni = skipsubscript (string, i);
379 if (string[ni] == ']')
383 else if (MEMBER (c, charlist))
387 temp = xmalloc (1 + c);
388 strncpy (temp, string + *sindex, c);
394 /* Extract the contents of STRING as if it is enclosed in double quotes.
395 SINDEX, when passed in, is the offset of the character immediately
396 following the opening double quote; on exit, SINDEX is left pointing after
397 the closing double quote. If STRIPDQ is non-zero, unquoted double
398 quotes are stripped and the string is terminated by a null byte.
399 Backslashes between the embedded double quotes are processed. If STRIPDQ
400 is zero, an unquoted `"' terminates the string. */
402 string_extract_double_quoted (string, sindex, stripdq)
404 int *sindex, stripdq;
407 char *temp, *ret; /* The new string we return. */
408 int pass_next, backquote, si; /* State variables for the machine. */
411 pass_next = backquote = dquote = 0;
412 temp = xmalloc (1 + strlen (string) - *sindex);
414 for (j = 0, i = *sindex; c = string[i]; i++)
416 /* Process a character that was quoted by a backslash. */
421 ``The backslash shall retain its special meaning as an escape
422 character only when followed by one of the characters:
425 If STRIPDQ is zero, we handle the double quotes here and let
426 expand_word_internal handle the rest. If STRIPDQ is non-zero,
427 we have already been through one round of backslash stripping,
428 and want to strip these backslashes only if DQUOTE is non-zero,
429 indicating that we are inside an embedded double-quoted string. */
431 /* If we are in an embedded quoted string, then don't strip
432 backslashes before characters for which the backslash
433 retains its special meaning, but remove backslashes in
434 front of other characters. If we are not in an
435 embedded quoted string, don't strip backslashes at all.
436 This mess is necessary because the string was already
437 surrounded by double quotes (and sh has some really weird
439 The returned string will be run through expansion as if
440 it were double-quoted. */
441 if ((stripdq == 0 && c != '"') ||
442 (stripdq && ((dquote && strchr (slashify_in_quotes, c)) || dquote == 0)))
449 /* A backslash protects the next character. The code just above
450 handles preserving the backslash in front of any character but
458 /* Inside backquotes, ``the portion of the quoted string from the
459 initial backquote and the characters up to the next backquote
460 that is not preceded by a backslash, having escape characters
461 removed, defines that command''. */
477 /* Pass everything between `$(' and the matching `)' or a quoted
478 ${ ... } pair through according to the Posix.2 specification. */
479 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
482 if (string[i + 1] == LPAREN)
483 ret = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
485 ret = extract_dollar_brace_string (string, &si, 1);
488 temp[j++] = string[i + 1];
490 for (t = 0; ret[t]; t++, j++)
492 temp[j++] = string[si];
499 /* Add any character but a double quote to the quoted string we're
518 /* Point to after the closing quote. */
526 /* This should really be another option to string_extract_double_quoted. */
528 skip_double_quoted (string, sind)
534 int pass_next, backquote, si;
536 pass_next = backquote = 0;
538 for (j = 0, i = sind; c = string[i]; i++)
561 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
564 if (string[i + 1] == LPAREN)
565 ret = extract_delimited_string (string, &si, "$(", "(", ")");
567 ret = extract_dollar_brace_string (string, &si, 0);
585 /* Extract the contents of STRING as if it is enclosed in single quotes.
586 SINDEX, when passed in, is the offset of the character immediately
587 following the opening single quote; on exit, SINDEX is left pointing after
588 the closing single quote. */
590 string_extract_single_quoted (string, sindex)
597 for (i = *sindex; string[i] && string[i] != '\''; i++)
602 strncpy (t, string + *sindex, j);
613 skip_single_quoted (string, sind)
619 for (i = sind; string[i] && string[i] != '\''; i++)
626 /* Just like string_extract, but doesn't hack backslashes or any of
627 that other stuff. Obeys quoting. Used to do splitting on $IFS. */
629 string_extract_verbatim (string, sindex, charlist)
630 char *string, *charlist;
633 register int i = *sindex;
637 if (charlist[0] == '\'' && charlist[1] == '\0')
639 temp = string_extract_single_quoted (string, sindex);
640 --*sindex; /* leave *sindex at separator character */
644 for (i = *sindex; c = string[i]; i++)
652 if (MEMBER (c, charlist))
657 temp = xmalloc (1 + c);
658 strncpy (temp, string + *sindex, c);
665 /* Extract the $( construct in STRING, and return a new string.
666 Start extracting at (SINDEX) as if we had just seen "$(".
667 Make (SINDEX) get the position of the matching ")". */
669 extract_command_subst (string, sindex)
673 return (extract_delimited_string (string, sindex, "$(", "(", ")"));
676 /* Extract the $[ construct in STRING, and return a new string.
677 Start extracting at (SINDEX) as if we had just seen "$[".
678 Make (SINDEX) get the position of the matching "]". */
680 extract_arithmetic_subst (string, sindex)
684 return (extract_delimited_string (string, sindex, "$[", "[", "]"));
687 #if defined (PROCESS_SUBSTITUTION)
688 /* Extract the <( or >( construct in STRING, and return a new string.
689 Start extracting at (SINDEX) as if we had just seen "<(".
690 Make (SINDEX) get the position of the matching ")". */ /*))*/
692 extract_process_subst (string, starter, sindex)
697 return (extract_delimited_string (string, sindex, starter, "(", ")"));
699 #endif /* PROCESS_SUBSTITUTION */
701 #if defined (ARRAY_VARS)
703 extract_array_assignment_list (string, sindex)
707 return (extract_delimited_string (string, sindex, "(", (char *)NULL, ")"));
711 /* Extract and create a new string from the contents of STRING, a
712 character string delimited with OPENER and CLOSER. SINDEX is
713 the address of an int describing the current offset in STRING;
714 it should point to just after the first OPENER found. On exit,
715 SINDEX gets the position of the last character of the matching CLOSER.
716 If OPENER is more than a single character, ALT_OPENER, if non-null,
717 contains a character string that can also match CLOSER and thus
718 needs to be skipped. */
720 extract_delimited_string (string, sindex, opener, alt_opener, closer)
723 char *opener, *alt_opener, *closer;
727 int pass_character, nesting_level;
728 int len_closer, len_opener, len_alt_opener;
730 len_opener = STRLEN (opener);
731 len_alt_opener = STRLEN (alt_opener);
732 len_closer = STRLEN (closer);
739 while (nesting_level)
746 if (pass_character) /* previous char was backslash */
761 if (c == '\\' && delimiter == '"' &&
762 (member (string[i], slashify_in_quotes)))
772 /* Process a nested OPENER. */
773 if (STREQN (string + i, opener, len_opener))
776 t = extract_delimited_string (string, &si, opener, alt_opener, closer);
782 /* Process a nested ALT_OPENER */
783 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
785 si = i + len_alt_opener;
786 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer);
792 /* If the current substring terminates the delimited string, decrement
793 the nesting level. */
794 if (STREQN (string + i, closer, len_closer))
796 i += len_closer - 1; /* move to last char of the closer */
798 if (nesting_level == 0)
802 /* Pass old-style command substitution through verbatim. */
806 t = string_extract (string, &si, "`", 0);
812 /* Pass single-quoted strings through verbatim. */
816 i = skip_single_quoted (string, si);
820 /* Pass embedded double-quoted strings through verbatim as well. */
824 i = skip_double_quoted (string, si);
828 i++; /* move past this character, which was not special. */
831 if (c == 0 && nesting_level)
833 report_error ("bad substitution: no `%s' in %s", closer, string);
834 jump_to_top_level (DISCARD);
837 si = i - *sindex - len_closer + 1;
838 result = xmalloc (1 + si);
839 strncpy (result, string + *sindex, si);
846 /* Extract a parameter expansion expression within ${ and } from STRING.
847 Obey the Posix.2 rules for finding the ending `}': count braces while
848 skipping over enclosed quoted strings and command substitutions.
849 SINDEX is the address of an int describing the current offset in STRING;
850 it should point to just after the first `{' found. On exit, SINDEX
851 gets the position of the matching `}'. QUOTED is non-zero if this
852 occurs inside double quotes. */
853 /* XXX -- this is very similar to extract_delimited_string -- XXX */
855 extract_dollar_brace_string (string, sindex, quoted)
859 register int i, c, l;
860 int pass_character, nesting_level, si;
867 for (i = *sindex; (c = string[i]); i++)
875 /* CTLESCs and backslashes quote the next character. */
876 if (c == CTLESC || c == '\\')
882 if (string[i] == '$' && string[i+1] == LBRACE)
892 if (nesting_level == 0)
897 /* Pass the contents of old-style command substitutions through
902 t = string_extract (string, &si, "`", 0);
908 /* Pass the contents of new-style command substitutions and
909 arithmetic substitutions through verbatim. */
910 if (string[i] == '$' && string[i+1] == LPAREN)
913 t = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
919 /* Pass the contents of single-quoted and double-quoted strings
921 if (c == '\'' || c == '"')
924 i = (c == '\'') ? skip_single_quoted (string, si)
925 : skip_double_quoted (string, si);
926 /* skip_XXX_quoted leaves index one past close quote */
932 if (c == 0 && nesting_level)
934 report_error ("bad substitution: no ending `}' in %s", string);
935 jump_to_top_level (DISCARD);
939 result = xmalloc (1 + l);
940 strncpy (result, string + *sindex, l);
947 /* Remove backslashes which are quoting backquotes from STRING. Modifies
948 STRING, and returns a pointer to it. */
950 de_backslash (string)
955 for (i = 0, l = strlen (string); i < l; i++)
956 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
957 string[i + 1] == '$'))
958 strcpy (string + i, string + i + 1); /* XXX - should be memmove */
964 /* Replace instances of \! in a string with !. */
966 unquote_bang (string)
972 temp = xmalloc (1 + strlen (string));
974 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
976 if (string[i] == '\\' && string[i + 1] == '!')
982 strcpy (string, temp);
987 #if defined (READLINE)
988 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
989 an unclosed quoted string), or if the character at EINDEX is quoted
992 char_is_quoted (string, eindex)
996 int i, pass_next, quoted;
998 for (i = pass_next = quoted = 0; i <= eindex; i++)
1003 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1007 else if (string[i] == '\'' || string[i] == '"')
1009 i = (string[i] == '\'') ? skip_single_quoted (string, ++i)
1010 : skip_double_quoted (string, ++i);
1013 i--; /* the skip functions increment past the closing quote. */
1015 else if (string[i] == '\\')
1025 unclosed_pair (string, eindex, openstr)
1030 int i, pass_next, openc, olen;
1032 olen = strlen (openstr);
1033 for (i = pass_next = openc = 0; i <= eindex; i++)
1038 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1042 else if (STREQN (string + i, openstr, olen))
1047 else if (string[i] == '\'' || string[i] == '"')
1049 i = (string[i] == '\'') ? skip_single_quoted (string, i)
1050 : skip_double_quoted (string, i);
1054 else if (string[i] == '\\')
1062 #endif /* READLINE */
1066 /* Extract the name of the variable to bind to from the assignment string. */
1068 assignment_name (string)
1074 offset = assignment (string);
1076 return (char *)NULL;
1077 temp = xmalloc (offset + 1);
1078 strncpy (temp, string, offset);
1079 temp[offset] = '\0';
1084 /* **************************************************************** */
1086 /* Functions to convert strings to WORD_LISTs and vice versa */
1088 /* **************************************************************** */
1090 /* Return a single string of all the words in LIST. SEP is the separator
1091 to put between individual elements of LIST in the output string. */
1093 string_list_internal (list, sep)
1097 register WORD_LIST *t;
1099 int word_len, sep_len, result_size;
1102 return ((char *)NULL);
1104 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1105 sep_len = STRLEN (sep);
1108 for (t = list; t; t = t->next)
1111 result_size += sep_len;
1112 result_size += strlen (t->word->word);
1115 r = result = xmalloc (result_size + 1);
1117 for (t = list; t; t = t->next)
1119 if (t != list && sep_len)
1123 FASTCOPY (sep, r, sep_len);
1130 word_len = strlen (t->word->word);
1131 FASTCOPY (t->word->word, r, word_len);
1139 /* Return a single string of all the words present in LIST, separating
1140 each word with a space. */
1145 return (string_list_internal (list, " "));
1148 /* Return a single string of all the words present in LIST, obeying the
1149 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1150 expansion [of $*] appears within a double quoted string, it expands
1151 to a single field with the value of each parameter separated by the
1152 first character of the IFS variable, or by a <space> if IFS is unset." */
1154 string_list_dollar_star (list)
1159 ifs = get_string_value ("IFS");
1161 sep[0] = (ifs == 0) ? ' ' : *ifs;
1164 return (string_list_internal (list, sep));
1167 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1168 is non-zero, the $@ appears within double quotes, and we should quote
1169 the list before converting it into a string. If IFS is unset, and the
1170 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1171 in the words in the list, because the default value of $IFS is
1172 <space><tab><newline>, IFS characters in the words in the list should
1173 also be split. If IFS is null, and the word is not quoted, we need
1174 to quote the words in the list to preserve the positional parameters
1177 string_list_dollar_at (list, quoted)
1184 ifs = get_string_value ("IFS");
1186 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1189 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1191 : list_quote_escapes (list);
1192 return (string_list_internal (tlist, sep));
1195 /* Return the list of words present in STRING. Separate the string into
1196 words at any of the characters found in SEPARATORS. If QUOTED is
1197 non-zero then word in the list will have its quoted flag set, otherwise
1198 the quoted flag is left as make_word () deemed fit.
1200 This obeys the P1003.2 word splitting semantics. If `separators' is
1201 exactly <space><tab><newline>, then the splitting algorithm is that of
1202 the Bourne shell, which treats any sequence of characters from `separators'
1203 as a delimiter. If IFS is unset, which results in `separators' being set
1204 to "", no splitting occurs. If separators has some other value, the
1205 following rules are applied (`IFS white space' means zero or more
1206 occurrences of <space>, <tab>, or <newline>, as long as those characters
1207 are in `separators'):
1209 1) IFS white space is ignored at the start and the end of the
1211 2) Each occurrence of a character in `separators' that is not
1212 IFS white space, along with any adjacent occurrences of
1213 IFS white space delimits a field.
1214 3) Any nonzero-length sequence of IFS white space delimits a field.
1217 /* BEWARE! list_string strips null arguments. Don't call it twice and
1218 expect to have "" preserved! */
1220 /* This performs word splitting and quoted null character removal on
1222 #define issep(c) (member ((c), separators))
1225 list_string (string, separators, quoted)
1226 register char *string, *separators;
1231 char *current_word, *s;
1232 int sindex, sh_style_split;
1234 if (!string || !*string)
1235 return ((WORD_LIST *)NULL);
1238 separators && *separators && (STREQ (separators, " \t\n"));
1240 /* Remove sequences of whitespace at the beginning of STRING, as
1241 long as those characters appear in IFS. Do not do this if
1242 STRING is quoted or if there are no separator characters. */
1243 if (!quoted || !separators || !*separators)
1245 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1248 return ((WORD_LIST *)NULL);
1253 /* OK, now STRING points to a word that does not begin with white space.
1254 The splitting algorithm is:
1255 extract a word, stopping at a separator
1256 skip sequences of spc, tab, or nl as long as they are separators
1257 This obeys the field splitting rules in Posix.2. */
1258 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1260 current_word = string_extract_verbatim (string, &sindex, separators);
1261 if (current_word == 0)
1264 /* If we have a quoted empty string, add a quoted null argument. We
1265 want to preserve the quoted null character iff this is a quoted
1266 empty string; otherwise the quoted null characters are removed
1268 if (QUOTED_NULL (current_word))
1270 t = make_bare_word ("");
1271 t->flags |= W_QUOTED;
1273 t->word = make_quoted_char ('\0');
1274 result = make_word_list (t, result);
1276 else if (current_word[0] != '\0')
1278 /* If we have something, then add it regardless. However,
1279 perform quoted null character removal on the current word. */
1280 remove_quoted_nulls (current_word);
1282 result = make_word_list (make_word (current_word), result);
1284 result = add_string_to_list (current_word, result);
1286 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
1287 result->word->flags |= W_QUOTED;
1290 /* If we're not doing sequences of separators in the traditional
1291 Bourne shell style, then add a quoted null argument. */
1292 else if (!sh_style_split && !spctabnl (string[sindex]))
1294 t = make_bare_word ("");
1295 t->flags |= W_QUOTED;
1297 t->word = make_quoted_char ('\0');
1298 result = make_word_list (t, result);
1301 free (current_word);
1303 /* Move past the current separator character. */
1307 /* Now skip sequences of space, tab, or newline characters if they are
1308 in the list of separators. */
1309 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
1312 return (REVERSE_LIST (result, WORD_LIST *));
1315 /* Parse a single word from STRING, using SEPARATORS to separate fields.
1316 ENDPTR is set to the first character after the word. This is used by
1318 XXX - this function is very similar to list_string; they should be
1321 get_word_from_string (stringp, separators, endptr)
1322 char **stringp, *separators, **endptr;
1326 int sindex, sh_style_split;
1328 if (!stringp || !*stringp || !**stringp)
1329 return ((char *)NULL);
1334 separators && *separators && (STREQ (separators, " \t\n"));
1336 /* Remove sequences of whitespace at the beginning of STRING, as
1337 long as those characters appear in IFS. */
1338 if (sh_style_split || !separators || !*separators)
1340 for (; *s && spctabnl (*s) && issep (*s); s++);
1342 /* If the string is nothing but whitespace, update it and return. */
1348 return ((char *)NULL);
1352 /* OK, S points to a word that does not begin with white space.
1353 Now extract a word, stopping at a separator, save a pointer to
1354 the first character after the word, then skip sequences of spc,
1355 tab, or nl as long as they are separators.
1357 This obeys the field splitting rules in Posix.2. */
1359 current_word = string_extract_verbatim (s, &sindex, separators);
1361 /* Set ENDPTR to the first character after the end of the word. */
1363 *endptr = s + sindex;
1365 /* Move past the current separator character. */
1369 /* Now skip sequences of space, tab, or newline characters if they are
1370 in the list of separators. */
1371 while (s[sindex] && spctabnl (s[sindex]) && issep (s[sindex]))
1374 /* Update STRING to point to the next field. */
1375 *stringp = s + sindex;
1376 return (current_word);
1379 /* Remove IFS white space at the end of STRING. Start at the end
1380 of the string and walk backwards until the beginning of the string
1381 or we find a character that's not IFS white space and not CTLESC.
1382 Only let CTLESC escape a white space character if SAW_ESCAPE is
1385 strip_trailing_ifs_whitespace (string, separators, saw_escape)
1386 char *string, *separators;
1391 s = string + STRLEN (string) - 1;
1392 while (s > string && ((spctabnl (*s) && issep (*s)) ||
1393 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
1399 #if defined (ARRAY_VARS)
1401 list_string_with_quotes (string)
1406 int c, i, tokstart, len;
1408 for (s = string; s && *s && spctabnl (*s); s++)
1410 if (s == 0 || *s == 0)
1411 return ((WORD_LIST *)NULL);
1414 list = (WORD_LIST *)NULL;
1425 i = skip_single_quoted (s, ++i);
1427 i = skip_double_quoted (s, ++i);
1428 else if (c == 0 || spctabnl (c))
1430 /* We have found the end of a token. Make a word out of it and
1431 add it to the word list. */
1433 token = xmalloc (len + 1);
1434 strncpy (token, s + tokstart, len);
1437 list = make_word_list (make_word (token), list);
1439 list = add_string_to_list (token, list);
1442 while (spctabnl (s[i]))
1450 i++; /* normal character */
1452 return (REVERSE_LIST (list, WORD_LIST *));
1454 #endif /* ARRAY_VARS */
1456 /********************************************************/
1458 /* Functions to perform assignment statements */
1460 /********************************************************/
1462 #if defined (ARRAY_VARS)
1464 do_array_element_assignment (name, value)
1471 t = strchr (name, '[');
1473 return ((SHELL_VAR *)NULL);
1475 ni = skipsubscript (name, ind);
1476 if ((ALL_ELEMENT_SUB (t[1]) && t[2] == ']') || (ni <= ind + 1))
1478 report_error ("%s: bad array subscript", name);
1479 return ((SHELL_VAR *)NULL);
1482 ind = array_expand_index (t, ni - ind);
1485 t[-1] = '['; /* restore original name */
1486 report_error ("%s: bad array subscript", name);
1487 return ((SHELL_VAR *)NULL);
1489 entry = bind_array_variable (name, ind, value);
1490 t[-1] = '['; /* restore original name */
1493 #endif /* ARRAY_VARS */
1495 /* Given STRING, an assignment string, get the value of the right side
1496 of the `=', and bind it to the left side. If EXPAND is true, then
1497 perform parameter expansion, command substitution, and arithmetic
1498 expansion on the right-hand side. Perform tilde expansion in any
1499 case. Do not perform word splitting on the result of expansion. */
1501 do_assignment_internal (string, expand)
1508 #if defined (ARRAY_VARS)
1510 int ni, assign_list = 0;
1513 offset = assignment (string);
1514 name = savestring (string);
1515 value = (char *)NULL;
1517 if (name[offset] == '=')
1522 temp = name + offset + 1;
1524 #if defined (ARRAY_VARS)
1525 if (expand && temp[0] == LPAREN && strchr (temp, RPAREN))
1527 assign_list = ni = 1;
1528 value = extract_delimited_string (temp, &ni, "(", (char *)NULL, ")");
1533 /* Perform tilde expansion. */
1534 if (expand && temp[0])
1536 temp = (strchr (temp, '~') && unquoted_member ('~', temp))
1537 ? bash_tilde_expand (temp)
1538 : savestring (temp);
1540 value = maybe_expand_string (temp, 0, expand_string_unsplit);
1544 value = savestring (temp);
1549 value = xmalloc (1);
1553 if (echo_command_at_execute)
1554 #if defined (ARRAY_VARS)
1556 fprintf (stderr, "%s%s=(%s)\n", indirection_level_string (), name, value);
1559 fprintf (stderr, "%s%s=%s\n", indirection_level_string (), name, value);
1561 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
1563 #if defined (ARRAY_VARS)
1564 if (t = strchr (name, '['))
1568 report_error ("%s: cannot assign list to array member", name);
1571 entry = do_array_element_assignment (name, value);
1575 else if (assign_list)
1576 entry = assign_array_from_string (name, value);
1578 #endif /* ARRAY_VARS */
1579 entry = bind_variable (name, value);
1581 stupidly_hack_special_variables (name);
1584 entry->attributes &= ~att_invisible;
1586 /* Return 1 if the assignment seems to have been performed correctly. */
1587 ASSIGN_RETURN (entry ? ((entry->attributes & att_readonly) == 0) : 0);
1590 /* Perform the assignment statement in STRING, and expand the
1591 right side by doing command and parameter expansion. */
1593 do_assignment (string)
1596 return do_assignment_internal (string, 1);
1599 /* Given STRING, an assignment string, get the value of the right side
1600 of the `=', and bind it to the left side. Do not do command and
1601 parameter substitution on the right hand side. */
1603 do_assignment_no_expand (string)
1606 return do_assignment_internal (string, 0);
1609 /***************************************************
1611 * Functions to manage the positional parameters *
1613 ***************************************************/
1615 /* Return the word list that corresponds to `$*'. */
1617 list_rest_of_args ()
1619 register WORD_LIST *list, *args;
1622 /* Break out of the loop as soon as one of the dollar variables is null. */
1623 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
1624 list = make_word_list (make_bare_word (dollar_vars[i]), list);
1626 for (args = rest_of_args; args; args = args->next)
1627 list = make_word_list (make_bare_word (args->word->word), list);
1629 return (REVERSE_LIST (list, WORD_LIST *));
1635 register WORD_LIST *list;
1638 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
1640 for (list = rest_of_args; list; list = list->next)
1645 /* Return the value of a positional parameter. This handles values > 10. */
1647 get_dollar_var_value (ind)
1654 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
1655 else /* We want something like ${11} */
1658 for (p = rest_of_args; p && ind--; p = p->next)
1660 temp = p ? savestring (p->word->word) : (char *)NULL;
1665 /* Make a single large string out of the dollar digit variables,
1666 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
1667 case of "$*" with respect to IFS. */
1669 string_rest_of_args (dollar_star)
1672 register WORD_LIST *list;
1675 list = list_rest_of_args ();
1676 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
1677 dispose_words (list);
1681 /* Return a string containing the positional parameters from START to
1682 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
1683 which only makes a difference if QUOTED is non-zero. */
1685 pos_params (string, start, end, quoted)
1687 int start, end, quoted;
1689 WORD_LIST *save, *params, *h, *t;
1693 save = params = list_rest_of_args ();
1695 return ((char *)NULL);
1697 for (i = 1; params && i < start; i++)
1698 params = params->next;
1700 return ((char *)NULL);
1701 for (h = t = params; params && i < end; i++)
1704 params = params->next;
1707 t->next = (WORD_LIST *)NULL;
1708 if (string[0] == '*')
1709 ret = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (h) : string_list (h);
1711 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
1714 dispose_words (save);
1718 /******************************************************************/
1720 /* Functions to expand strings to strings or WORD_LISTs */
1722 /******************************************************************/
1724 #if defined (PROCESS_SUBSTITUTION)
1725 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC)
1727 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
1730 /* If there are any characters in STRING that require full expansion,
1731 then call FUNC to expand STRING; otherwise just perform quote
1732 removal if necessary. This returns a new string. */
1734 maybe_expand_string (string, quoted, func)
1737 WORD_LIST *(*func)();
1743 for (i = saw_quote = 0; string[i]; i++)
1745 if (EXP_CHAR (string[i]))
1747 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
1753 list = (*func) (string, quoted);
1756 ret = string_list (list);
1757 dispose_words (list);
1762 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
1763 ret = string_quote_removal (string, quoted);
1765 ret = savestring (string);
1769 static inline char *
1770 expand_string_to_string (string, quoted, func)
1773 WORD_LIST *(*func)();
1778 if (string == 0 || *string == '\0')
1779 return ((char *)NULL);
1781 list = (*func) (string, quoted);
1784 ret = string_list (list);
1785 dispose_words (list);
1793 #if defined (COND_COMMAND)
1794 /* Just remove backslashes in STRING. Returns a new string. */
1796 remove_backslashes (string)
1801 r = ret = xmalloc (strlen (string) + 1);
1802 for (s = string; s && *s; )
1814 /* This needs better error handling. */
1815 /* Expand W for use as an argument to a unary or binary operator in a
1816 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
1817 to the != or == operator, and should be treated as a pattern. In
1818 this case, we quote the string specially for the globbing code. The
1819 caller is responsible for removing the backslashes if the unquoted
1820 words is needed later. */
1822 cond_expand_word (w, special)
1829 if (w->word == 0 || w->word[0] == '\0')
1830 return ((char *)NULL);
1832 l = call_expand_word_internal (w, 0, (int *)0, (int *)0);
1838 r = string_list (l);
1842 p = string_list (l);
1843 r = quote_string_for_globbing (p, QGLOB_CVTNULL);
1855 /* Call expand_word_internal to expand W and handle error returns.
1856 A convenience function for functions that don't want to handle
1857 any errors or free any memory before aborting. */
1859 call_expand_word_internal (w, q, c, e)
1865 result = expand_word_internal (w, q, c, e);
1866 if (result == &expand_word_error)
1868 /* By convention, each time this error is returned, w->word has
1869 already been freed. */
1870 w->word = (char *)NULL;
1871 jump_to_top_level (DISCARD);
1874 else if (result == &expand_word_fatal)
1875 jump_to_top_level (FORCE_EOF);
1881 /* Perform parameter expansion, command substitution, and arithmetic
1882 expansion on STRING, as if it were a word. Leave the result quoted. */
1884 expand_string_internal (string, quoted)
1891 if (string == 0 || *string == 0)
1892 return ((WORD_LIST *)NULL);
1894 bzero ((char *)&td, sizeof (td));
1896 tresult = call_expand_word_internal (&td, quoted, (int *)NULL, (int *)NULL);
1900 /* Expand STRING by performing parameter expansion, command substitution,
1901 and arithmetic expansion. Dequote the resulting WORD_LIST before
1902 returning it, but do not perform word splitting. The call to
1903 remove_quoted_nulls () is in here because word splitting normally
1904 takes care of quote removal. */
1906 expand_string_unsplit (string, quoted)
1912 if (!string || !*string)
1913 return ((WORD_LIST *)NULL);
1915 value = expand_string_internal (string, quoted);
1919 remove_quoted_nulls (value->word->word);
1920 dequote_list (value);
1925 /* Expand STRING just as if you were expanding a word, but do not dequote
1926 the resultant WORD_LIST. This is called only from within this file,
1927 and is used to correctly preserve quoted characters when expanding
1928 things like ${1+"$@"}. This does parameter expansion, command
1929 subsitution, arithmetic expansion, and word splitting. */
1931 expand_string_leave_quoted (string, quoted)
1938 if (string == 0 || *string == '\0')
1939 return ((WORD_LIST *)NULL);
1941 tlist = expand_string_internal (string, quoted);
1945 tresult = word_list_split (tlist);
1946 dispose_words (tlist);
1949 return ((WORD_LIST *)NULL);
1952 /* This does not perform word splitting or dequote the WORD_LIST
1955 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
1957 int quoted, *dollar_at_p, *has_dollar_at;
1962 if (string == 0 || *string == '\0')
1963 return (WORD_LIST *)NULL;
1965 bzero ((char *)&td, sizeof (td));
1967 tresult = call_expand_word_internal (&td, quoted, dollar_at_p, has_dollar_at);
1971 /* Expand STRING just as if you were expanding a word. This also returns
1972 a list of words. Note that filename globbing is *NOT* done for word
1973 or string expansion, just when the shell is expanding a command. This
1974 does parameter expansion, command substitution, arithmetic expansion,
1975 and word splitting. Dequote the resultant WORD_LIST before returning. */
1977 expand_string (string, quoted)
1983 if (!string || !*string)
1984 return ((WORD_LIST *)NULL);
1986 result = expand_string_leave_quoted (string, quoted);
1987 return (result ? dequote_list (result) : result);
1990 /***************************************************
1992 * Functions to handle quoting chars *
1994 ***************************************************/
1998 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
1999 The parser passes CTLNUL as CTLESC CTLNUL. */
2001 /* The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2002 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2003 data stream pass through properly.
2004 Here we remove doubled CTLESC characters inside quoted strings before
2005 quoting the entire string, so we do not double the number of CTLESC
2008 remove_quoted_escapes (string)
2018 t1 = t = xmalloc (strlen (string) + 1);
2019 for (docopy = 0, s = string; *s; s++, t1++)
2021 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2035 /* Quote escape characters in string s, but no other characters. This is
2036 used to protect CTLESC and CTLNUL in variable values from the rest of
2037 the word expansion process after the variable is expanded. */
2039 quote_escapes (string)
2042 register char *s, *t;
2045 result = xmalloc ((strlen (string) * 2) + 1);
2046 for (s = string, t = result; *s; )
2048 if (*s == CTLESC || *s == CTLNUL)
2057 list_quote_escapes (list)
2060 register WORD_LIST *w;
2063 for (w = list; w; w = w->next)
2066 w->word->word = quote_escapes (t);
2072 #ifdef INCLUDE_UNUSED
2074 dequote_escapes (string)
2077 register char *s, *t;
2080 result = xmalloc (strlen (string) + 1);
2081 for (s = string, t = result; *s; )
2083 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2101 register WORD_LIST *tlist;
2103 for (tlist = list; tlist; tlist = tlist->next)
2105 s = dequote_string (tlist->word->word);
2106 free (tlist->word->word);
2107 tlist->word->word = s;
2113 make_quoted_char (c)
2133 /* Quote STRING. Return a new string. */
2135 quote_string (string)
2143 result = xmalloc (2);
2149 result = xmalloc ((strlen (string) * 2) + 1);
2151 for (t = result; *string; )
2161 /* De-quoted quoted characters in STRING. */
2163 dequote_string (string)
2169 result = xmalloc (strlen (string) + 1);
2171 if (QUOTED_NULL (string))
2177 /* If no character in the string can be quoted, don't bother examining
2178 each character. Just return a copy of the string passed to us. */
2179 if (strchr (string, CTLESC) == NULL) /* XXX */
2181 strcpy (result, string); /* XXX */
2182 return (result); /* XXX */
2185 for (t = result; *string; string++, t++)
2187 if (*string == CTLESC)
2202 /* Quote the entire WORD_LIST list. */
2207 register WORD_LIST *w;
2210 for (w = list; w; w = w->next)
2213 w->word->word = quote_string (t);
2215 w->word->flags |= W_QUOTED;
2220 /* Perform quoted null character removal on STRING. We don't allow any
2221 quoted null characters in the middle or at the ends of strings because
2222 of how expand_word_internal works. remove_quoted_nulls () turns
2223 STRING into an empty string iff it only consists of a quoted null,
2224 and removes all unquoted CTLNUL characters. */
2226 #define remove_quoted_nulls(string) \
2227 do { if (QUOTED_NULL (string)) string[0] ='\0'; } while (0)
2230 remove_quoted_nulls (string)
2235 nstr = savestring (string);
2237 for (p = nstr, s = string; *s; s++)
2241 *p++ = *s++; /* CTLESC */
2244 *p++ = *s; /* quoted char */
2252 strcpy (string, nstr);
2256 /* Perform quoted null character removal on each element of LIST.
2257 This modifies LIST. */
2259 word_list_remove_quoted_nulls (list)
2262 register WORD_LIST *t;
2264 for (t = list; t; t = t->next)
2265 remove_quoted_nulls (t->word->word);
2268 /* **************************************************************** */
2270 /* Functions for Matching and Removing Patterns */
2272 /* **************************************************************** */
2274 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
2275 can have one of 4 values:
2276 RP_LONG_LEFT remove longest matching portion at start of PARAM
2277 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
2278 RP_LONG_RIGHT remove longest matching portion at end of PARAM
2279 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
2282 #define RP_LONG_LEFT 1
2283 #define RP_SHORT_LEFT 2
2284 #define RP_LONG_RIGHT 3
2285 #define RP_SHORT_RIGHT 4
2288 remove_pattern (param, pattern, op)
2289 char *param, *pattern;
2294 register char *p, *ret, c;
2296 if (param == NULL || *param == '\0')
2298 if (pattern == NULL || *pattern == '\0') /* minor optimization */
2299 return (savestring (param));
2301 len = STRLEN (param);
2306 case RP_LONG_LEFT: /* remove longest match at start */
2307 for (p = end; p >= param; p--)
2310 if (fnmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2313 return (savestring (p));
2319 case RP_SHORT_LEFT: /* remove shortest match at start */
2320 for (p = param; p <= end; p++)
2323 if (fnmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2326 return (savestring (p));
2332 case RP_LONG_RIGHT: /* remove longest match at end */
2333 for (p = param; p <= end; p++)
2335 if (fnmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2338 ret = savestring (param);
2345 case RP_SHORT_RIGHT: /* remove shortest match at end */
2346 for (p = end; p >= param; p--)
2348 if (fnmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2351 ret = savestring (param);
2358 return (savestring (param)); /* no match, return original string */
2361 /* Return 1 of the first character of STRING could match the first
2362 character of pattern PAT. Used to avoid n2 calls to fnmatch(). */
2364 match_pattern_char (pat, string)
2375 return (*string == c);
2377 return (*string == *pat);
2379 return (*string == LPAREN ? 1 : (*string != '\0'));
2385 return (*string == LPAREN ? 1 : (*string == c));
2387 return (*string != '\0');
2391 /* Match PAT anywhere in STRING and return the match boundaries.
2392 This returns 1 in case of a successful match, 0 otherwise. SP
2393 and EP are pointers into the string where the match begins and
2394 ends, respectively. MTYPE controls what kind of match is attempted.
2395 MATCH_BEG and MATCH_END anchor the match at the beginning and end
2396 of the string, respectively. The longest match is returned. */
2398 match_pattern (string, pat, mtype, sp, ep)
2404 register char *p, *p1;
2407 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
2410 end = string + STRLEN (string);
2415 for (p = string; p <= end; p++)
2417 if (match_pattern_char (pat, p))
2419 for (p1 = end; p1 >= p; p1--)
2421 c = *p1; *p1 = '\0';
2422 if (fnmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2436 if (match_pattern_char (pat, string) == 0)
2438 for (p = end; p >= string; p--)
2441 if (fnmatch (pat, string, FNMATCH_EXTFLAG) == 0)
2453 for (p = string; p <= end; p++)
2454 if (fnmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2467 getpatspec (c, value)
2472 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
2474 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
2477 /* Posix.2 says that the WORD should be run through tilde expansion,
2478 parameter expansion, command substitution and arithmetic expansion.
2479 This leaves the result quoted, so quote_string_for_globbing () has
2480 to be called to fix it up for fnmatch (). If QUOTED is non-zero,
2481 it means that the entire expression was enclosed in double quotes.
2482 This means that quoting characters in the pattern do not make any
2483 special pattern characters quoted. For example, the `*' in the
2484 following retains its special meaning: "${foo#'*'}". */
2486 getpattern (value, quoted, expandpat)
2488 int quoted, expandpat;
2494 tword = strchr (value, '~') ? bash_tilde_expand (value) : savestring (value);
2496 /* expand_string_internal () leaves WORD quoted and does not perform
2498 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
2501 pat = string_extract_double_quoted (tword, &i, 1);
2506 /* There is a problem here: how to handle single or double quotes in the
2507 pattern string when the whole expression is between double quotes? */
2509 l = *tword ? expand_string_for_rhs (tword, quoted, (int *)NULL, (int *)NULL)
2511 l = *tword ? expand_string_for_rhs (tword,
2512 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_NOQUOTE : quoted,
2513 (int *)NULL, (int *)NULL)
2517 pat = string_list (l);
2521 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
2528 /* Handle removing a pattern from a string as a result of ${name%[%]value}
2529 or ${name#[#]value}. */
2531 parameter_brace_remove_pattern (value, temp, c, quoted)
2536 char *pattern, *tword;
2538 patspec = getpatspec (c, value);
2539 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2542 pattern = getpattern (value, quoted, 1);
2544 tword = remove_pattern (temp, pattern, patspec);
2551 list_remove_pattern (list, pattern, patspec, type, quoted)
2554 int patspec, type, quoted;
2560 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
2562 tword = remove_pattern (l->word->word, pattern, patspec);
2563 w = make_bare_word (tword);
2565 new = make_word_list (w, new);
2568 l = REVERSE_LIST (new, WORD_LIST *);
2570 tword = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
2572 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
2579 parameter_list_remove_pattern (value, type, c, quoted)
2581 int type, c, quoted;
2584 char *pattern, *ret;
2587 patspec = getpatspec (c, value);
2588 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2591 pattern = getpattern (value, quoted, 1);
2593 list = list_rest_of_args ();
2594 ret = list_remove_pattern (list, pattern, patspec, type, quoted);
2595 dispose_words (list);
2600 #if defined (ARRAY_VARS)
2602 array_remove_pattern (value, aspec, aval, c, quoted)
2603 char *value, *aspec, *aval; /* AVAL == evaluated ASPEC */
2608 char *ret, *t, *pattern;
2611 var = array_variable_part (aspec, &t, &len);
2613 return ((char *)NULL);
2615 patspec = getpatspec (c, value);
2616 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2619 pattern = getpattern (value, quoted, 1);
2621 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
2623 if (array_p (var) == 0)
2625 report_error ("%s: bad array subscript", aspec);
2627 return ((char *)NULL);
2629 l = array_to_word_list (array_cell (var));
2631 return ((char *)NULL);
2632 ret = list_remove_pattern (l, pattern, patspec, t[0], quoted);
2637 ret = remove_pattern (aval, pattern, patspec);
2640 t = quote_escapes (ret);
2649 #endif /* ARRAY_VARS */
2651 /*******************************************
2653 * Functions to expand WORD_DESCs *
2655 *******************************************/
2657 /* Expand WORD, performing word splitting on the result. This does
2658 parameter expansion, command substitution, arithmetic expansion,
2659 word splitting, and quote removal. */
2662 expand_word (word, quoted)
2666 WORD_LIST *result, *tresult;
2668 tresult = call_expand_word_internal (word, quoted, (int *)NULL, (int *)NULL);
2669 result = word_list_split (tresult);
2670 dispose_words (tresult);
2671 return (result ? dequote_list (result) : result);
2674 /* Expand WORD, but do not perform word splitting on the result. This
2675 does parameter expansion, command substitution, arithmetic expansion,
2676 and quote removal. */
2678 expand_word_no_split (word, quoted)
2684 result = call_expand_word_internal (word, quoted, (int *)NULL, (int *)NULL);
2685 return (result ? dequote_list (result) : result);
2688 /* Perform shell expansions on WORD, but do not perform word splitting or
2689 quote removal on the result. */
2691 expand_word_leave_quoted (word, quoted)
2695 return (call_expand_word_internal (word, quoted, (int *)NULL, (int *)NULL));
2698 #if defined (PROCESS_SUBSTITUTION)
2700 /*****************************************************************/
2702 /* Hacking Process Substitution */
2704 /*****************************************************************/
2706 #if !defined (HAVE_DEV_FD)
2707 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
2708 of FIFOs the shell has open. unlink_fifo_list will walk the list and
2709 unlink all of them. add_fifo_list adds the name of an open FIFO to the
2710 list. NFIFO is a count of the number of FIFOs in the list. */
2711 #define FIFO_INCR 20
2712 extern char *mktemp ();
2714 static char **fifo_list = (char **)NULL;
2716 static int fifo_list_size;
2719 add_fifo_list (pathname)
2722 if (nfifo >= fifo_list_size - 1)
2724 fifo_list_size += FIFO_INCR;
2725 fifo_list = (char **)xrealloc (fifo_list,
2726 fifo_list_size * sizeof (char *));
2729 fifo_list[nfifo++] = savestring (pathname);
2740 unlink (fifo_list[nfifo]);
2741 free (fifo_list[nfifo]);
2742 fifo_list[nfifo] = (char *)NULL;
2752 tname = mktemp (savestring ("/tmp/sh-np-XXXXXX"));
2753 if (mkfifo (tname, 0600) < 0)
2756 return ((char *)NULL);
2759 add_fifo_list (tname);
2763 #else /* HAVE_DEV_FD */
2765 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
2766 has open to children. NFDS is a count of the number of bits currently
2767 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
2769 static char *dev_fd_list = (char *)NULL;
2771 static int totfds; /* The highest possible number of open files. */
2777 if (!dev_fd_list || fd >= totfds)
2782 totfds = getdtablesize ();
2783 if (totfds < 0 || totfds > 256)
2788 dev_fd_list = xrealloc (dev_fd_list, totfds);
2789 bzero (dev_fd_list + ofds, totfds - ofds);
2792 dev_fd_list[fd] = 1;
2804 for (i = 0; nfds && i < totfds; i++)
2815 #if defined (NOTDEF)
2816 print_dev_fd_list ()
2820 fprintf (stderr, "pid %d: dev_fd_list:", getpid ());
2823 for (i = 0; i < totfds; i++)
2826 fprintf (stderr, " %d", i);
2828 fprintf (stderr, "\n");
2833 make_dev_fd_filename (fd)
2838 ret = xmalloc (sizeof (DEV_FD_PREFIX) + 4);
2839 sprintf (ret, "%s%d", DEV_FD_PREFIX, fd);
2844 #endif /* HAVE_DEV_FD */
2846 /* Return a filename that will open a connection to the process defined by
2847 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
2848 a filename in /dev/fd corresponding to a descriptor that is one of the
2849 ends of the pipe. If not defined, we use named pipes on systems that have
2850 them. Systems without /dev/fd and named pipes are out of luck.
2852 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
2853 use the read end of the pipe and dup that file descriptor to fd 0 in
2854 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
2855 writing or use the write end of the pipe in the child, and dup that
2856 file descriptor to fd 1 in the child. The parent does the opposite. */
2859 process_substitute (string, open_for_read_in_child)
2861 int open_for_read_in_child;
2866 #if defined (HAVE_DEV_FD)
2867 int parent_pipe_fd, child_pipe_fd;
2869 #endif /* HAVE_DEV_FD */
2870 #if defined (JOB_CONTROL)
2871 pid_t old_pipeline_pgrp;
2874 if (!string || !*string || wordexp_only)
2875 return ((char *)NULL);
2877 #if !defined (HAVE_DEV_FD)
2878 pathname = make_named_pipe ();
2879 #else /* HAVE_DEV_FD */
2880 if (pipe (fildes) < 0)
2882 sys_error ("cannot make pipe for process substitution");
2883 return ((char *)NULL);
2885 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
2886 the pipe in the parent, otherwise the read end. */
2887 parent_pipe_fd = fildes[open_for_read_in_child];
2888 child_pipe_fd = fildes[1 - open_for_read_in_child];
2889 /* Move the parent end of the pipe to some high file descriptor, to
2890 avoid clashes with FDs used by the script. */
2891 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
2893 pathname = make_dev_fd_filename (parent_pipe_fd);
2894 #endif /* HAVE_DEV_FD */
2898 sys_error ("cannot make pipe for process substitution");
2899 return ((char *)NULL);
2902 old_pid = last_made_pid;
2904 #if defined (JOB_CONTROL)
2905 old_pipeline_pgrp = pipeline_pgrp;
2906 pipeline_pgrp = shell_pgrp;
2908 cleanup_the_pipeline ();
2912 #endif /* JOB_CONTROL */
2914 pid = make_child ((char *)NULL, 1);
2917 reset_terminating_signals (); /* XXX */
2918 /* Cancel traps, in trap.c. */
2919 restore_original_signals ();
2920 setup_async_signals ();
2921 subshell_environment = SUBSHELL_COMSUB;
2924 #if defined (JOB_CONTROL)
2925 set_sigchld_handler ();
2926 stop_making_children ();
2927 pipeline_pgrp = old_pipeline_pgrp;
2928 #endif /* JOB_CONTROL */
2932 sys_error ("cannot make child for process substitution");
2934 #if defined (HAVE_DEV_FD)
2935 close (parent_pipe_fd);
2936 close (child_pipe_fd);
2937 #endif /* HAVE_DEV_FD */
2938 return ((char *)NULL);
2943 #if defined (JOB_CONTROL)
2944 restore_pipeline (1);
2947 last_made_pid = old_pid;
2949 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
2951 #endif /* JOB_CONTROL && PGRP_PIPE */
2953 #if defined (HAVE_DEV_FD)
2954 close (child_pipe_fd);
2955 #endif /* HAVE_DEV_FD */
2960 set_sigint_handler ();
2962 #if defined (JOB_CONTROL)
2963 set_job_control (0);
2964 #endif /* JOB_CONTROL */
2966 #if !defined (HAVE_DEV_FD)
2967 /* Open the named pipe in the child. */
2968 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
2971 sys_error ("cannot open named pipe %s for %s", pathname,
2972 open_for_read_in_child ? "reading" : "writing");
2975 #else /* HAVE_DEV_FD */
2977 #endif /* HAVE_DEV_FD */
2979 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
2981 sys_error ("cannot duplicate named pipe %s as fd %d", pathname,
2982 open_for_read_in_child ? 0 : 1);
2988 /* Need to close any files that this process has open to pipes inherited
2990 if (current_fds_to_close)
2992 close_fd_bitmap (current_fds_to_close);
2993 current_fds_to_close = (struct fd_bitmap *)NULL;
2996 #if defined (HAVE_DEV_FD)
2997 /* Make sure we close the parent's end of the pipe and clear the slot
2998 in the fd list so it is not closed later, if reallocated by, for
2999 instance, pipe(2). */
3000 close (parent_pipe_fd);
3001 dev_fd_list[parent_pipe_fd] = 0;
3002 #endif /* HAVE_DEV_FD */
3004 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
3006 #if !defined (HAVE_DEV_FD)
3007 /* Make sure we close the named pipe in the child before we exit. */
3008 close (open_for_read_in_child ? 0 : 1);
3009 #endif /* !HAVE_DEV_FD */
3014 #endif /* PROCESS_SUBSTITUTION */
3016 /***********************************/
3018 /* Command Substitution */
3020 /***********************************/
3023 read_comsub (fd, quoted)
3026 char *istring, buf[128], *bufp;
3027 int bufn, istring_index, istring_size, c;
3029 istring = (char *)NULL;
3030 istring_index = istring_size = bufn = 0;
3032 /* Read the output of the command through the pipe. */
3039 while ((bufn = read (fd, buf, sizeof(buf))) < 0 && errno == EINTR)
3047 /* Add the character to ISTRING, possibly after resizing it. */
3048 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
3050 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
3051 istring[istring_index++] = CTLESC;
3053 istring[istring_index++] = c;
3057 istring[istring_index] = '\0';
3059 /* If we read no output, just return now and save ourselves some
3061 if (istring_index == 0)
3064 return (char *)NULL;
3067 /* Strip trailing newlines from the output of the command. */
3068 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
3070 while (istring_index > 0)
3072 if (istring[istring_index - 1] == '\n')
3076 /* If the newline was quoted, remove the quoting char. */
3077 if (istring[istring_index - 1] == CTLESC)
3083 istring[istring_index] = '\0';
3086 strip_trailing (istring, istring_index - 1, 1);
3091 /* Perform command substitution on STRING. This returns a string,
3094 command_substitute (string, quoted)
3098 pid_t pid, old_pid, old_pipeline_pgrp;
3100 int result, fildes[2];
3102 istring = (char *)NULL;
3104 /* Don't fork () if there is no need to. In the case of no command to
3105 run, just return NULL. */
3106 if (!string || !*string || (string[0] == '\n' && !string[1]))
3107 return ((char *)NULL);
3109 if (wordexp_only && read_but_dont_execute)
3111 last_command_exit_value = 125;
3112 jump_to_top_level (EXITPROG);
3115 /* Pipe the output of executing STRING into the current shell. */
3116 if (pipe (fildes) < 0)
3118 sys_error ("cannot make pipes for command substitution");
3122 old_pid = last_made_pid;
3123 #if defined (JOB_CONTROL)
3124 old_pipeline_pgrp = pipeline_pgrp;
3125 pipeline_pgrp = shell_pgrp;
3126 cleanup_the_pipeline ();
3129 pid = make_child ((char *)NULL, 0);
3131 /* Reset the signal handlers in the child, but don't free the
3133 reset_signal_handlers ();
3135 #if defined (JOB_CONTROL)
3136 set_sigchld_handler ();
3137 stop_making_children ();
3138 pipeline_pgrp = old_pipeline_pgrp;
3139 #endif /* JOB_CONTROL */
3143 sys_error ("cannot make child for command substitution");
3149 return ((char *)NULL);
3154 set_sigint_handler (); /* XXX */
3155 #if defined (JOB_CONTROL)
3156 set_job_control (0);
3158 if (dup2 (fildes[1], 1) < 0)
3160 sys_error ("command_substitute: cannot duplicate pipe as fd 1");
3161 exit (EXECUTION_FAILURE);
3164 /* If standard output is closed in the parent shell
3165 (such as after `exec >&-'), file descriptor 1 will be
3166 the lowest available file descriptor, and end up in
3167 fildes[0]. This can happen for stdin and stderr as well,
3168 but stdout is more important -- it will cause no output
3169 to be generated from this command. */
3170 if ((fildes[1] != fileno (stdin)) &&
3171 (fildes[1] != fileno (stdout)) &&
3172 (fildes[1] != fileno (stderr)))
3175 if ((fildes[0] != fileno (stdin)) &&
3176 (fildes[0] != fileno (stdout)) &&
3177 (fildes[0] != fileno (stderr)))
3180 /* The currently executing shell is not interactive. */
3183 /* This is a subshell environment. */
3184 subshell_environment = SUBSHELL_COMSUB;
3186 /* Command substitution does not inherit the -e flag. */
3187 exit_immediately_on_error = 0;
3189 remove_quoted_escapes (string);
3191 startup_state = 2; /* see if we can avoid a fork */
3192 /* Give command substitution a place to jump back to on failure,
3193 so we don't go back up to main (). */
3194 result = setjmp (top_level);
3196 if (result == EXITPROG)
3197 exit (last_command_exit_value);
3199 exit (EXECUTION_FAILURE);
3201 exit (parse_and_execute (string, "command substitution", SEVAL_NOHIST));
3205 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
3207 #endif /* JOB_CONTROL && PGRP_PIPE */
3211 istring = read_comsub (fildes[0], quoted);
3215 last_command_exit_value = wait_for (pid);
3216 last_command_subst_pid = pid;
3217 last_made_pid = old_pid;
3219 #if defined (JOB_CONTROL)
3220 /* If last_command_exit_value > 128, then the substituted command
3221 was terminated by a signal. If that signal was SIGINT, then send
3222 SIGINT to ourselves. This will break out of loops, for instance. */
3223 if (last_command_exit_value == (128 + SIGINT))
3224 kill (getpid (), SIGINT);
3226 /* wait_for gives the terminal back to shell_pgrp. If some other
3227 process group should have it, give it away to that group here.
3228 pipeline_pgrp is non-zero only while we are constructing a
3229 pipline, so what we are concerned about is whether or not that
3230 pipeline was started in the background. A pipeline started in
3231 the background should never get the tty back here. */
3233 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
3235 if (interactive && pipeline_pgrp != (pid_t)0 && subshell_environment != SUBSHELL_ASYNC)
3237 give_terminal_to (pipeline_pgrp);
3238 #endif /* JOB_CONTROL */
3244 /********************************************************
3246 * Utility functions for parameter expansion *
3248 ********************************************************/
3250 /* Utility functions to manage arrays and their contents for expansion */
3252 #if defined (ARRAY_VARS)
3254 valid_array_reference (name)
3260 t = strchr (name, '[');
3264 r = legal_identifier (name);
3268 /* Check for a properly-terminated non-blank subscript. */
3269 len = skipsubscript (t, 0);
3270 if (t[len] != ']' || len == 1)
3272 for (r = 1; r < len; r++)
3273 if (whitespace (t[r]) == 0)
3280 /* Expand the array index beginning at S and extending LEN characters. */
3282 array_expand_index (s, len)
3289 exp = xmalloc (len);
3290 strncpy (exp, s, len - 1);
3291 exp[len - 1] = '\0';
3292 t = maybe_expand_string (exp, 0, expand_string);
3293 this_command_name = (char *)NULL;
3294 val = evalexp (t, &expok);
3298 jump_to_top_level (DISCARD);
3302 /* Return the variable specified by S without any subscript. If non-null,
3303 return the index of the start of the subscript in *SUBP. If non-null,
3304 the length of the subscript is returned in *LENP. */
3306 array_variable_part (s, subp, lenp)
3314 t = strchr (s, '[');
3316 ni = skipsubscript (s, ind);
3317 if (ni <= ind + 1 || s[ni] != ']')
3319 report_error ("%s: bad array subscript", s);
3320 return ((SHELL_VAR *)NULL);
3324 var = find_variable (s);
3335 array_value_internal (s, quoted, allow_all)
3337 int quoted, allow_all;
3340 char *retval, *t, *temp;
3341 WORD_LIST *l, *list;
3344 var = array_variable_part (s, &t, &len);
3347 return (char *)NULL;
3349 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
3351 if (array_p (var) == 0 || allow_all == 0)
3353 report_error ("%s: bad array subscript", s);
3354 return ((char *)NULL);
3356 l = array_to_word_list (array_cell (var));
3357 if (l == (WORD_LIST *)NULL)
3358 return ((char *) NULL);
3361 if (t[0] == '*') /* ${name[*]} */
3362 retval = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
3363 else /* ${name[@]} */
3364 retval = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
3366 if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
3368 temp = string_list_dollar_star (l);
3369 retval = quote_string (temp);
3372 else /* ${name[@]} or unquoted ${name[*]} */
3373 retval = string_list_dollar_at (l, quoted);
3380 ind = array_expand_index (t, len);
3383 report_error ("%s: bad array subscript", var->name);
3384 return ((char *)NULL);
3386 if (array_p (var) == 0)
3387 return (ind == 0 ? savestring (value_cell (var)) : (char *)NULL);
3388 retval = array_reference (array_cell (var), ind);
3390 retval = quote_escapes (retval);
3397 array_value (s, quoted)
3401 return (array_value_internal (s, quoted, 1));
3404 /* Return the value of the array indexing expression S as a single string.
3405 If ALLOW_ALL is 0, do not allow `@' and `*' subscripts. This is used
3406 by other parts of the shell such as the arithmetic expression evaluator
3409 get_array_value (s, allow_all)
3413 return (array_value_internal (s, 0, allow_all));
3417 array_length_reference (s)
3425 var = array_variable_part (s, &t, &len);
3427 /* If unbound variables should generate an error, report one and return
3429 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
3433 report_error ("%s: unbound variable", s);
3439 else if (array_p (var) == 0)
3442 array = array_cell (var);
3444 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
3445 return (array_num_elements (array));
3447 ind = array_expand_index (t, len);
3450 report_error ("%s: bad array subscript", t);
3453 t = array_reference (array, ind);
3458 #endif /* ARRAY_VARS */
3461 valid_brace_expansion_word (name, var_is_special)
3465 if (digit (*name) && all_digits (name))
3467 else if (var_is_special)
3469 #if defined (ARRAY_VARS)
3470 else if (valid_array_reference (name))
3472 #endif /* ARRAY_VARS */
3473 else if (legal_identifier (name))
3479 /* Parameter expand NAME, and return a new string which is the expansion,
3480 or NULL if there was no expansion.
3481 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
3482 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
3483 NAME was found inside of a double-quoted expression. */
3485 parameter_brace_expand_word (name, var_is_special, quoted)
3487 int var_is_special, quoted;
3494 /* Handle multiple digit arguments, as in ${11}. */
3497 arg_index = atoi (name);
3498 temp = get_dollar_var_value (arg_index);
3500 else if (var_is_special) /* ${@} */
3503 tt = xmalloc (2 + strlen (name));
3504 tt[sindex = 0] = '$';
3505 strcpy (tt + 1, name);
3507 l = expand_string_leave_quoted (tt, quoted);
3509 temp = string_list (l);
3512 temp = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
3513 (int *)NULL, (int *)NULL, 0);
3517 #if defined (ARRAY_VARS)
3518 else if (valid_array_reference (name))
3520 temp = array_value (name, quoted);
3523 else if (var = find_variable (name))
3525 if (var && invisible_p (var) == 0)
3527 #if defined (ARRAY_VARS)
3528 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
3530 temp = value_cell (var);
3534 temp = quote_escapes (temp);
3536 if (tempvar_p (var))
3537 dispose_variable (var);
3540 temp = (char *)NULL;
3543 temp = (char *)NULL;
3548 /* Expand an indirect reference to a variable: ${!NAME} expands to the
3549 value of the variable whose name is the value of NAME. */
3551 parameter_brace_expand_indir (name, var_is_special, quoted)
3553 int var_is_special, quoted;
3557 t = parameter_brace_expand_word (name, var_is_special, quoted);
3560 temp = parameter_brace_expand_word (t, t[0] == '@' && t[1] == '\0', quoted);
3565 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
3566 depending on the value of C, the separating character. C can be one of
3567 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
3568 between double quotes. */
3570 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
3572 int c, quoted, *qdollaratp, *hasdollarat;
3575 char *t, *t1, *temp;
3578 temp = (*value == '~' || (strchr (value, '~') && unquoted_substring ("=~", value)))
3579 ? bash_tilde_expand (value)
3580 : savestring (value);
3582 /* If the entire expression is between double quotes, we want to treat
3583 the value as a double-quoted string, with the exception that we strip
3584 embedded unescaped double quotes. */
3585 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *temp)
3588 t = string_extract_double_quoted (temp, &hasdol, 1);
3594 /* XXX was 0 not quoted */
3595 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
3598 *hasdollarat = hasdol || (l && l->next);
3602 /* The expansion of TEMP returned something. We need to treat things
3603 slightly differently if HASDOL is non-zero. */
3604 temp = string_list (l);
3605 /* If l->next is not null, we know that TEMP contained "$@", since that
3606 is the only expansion that creates more than one word. */
3607 if ((hasdol && quoted) || l->next)
3611 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
3613 /* The brace expansion occurred between double quotes and there was
3614 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
3615 it does not expand to anything. In this case, we want to return
3616 a quoted empty string. */
3622 temp = (char *)NULL;
3624 if (c == '-' || c == '+')
3628 t = temp ? savestring (temp) : savestring ("");
3629 t1 = dequote_string (t);
3631 bind_variable (name, t1);
3636 /* Deal with the right hand side of a ${name:?value} expansion in the case
3637 that NAME is null or not set. If VALUE is non-null it is expanded and
3638 used as the error message to print, otherwise a standard message is
3641 parameter_brace_expand_error (name, value)
3647 if (value && *value)
3649 l = expand_string (value, 0);
3650 temp = string_list (l);
3651 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
3656 report_error ("%s: parameter null or not set", name);
3658 /* Free the data we have allocated during this expansion, since we
3659 are about to longjmp out. */
3664 /* Return 1 if NAME is something for which parameter_brace_expand_length is
3667 valid_length_expression (name)
3670 return (!name[1] || /* ${#} */
3671 ((name[1] == '@' || name[1] == '*') && !name[2]) || /* ${#@}, ${#*} */
3672 (member (name[1], "-?$!#") && !name[2]) || /* ${#-}, etc. */
3673 (digit (name[1]) && all_digits (name + 1)) || /* ${#11} */
3674 #if defined (ARRAY_VARS)
3675 valid_array_reference (name + 1) || /* ${#a[7]} */
3677 legal_identifier (name + 1)); /* ${#PS1} */
3680 /* Handle the parameter brace expansion that requires us to return the
3681 length of a parameter. */
3683 parameter_brace_expand_length (name)
3689 #if defined (ARRAY_VARS)
3693 if (name[1] == '\0') /* ${#} */
3694 number = number_of_args ();
3695 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
3696 number = number_of_args ();
3697 else if (member (name[1], "-?$!#") && name[2] == '\0')
3699 /* Take the lengths of some of the shell's special parameters. */
3703 t = which_set_flags ();
3706 t = itos (last_command_exit_value);
3709 t = itos (dollar_dollar_pid);
3712 if (last_asynchronous_pid == NO_PID)
3715 t = itos ((int)last_asynchronous_pid);
3718 t = itos (number_of_args ());
3721 number = STRLEN (t);
3724 #if defined (ARRAY_VARS)
3725 else if (valid_array_reference (name + 1))
3726 number = array_length_reference (name + 1);
3727 #endif /* ARRAY_VARS */
3732 if (digit (name[1])) /* ${#1} */
3734 t = get_dollar_var_value (atoi (name + 1));
3735 number = STRLEN (t);
3738 #if defined (ARRAY_VARS)
3739 else if ((var = find_variable (name + 1)) && array_p (var))
3741 t = array_reference (array_cell (var), 0);
3742 number = STRLEN (t);
3747 newname = savestring (name);
3749 list = expand_string (newname, Q_DOUBLE_QUOTES);
3750 t = list ? string_list (list) : (char *)NULL;
3753 dispose_words (list);
3755 number = STRLEN (t);
3763 /* Verify and limit the start and end of the desired substring. If
3764 VTYPE == 0, a regular shell variable is being used; if it is 1,
3765 then the positional parameters are being used; if it is 2, then
3766 VALUE is really a pointer to an array variable that should be used.
3767 Return value is 1 if both values were OK, 0 if there was a problem
3768 with an invalid expression, or -1 if the values were out of range. */
3770 verify_substring_values (value, substr, vtype, e1p, e2p)
3771 char *value, *substr;
3772 int vtype, *e1p, *e2p;
3776 #if defined (ARRAY_VARS)
3780 t = strchr (substr, ':');
3783 temp1 = maybe_expand_string (substr, Q_DOUBLE_QUOTES, expand_string);
3784 *e1p = evalexp (temp1, &expok);
3792 case VT_ARRAYMEMBER:
3793 len = strlen (value);
3796 len = number_of_args () + 1;
3798 #if defined (ARRAY_VARS)
3801 len = array_num_elements (a) + 1;
3806 if (*e1p < 0) /* negative offsets count from end */
3809 if (*e1p >= len || *e1p < 0)
3815 temp1 = maybe_expand_string (t, Q_DOUBLE_QUOTES, expand_string);
3817 *e2p = evalexp (temp1, &expok);
3823 internal_error ("%s: substring expression < 0", t);
3826 *e2p += *e1p; /* want E2 chars starting at E1 */
3836 /* Return the type of variable specified by VARNAME (simple variable,
3837 positional param, or array variable). Also return the value specified
3838 by VARNAME (value of a variable or a reference to an array element). */
3840 get_var_and_type (varname, value, varp, valp)
3841 char *varname, *value;
3847 #if defined (ARRAY_VARS)
3851 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0'; /* VT_POSPARMS */
3852 *varp = (SHELL_VAR *)NULL;
3854 #if defined (ARRAY_VARS)
3855 if (valid_array_reference (varname))
3857 v = array_variable_part (varname, &temp, (int *)0);
3858 if (v && array_p (v))
3860 if ((temp[0] == '@' || temp[0] == '*') && temp[1] == ']')
3862 vtype = VT_ARRAYVAR;
3863 *valp = (char *)array_cell (v);
3867 vtype = VT_ARRAYMEMBER;
3868 *valp = array_value (varname, 1);
3875 else if ((v = find_variable (varname)) && array_p (v))
3877 vtype = VT_VARIABLE;
3879 *valp = array_reference (array_cell (v), 0);
3888 /******************************************************/
3890 /* Functions to extract substrings of variable values */
3892 /******************************************************/
3894 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
3895 is `@', use the positional parameters; otherwise, use the value of
3896 VARNAME. If VARNAME is an array variable, use the array elements. */
3899 parameter_brace_substring (varname, value, substr, quoted)
3900 char *varname, *value, *substr;
3903 int e1, e2, vtype, r;
3908 return ((char *)NULL);
3910 this_command_name = varname;
3912 vtype = get_var_and_type (varname, value, &v, &val);
3914 return ((char *)NULL);
3916 r = verify_substring_values (val, substr, vtype, &e1, &e2);
3919 if (val && vtype == VT_ARRAYMEMBER)
3921 return ((r == 0) ? &expand_param_error : (char *)NULL);
3927 case VT_ARRAYMEMBER:
3928 temp = quoted ? quoted_substring (value, e1, e2) : substring (value, e1, e2);
3931 temp = pos_params (varname, e1, e2, quoted);
3933 #if defined (ARRAY_VARS)
3935 temp = array_subrange (array_cell (v), e1, e2, quoted);
3943 /****************************************************************/
3945 /* Functions to perform pattern substitution on variable values */
3947 /****************************************************************/
3950 pat_subst (string, pat, rep, mflags)
3951 char *string, *pat, *rep;
3954 char *ret, *s, *e, *str;
3955 int rsize, rptr, l, replen, mtype;
3957 ret = xmalloc (rsize = 64);
3960 mtype = mflags & MATCH_TYPEMASK;
3962 for (replen = STRLEN (rep), rptr = 0, str = string;;)
3964 if (match_pattern (str, pat, mtype, &s, &e) == 0)
3967 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
3969 /* OK, now copy the leading unmatched portion of the string (from
3970 str to s) to ret starting at rptr (the current offset). Then copy
3971 the replacement string at ret + rptr + (s - str). Increment
3972 rptr (if necessary) and str and go on. */
3975 strncpy (ret + rptr, str, l);
3980 strncpy (ret + rptr, rep, replen);
3983 str = e; /* e == end of match */
3984 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
3988 /* Now copy the unmatched portion of the input string */
3991 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
3992 strcpy (ret + rptr, str);
4000 /* Do pattern match and replacement on the positional parameters. */
4002 pos_params_pat_subst (string, pat, rep, mflags)
4003 char *string, *pat, *rep;
4006 WORD_LIST *save, *params;
4010 save = params = list_rest_of_args ();
4012 return ((char *)NULL);
4014 for ( ; params; params = params->next)
4016 ret = pat_subst (params->word->word, pat, rep, mflags);
4017 w = make_bare_word (ret);
4018 dispose_word (params->word);
4023 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
4024 dispose_words (save);
4029 /* Perform pattern substitution on VALUE, which is the expansion of
4030 VARNAME. PATSUB is an expression supplying the pattern to match
4031 and the string to substitute. QUOTED is a flags word containing
4032 the type of quoting currently in effect. */
4034 parameter_brace_patsub (varname, value, patsub, quoted)
4035 char *varname, *value, *patsub;
4039 char *val, *temp, *pat, *rep, *p;
4043 return ((char *)NULL);
4045 this_command_name = varname;
4047 vtype = get_var_and_type (varname, value, &v, &val);
4049 return ((char *)NULL);
4054 mflags |= MATCH_GLOBREP;
4058 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4059 mflags |= MATCH_QUOTED;
4061 if (rep = quoted_strchr (patsub, '/', ST_BACKSL))
4066 if (rep && *rep == '\0')
4069 /* Expand PAT and REP for command, variable and parameter, arithmetic,
4070 and process substitution. Also perform quote removal. Do not
4071 perform word splitting or filename generation. */
4073 pat = maybe_expand_string (patsub, quoted, expand_string_unsplit);
4075 pat = maybe_expand_string (patsub, (quoted & ~Q_DOUBLE_QUOTES), expand_string_unsplit);
4079 if ((mflags & MATCH_QUOTED) == 0)
4080 rep = maybe_expand_string (rep, quoted, expand_string_unsplit);
4082 rep = expand_string_to_string (rep, quoted, expand_string_unsplit);
4086 if (pat && pat[0] == '#')
4088 mflags |= MATCH_BEG;
4091 else if (pat && pat[0] == '%')
4093 mflags |= MATCH_END;
4097 mflags |= MATCH_ANY;
4099 /* OK, we now want to substitute REP for PAT in VAL. If
4100 flags & MATCH_GLOBREP is non-zero, the substitution is done
4101 everywhere, otherwise only the first occurrence of PAT is
4106 case VT_ARRAYMEMBER:
4107 temp = pat_subst (val, p, rep, mflags);
4110 temp = pos_params_pat_subst (val, p, rep, mflags);
4112 #if defined (ARRAY_VARS)
4114 temp = array_pat_subst (array_cell (v), p, rep, mflags);
4119 if (val && v && array_p (v) && vtype == VT_ARRAYMEMBER)
4128 /****************************************************************/
4130 /* Functions to perform parameter expansion on a string */
4132 /****************************************************************/
4134 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
4136 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
4138 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
4140 int check_nullness, var_is_set, var_is_null, var_is_special;
4141 int want_substring, want_indir, want_patsub;
4142 char *name, *value, *temp, *temp1;
4143 int t_index, sindex, c, number;
4145 value = (char *)NULL;
4146 var_is_set = var_is_null = var_is_special = check_nullness = 0;
4147 want_substring = want_indir = want_patsub = 0;
4151 name = string_extract (string, &t_index, "#%:-=?+/}", 1);
4153 /* If the name really consists of a special variable, then make sure
4154 that we have the entire name. We don't allow indirect references
4155 to special variables except `#', `?', `@' and `*'. */
4156 if ((sindex == t_index &&
4157 (string[t_index] == '-' ||
4158 string[t_index] == '?' ||
4159 string[t_index] == '#')) ||
4160 (sindex == t_index - 1 && string[sindex] == '!' &&
4161 (string[t_index] == '#' ||
4162 string[t_index] == '?' ||
4163 string[t_index] == '@' ||
4164 string[t_index] == '*')))
4168 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
4169 name = xmalloc (3 + (strlen (temp1)));
4170 *name = string[sindex];
4171 if (string[sindex] == '!')
4173 /* indirect reference of $#, $?, $@, or $* */
4174 name[1] = string[sindex + 1];
4175 strcpy (name + 2, temp1);
4178 strcpy (name + 1, temp1);
4183 /* Find out what character ended the variable name. Then
4184 do the appropriate thing. */
4185 if (c = string[sindex])
4188 /* If c is followed by one of the valid parameter expansion
4189 characters, move past it as normal. If not, assume that
4190 a substring specification is being given, and do not move
4192 if (c == ':' && member (string[sindex], "-=?+"))
4195 if (c = string[sindex])
4198 else if (c == ':' && string[sindex] != RBRACE)
4200 else if (c == '/' && string[sindex] != RBRACE)
4203 /* Catch the valid and invalid brace expressions that made it through the
4205 /* ${#-} is a valid expansion and means to take the length of $-.
4206 Similarly for ${#?} and ${##}... */
4207 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4208 member (c, "-?#") && string[sindex] == RBRACE)
4210 name = xrealloc (name, 3);
4213 c = string[sindex++];
4216 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
4217 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4218 member (c, "%:=+/") && string[sindex] == RBRACE)
4220 temp = (char *)NULL;
4221 goto bad_substitution;
4224 /* Indirect expansion begins with a `!'. A valid indirect expansion is
4225 either a variable name, one of the positional parameters or a special
4226 variable that expands to one of the positional parameters. */
4227 want_indir = *name == '!' &&
4228 (legal_variable_starter (name[1]) || digit (name[1]) || member (name[1], "#?@*"));
4230 /* Determine the value of this variable. */
4232 /* Check for special variables, directly referenced. */
4233 if ((digit (*name) && all_digits (name)) ||
4234 (name[1] == '\0' && member (*name, "#-?$!@*")) ||
4235 (want_indir && name[2] == '\0' && member (name[1], "#?@*")))
4238 /* Check for special expansion things, like the length of a parameter */
4239 if (*name == '#' && name[1])
4241 /* If we are not pointing at the character just after the
4242 closing brace, then we haven't gotten all of the name.
4243 Since it begins with a special character, this is a bad
4244 substitution. Also check NAME for validity before trying
4246 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
4248 temp = (char *)NULL;
4249 goto bad_substitution;
4252 number = parameter_brace_expand_length (name);
4256 return ((number < 0) ? &expand_param_error : itos (number));
4259 /* ${@} is identical to $@. */
4260 if (name[0] == '@' && name[1] == '\0')
4262 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4263 *quoted_dollar_atp = 1;
4265 if (contains_dollar_at)
4266 *contains_dollar_at = 1;
4269 /* Make sure that NAME is valid before trying to go on. */
4270 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
4271 var_is_special) == 0)
4273 temp = (char *)NULL;
4274 goto bad_substitution;
4278 temp = parameter_brace_expand_indir (name + 1, var_is_special, quoted);
4280 temp = parameter_brace_expand_word (name, var_is_special, quoted);
4282 #if defined (ARRAY_VARS)
4284 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && valid_array_reference (name))
4286 if (valid_array_reference (name))
4289 temp1 = strchr (name, '[');
4290 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4292 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4293 *quoted_dollar_atp = 1;
4294 if (contains_dollar_at)
4295 *contains_dollar_at = 1;
4297 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4298 which should result in separate words even when IFS is unset. */
4299 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4301 if (contains_dollar_at)
4302 *contains_dollar_at = 1;
4307 var_is_set = temp != (char *)0;
4308 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
4310 /* Get the rest of the stuff inside the braces. */
4311 if (c && c != RBRACE)
4313 /* Extract the contents of the ${ ... } expansion
4314 according to the Posix.2 rules. */
4315 value = extract_dollar_brace_string (string, &sindex, quoted);
4316 if (string[sindex] == RBRACE)
4319 goto bad_substitution;
4322 value = (char *)NULL;
4326 /* If this is a substring spec, process it and add the result. */
4329 temp1 = parameter_brace_substring (name, temp, value, quoted);
4335 else if (want_patsub)
4337 temp1 = parameter_brace_patsub (name, temp, value, quoted);
4344 /* Do the right thing based on which character ended the variable name. */
4350 report_error ("%s: bad substitution", string ? string : "??");
4354 return &expand_param_error;
4357 if (var_is_set == 0 && unbound_vars_is_error)
4359 report_error ("%s: unbound variable", name);
4363 last_command_exit_value = EXECUTION_FAILURE;
4364 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4368 case '#': /* ${param#[#]pattern} */
4369 case '%': /* ${param%[%]pattern} */
4370 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
4375 if ((name[0] == '@' || name[0] == '*') && name[1] == '\0')
4376 temp1 = parameter_list_remove_pattern (value, name[0], c, quoted);
4377 #if defined (ARRAY_VARS)
4378 else if (valid_array_reference (name))
4379 temp1 = array_remove_pattern (value, name, temp, c, quoted);
4382 temp1 = parameter_brace_remove_pattern (value, temp, c, quoted);
4392 if (var_is_set && var_is_null == 0)
4394 /* We don't want the value of the named variable for
4395 anything, just the value of the right hand side. */
4401 temp = parameter_brace_expand_rhs (name, value, c,
4404 contains_dollar_at);
4408 temp = (char *)NULL;
4414 /* Otherwise do nothing; just use the value in TEMP. */
4416 else /* VAR not set or VAR is NULL. */
4419 temp = (char *)NULL;
4420 if (c == '=' && var_is_special)
4422 report_error ("$%s: cannot assign in this way", name);
4425 return &expand_param_error;
4429 parameter_brace_expand_error (name, value);
4430 return (interactive ? &expand_param_error : &expand_param_fatal);
4433 temp = parameter_brace_expand_rhs (name, value, c, quoted,
4435 contains_dollar_at);
4444 /* Expand a single ${xxx} expansion. The braces are optional. When
4445 the braces are used, parameter_brace_expand() does the work,
4446 possibly calling param_expand recursively. */
4448 param_expand (string, sindex, quoted, expanded_something,
4449 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
4452 int *sindex, quoted, *expanded_something, *contains_dollar_at;
4453 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
4456 int zindex, number, c, t_index, expok;
4458 WORD_LIST *list, *tlist;
4461 c = string[++zindex];
4463 temp = (char *)NULL;
4465 /* Do simple cases first. Switch on what follows '$'. */
4479 temp1 = dollar_vars[digit_value (c)];
4480 if (unbound_vars_is_error && temp1 == (char *)NULL)
4482 report_error ("$%c: unbound variable", c);
4483 last_command_exit_value = EXECUTION_FAILURE;
4484 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4486 temp = temp1 ? savestring (temp1) : (char *)NULL;
4489 /* $$ -- pid of the invoking shell. */
4491 temp = itos (dollar_dollar_pid);
4494 /* $# -- number of positional parameters. */
4496 temp = itos (number_of_args ());
4499 /* $? -- return value of the last synchronous command. */
4501 temp = itos (last_command_exit_value);
4504 /* $- -- flags supplied to the shell on invocation or by `set'. */
4506 temp = which_set_flags ();
4509 /* $! -- Pid of the last asynchronous command. */
4511 /* If no asynchronous pids have been created, expand to nothing.
4512 If `set -u' has been executed, and no async processes have
4513 been created, this is an expansion error. */
4514 if (last_asynchronous_pid == NO_PID)
4516 if (expanded_something)
4517 *expanded_something = 0;
4518 temp = (char *)NULL;
4519 if (unbound_vars_is_error)
4521 report_error ("$%c: unbound variable", c);
4522 last_command_exit_value = EXECUTION_FAILURE;
4523 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4527 temp = itos ((int)last_asynchronous_pid);
4530 /* The only difference between this and $@ is when the arg is quoted. */
4531 case '*': /* `$*' */
4532 list = list_rest_of_args ();
4534 /* If there are no command-line arguments, this should just
4535 disappear if there are other characters in the expansion,
4536 even if it's quoted. */
4537 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
4538 temp = (char *)NULL;
4539 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4541 /* If we have "$*" we want to make a string of the positional
4542 parameters, separated by the first character of $IFS, and
4543 quote the whole string, including the separators. If IFS
4544 is unset, the parameters are separated by ' '; if $IFS is
4545 null, the parameters are concatenated. */
4546 temp = string_list_dollar_star (list);
4547 temp1 = quote_string (temp);
4553 /* If the $* is not quoted it is identical to $@ */
4554 temp = string_list_dollar_at (list, quoted);
4555 if (contains_dollar_at)
4556 *contains_dollar_at = 1;
4559 dispose_words (list);
4562 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
4563 means that we have to turn quoting off after we split into
4564 the individually quoted arguments so that the final split
4565 on the first character of $IFS is still done. */
4566 case '@': /* `$@' */
4567 list = list_rest_of_args ();
4569 /* We want to flag the fact that we saw this. We can't turn
4570 off quoting entirely, because other characters in the
4571 string might need it (consider "\"$@\""), but we need some
4572 way to signal that the final split on the first character
4573 of $IFS should be done, even though QUOTED is 1. */
4574 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
4575 *quoted_dollar_at_p = 1;
4576 if (contains_dollar_at)
4577 *contains_dollar_at = 1;
4579 /* We want to separate the positional parameters with the first
4580 character of $IFS in case $IFS is something other than a space.
4581 We also want to make sure that splitting is done no matter what --
4582 according to POSIX.2, this expands to a list of the positional
4583 parameters no matter what IFS is set to. */
4584 temp = string_list_dollar_at (list, quoted);
4586 dispose_words (list);
4590 temp = parameter_brace_expand (string, &zindex, quoted,
4592 contains_dollar_at);
4593 if (temp == &expand_param_error || temp == &expand_param_fatal)
4597 /* quoted nulls should be removed if there is anything else
4599 /* Note that we saw the quoted null so we can add one back at
4600 the end of this function if there are no other characters
4601 in the string, discard TEMP, and go on. */
4602 if (temp && QUOTED_NULL (temp))
4604 if (had_quoted_null_p)
4605 *had_quoted_null_p = 1;
4607 temp = (char *)NULL;
4612 /* Do command or arithmetic substitution. */
4614 /* We have to extract the contents of this paren substitution. */
4615 t_index = zindex + 1;
4616 temp = extract_command_subst (string, &t_index);
4619 /* For Posix.2-style `$(( ))' arithmetic substitution,
4620 extract the expression and pass it to the evaluator. */
4621 if (temp && *temp == LPAREN)
4625 temp2 = savestring (temp1);
4626 t_index = strlen (temp2) - 1;
4628 if (temp2[t_index] != RPAREN)
4634 /* Cut off ending `)' */
4635 temp2[t_index] = '\0';
4637 /* Expand variables found inside the expression. */
4638 temp1 = maybe_expand_string (temp2, Q_DOUBLE_QUOTES, expand_string);
4642 /* No error messages. */
4643 this_command_name = (char *)NULL;
4644 number = evalexp (temp1, &expok);
4649 if (interactive_shell == 0 && posixly_correct)
4651 last_command_exit_value = EXECUTION_FAILURE;
4652 return (&expand_param_fatal);
4655 return (&expand_param_error);
4657 temp = itos (number);
4662 temp1 = command_substitute (temp, quoted);
4667 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
4668 away in a future bash release. */
4670 /* We have to extract the contents of this arithmetic substitution. */
4671 t_index = zindex + 1;
4672 temp = extract_arithmetic_subst (string, &t_index);
4675 /* Do initial variable expansion. */
4676 temp1 = maybe_expand_string (temp, Q_DOUBLE_QUOTES, expand_string);
4681 /* Find the variable in VARIABLE_LIST. */
4682 temp = (char *)NULL;
4684 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
4686 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
4688 /* If this isn't a variable name, then just output the `$'. */
4689 if (temp1 == 0 || *temp1 == '\0')
4695 if (expanded_something)
4696 *expanded_something = 0;
4700 /* If the variable exists, return its value cell. */
4701 var = find_variable (temp1);
4703 if (var && invisible_p (var) == 0 && value_cell (var))
4705 #if defined (ARRAY_VARS)
4708 temp = array_reference (array_cell (var), 0);
4710 temp = quote_escapes (temp);
4714 temp = quote_escapes (value_cell (var));
4716 if (tempvar_p (var)) /* XXX */
4718 dispose_variable (var); /* XXX */
4719 var = (SHELL_VAR *)NULL;
4724 temp = (char *)NULL;
4726 if (unbound_vars_is_error)
4727 report_error ("%s: unbound variable", temp1);
4735 last_command_exit_value = EXECUTION_FAILURE;
4736 return ((unbound_vars_is_error && interactive_shell == 0)
4737 ? &expand_param_fatal
4738 : &expand_param_error);
4749 /* Make a word list which is the result of parameter and variable
4750 expansion, command substitution, arithmetic substitution, and
4751 quote removal of WORD. Return a pointer to a WORD_LIST which is
4752 the result of the expansion. If WORD contains a null word, the
4753 word list returned is also null.
4755 QUOTED contains flag values defined in shell.h.
4757 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
4758 they point to an integer value which receives information about expansion.
4759 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
4760 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
4763 This only does word splitting in the case of $@ expansion. In that
4764 case, we split on ' '. */
4766 /* Values for the local variable quoted_state. */
4768 #define PARTIALLY_QUOTED 1
4769 #define WHOLLY_QUOTED 2
4772 expand_word_internal (word, quoted, contains_dollar_at, expanded_something)
4775 int *contains_dollar_at;
4776 int *expanded_something;
4782 /* The intermediate string that we build while expanding. */
4785 /* The current size of the above object. */
4788 /* Index into ISTRING. */
4791 /* Temporary string storage. */
4794 /* The text of WORD. */
4795 register char *string;
4797 /* The index into STRING. */
4800 /* This gets 1 if we see a $@ while quoted. */
4801 int quoted_dollar_at;
4803 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
4804 whether WORD contains no quoting characters, a partially quoted
4805 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
4808 int had_quoted_null;
4813 register int c; /* Current character. */
4814 int number; /* Temporary number value. */
4815 int t_index; /* For calls to string_extract_xxx. */
4817 istring = xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
4818 istring[istring_index = 0] = '\0';
4819 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
4820 quoted_state = UNQUOTED;
4822 string = word->word;
4824 goto finished_with_string;
4826 if (contains_dollar_at)
4827 *contains_dollar_at = 0;
4829 /* Begin the expansion. */
4835 /* Case on toplevel character. */
4839 goto finished_with_string;
4844 temp[1] = c = string[++sindex];
4854 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
4860 #if defined (PROCESS_SUBSTITUTION)
4861 /* Process substitution. */
4865 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || posixly_correct)
4871 t_index = sindex + 1; /* skip past both '<' and LPAREN */
4873 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
4876 /* If the process substitution specification is `<()', we want to
4877 open the pipe for writing in the child and produce output; if
4878 it is `>()', we want to open the pipe for reading in the child
4879 and consume input. */
4880 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
4884 goto dollar_add_string;
4886 #endif /* PROCESS_SUBSTITUTION */
4889 if (expanded_something)
4890 *expanded_something = 1;
4893 temp = param_expand (string, &sindex, quoted, expanded_something,
4894 &has_dollar_at, "ed_dollar_at,
4895 &had_quoted_null, 0);
4897 if (temp == &expand_param_error || temp == &expand_param_fatal)
4901 return ((temp == &expand_param_error) ? &expand_word_error
4902 : &expand_word_fatal);
4904 if (contains_dollar_at && has_dollar_at)
4905 *contains_dollar_at = 1;
4909 case '`': /* Backquoted command substitution. */
4913 if (expanded_something)
4914 *expanded_something = 1;
4916 temp = string_extract (string, &sindex, "`", 0);
4917 de_backslash (temp);
4918 temp1 = command_substitute (temp, quoted);
4921 goto dollar_add_string;
4925 if (string[sindex + 1] == '\n')
4931 c = string[++sindex];
4933 if (quoted & Q_HERE_DOCUMENT)
4934 temp1 = slashify_in_here_document;
4935 else if (quoted & Q_DOUBLE_QUOTES)
4936 temp1 = slashify_in_quotes;
4940 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && member (c, temp1) == 0)
4943 temp[0] = '\\'; temp[1] = c; temp[2] = '\0';
4946 /* This character is quoted, so add it in quoted mode. */
4947 temp = make_quoted_char (c);
4954 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
4958 temp = string_extract_double_quoted (string, &sindex, 0);
4960 /* If the quotes surrounded the entire string, then the
4961 whole word was quoted. */
4962 quoted_state = (t_index == 1 && string[sindex] == '\0')
4968 tword = make_word (temp); /* XXX */
4970 temp = (char *)NULL;
4973 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, &has_dollar_at, (int *)NULL);
4975 if (list == &expand_word_error || list == &expand_word_fatal)
4979 /* expand_word_internal has already freed temp_word->word
4980 for us because of the way it prints error messages. */
4981 tword->word = (char *)NULL;
4982 dispose_word (tword);
4986 dispose_word (tword);
4988 /* "$@" (a double-quoted dollar-at) expands into nothing,
4989 not even a NULL word, when there are no positional
4991 if (list == 0 && has_dollar_at)
4997 /* If we get "$@", we know we have expanded something, so we
4998 need to remember it for the final split on $IFS. This is
4999 a special case; it's the only case where a quoted string
5000 can expand into more than one word. It's going to come back
5001 from the above call to expand_word_internal as a list with
5002 a single word, in which all characters are quoted and
5003 separated by blanks. What we want to do is to turn it back
5004 into a list for the next piece of code. */
5006 dequote_list (list);
5011 if (contains_dollar_at)
5012 *contains_dollar_at = 1;
5013 if (expanded_something)
5014 *expanded_something = 1;
5019 /* What we have is "". This is a minor optimization. */
5021 list = (WORD_LIST *)NULL;
5024 /* The code above *might* return a list (consider the case of "$@",
5025 where it returns "$1", "$2", etc.). We can't throw away the
5026 rest of the list, and we have to make sure each word gets added
5027 as quoted. We test on tresult->next: if it is non-NULL, we
5028 quote the whole list, save it to a string with string_list, and
5029 add that string. We don't need to quote the results of this
5030 (and it would be wrong, since that would quote the separators
5031 as well), so we go directly to add_string. */
5036 temp = string_list (quote_list (list));
5037 dispose_words (list);
5042 temp = savestring (list->word->word);
5043 dispose_words (list);
5045 /* If the string is not a quoted null string, we want
5046 to remove any embedded unquoted CTLNUL characters.
5047 We do not want to turn quoted null strings back into
5048 the empty string, though. We do this because we
5049 want to remove any quoted nulls from expansions that
5050 contain other characters. For example, if we have
5051 x"$*"y or "x$*y" and there are no positional parameters,
5052 the $* should expand into nothing. */
5053 if (QUOTED_NULL (temp) == 0)
5054 remove_quoted_nulls (temp); /* XXX */
5059 temp = (char *)NULL;
5061 /* We do not want to add quoted nulls to strings that are only
5062 partially quoted; we can throw them away. */
5063 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
5071 temp = quote_string (temp);
5085 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5089 temp = string_extract_single_quoted (string, &sindex);
5091 /* If the entire STRING was surrounded by single quotes,
5092 then the string is wholly quoted. */
5093 quoted_state = (t_index == 1 && string[sindex] == '\0')
5097 /* If all we had was '', it is a null expansion. */
5101 temp = (char *)NULL;
5104 remove_quoted_escapes (temp);
5106 /* We do not want to add quoted nulls to strings that are only
5107 partially quoted; such nulls are discarded. */
5108 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
5111 goto add_quoted_string;
5115 /* This is the fix for " $@ " */
5116 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5118 temp = make_quoted_char (c);
5119 goto dollar_add_string;
5123 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
5124 DEFAULT_ARRAY_SIZE);
5125 istring[istring_index++] = c;
5126 istring[istring_index] = '\0';
5128 /* Next character. */
5133 finished_with_string:
5134 /* OK, we're ready to return. If we have a quoted string, and
5135 quoted_dollar_at is not set, we do no splitting at all; otherwise
5136 we split on ' '. The routines that call this will handle what to
5137 do if nothing has been expanded. */
5139 /* Partially and wholly quoted strings which expand to the empty
5140 string are retained as an empty arguments. Unquoted strings
5141 which expand to the empty string are discarded. The single
5142 exception is the case of expanding "$@" when there are no
5143 positional parameters. In that case, we discard the expansion. */
5145 /* Because of how the code that handles "" and '' in partially
5146 quoted strings works, we need to make ISTRING into a QUOTED_NULL
5147 if we saw quoting characters, but the expansion was empty.
5148 "" and '' are tossed away before we get to this point when
5149 processing partially quoted strings. This makes "" and $xxx""
5150 equivalent when xxx is unset. We also look to see whether we
5151 saw a quoted null from a ${} expansion and add one back if we
5154 /* If we expand to nothing and there were no single or double quotes
5155 in the word, we throw it away. Otherwise, we return a NULL word.
5156 The single exception is for $@ surrounded by double quotes when
5157 there are no positional parameters. In that case, we also throw
5160 if (*istring == '\0')
5162 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
5164 istring[0] = CTLNUL;
5166 tword = make_bare_word (istring);
5167 list = make_word_list (tword, (WORD_LIST *)NULL);
5168 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5169 tword->flags |= W_QUOTED;
5171 /* According to sh, ksh, and Posix.2, if a word expands into nothing
5172 and a double-quoted "$@" appears anywhere in it, then the entire
5174 else if (quoted_state == UNQUOTED || quoted_dollar_at)
5175 list = (WORD_LIST *)NULL;
5179 tword = make_bare_word (istring);
5180 list = make_word_list (tword, (WORD_LIST *)NULL);
5181 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5182 tword->flags |= W_QUOTED;
5186 else if (word->flags & W_NOSPLIT)
5188 tword = make_bare_word (istring);
5189 list = make_word_list (tword, (WORD_LIST *)NULL);
5190 if (word->flags & W_ASSIGNMENT)
5191 tword->flags |= W_ASSIGNMENT; /* XXX */
5192 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5193 tword->flags |= W_QUOTED;
5199 if (quoted_dollar_at || has_dollar_at)
5201 var = find_variable ("IFS");
5202 ifs_chars = var ? value_cell (var) : " \t\n";
5205 ifs_chars = (char *)NULL;
5207 /* If we have $@, we need to split the results no matter what. If
5208 IFS is unset or NULL, string_list_dollar_at has separated the
5209 positional parameters with a space, so we split on space (we have
5210 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
5211 string_list_dollar_at has separated the positional parameters
5212 with the first character of $IFS, so we split on $IFS. */
5213 if (has_dollar_at && ifs_chars)
5214 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
5217 tword = make_bare_word (istring);
5218 list = make_word_list (tword, (WORD_LIST *)NULL);
5219 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
5220 tword->flags |= W_QUOTED;
5221 if (word->flags & W_ASSIGNMENT)
5222 tword->flags |= W_ASSIGNMENT;
5230 /* **************************************************************** */
5232 /* Functions for Quote Removal */
5234 /* **************************************************************** */
5236 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
5237 backslash quoting rules for within double quotes. */
5239 string_quote_removal (string, quoted)
5243 char *r, *result_string, *temp;
5244 int sindex, tindex, c, dquote;
5246 /* The result can be no longer than the original string. */
5247 r = result_string = xmalloc (strlen (string) + 1);
5249 for (dquote = sindex = 0; c = string[sindex];)
5254 c = string[++sindex];
5255 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && member (c, slashify_in_quotes) == 0)
5265 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
5271 tindex = sindex + 1;
5272 temp = string_extract_single_quoted (string, &tindex);
5283 dquote = 1 - dquote;
5289 return (result_string);
5294 /* Perform quote removal on word WORD. This allocates and returns a new
5297 word_quote_removal (word, quoted)
5304 t = string_quote_removal (word->word, quoted);
5305 w = make_bare_word (t);
5310 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
5311 the members of the list are treated as if they are surrounded by
5312 double quotes. Return a new list, or NULL if LIST is NULL. */
5314 word_list_quote_removal (list, quoted)
5318 WORD_LIST *result, *t, *tresult;
5320 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5322 tresult = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
5323 tresult->word = word_quote_removal (t->word, quoted);
5324 tresult->next = (WORD_LIST *)NULL;
5325 result = (WORD_LIST *) list_append (result, tresult);
5331 /*******************************************
5333 * Functions to perform word splitting *
5335 *******************************************/
5337 /* This splits a single word into a WORD LIST on $IFS, but only if the word
5338 is not quoted. list_string () performs quote removal for us, even if we
5339 don't do any splitting. */
5350 ifs = find_variable ("IFS");
5351 /* If IFS is unset, it defaults to " \t\n". */
5352 ifs_chars = ifs ? value_cell (ifs) : " \t\n";
5354 if ((w->flags & W_QUOTED) || !ifs_chars)
5357 result = list_string (w->word, ifs_chars, w->flags & W_QUOTED);
5359 if (ifs && tempvar_p (ifs)) /* XXX */
5360 dispose_variable (ifs); /* XXX */
5363 result = (WORD_LIST *)NULL;
5368 /* Perform word splitting on LIST and return the RESULT. It is possible
5369 to return (WORD_LIST *)NULL. */
5371 word_list_split (list)
5374 WORD_LIST *result, *t, *tresult;
5376 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5378 tresult = word_split (t->word);
5379 result = (WORD_LIST *) list_append (result, tresult);
5384 /**************************************************
5386 * Functions to expand an entire WORD_LIST *
5388 **************************************************/
5390 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
5391 ELIST, and set ELIST to the new list. */
5392 #define PREPEND_LIST(nlist, elist) \
5393 do { nlist->next = elist; elist = nlist; } while (0)
5395 static WORD_LIST *varlist = (WORD_LIST *)NULL;
5397 /* Separate out any initial variable assignments from TLIST. If set -k has
5398 been executed, remove all assignment statements from TLIST. Initial
5399 variable assignments and other environment assignments are placed
5402 separate_out_assignments (tlist)
5405 register WORD_LIST *vp, *lp;
5408 return ((WORD_LIST *)NULL);
5410 varlist = (WORD_LIST *)NULL;
5413 /* Separate out variable assignments at the start of the command.
5414 Loop invariant: vp->next == lp
5416 lp = list of words left after assignment statements skipped
5417 tlist = original list of words
5419 while (lp && (lp->word->flags & W_ASSIGNMENT))
5425 /* If lp != tlist, we have some initial assignment statements. */
5426 /* We make VARLIST point to the list of assignment words and
5427 TLIST point to the remaining words. */
5431 /* ASSERT(vp->next == lp); */
5432 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
5433 tlist = lp; /* remainder of word list */
5436 /* vp == end of variable list */
5437 /* tlist == remainder of original word list without variable assignments */
5439 /* All the words in tlist were assignment statements */
5440 return ((WORD_LIST *)NULL);
5442 /* ASSERT(tlist != NULL); */
5443 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
5445 /* If the -k option is in effect, we need to go through the remaining
5446 words, separate out the assignment words, and place them on VARLIST. */
5447 if (place_keywords_in_env)
5449 WORD_LIST *tp; /* tp == running pointer into tlist */
5454 /* Loop Invariant: tp->next == lp */
5455 /* Loop postcondition: tlist == word list without assignment statements */
5458 if (lp->word->flags & W_ASSIGNMENT)
5460 /* Found an assignment statement, add this word to end of
5470 /* Remove the word pointed to by LP from TLIST. */
5471 tp->next = lp->next;
5472 /* ASSERT(vp == lp); */
5473 lp->next = (WORD_LIST *)NULL;
5486 #define WEXP_VARASSIGN 0x001
5487 #define WEXP_BRACEEXP 0x002
5488 #define WEXP_TILDEEXP 0x004
5489 #define WEXP_PARAMEXP 0x008
5490 #define WEXP_PATHEXP 0x010
5492 /* All of the expansions, including variable assignments at the start of
5494 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5496 /* All of the expansions except variable assignments at the start of
5498 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5500 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
5501 expansion, command substitution, arithmetic expansion, word splitting, and
5503 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
5505 /* Take the list of words in LIST and do the various substitutions. Return
5506 a new list of words which is the expanded list, and without things like
5507 variable assignments. */
5513 return (expand_word_list_internal (list, WEXP_ALL));
5516 /* Same as expand_words (), but doesn't hack variable or environment
5519 expand_words_no_vars (list)
5522 return (expand_word_list_internal (list, WEXP_NOVARS));
5526 expand_words_shellexp (list)
5529 return (expand_word_list_internal (list, WEXP_SHELLEXP));
5533 glob_expand_word_list (tlist, eflags)
5537 char **glob_array, *temp_string;
5538 register int glob_index;
5539 WORD_LIST *glob_list, *output_list, *disposables, *next;
5542 output_list = disposables = (WORD_LIST *)NULL;
5543 glob_array = (char **)NULL;
5546 /* For each word, either globbing is attempted or the word is
5547 added to orig_list. If globbing succeeds, the results are
5548 added to orig_list and the word (tlist) is added to the list
5549 of disposable words. If globbing fails and failed glob
5550 expansions are left unchanged (the shell default), the
5551 original word is added to orig_list. If globbing fails and
5552 failed glob expansions are removed, the original word is
5553 added to the list of disposable words. orig_list ends up
5554 in reverse order and requires a call to reverse_list to
5555 be set right. After all words are examined, the disposable
5559 /* If the word isn't an assignment and contains an unquoted
5560 pattern matching character, then glob it. */
5561 if ((tlist->word->flags & W_ASSIGNMENT) == 0 &&
5562 unquoted_glob_pattern_p (tlist->word->word))
5564 glob_array = shell_glob_filename (tlist->word->word);
5566 /* Handle error cases.
5567 I don't think we should report errors like "No such file
5568 or directory". However, I would like to report errors
5569 like "Read failed". */
5571 if (GLOB_FAILED (glob_array))
5573 glob_array = (char **) xmalloc (sizeof (char *));
5574 glob_array[0] = (char *)NULL;
5577 /* Dequote the current word in case we have to use it. */
5578 if (glob_array[0] == NULL)
5580 temp_string = dequote_string (tlist->word->word);
5581 free (tlist->word->word);
5582 tlist->word->word = temp_string;
5585 /* Make the array into a word list. */
5586 glob_list = (WORD_LIST *)NULL;
5587 for (glob_index = 0; glob_array[glob_index]; glob_index++)
5589 tword = make_bare_word (glob_array[glob_index]);
5590 tword->flags |= W_GLOBEXP; /* XXX */
5591 glob_list = make_word_list (tword, glob_list);
5596 output_list = (WORD_LIST *)list_append (glob_list, output_list);
5597 PREPEND_LIST (tlist, disposables);
5599 else if (allow_null_glob_expansion == 0)
5601 /* Failed glob expressions are left unchanged. */
5602 PREPEND_LIST (tlist, output_list);
5606 /* Failed glob expressions are removed. */
5607 PREPEND_LIST (tlist, disposables);
5612 /* Dequote the string. */
5613 temp_string = dequote_string (tlist->word->word);
5614 free (tlist->word->word);
5615 tlist->word->word = temp_string;
5616 PREPEND_LIST (tlist, output_list);
5619 free_array (glob_array);
5620 glob_array = (char **)NULL;
5626 dispose_words (disposables);
5629 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5631 return (output_list);
5634 #if defined (BRACE_EXPANSION)
5636 brace_expand_word_list (tlist, eflags)
5640 register char **expansions;
5642 WORD_LIST *disposables, *output_list, *next;
5646 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
5650 /* Only do brace expansion if the word has a brace character. If
5651 not, just add the word list element to BRACES and continue. In
5652 the common case, at least when running shell scripts, this will
5653 degenerate to a bunch of calls to `strchr', and then what is
5654 basically a reversal of TLIST into BRACES, which is corrected
5655 by a call to reverse_list () on BRACES when the end of TLIST
5657 if (strchr (tlist->word->word, LBRACE))
5659 expansions = brace_expand (tlist->word->word);
5661 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
5663 w = make_word (temp_string);
5664 /* If brace expansion didn't change the word, preserve
5665 the flags. We may want to preserve the flags
5666 unconditionally someday -- XXX */
5667 if (STREQ (temp_string, tlist->word->word))
5668 w->flags = tlist->word->flags;
5669 output_list = make_word_list (w, output_list);
5670 free (expansions[eindex]);
5674 /* Add TLIST to the list of words to be freed after brace
5675 expansion has been performed. */
5676 PREPEND_LIST (tlist, disposables);
5679 PREPEND_LIST (tlist, output_list);
5683 dispose_words (disposables);
5686 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5688 return (output_list);
5693 shell_expand_word_list (tlist, eflags)
5697 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
5698 int expanded_something, has_dollar_at;
5701 /* We do tilde expansion all the time. This is what 1003.2 says. */
5702 new_list = (WORD_LIST *)NULL;
5703 for (orig_list = tlist; tlist; tlist = next)
5705 temp_string = tlist->word->word;
5709 /* Posix.2 section 3.6.1 says that tildes following `=' in words
5710 which are not assignment statements are not expanded. We do
5711 this only if POSIXLY_CORRECT is enabled. Essentially, we do
5712 tilde expansion on unquoted assignment statements (flags include
5713 W_ASSIGNMENT but not W_QUOTED). */
5714 if (temp_string[0] == '~' ||
5715 (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
5716 posixly_correct == 0 &&
5717 strchr (temp_string, '~') &&
5718 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string))))
5720 tlist->word->word = bash_tilde_expand (temp_string);
5724 expanded_something = 0;
5725 expanded = expand_word_internal
5726 (tlist->word, 0, &has_dollar_at, &expanded_something);
5728 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
5730 /* By convention, each time this error is returned,
5731 tlist->word->word has already been freed. */
5732 tlist->word->word = (char *)NULL;
5734 /* Dispose our copy of the original list. */
5735 dispose_words (orig_list);
5736 /* Dispose the new list we're building. */
5737 dispose_words (new_list);
5739 if (expanded == &expand_word_error)
5740 jump_to_top_level (DISCARD);
5742 jump_to_top_level (FORCE_EOF);
5745 /* Don't split words marked W_NOSPLIT. */
5746 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
5748 temp_list = word_list_split (expanded);
5749 dispose_words (expanded);
5753 /* If no parameter expansion, command substitution, process
5754 substitution, or arithmetic substitution took place, then
5755 do not do word splitting. We still have to remove quoted
5756 null characters from the result. */
5757 word_list_remove_quoted_nulls (expanded);
5758 temp_list = expanded;
5761 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
5762 new_list = (WORD_LIST *)list_append (expanded, new_list);
5766 dispose_words (orig_list);
5769 new_list = REVERSE_LIST (new_list, WORD_LIST *);
5774 /* The workhorse for expand_words () and expand_words_no_vars ().
5775 First arg is LIST, a WORD_LIST of words.
5776 Second arg DO_VARS is non-zero if you want to do environment and
5777 variable assignments, else zero.
5779 This does all of the substitutions: brace expansion, tilde expansion,
5780 parameter expansion, command substitution, arithmetic expansion,
5781 process substitution, word splitting, and pathname expansion, according
5782 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
5783 set, or for which no expansion is done, do not undergo word splitting.
5784 Words with the W_ASSIGNMENT bit set do not undergo pathname expansion. */
5786 expand_word_list_internal (list, eflags)
5790 WORD_LIST *new_list, *temp_list;
5794 return ((WORD_LIST *)NULL);
5796 new_list = copy_word_list (list);
5798 if (eflags & WEXP_VARASSIGN)
5800 new_list = separate_out_assignments (new_list);
5805 /* All the words were variable assignments, so they are placed
5806 into the shell's environment. */
5807 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5809 this_command_name = (char *)NULL; /* no arithmetic errors */
5810 tint = do_assignment (temp_list->word->word);
5811 /* Variable assignment errors in non-interactive shells
5812 running in Posix.2 mode cause the shell to exit. */
5813 if (tint == 0 && interactive_shell == 0 && posixly_correct)
5815 last_command_exit_value = EXECUTION_FAILURE;
5816 jump_to_top_level (FORCE_EOF);
5819 dispose_words (varlist);
5820 varlist = (WORD_LIST *)NULL;
5822 return ((WORD_LIST *)NULL);
5826 /* Begin expanding the words that remain. The expansions take place on
5827 things that aren't really variable assignments. */
5829 #if defined (BRACE_EXPANSION)
5830 /* Do brace expansion on this word if there are any brace characters
5832 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
5833 new_list = brace_expand_word_list (new_list, eflags);
5834 #endif /* BRACE_EXPANSION */
5836 /* Perform the `normal' shell expansions: tilde expansion, parameter and
5837 variable substitution, command substitution, arithmetic expansion,
5838 and word splitting. */
5839 new_list = shell_expand_word_list (new_list, eflags);
5841 /* Okay, we're almost done. Now let's just do some filename
5845 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
5846 /* Glob expand the word list unless globbing has been disabled. */
5847 new_list = glob_expand_word_list (new_list, eflags);
5849 /* Dequote the words, because we're not performing globbing. */
5850 new_list = dequote_list (new_list);
5853 if ((eflags & WEXP_VARASSIGN) && varlist)
5855 Function *assign_func;
5857 /* If the remainder of the words expand to nothing, Posix.2 requires
5858 that the variable and environment assignments affect the shell's
5860 assign_func = new_list ? assign_in_env : do_assignment;
5862 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5864 this_command_name = (char *)NULL;
5865 tint = (*assign_func) (temp_list->word->word);
5866 /* Variable assignment errors in non-interactive shells running
5867 in Posix.2 mode cause the shell to exit. */
5868 if (tint == 0 && assign_func == do_assignment &&
5869 interactive_shell == 0 && posixly_correct)
5871 last_command_exit_value = EXECUTION_FAILURE;
5872 jump_to_top_level (FORCE_EOF);
5876 dispose_words (varlist);
5877 varlist = (WORD_LIST *)NULL;
5881 tint = list_length (new_list) + 1;
5882 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
5883 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
5884 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
5885 glob_argv_flags[tint] = '\0';