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 /* Testing quoted_dollar_at makes sure that "$@" is
5037 split correctly when $IFS does not contain a space. */
5038 temp = quoted_dollar_at
5039 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
5040 : string_list (quote_list (list));
5041 dispose_words (list);
5046 temp = savestring (list->word->word);
5047 dispose_words (list);
5049 /* If the string is not a quoted null string, we want
5050 to remove any embedded unquoted CTLNUL characters.
5051 We do not want to turn quoted null strings back into
5052 the empty string, though. We do this because we
5053 want to remove any quoted nulls from expansions that
5054 contain other characters. For example, if we have
5055 x"$*"y or "x$*y" and there are no positional parameters,
5056 the $* should expand into nothing. */
5057 if (QUOTED_NULL (temp) == 0)
5058 remove_quoted_nulls (temp); /* XXX */
5063 temp = (char *)NULL;
5065 /* We do not want to add quoted nulls to strings that are only
5066 partially quoted; we can throw them away. */
5067 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
5075 temp = quote_string (temp);
5089 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5093 temp = string_extract_single_quoted (string, &sindex);
5095 /* If the entire STRING was surrounded by single quotes,
5096 then the string is wholly quoted. */
5097 quoted_state = (t_index == 1 && string[sindex] == '\0')
5101 /* If all we had was '', it is a null expansion. */
5105 temp = (char *)NULL;
5108 remove_quoted_escapes (temp);
5110 /* We do not want to add quoted nulls to strings that are only
5111 partially quoted; such nulls are discarded. */
5112 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
5115 goto add_quoted_string;
5119 /* This is the fix for " $@ " */
5120 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5122 temp = make_quoted_char (c);
5123 goto dollar_add_string;
5127 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
5128 DEFAULT_ARRAY_SIZE);
5129 istring[istring_index++] = c;
5130 istring[istring_index] = '\0';
5132 /* Next character. */
5137 finished_with_string:
5138 /* OK, we're ready to return. If we have a quoted string, and
5139 quoted_dollar_at is not set, we do no splitting at all; otherwise
5140 we split on ' '. The routines that call this will handle what to
5141 do if nothing has been expanded. */
5143 /* Partially and wholly quoted strings which expand to the empty
5144 string are retained as an empty arguments. Unquoted strings
5145 which expand to the empty string are discarded. The single
5146 exception is the case of expanding "$@" when there are no
5147 positional parameters. In that case, we discard the expansion. */
5149 /* Because of how the code that handles "" and '' in partially
5150 quoted strings works, we need to make ISTRING into a QUOTED_NULL
5151 if we saw quoting characters, but the expansion was empty.
5152 "" and '' are tossed away before we get to this point when
5153 processing partially quoted strings. This makes "" and $xxx""
5154 equivalent when xxx is unset. We also look to see whether we
5155 saw a quoted null from a ${} expansion and add one back if we
5158 /* If we expand to nothing and there were no single or double quotes
5159 in the word, we throw it away. Otherwise, we return a NULL word.
5160 The single exception is for $@ surrounded by double quotes when
5161 there are no positional parameters. In that case, we also throw
5164 if (*istring == '\0')
5166 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
5168 istring[0] = CTLNUL;
5170 tword = make_bare_word (istring);
5171 list = make_word_list (tword, (WORD_LIST *)NULL);
5172 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5173 tword->flags |= W_QUOTED;
5175 /* According to sh, ksh, and Posix.2, if a word expands into nothing
5176 and a double-quoted "$@" appears anywhere in it, then the entire
5178 else if (quoted_state == UNQUOTED || quoted_dollar_at)
5179 list = (WORD_LIST *)NULL;
5183 tword = make_bare_word (istring);
5184 list = make_word_list (tword, (WORD_LIST *)NULL);
5185 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5186 tword->flags |= W_QUOTED;
5190 else if (word->flags & W_NOSPLIT)
5192 tword = make_bare_word (istring);
5193 list = make_word_list (tword, (WORD_LIST *)NULL);
5194 if (word->flags & W_ASSIGNMENT)
5195 tword->flags |= W_ASSIGNMENT; /* XXX */
5196 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5197 tword->flags |= W_QUOTED;
5203 if (quoted_dollar_at || has_dollar_at)
5205 var = find_variable ("IFS");
5206 ifs_chars = var ? value_cell (var) : " \t\n";
5209 ifs_chars = (char *)NULL;
5211 /* If we have $@, we need to split the results no matter what. If
5212 IFS is unset or NULL, string_list_dollar_at has separated the
5213 positional parameters with a space, so we split on space (we have
5214 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
5215 string_list_dollar_at has separated the positional parameters
5216 with the first character of $IFS, so we split on $IFS. */
5217 if (has_dollar_at && ifs_chars)
5218 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
5221 tword = make_bare_word (istring);
5222 list = make_word_list (tword, (WORD_LIST *)NULL);
5223 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
5224 tword->flags |= W_QUOTED;
5225 if (word->flags & W_ASSIGNMENT)
5226 tword->flags |= W_ASSIGNMENT;
5234 /* **************************************************************** */
5236 /* Functions for Quote Removal */
5238 /* **************************************************************** */
5240 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
5241 backslash quoting rules for within double quotes. */
5243 string_quote_removal (string, quoted)
5247 char *r, *result_string, *temp;
5248 int sindex, tindex, c, dquote;
5250 /* The result can be no longer than the original string. */
5251 r = result_string = xmalloc (strlen (string) + 1);
5253 for (dquote = sindex = 0; c = string[sindex];)
5258 c = string[++sindex];
5259 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && member (c, slashify_in_quotes) == 0)
5269 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
5275 tindex = sindex + 1;
5276 temp = string_extract_single_quoted (string, &tindex);
5287 dquote = 1 - dquote;
5293 return (result_string);
5298 /* Perform quote removal on word WORD. This allocates and returns a new
5301 word_quote_removal (word, quoted)
5308 t = string_quote_removal (word->word, quoted);
5309 w = make_bare_word (t);
5314 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
5315 the members of the list are treated as if they are surrounded by
5316 double quotes. Return a new list, or NULL if LIST is NULL. */
5318 word_list_quote_removal (list, quoted)
5322 WORD_LIST *result, *t, *tresult;
5324 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5326 tresult = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
5327 tresult->word = word_quote_removal (t->word, quoted);
5328 tresult->next = (WORD_LIST *)NULL;
5329 result = (WORD_LIST *) list_append (result, tresult);
5335 /*******************************************
5337 * Functions to perform word splitting *
5339 *******************************************/
5341 /* This splits a single word into a WORD LIST on $IFS, but only if the word
5342 is not quoted. list_string () performs quote removal for us, even if we
5343 don't do any splitting. */
5354 ifs = find_variable ("IFS");
5355 /* If IFS is unset, it defaults to " \t\n". */
5356 ifs_chars = ifs ? value_cell (ifs) : " \t\n";
5358 if ((w->flags & W_QUOTED) || !ifs_chars)
5361 result = list_string (w->word, ifs_chars, w->flags & W_QUOTED);
5363 if (ifs && tempvar_p (ifs)) /* XXX */
5364 dispose_variable (ifs); /* XXX */
5367 result = (WORD_LIST *)NULL;
5372 /* Perform word splitting on LIST and return the RESULT. It is possible
5373 to return (WORD_LIST *)NULL. */
5375 word_list_split (list)
5378 WORD_LIST *result, *t, *tresult;
5380 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5382 tresult = word_split (t->word);
5383 result = (WORD_LIST *) list_append (result, tresult);
5388 /**************************************************
5390 * Functions to expand an entire WORD_LIST *
5392 **************************************************/
5394 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
5395 ELIST, and set ELIST to the new list. */
5396 #define PREPEND_LIST(nlist, elist) \
5397 do { nlist->next = elist; elist = nlist; } while (0)
5399 static WORD_LIST *varlist = (WORD_LIST *)NULL;
5401 /* Separate out any initial variable assignments from TLIST. If set -k has
5402 been executed, remove all assignment statements from TLIST. Initial
5403 variable assignments and other environment assignments are placed
5406 separate_out_assignments (tlist)
5409 register WORD_LIST *vp, *lp;
5412 return ((WORD_LIST *)NULL);
5414 varlist = (WORD_LIST *)NULL;
5417 /* Separate out variable assignments at the start of the command.
5418 Loop invariant: vp->next == lp
5420 lp = list of words left after assignment statements skipped
5421 tlist = original list of words
5423 while (lp && (lp->word->flags & W_ASSIGNMENT))
5429 /* If lp != tlist, we have some initial assignment statements. */
5430 /* We make VARLIST point to the list of assignment words and
5431 TLIST point to the remaining words. */
5435 /* ASSERT(vp->next == lp); */
5436 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
5437 tlist = lp; /* remainder of word list */
5440 /* vp == end of variable list */
5441 /* tlist == remainder of original word list without variable assignments */
5443 /* All the words in tlist were assignment statements */
5444 return ((WORD_LIST *)NULL);
5446 /* ASSERT(tlist != NULL); */
5447 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
5449 /* If the -k option is in effect, we need to go through the remaining
5450 words, separate out the assignment words, and place them on VARLIST. */
5451 if (place_keywords_in_env)
5453 WORD_LIST *tp; /* tp == running pointer into tlist */
5458 /* Loop Invariant: tp->next == lp */
5459 /* Loop postcondition: tlist == word list without assignment statements */
5462 if (lp->word->flags & W_ASSIGNMENT)
5464 /* Found an assignment statement, add this word to end of
5474 /* Remove the word pointed to by LP from TLIST. */
5475 tp->next = lp->next;
5476 /* ASSERT(vp == lp); */
5477 lp->next = (WORD_LIST *)NULL;
5490 #define WEXP_VARASSIGN 0x001
5491 #define WEXP_BRACEEXP 0x002
5492 #define WEXP_TILDEEXP 0x004
5493 #define WEXP_PARAMEXP 0x008
5494 #define WEXP_PATHEXP 0x010
5496 /* All of the expansions, including variable assignments at the start of
5498 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5500 /* All of the expansions except variable assignments at the start of
5502 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5504 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
5505 expansion, command substitution, arithmetic expansion, word splitting, and
5507 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
5509 /* Take the list of words in LIST and do the various substitutions. Return
5510 a new list of words which is the expanded list, and without things like
5511 variable assignments. */
5517 return (expand_word_list_internal (list, WEXP_ALL));
5520 /* Same as expand_words (), but doesn't hack variable or environment
5523 expand_words_no_vars (list)
5526 return (expand_word_list_internal (list, WEXP_NOVARS));
5530 expand_words_shellexp (list)
5533 return (expand_word_list_internal (list, WEXP_SHELLEXP));
5537 glob_expand_word_list (tlist, eflags)
5541 char **glob_array, *temp_string;
5542 register int glob_index;
5543 WORD_LIST *glob_list, *output_list, *disposables, *next;
5546 output_list = disposables = (WORD_LIST *)NULL;
5547 glob_array = (char **)NULL;
5550 /* For each word, either globbing is attempted or the word is
5551 added to orig_list. If globbing succeeds, the results are
5552 added to orig_list and the word (tlist) is added to the list
5553 of disposable words. If globbing fails and failed glob
5554 expansions are left unchanged (the shell default), the
5555 original word is added to orig_list. If globbing fails and
5556 failed glob expansions are removed, the original word is
5557 added to the list of disposable words. orig_list ends up
5558 in reverse order and requires a call to reverse_list to
5559 be set right. After all words are examined, the disposable
5563 /* If the word isn't an assignment and contains an unquoted
5564 pattern matching character, then glob it. */
5565 if ((tlist->word->flags & W_ASSIGNMENT) == 0 &&
5566 unquoted_glob_pattern_p (tlist->word->word))
5568 glob_array = shell_glob_filename (tlist->word->word);
5570 /* Handle error cases.
5571 I don't think we should report errors like "No such file
5572 or directory". However, I would like to report errors
5573 like "Read failed". */
5575 if (GLOB_FAILED (glob_array))
5577 glob_array = (char **) xmalloc (sizeof (char *));
5578 glob_array[0] = (char *)NULL;
5581 /* Dequote the current word in case we have to use it. */
5582 if (glob_array[0] == NULL)
5584 temp_string = dequote_string (tlist->word->word);
5585 free (tlist->word->word);
5586 tlist->word->word = temp_string;
5589 /* Make the array into a word list. */
5590 glob_list = (WORD_LIST *)NULL;
5591 for (glob_index = 0; glob_array[glob_index]; glob_index++)
5593 tword = make_bare_word (glob_array[glob_index]);
5594 tword->flags |= W_GLOBEXP; /* XXX */
5595 glob_list = make_word_list (tword, glob_list);
5600 output_list = (WORD_LIST *)list_append (glob_list, output_list);
5601 PREPEND_LIST (tlist, disposables);
5603 else if (allow_null_glob_expansion == 0)
5605 /* Failed glob expressions are left unchanged. */
5606 PREPEND_LIST (tlist, output_list);
5610 /* Failed glob expressions are removed. */
5611 PREPEND_LIST (tlist, disposables);
5616 /* Dequote the string. */
5617 temp_string = dequote_string (tlist->word->word);
5618 free (tlist->word->word);
5619 tlist->word->word = temp_string;
5620 PREPEND_LIST (tlist, output_list);
5623 free_array (glob_array);
5624 glob_array = (char **)NULL;
5630 dispose_words (disposables);
5633 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5635 return (output_list);
5638 #if defined (BRACE_EXPANSION)
5640 brace_expand_word_list (tlist, eflags)
5644 register char **expansions;
5646 WORD_LIST *disposables, *output_list, *next;
5650 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
5654 /* Only do brace expansion if the word has a brace character. If
5655 not, just add the word list element to BRACES and continue. In
5656 the common case, at least when running shell scripts, this will
5657 degenerate to a bunch of calls to `strchr', and then what is
5658 basically a reversal of TLIST into BRACES, which is corrected
5659 by a call to reverse_list () on BRACES when the end of TLIST
5661 if (strchr (tlist->word->word, LBRACE))
5663 expansions = brace_expand (tlist->word->word);
5665 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
5667 w = make_word (temp_string);
5668 /* If brace expansion didn't change the word, preserve
5669 the flags. We may want to preserve the flags
5670 unconditionally someday -- XXX */
5671 if (STREQ (temp_string, tlist->word->word))
5672 w->flags = tlist->word->flags;
5673 output_list = make_word_list (w, output_list);
5674 free (expansions[eindex]);
5678 /* Add TLIST to the list of words to be freed after brace
5679 expansion has been performed. */
5680 PREPEND_LIST (tlist, disposables);
5683 PREPEND_LIST (tlist, output_list);
5687 dispose_words (disposables);
5690 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5692 return (output_list);
5697 shell_expand_word_list (tlist, eflags)
5701 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
5702 int expanded_something, has_dollar_at;
5705 /* We do tilde expansion all the time. This is what 1003.2 says. */
5706 new_list = (WORD_LIST *)NULL;
5707 for (orig_list = tlist; tlist; tlist = next)
5709 temp_string = tlist->word->word;
5713 /* Posix.2 section 3.6.1 says that tildes following `=' in words
5714 which are not assignment statements are not expanded. We do
5715 this only if POSIXLY_CORRECT is enabled. Essentially, we do
5716 tilde expansion on unquoted assignment statements (flags include
5717 W_ASSIGNMENT but not W_QUOTED). */
5718 if (temp_string[0] == '~' ||
5719 (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
5720 posixly_correct == 0 &&
5721 strchr (temp_string, '~') &&
5722 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string))))
5724 tlist->word->word = bash_tilde_expand (temp_string);
5728 expanded_something = 0;
5729 expanded = expand_word_internal
5730 (tlist->word, 0, &has_dollar_at, &expanded_something);
5732 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
5734 /* By convention, each time this error is returned,
5735 tlist->word->word has already been freed. */
5736 tlist->word->word = (char *)NULL;
5738 /* Dispose our copy of the original list. */
5739 dispose_words (orig_list);
5740 /* Dispose the new list we're building. */
5741 dispose_words (new_list);
5743 if (expanded == &expand_word_error)
5744 jump_to_top_level (DISCARD);
5746 jump_to_top_level (FORCE_EOF);
5749 /* Don't split words marked W_NOSPLIT. */
5750 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
5752 temp_list = word_list_split (expanded);
5753 dispose_words (expanded);
5757 /* If no parameter expansion, command substitution, process
5758 substitution, or arithmetic substitution took place, then
5759 do not do word splitting. We still have to remove quoted
5760 null characters from the result. */
5761 word_list_remove_quoted_nulls (expanded);
5762 temp_list = expanded;
5765 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
5766 new_list = (WORD_LIST *)list_append (expanded, new_list);
5770 dispose_words (orig_list);
5773 new_list = REVERSE_LIST (new_list, WORD_LIST *);
5778 /* The workhorse for expand_words () and expand_words_no_vars ().
5779 First arg is LIST, a WORD_LIST of words.
5780 Second arg DO_VARS is non-zero if you want to do environment and
5781 variable assignments, else zero.
5783 This does all of the substitutions: brace expansion, tilde expansion,
5784 parameter expansion, command substitution, arithmetic expansion,
5785 process substitution, word splitting, and pathname expansion, according
5786 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
5787 set, or for which no expansion is done, do not undergo word splitting.
5788 Words with the W_ASSIGNMENT bit set do not undergo pathname expansion. */
5790 expand_word_list_internal (list, eflags)
5794 WORD_LIST *new_list, *temp_list;
5798 return ((WORD_LIST *)NULL);
5800 new_list = copy_word_list (list);
5802 if (eflags & WEXP_VARASSIGN)
5804 new_list = separate_out_assignments (new_list);
5809 /* All the words were variable assignments, so they are placed
5810 into the shell's environment. */
5811 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5813 this_command_name = (char *)NULL; /* no arithmetic errors */
5814 tint = do_assignment (temp_list->word->word);
5815 /* Variable assignment errors in non-interactive shells
5816 running in Posix.2 mode cause the shell to exit. */
5817 if (tint == 0 && interactive_shell == 0 && posixly_correct)
5819 last_command_exit_value = EXECUTION_FAILURE;
5820 jump_to_top_level (FORCE_EOF);
5823 dispose_words (varlist);
5824 varlist = (WORD_LIST *)NULL;
5826 return ((WORD_LIST *)NULL);
5830 /* Begin expanding the words that remain. The expansions take place on
5831 things that aren't really variable assignments. */
5833 #if defined (BRACE_EXPANSION)
5834 /* Do brace expansion on this word if there are any brace characters
5836 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
5837 new_list = brace_expand_word_list (new_list, eflags);
5838 #endif /* BRACE_EXPANSION */
5840 /* Perform the `normal' shell expansions: tilde expansion, parameter and
5841 variable substitution, command substitution, arithmetic expansion,
5842 and word splitting. */
5843 new_list = shell_expand_word_list (new_list, eflags);
5845 /* Okay, we're almost done. Now let's just do some filename
5849 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
5850 /* Glob expand the word list unless globbing has been disabled. */
5851 new_list = glob_expand_word_list (new_list, eflags);
5853 /* Dequote the words, because we're not performing globbing. */
5854 new_list = dequote_list (new_list);
5857 if ((eflags & WEXP_VARASSIGN) && varlist)
5859 Function *assign_func;
5861 /* If the remainder of the words expand to nothing, Posix.2 requires
5862 that the variable and environment assignments affect the shell's
5864 assign_func = new_list ? assign_in_env : do_assignment;
5866 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5868 this_command_name = (char *)NULL;
5869 tint = (*assign_func) (temp_list->word->word);
5870 /* Variable assignment errors in non-interactive shells running
5871 in Posix.2 mode cause the shell to exit. */
5872 if (tint == 0 && assign_func == do_assignment &&
5873 interactive_shell == 0 && posixly_correct)
5875 last_command_exit_value = EXECUTION_FAILURE;
5876 jump_to_top_level (FORCE_EOF);
5880 dispose_words (varlist);
5881 varlist = (WORD_LIST *)NULL;
5885 tint = list_length (new_list) + 1;
5886 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
5887 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
5888 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
5889 glob_argv_flags[tint] = '\0';