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;
82 pid_t current_command_subst_pid = NO_PID;
84 /* Extern functions and variables from different files. */
85 extern int last_command_exit_value, interactive, interactive_shell;
86 extern int subshell_environment, startup_state;
87 extern int dollar_dollar_pid;
88 extern int posixly_correct;
89 extern char *this_command_name;
90 extern struct fd_bitmap *current_fds_to_close;
91 extern int wordexp_only;
93 extern void getopts_reset ();
95 /* Non-zero means to allow unmatched globbed filenames to expand to
97 int allow_null_glob_expansion;
99 /* Variables to keep track of which words in an expanded word list (the
100 output of expand_word_list_internal) are the result of globbing
101 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c. */
102 char *glob_argv_flags;
103 static int glob_argv_flags_size;
105 static WORD_LIST expand_word_error, expand_word_fatal;
106 static char expand_param_error, expand_param_fatal;
108 static int doing_completion = 0;
110 static char *make_quoted_char ();
111 static void remove_quoted_nulls ();
112 static char *param_expand ();
113 static char *maybe_expand_string ();
114 static WORD_LIST *call_expand_word_internal ();
115 static WORD_LIST *expand_string_internal ();
116 static WORD_LIST *expand_word_internal (), *expand_word_list_internal ();
117 static WORD_LIST *expand_string_leave_quoted ();
118 static WORD_LIST *expand_string_for_rhs ();
119 static char *getifs ();
120 static WORD_LIST *word_list_split ();
121 static WORD_LIST *quote_list (), *dequote_list ();
122 static char *quote_escapes ();
123 static WORD_LIST *list_quote_escapes ();
124 static int unquoted_substring (), unquoted_member ();
125 static int do_assignment_internal ();
126 static char *string_extract_verbatim (), *string_extract ();
127 static char *string_extract_double_quoted (), *string_extract_single_quoted ();
128 static char *string_list_dollar_at (), *string_list_dollar_star ();
129 static inline int skip_single_quoted (), skip_double_quoted ();
130 static char *extract_delimited_string ();
131 static char *extract_dollar_brace_string ();
133 /* **************************************************************** */
135 /* Utility Functions */
137 /* **************************************************************** */
139 /* Cons a new string from STRING starting at START and ending at END,
140 not including END. */
142 substring (string, start, end)
147 register char *result;
150 result = xmalloc (len + 1);
151 strncpy (result, string + start, len);
157 quoted_substring (string, start, end)
162 register char *result, *s, *r;
166 /* Move to string[start], skipping quoted characters. */
167 for (s = string, l = 0; *s && l < start; )
179 r = result = xmalloc (2*len + 1); /* save room for quotes */
181 /* Copy LEN characters, including quote characters. */
183 for (l = 0; l < len; s++)
196 /* Find the first occurrence of character C in string S, obeying shell
197 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
198 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
199 escaped with CTLESC are skipped. */
201 quoted_strchr (s, c, flags)
209 if (((flags & ST_BACKSL) && *p == '\\')
210 || ((flags & ST_CTLESC) && *p == CTLESC))
214 return ((char *)NULL);
220 return ((char *)NULL);
223 /* Return 1 if CHARACTER appears in an unquoted portion of
224 STRING. Return 0 otherwise. */
226 unquoted_member (character, string)
232 for (sindex = 0; c = string[sindex]; )
250 sindex = skip_single_quoted (string, ++sindex);
254 sindex = skip_double_quoted (string, ++sindex);
261 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
263 unquoted_substring (substr, string)
264 char *substr, *string;
266 int sindex, c, sublen;
268 if (substr == 0 || *substr == '\0')
271 sublen = strlen (substr);
272 for (sindex = 0; c = string[sindex]; )
274 if (STREQN (string + sindex, substr, sublen))
287 sindex = skip_single_quoted (string, ++sindex);
291 sindex = skip_double_quoted (string, ++sindex);
302 /* Most of the substitutions must be done in parallel. In order
303 to avoid using tons of unclear goto's, I have some functions
304 for manipulating malloc'ed strings. They all take INDX, a
305 pointer to an integer which is the offset into the string
306 where manipulation is taking place. They also take SIZE, a
307 pointer to an integer which is the current length of the
308 character array for this string. */
310 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
311 of space allocated to TARGET. SOURCE can be NULL, in which
312 case nothing happens. Gets rid of SOURCE by freeing it.
313 Returns TARGET in case the location has changed. */
315 sub_append_string (source, target, indx, size)
316 char *source, *target;
323 srclen = STRLEN (source);
324 if (srclen >= (int)(*size - *indx))
327 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
328 target = xrealloc (target, (*size = n));
331 FASTCOPY (source, target + *indx, srclen);
333 target[*indx] = '\0';
342 /* Append the textual representation of NUMBER to TARGET.
343 INDX and SIZE are as in SUB_APPEND_STRING. */
345 sub_append_number (number, target, indx, size)
346 int number, *indx, *size;
351 temp = itos (number);
352 return (sub_append_string (temp, target, indx, size));
356 /* Extract a substring from STRING, starting at SINDEX and ending with
357 one of the characters in CHARLIST. Don't make the ending character
358 part of the string. Leave SINDEX pointing at the ending character.
359 Understand about backslashes in the string. If VARNAME is non-zero,
360 and array variables have been compiled into the shell, everything
361 between a `[' and a corresponding `]' is skipped over. */
363 string_extract (string, sindex, charlist, varname)
364 char *string, *charlist;
365 int *sindex, varname;
370 for (i = *sindex; c = string[i]; i++)
377 #if defined (ARRAY_VARS)
378 else if (varname && c == '[')
381 /* If this is an array subscript, skip over it and continue. */
382 ni = skipsubscript (string, i);
383 if (string[ni] == ']')
387 else if (MEMBER (c, charlist))
391 temp = xmalloc (1 + c);
392 strncpy (temp, string + *sindex, c);
398 /* Extract the contents of STRING as if it is enclosed in double quotes.
399 SINDEX, when passed in, is the offset of the character immediately
400 following the opening double quote; on exit, SINDEX is left pointing after
401 the closing double quote. If STRIPDQ is non-zero, unquoted double
402 quotes are stripped and the string is terminated by a null byte.
403 Backslashes between the embedded double quotes are processed. If STRIPDQ
404 is zero, an unquoted `"' terminates the string. */
406 string_extract_double_quoted (string, sindex, stripdq)
408 int *sindex, stripdq;
411 char *temp, *ret; /* The new string we return. */
412 int pass_next, backquote, si; /* State variables for the machine. */
415 pass_next = backquote = dquote = 0;
416 temp = xmalloc (1 + strlen (string) - *sindex);
418 for (j = 0, i = *sindex; c = string[i]; i++)
420 /* Process a character that was quoted by a backslash. */
425 ``The backslash shall retain its special meaning as an escape
426 character only when followed by one of the characters:
429 If STRIPDQ is zero, we handle the double quotes here and let
430 expand_word_internal handle the rest. If STRIPDQ is non-zero,
431 we have already been through one round of backslash stripping,
432 and want to strip these backslashes only if DQUOTE is non-zero,
433 indicating that we are inside an embedded double-quoted string. */
435 /* If we are in an embedded quoted string, then don't strip
436 backslashes before characters for which the backslash
437 retains its special meaning, but remove backslashes in
438 front of other characters. If we are not in an
439 embedded quoted string, don't strip backslashes at all.
440 This mess is necessary because the string was already
441 surrounded by double quotes (and sh has some really weird
443 The returned string will be run through expansion as if
444 it were double-quoted. */
445 if ((stripdq == 0 && c != '"') ||
446 (stripdq && ((dquote && strchr (slashify_in_quotes, c)) || dquote == 0)))
453 /* A backslash protects the next character. The code just above
454 handles preserving the backslash in front of any character but
462 /* Inside backquotes, ``the portion of the quoted string from the
463 initial backquote and the characters up to the next backquote
464 that is not preceded by a backslash, having escape characters
465 removed, defines that command''. */
481 /* Pass everything between `$(' and the matching `)' or a quoted
482 ${ ... } pair through according to the Posix.2 specification. */
483 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
486 if (string[i + 1] == LPAREN)
487 ret = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
489 ret = extract_dollar_brace_string (string, &si, 1);
492 temp[j++] = string[i + 1];
494 for (t = 0; ret[t]; t++, j++)
496 temp[j++] = string[si];
503 /* Add any character but a double quote to the quoted string we're
522 /* Point to after the closing quote. */
530 /* This should really be another option to string_extract_double_quoted. */
532 skip_double_quoted (string, sind)
538 int pass_next, backquote, si;
540 pass_next = backquote = 0;
542 for (j = 0, i = sind; c = string[i]; i++)
565 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
568 if (string[i + 1] == LPAREN)
569 ret = extract_delimited_string (string, &si, "$(", "(", ")");
571 ret = extract_dollar_brace_string (string, &si, 0);
589 /* Extract the contents of STRING as if it is enclosed in single quotes.
590 SINDEX, when passed in, is the offset of the character immediately
591 following the opening single quote; on exit, SINDEX is left pointing after
592 the closing single quote. */
594 string_extract_single_quoted (string, sindex)
601 for (i = *sindex; string[i] && string[i] != '\''; i++)
606 strncpy (t, string + *sindex, j);
617 skip_single_quoted (string, sind)
623 for (i = sind; string[i] && string[i] != '\''; i++)
630 /* Just like string_extract, but doesn't hack backslashes or any of
631 that other stuff. Obeys quoting. Used to do splitting on $IFS. */
633 string_extract_verbatim (string, sindex, charlist)
634 char *string, *charlist;
637 register int i = *sindex;
641 if (charlist[0] == '\'' && charlist[1] == '\0')
643 temp = string_extract_single_quoted (string, sindex);
644 --*sindex; /* leave *sindex at separator character */
648 for (i = *sindex; c = string[i]; i++)
656 if (MEMBER (c, charlist))
661 temp = xmalloc (1 + c);
662 strncpy (temp, string + *sindex, c);
669 /* Extract the $( construct in STRING, and return a new string.
670 Start extracting at (SINDEX) as if we had just seen "$(".
671 Make (SINDEX) get the position of the matching ")". */
673 extract_command_subst (string, sindex)
677 return (extract_delimited_string (string, sindex, "$(", "(", ")"));
680 /* Extract the $[ construct in STRING, and return a new string.
681 Start extracting at (SINDEX) as if we had just seen "$[".
682 Make (SINDEX) get the position of the matching "]". */
684 extract_arithmetic_subst (string, sindex)
688 return (extract_delimited_string (string, sindex, "$[", "[", "]"));
691 #if defined (PROCESS_SUBSTITUTION)
692 /* Extract the <( or >( construct in STRING, and return a new string.
693 Start extracting at (SINDEX) as if we had just seen "<(".
694 Make (SINDEX) get the position of the matching ")". */ /*))*/
696 extract_process_subst (string, starter, sindex)
701 return (extract_delimited_string (string, sindex, starter, "(", ")"));
703 #endif /* PROCESS_SUBSTITUTION */
705 #if defined (ARRAY_VARS)
707 extract_array_assignment_list (string, sindex)
711 return (extract_delimited_string (string, sindex, "(", (char *)NULL, ")"));
715 /* Extract and create a new string from the contents of STRING, a
716 character string delimited with OPENER and CLOSER. SINDEX is
717 the address of an int describing the current offset in STRING;
718 it should point to just after the first OPENER found. On exit,
719 SINDEX gets the position of the last character of the matching CLOSER.
720 If OPENER is more than a single character, ALT_OPENER, if non-null,
721 contains a character string that can also match CLOSER and thus
722 needs to be skipped. */
724 extract_delimited_string (string, sindex, opener, alt_opener, closer)
727 char *opener, *alt_opener, *closer;
731 int pass_character, nesting_level;
732 int len_closer, len_opener, len_alt_opener;
734 len_opener = STRLEN (opener);
735 len_alt_opener = STRLEN (alt_opener);
736 len_closer = STRLEN (closer);
743 while (nesting_level)
750 if (pass_character) /* previous char was backslash */
765 if (c == '\\' && delimiter == '"' &&
766 (member (string[i], slashify_in_quotes)))
776 /* Process a nested OPENER. */
777 if (STREQN (string + i, opener, len_opener))
780 t = extract_delimited_string (string, &si, opener, alt_opener, closer);
786 /* Process a nested ALT_OPENER */
787 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
789 si = i + len_alt_opener;
790 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer);
796 /* If the current substring terminates the delimited string, decrement
797 the nesting level. */
798 if (STREQN (string + i, closer, len_closer))
800 i += len_closer - 1; /* move to last char of the closer */
802 if (nesting_level == 0)
806 /* Pass old-style command substitution through verbatim. */
810 t = string_extract (string, &si, "`", 0);
816 /* Pass single-quoted strings through verbatim. */
820 i = skip_single_quoted (string, si);
824 /* Pass embedded double-quoted strings through verbatim as well. */
828 i = skip_double_quoted (string, si);
832 i++; /* move past this character, which was not special. */
835 if (c == 0 && nesting_level)
837 report_error ("bad substitution: no `%s' in %s", closer, string);
838 jump_to_top_level (DISCARD);
841 si = i - *sindex - len_closer + 1;
842 result = xmalloc (1 + si);
843 strncpy (result, string + *sindex, si);
850 /* Extract a parameter expansion expression within ${ and } from STRING.
851 Obey the Posix.2 rules for finding the ending `}': count braces while
852 skipping over enclosed quoted strings and command substitutions.
853 SINDEX is the address of an int describing the current offset in STRING;
854 it should point to just after the first `{' found. On exit, SINDEX
855 gets the position of the matching `}'. QUOTED is non-zero if this
856 occurs inside double quotes. */
857 /* XXX -- this is very similar to extract_delimited_string -- XXX */
859 extract_dollar_brace_string (string, sindex, quoted)
863 register int i, c, l;
864 int pass_character, nesting_level, si;
871 for (i = *sindex; (c = string[i]); i++)
879 /* CTLESCs and backslashes quote the next character. */
880 if (c == CTLESC || c == '\\')
886 if (string[i] == '$' && string[i+1] == LBRACE)
896 if (nesting_level == 0)
901 /* Pass the contents of old-style command substitutions through
906 t = string_extract (string, &si, "`", 0);
912 /* Pass the contents of new-style command substitutions and
913 arithmetic substitutions through verbatim. */
914 if (string[i] == '$' && string[i+1] == LPAREN)
917 t = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
923 /* Pass the contents of single-quoted and double-quoted strings
925 if (c == '\'' || c == '"')
928 i = (c == '\'') ? skip_single_quoted (string, si)
929 : skip_double_quoted (string, si);
930 /* skip_XXX_quoted leaves index one past close quote */
936 if (c == 0 && nesting_level && doing_completion == 0)
938 report_error ("bad substitution: no ending `}' in %s", string);
939 jump_to_top_level (DISCARD);
943 result = xmalloc (1 + l);
944 strncpy (result, string + *sindex, l);
951 /* Remove backslashes which are quoting backquotes from STRING. Modifies
952 STRING, and returns a pointer to it. */
954 de_backslash (string)
959 for (i = 0, l = strlen (string); i < l; i++)
960 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
961 string[i + 1] == '$'))
962 strcpy (string + i, string + i + 1); /* XXX - should be memmove */
968 /* Replace instances of \! in a string with !. */
970 unquote_bang (string)
976 temp = xmalloc (1 + strlen (string));
978 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
980 if (string[i] == '\\' && string[i + 1] == '!')
986 strcpy (string, temp);
991 #if defined (READLINE)
992 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
993 an unclosed quoted string), or if the character at EINDEX is quoted
994 by a backslash. DOING_COMPLETION is used to flag that the various
995 single and double-quoted string parsing functions should not return an
996 error if there are unclosed quotes or braces. */
998 #define CQ_RETURN(x) do { doing_completion = 0; return (x); } while (0)
1001 char_is_quoted (string, eindex)
1005 int i, pass_next, quoted;
1007 doing_completion = 1;
1008 for (i = pass_next = quoted = 0; i <= eindex; i++)
1013 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1017 else if (string[i] == '\'' || string[i] == '"')
1019 i = (string[i] == '\'') ? skip_single_quoted (string, ++i)
1020 : skip_double_quoted (string, ++i);
1023 i--; /* the skip functions increment past the closing quote. */
1025 else if (string[i] == '\\')
1035 unclosed_pair (string, eindex, openstr)
1040 int i, pass_next, openc, olen;
1042 olen = strlen (openstr);
1043 for (i = pass_next = openc = 0; i <= eindex; i++)
1048 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1052 else if (STREQN (string + i, openstr, olen))
1057 else if (string[i] == '\'' || string[i] == '"')
1059 i = (string[i] == '\'') ? skip_single_quoted (string, i)
1060 : skip_double_quoted (string, i);
1064 else if (string[i] == '\\')
1072 #endif /* READLINE */
1076 /* Extract the name of the variable to bind to from the assignment string. */
1078 assignment_name (string)
1084 offset = assignment (string);
1086 return (char *)NULL;
1087 temp = xmalloc (offset + 1);
1088 strncpy (temp, string, offset);
1089 temp[offset] = '\0';
1094 /* **************************************************************** */
1096 /* Functions to convert strings to WORD_LISTs and vice versa */
1098 /* **************************************************************** */
1100 /* Return a single string of all the words in LIST. SEP is the separator
1101 to put between individual elements of LIST in the output string. */
1103 string_list_internal (list, sep)
1107 register WORD_LIST *t;
1109 int word_len, sep_len, result_size;
1112 return ((char *)NULL);
1114 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1115 sep_len = STRLEN (sep);
1118 for (t = list; t; t = t->next)
1121 result_size += sep_len;
1122 result_size += strlen (t->word->word);
1125 r = result = xmalloc (result_size + 1);
1127 for (t = list; t; t = t->next)
1129 if (t != list && sep_len)
1133 FASTCOPY (sep, r, sep_len);
1140 word_len = strlen (t->word->word);
1141 FASTCOPY (t->word->word, r, word_len);
1149 /* Return a single string of all the words present in LIST, separating
1150 each word with a space. */
1155 return (string_list_internal (list, " "));
1158 /* Return a single string of all the words present in LIST, obeying the
1159 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1160 expansion [of $*] appears within a double quoted string, it expands
1161 to a single field with the value of each parameter separated by the
1162 first character of the IFS variable, or by a <space> if IFS is unset." */
1164 string_list_dollar_star (list)
1169 ifs = get_string_value ("IFS");
1171 sep[0] = (ifs == 0) ? ' ' : *ifs;
1174 return (string_list_internal (list, sep));
1177 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1178 is non-zero, the $@ appears within double quotes, and we should quote
1179 the list before converting it into a string. If IFS is unset, and the
1180 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1181 in the words in the list, because the default value of $IFS is
1182 <space><tab><newline>, IFS characters in the words in the list should
1183 also be split. If IFS is null, and the word is not quoted, we need
1184 to quote the words in the list to preserve the positional parameters
1187 string_list_dollar_at (list, quoted)
1194 ifs = get_string_value ("IFS");
1196 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1199 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1201 : list_quote_escapes (list);
1202 return (string_list_internal (tlist, sep));
1205 /* Return the list of words present in STRING. Separate the string into
1206 words at any of the characters found in SEPARATORS. If QUOTED is
1207 non-zero then word in the list will have its quoted flag set, otherwise
1208 the quoted flag is left as make_word () deemed fit.
1210 This obeys the P1003.2 word splitting semantics. If `separators' is
1211 exactly <space><tab><newline>, then the splitting algorithm is that of
1212 the Bourne shell, which treats any sequence of characters from `separators'
1213 as a delimiter. If IFS is unset, which results in `separators' being set
1214 to "", no splitting occurs. If separators has some other value, the
1215 following rules are applied (`IFS white space' means zero or more
1216 occurrences of <space>, <tab>, or <newline>, as long as those characters
1217 are in `separators'):
1219 1) IFS white space is ignored at the start and the end of the
1221 2) Each occurrence of a character in `separators' that is not
1222 IFS white space, along with any adjacent occurrences of
1223 IFS white space delimits a field.
1224 3) Any nonzero-length sequence of IFS white space delimits a field.
1227 /* BEWARE! list_string strips null arguments. Don't call it twice and
1228 expect to have "" preserved! */
1230 /* This performs word splitting and quoted null character removal on
1232 #define issep(c) (member ((c), separators))
1235 list_string (string, separators, quoted)
1236 register char *string, *separators;
1241 char *current_word, *s;
1242 int sindex, sh_style_split;
1244 if (!string || !*string)
1245 return ((WORD_LIST *)NULL);
1248 separators && *separators && (STREQ (separators, " \t\n"));
1250 /* Remove sequences of whitespace at the beginning of STRING, as
1251 long as those characters appear in IFS. Do not do this if
1252 STRING is quoted or if there are no separator characters. */
1253 if (!quoted || !separators || !*separators)
1255 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1258 return ((WORD_LIST *)NULL);
1263 /* OK, now STRING points to a word that does not begin with white space.
1264 The splitting algorithm is:
1265 extract a word, stopping at a separator
1266 skip sequences of spc, tab, or nl as long as they are separators
1267 This obeys the field splitting rules in Posix.2. */
1268 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1270 current_word = string_extract_verbatim (string, &sindex, separators);
1271 if (current_word == 0)
1274 /* If we have a quoted empty string, add a quoted null argument. We
1275 want to preserve the quoted null character iff this is a quoted
1276 empty string; otherwise the quoted null characters are removed
1278 if (QUOTED_NULL (current_word))
1280 t = make_bare_word ("");
1281 t->flags |= W_QUOTED;
1283 t->word = make_quoted_char ('\0');
1284 result = make_word_list (t, result);
1286 else if (current_word[0] != '\0')
1288 /* If we have something, then add it regardless. However,
1289 perform quoted null character removal on the current word. */
1290 remove_quoted_nulls (current_word);
1292 result = make_word_list (make_word (current_word), result);
1294 result = add_string_to_list (current_word, result);
1296 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
1297 result->word->flags |= W_QUOTED;
1300 /* If we're not doing sequences of separators in the traditional
1301 Bourne shell style, then add a quoted null argument. */
1302 else if (!sh_style_split && !spctabnl (string[sindex]))
1304 t = make_bare_word ("");
1305 t->flags |= W_QUOTED;
1307 t->word = make_quoted_char ('\0');
1308 result = make_word_list (t, result);
1311 free (current_word);
1313 /* Move past the current separator character. */
1317 /* Now skip sequences of space, tab, or newline characters if they are
1318 in the list of separators. */
1319 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
1322 return (REVERSE_LIST (result, WORD_LIST *));
1325 /* Parse a single word from STRING, using SEPARATORS to separate fields.
1326 ENDPTR is set to the first character after the word. This is used by
1328 XXX - this function is very similar to list_string; they should be
1331 get_word_from_string (stringp, separators, endptr)
1332 char **stringp, *separators, **endptr;
1336 int sindex, sh_style_split;
1338 if (!stringp || !*stringp || !**stringp)
1339 return ((char *)NULL);
1344 separators && *separators && (STREQ (separators, " \t\n"));
1346 /* Remove sequences of whitespace at the beginning of STRING, as
1347 long as those characters appear in IFS. */
1348 if (sh_style_split || !separators || !*separators)
1350 for (; *s && spctabnl (*s) && issep (*s); s++);
1352 /* If the string is nothing but whitespace, update it and return. */
1358 return ((char *)NULL);
1362 /* OK, S points to a word that does not begin with white space.
1363 Now extract a word, stopping at a separator, save a pointer to
1364 the first character after the word, then skip sequences of spc,
1365 tab, or nl as long as they are separators.
1367 This obeys the field splitting rules in Posix.2. */
1369 current_word = string_extract_verbatim (s, &sindex, separators);
1371 /* Set ENDPTR to the first character after the end of the word. */
1373 *endptr = s + sindex;
1375 /* Move past the current separator character. */
1379 /* Now skip sequences of space, tab, or newline characters if they are
1380 in the list of separators. */
1381 while (s[sindex] && spctabnl (s[sindex]) && issep (s[sindex]))
1384 /* Update STRING to point to the next field. */
1385 *stringp = s + sindex;
1386 return (current_word);
1389 /* Remove IFS white space at the end of STRING. Start at the end
1390 of the string and walk backwards until the beginning of the string
1391 or we find a character that's not IFS white space and not CTLESC.
1392 Only let CTLESC escape a white space character if SAW_ESCAPE is
1395 strip_trailing_ifs_whitespace (string, separators, saw_escape)
1396 char *string, *separators;
1401 s = string + STRLEN (string) - 1;
1402 while (s > string && ((spctabnl (*s) && issep (*s)) ||
1403 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
1409 #if defined (ARRAY_VARS)
1411 list_string_with_quotes (string)
1416 int c, i, tokstart, len;
1418 for (s = string; s && *s && spctabnl (*s); s++)
1420 if (s == 0 || *s == 0)
1421 return ((WORD_LIST *)NULL);
1424 list = (WORD_LIST *)NULL;
1435 i = skip_single_quoted (s, ++i);
1437 i = skip_double_quoted (s, ++i);
1438 else if (c == 0 || spctabnl (c))
1440 /* We have found the end of a token. Make a word out of it and
1441 add it to the word list. */
1443 token = xmalloc (len + 1);
1444 strncpy (token, s + tokstart, len);
1447 list = make_word_list (make_word (token), list);
1449 list = add_string_to_list (token, list);
1452 while (spctabnl (s[i]))
1460 i++; /* normal character */
1462 return (REVERSE_LIST (list, WORD_LIST *));
1464 #endif /* ARRAY_VARS */
1466 /********************************************************/
1468 /* Functions to perform assignment statements */
1470 /********************************************************/
1472 #if defined (ARRAY_VARS)
1474 do_array_element_assignment (name, value)
1481 t = strchr (name, '[');
1483 return ((SHELL_VAR *)NULL);
1485 ni = skipsubscript (name, ind);
1486 if ((ALL_ELEMENT_SUB (t[1]) && t[2] == ']') || (ni <= ind + 1))
1488 report_error ("%s: bad array subscript", name);
1489 return ((SHELL_VAR *)NULL);
1492 ind = array_expand_index (t, ni - ind);
1495 t[-1] = '['; /* restore original name */
1496 report_error ("%s: bad array subscript", name);
1497 return ((SHELL_VAR *)NULL);
1499 entry = bind_array_variable (name, ind, value);
1500 t[-1] = '['; /* restore original name */
1503 #endif /* ARRAY_VARS */
1505 /* Given STRING, an assignment string, get the value of the right side
1506 of the `=', and bind it to the left side. If EXPAND is true, then
1507 perform parameter expansion, command substitution, and arithmetic
1508 expansion on the right-hand side. Perform tilde expansion in any
1509 case. Do not perform word splitting on the result of expansion. */
1511 do_assignment_internal (string, expand)
1518 #if defined (ARRAY_VARS)
1520 int ni, assign_list = 0;
1523 offset = assignment (string);
1524 name = savestring (string);
1525 value = (char *)NULL;
1527 if (name[offset] == '=')
1532 temp = name + offset + 1;
1534 #if defined (ARRAY_VARS)
1535 if (expand && temp[0] == LPAREN && strchr (temp, RPAREN))
1537 assign_list = ni = 1;
1538 value = extract_delimited_string (temp, &ni, "(", (char *)NULL, ")");
1543 /* Perform tilde expansion. */
1544 if (expand && temp[0])
1546 temp = (strchr (temp, '~') && unquoted_member ('~', temp))
1547 ? bash_tilde_expand (temp)
1548 : savestring (temp);
1550 value = maybe_expand_string (temp, 0, expand_string_unsplit);
1554 value = savestring (temp);
1559 value = xmalloc (1);
1563 if (echo_command_at_execute)
1564 #if defined (ARRAY_VARS)
1566 fprintf (stderr, "%s%s=(%s)\n", indirection_level_string (), name, value);
1569 fprintf (stderr, "%s%s=%s\n", indirection_level_string (), name, value);
1571 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
1573 #if defined (ARRAY_VARS)
1574 if (t = strchr (name, '['))
1578 report_error ("%s: cannot assign list to array member", name);
1581 entry = do_array_element_assignment (name, value);
1585 else if (assign_list)
1586 entry = assign_array_from_string (name, value);
1588 #endif /* ARRAY_VARS */
1589 entry = bind_variable (name, value);
1591 stupidly_hack_special_variables (name);
1594 entry->attributes &= ~att_invisible;
1596 /* Return 1 if the assignment seems to have been performed correctly. */
1597 ASSIGN_RETURN (entry ? ((entry->attributes & att_readonly) == 0) : 0);
1600 /* Perform the assignment statement in STRING, and expand the
1601 right side by doing command and parameter expansion. */
1603 do_assignment (string)
1606 return do_assignment_internal (string, 1);
1609 /* Given STRING, an assignment string, get the value of the right side
1610 of the `=', and bind it to the left side. Do not do command and
1611 parameter substitution on the right hand side. */
1613 do_assignment_no_expand (string)
1616 return do_assignment_internal (string, 0);
1619 /***************************************************
1621 * Functions to manage the positional parameters *
1623 ***************************************************/
1625 /* Return the word list that corresponds to `$*'. */
1627 list_rest_of_args ()
1629 register WORD_LIST *list, *args;
1632 /* Break out of the loop as soon as one of the dollar variables is null. */
1633 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
1634 list = make_word_list (make_bare_word (dollar_vars[i]), list);
1636 for (args = rest_of_args; args; args = args->next)
1637 list = make_word_list (make_bare_word (args->word->word), list);
1639 return (REVERSE_LIST (list, WORD_LIST *));
1645 register WORD_LIST *list;
1648 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
1650 for (list = rest_of_args; list; list = list->next)
1655 /* Return the value of a positional parameter. This handles values > 10. */
1657 get_dollar_var_value (ind)
1664 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
1665 else /* We want something like ${11} */
1668 for (p = rest_of_args; p && ind--; p = p->next)
1670 temp = p ? savestring (p->word->word) : (char *)NULL;
1675 /* Make a single large string out of the dollar digit variables,
1676 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
1677 case of "$*" with respect to IFS. */
1679 string_rest_of_args (dollar_star)
1682 register WORD_LIST *list;
1685 list = list_rest_of_args ();
1686 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
1687 dispose_words (list);
1691 /* Return a string containing the positional parameters from START to
1692 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
1693 which only makes a difference if QUOTED is non-zero. */
1695 pos_params (string, start, end, quoted)
1697 int start, end, quoted;
1699 WORD_LIST *save, *params, *h, *t;
1703 save = params = list_rest_of_args ();
1705 return ((char *)NULL);
1707 for (i = 1; params && i < start; i++)
1708 params = params->next;
1710 return ((char *)NULL);
1711 for (h = t = params; params && i < end; i++)
1714 params = params->next;
1717 t->next = (WORD_LIST *)NULL;
1718 if (string[0] == '*')
1719 ret = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (h) : string_list (h);
1721 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
1724 dispose_words (save);
1728 /******************************************************************/
1730 /* Functions to expand strings to strings or WORD_LISTs */
1732 /******************************************************************/
1734 #if defined (PROCESS_SUBSTITUTION)
1735 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC)
1737 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
1740 /* If there are any characters in STRING that require full expansion,
1741 then call FUNC to expand STRING; otherwise just perform quote
1742 removal if necessary. This returns a new string. */
1744 maybe_expand_string (string, quoted, func)
1747 WORD_LIST *(*func)();
1753 for (i = saw_quote = 0; string[i]; i++)
1755 if (EXP_CHAR (string[i]))
1757 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
1763 list = (*func) (string, quoted);
1766 ret = string_list (list);
1767 dispose_words (list);
1772 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
1773 ret = string_quote_removal (string, quoted);
1775 ret = savestring (string);
1779 static inline char *
1780 expand_string_to_string (string, quoted, func)
1783 WORD_LIST *(*func)();
1788 if (string == 0 || *string == '\0')
1789 return ((char *)NULL);
1791 list = (*func) (string, quoted);
1794 ret = string_list (list);
1795 dispose_words (list);
1803 #if defined (COND_COMMAND)
1804 /* Just remove backslashes in STRING. Returns a new string. */
1806 remove_backslashes (string)
1811 r = ret = xmalloc (strlen (string) + 1);
1812 for (s = string; s && *s; )
1824 /* This needs better error handling. */
1825 /* Expand W for use as an argument to a unary or binary operator in a
1826 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
1827 to the != or == operator, and should be treated as a pattern. In
1828 this case, we quote the string specially for the globbing code. The
1829 caller is responsible for removing the backslashes if the unquoted
1830 words is needed later. */
1832 cond_expand_word (w, special)
1839 if (w->word == 0 || w->word[0] == '\0')
1840 return ((char *)NULL);
1842 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
1848 r = string_list (l);
1852 p = string_list (l);
1853 r = quote_string_for_globbing (p, QGLOB_CVTNULL);
1865 /* Call expand_word_internal to expand W and handle error returns.
1866 A convenience function for functions that don't want to handle
1867 any errors or free any memory before aborting. */
1869 call_expand_word_internal (w, q, i, c, e)
1875 result = expand_word_internal (w, q, i, c, e);
1876 if (result == &expand_word_error)
1878 /* By convention, each time this error is returned, w->word has
1879 already been freed. */
1880 w->word = (char *)NULL;
1881 jump_to_top_level (DISCARD);
1884 else if (result == &expand_word_fatal)
1885 jump_to_top_level (FORCE_EOF);
1891 /* Perform parameter expansion, command substitution, and arithmetic
1892 expansion on STRING, as if it were a word. Leave the result quoted. */
1894 expand_string_internal (string, quoted)
1901 if (string == 0 || *string == 0)
1902 return ((WORD_LIST *)NULL);
1904 bzero ((char *)&td, sizeof (td));
1906 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
1910 /* Expand STRING by performing parameter expansion, command substitution,
1911 and arithmetic expansion. Dequote the resulting WORD_LIST before
1912 returning it, but do not perform word splitting. The call to
1913 remove_quoted_nulls () is in here because word splitting normally
1914 takes care of quote removal. */
1916 expand_string_unsplit (string, quoted)
1922 if (!string || !*string)
1923 return ((WORD_LIST *)NULL);
1925 value = expand_string_internal (string, quoted);
1929 remove_quoted_nulls (value->word->word);
1930 dequote_list (value);
1935 /* Expand STRING just as if you were expanding a word, but do not dequote
1936 the resultant WORD_LIST. This is called only from within this file,
1937 and is used to correctly preserve quoted characters when expanding
1938 things like ${1+"$@"}. This does parameter expansion, command
1939 substitution, arithmetic expansion, and word splitting. */
1941 expand_string_leave_quoted (string, quoted)
1948 if (string == 0 || *string == '\0')
1949 return ((WORD_LIST *)NULL);
1951 tlist = expand_string_internal (string, quoted);
1955 tresult = word_list_split (tlist);
1956 dispose_words (tlist);
1959 return ((WORD_LIST *)NULL);
1962 /* This does not perform word splitting or dequote the WORD_LIST
1965 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
1967 int quoted, *dollar_at_p, *has_dollar_at;
1972 if (string == 0 || *string == '\0')
1973 return (WORD_LIST *)NULL;
1975 bzero ((char *)&td, sizeof (td));
1977 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
1981 /* Expand STRING just as if you were expanding a word. This also returns
1982 a list of words. Note that filename globbing is *NOT* done for word
1983 or string expansion, just when the shell is expanding a command. This
1984 does parameter expansion, command substitution, arithmetic expansion,
1985 and word splitting. Dequote the resultant WORD_LIST before returning. */
1987 expand_string (string, quoted)
1993 if (!string || !*string)
1994 return ((WORD_LIST *)NULL);
1996 result = expand_string_leave_quoted (string, quoted);
1997 return (result ? dequote_list (result) : result);
2000 /***************************************************
2002 * Functions to handle quoting chars *
2004 ***************************************************/
2008 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2009 The parser passes CTLNUL as CTLESC CTLNUL. */
2011 /* The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2012 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2013 data stream pass through properly.
2014 Here we remove doubled CTLESC characters inside quoted strings before
2015 quoting the entire string, so we do not double the number of CTLESC
2018 remove_quoted_escapes (string)
2028 t1 = t = xmalloc (strlen (string) + 1);
2029 for (docopy = 0, s = string; *s; s++, t1++)
2031 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2045 /* Quote escape characters in string s, but no other characters. This is
2046 used to protect CTLESC and CTLNUL in variable values from the rest of
2047 the word expansion process after the variable is expanded. */
2049 quote_escapes (string)
2052 register char *s, *t;
2055 result = xmalloc ((strlen (string) * 2) + 1);
2056 for (s = string, t = result; *s; )
2058 if (*s == CTLESC || *s == CTLNUL)
2067 list_quote_escapes (list)
2070 register WORD_LIST *w;
2073 for (w = list; w; w = w->next)
2076 w->word->word = quote_escapes (t);
2082 #ifdef INCLUDE_UNUSED
2084 dequote_escapes (string)
2087 register char *s, *t;
2090 result = xmalloc (strlen (string) + 1);
2091 for (s = string, t = result; *s; )
2093 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2111 register WORD_LIST *tlist;
2113 for (tlist = list; tlist; tlist = tlist->next)
2115 s = dequote_string (tlist->word->word);
2116 free (tlist->word->word);
2117 tlist->word->word = s;
2123 make_quoted_char (c)
2143 /* Quote STRING. Return a new string. */
2145 quote_string (string)
2153 result = xmalloc (2);
2159 result = xmalloc ((strlen (string) * 2) + 1);
2161 for (t = result; *string; )
2171 /* De-quoted quoted characters in STRING. */
2173 dequote_string (string)
2179 result = xmalloc (strlen (string) + 1);
2181 if (QUOTED_NULL (string))
2187 /* If no character in the string can be quoted, don't bother examining
2188 each character. Just return a copy of the string passed to us. */
2189 if (strchr (string, CTLESC) == NULL) /* XXX */
2191 strcpy (result, string); /* XXX */
2192 return (result); /* XXX */
2195 for (t = result; *string; string++, t++)
2197 if (*string == CTLESC)
2212 /* Quote the entire WORD_LIST list. */
2217 register WORD_LIST *w;
2220 for (w = list; w; w = w->next)
2223 w->word->word = quote_string (t);
2225 w->word->flags |= W_QUOTED;
2230 /* Perform quoted null character removal on STRING. We don't allow any
2231 quoted null characters in the middle or at the ends of strings because
2232 of how expand_word_internal works. remove_quoted_nulls () turns
2233 STRING into an empty string iff it only consists of a quoted null,
2234 and removes all unquoted CTLNUL characters. */
2236 #define remove_quoted_nulls(string) \
2237 do { if (QUOTED_NULL (string)) string[0] ='\0'; } while (0)
2240 remove_quoted_nulls (string)
2245 nstr = savestring (string);
2247 for (p = nstr, s = string; *s; s++)
2251 *p++ = *s++; /* CTLESC */
2254 *p++ = *s; /* quoted char */
2262 strcpy (string, nstr);
2266 /* Perform quoted null character removal on each element of LIST.
2267 This modifies LIST. */
2269 word_list_remove_quoted_nulls (list)
2272 register WORD_LIST *t;
2274 for (t = list; t; t = t->next)
2275 remove_quoted_nulls (t->word->word);
2278 /* **************************************************************** */
2280 /* Functions for Matching and Removing Patterns */
2282 /* **************************************************************** */
2284 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
2285 can have one of 4 values:
2286 RP_LONG_LEFT remove longest matching portion at start of PARAM
2287 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
2288 RP_LONG_RIGHT remove longest matching portion at end of PARAM
2289 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
2292 #define RP_LONG_LEFT 1
2293 #define RP_SHORT_LEFT 2
2294 #define RP_LONG_RIGHT 3
2295 #define RP_SHORT_RIGHT 4
2298 remove_pattern (param, pattern, op)
2299 char *param, *pattern;
2304 register char *p, *ret, c;
2306 if (param == NULL || *param == '\0')
2308 if (pattern == NULL || *pattern == '\0') /* minor optimization */
2309 return (savestring (param));
2311 len = STRLEN (param);
2316 case RP_LONG_LEFT: /* remove longest match at start */
2317 for (p = end; p >= param; p--)
2320 if (fnmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2323 return (savestring (p));
2329 case RP_SHORT_LEFT: /* remove shortest match at start */
2330 for (p = param; p <= end; p++)
2333 if (fnmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2336 return (savestring (p));
2342 case RP_LONG_RIGHT: /* remove longest match at end */
2343 for (p = param; p <= end; p++)
2345 if (fnmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2348 ret = savestring (param);
2355 case RP_SHORT_RIGHT: /* remove shortest match at end */
2356 for (p = end; p >= param; p--)
2358 if (fnmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2361 ret = savestring (param);
2368 return (savestring (param)); /* no match, return original string */
2371 /* Return 1 of the first character of STRING could match the first
2372 character of pattern PAT. Used to avoid n2 calls to fnmatch(). */
2374 match_pattern_char (pat, string)
2385 return (*string == c);
2387 return (*string == *pat);
2389 return (*string == LPAREN ? 1 : (*string != '\0'));
2395 return (*string == LPAREN ? 1 : (*string == c));
2397 return (*string != '\0');
2401 /* Match PAT anywhere in STRING and return the match boundaries.
2402 This returns 1 in case of a successful match, 0 otherwise. SP
2403 and EP are pointers into the string where the match begins and
2404 ends, respectively. MTYPE controls what kind of match is attempted.
2405 MATCH_BEG and MATCH_END anchor the match at the beginning and end
2406 of the string, respectively. The longest match is returned. */
2408 match_pattern (string, pat, mtype, sp, ep)
2414 register char *p, *p1;
2417 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
2420 end = string + STRLEN (string);
2425 for (p = string; p <= end; p++)
2427 if (match_pattern_char (pat, p))
2429 for (p1 = end; p1 >= p; p1--)
2431 c = *p1; *p1 = '\0';
2432 if (fnmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2446 if (match_pattern_char (pat, string) == 0)
2448 for (p = end; p >= string; p--)
2451 if (fnmatch (pat, string, FNMATCH_EXTFLAG) == 0)
2463 for (p = string; p <= end; p++)
2464 if (fnmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2477 getpatspec (c, value)
2482 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
2484 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
2487 /* Posix.2 says that the WORD should be run through tilde expansion,
2488 parameter expansion, command substitution and arithmetic expansion.
2489 This leaves the result quoted, so quote_string_for_globbing () has
2490 to be called to fix it up for fnmatch (). If QUOTED is non-zero,
2491 it means that the entire expression was enclosed in double quotes.
2492 This means that quoting characters in the pattern do not make any
2493 special pattern characters quoted. For example, the `*' in the
2494 following retains its special meaning: "${foo#'*'}". */
2496 getpattern (value, quoted, expandpat)
2498 int quoted, expandpat;
2504 tword = strchr (value, '~') ? bash_tilde_expand (value) : savestring (value);
2506 /* expand_string_internal () leaves WORD quoted and does not perform
2508 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
2511 pat = string_extract_double_quoted (tword, &i, 1);
2516 /* There is a problem here: how to handle single or double quotes in the
2517 pattern string when the whole expression is between double quotes? */
2519 l = *tword ? expand_string_for_rhs (tword, quoted, (int *)NULL, (int *)NULL)
2521 l = *tword ? expand_string_for_rhs (tword,
2522 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_NOQUOTE : quoted,
2523 (int *)NULL, (int *)NULL)
2527 pat = string_list (l);
2531 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
2538 /* Handle removing a pattern from a string as a result of ${name%[%]value}
2539 or ${name#[#]value}. */
2541 parameter_brace_remove_pattern (value, temp, c, quoted)
2546 char *pattern, *tword;
2548 patspec = getpatspec (c, value);
2549 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2552 pattern = getpattern (value, quoted, 1);
2554 tword = remove_pattern (temp, pattern, patspec);
2561 list_remove_pattern (list, pattern, patspec, type, quoted)
2564 int patspec, type, quoted;
2570 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
2572 tword = remove_pattern (l->word->word, pattern, patspec);
2573 w = make_bare_word (tword);
2575 new = make_word_list (w, new);
2578 l = REVERSE_LIST (new, WORD_LIST *);
2580 tword = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
2582 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
2589 parameter_list_remove_pattern (value, type, c, quoted)
2591 int type, c, quoted;
2594 char *pattern, *ret;
2597 patspec = getpatspec (c, value);
2598 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2601 pattern = getpattern (value, quoted, 1);
2603 list = list_rest_of_args ();
2604 ret = list_remove_pattern (list, pattern, patspec, type, quoted);
2605 dispose_words (list);
2610 #if defined (ARRAY_VARS)
2612 array_remove_pattern (value, aspec, aval, c, quoted)
2613 char *value, *aspec, *aval; /* AVAL == evaluated ASPEC */
2618 char *ret, *t, *pattern;
2621 var = array_variable_part (aspec, &t, &len);
2623 return ((char *)NULL);
2625 patspec = getpatspec (c, value);
2626 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2629 pattern = getpattern (value, quoted, 1);
2631 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
2633 if (array_p (var) == 0)
2635 report_error ("%s: bad array subscript", aspec);
2637 return ((char *)NULL);
2639 l = array_to_word_list (array_cell (var));
2641 return ((char *)NULL);
2642 ret = list_remove_pattern (l, pattern, patspec, t[0], quoted);
2647 ret = remove_pattern (aval, pattern, patspec);
2650 t = quote_escapes (ret);
2659 #endif /* ARRAY_VARS */
2661 /*******************************************
2663 * Functions to expand WORD_DESCs *
2665 *******************************************/
2667 /* Expand WORD, performing word splitting on the result. This does
2668 parameter expansion, command substitution, arithmetic expansion,
2669 word splitting, and quote removal. */
2672 expand_word (word, quoted)
2676 WORD_LIST *result, *tresult;
2678 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
2679 result = word_list_split (tresult);
2680 dispose_words (tresult);
2681 return (result ? dequote_list (result) : result);
2684 /* Expand WORD, but do not perform word splitting on the result. This
2685 does parameter expansion, command substitution, arithmetic expansion,
2686 and quote removal. */
2688 expand_word_no_split (word, quoted)
2694 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
2695 return (result ? dequote_list (result) : result);
2698 /* Perform shell expansions on WORD, but do not perform word splitting or
2699 quote removal on the result. */
2701 expand_word_leave_quoted (word, quoted)
2705 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
2708 #if defined (PROCESS_SUBSTITUTION)
2710 /*****************************************************************/
2712 /* Hacking Process Substitution */
2714 /*****************************************************************/
2716 #if !defined (HAVE_DEV_FD)
2717 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
2718 of FIFOs the shell has open. unlink_fifo_list will walk the list and
2719 unlink all of them. add_fifo_list adds the name of an open FIFO to the
2720 list. NFIFO is a count of the number of FIFOs in the list. */
2721 #define FIFO_INCR 20
2722 extern char *mktemp ();
2724 static char **fifo_list = (char **)NULL;
2726 static int fifo_list_size;
2729 add_fifo_list (pathname)
2732 if (nfifo >= fifo_list_size - 1)
2734 fifo_list_size += FIFO_INCR;
2735 fifo_list = (char **)xrealloc (fifo_list,
2736 fifo_list_size * sizeof (char *));
2739 fifo_list[nfifo++] = savestring (pathname);
2750 unlink (fifo_list[nfifo]);
2751 free (fifo_list[nfifo]);
2752 fifo_list[nfifo] = (char *)NULL;
2762 tname = mktemp (savestring ("/tmp/sh-np-XXXXXX"));
2763 if (mkfifo (tname, 0600) < 0)
2766 return ((char *)NULL);
2769 add_fifo_list (tname);
2773 #else /* HAVE_DEV_FD */
2775 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
2776 has open to children. NFDS is a count of the number of bits currently
2777 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
2779 static char *dev_fd_list = (char *)NULL;
2781 static int totfds; /* The highest possible number of open files. */
2787 if (!dev_fd_list || fd >= totfds)
2792 totfds = getdtablesize ();
2793 if (totfds < 0 || totfds > 256)
2798 dev_fd_list = xrealloc (dev_fd_list, totfds);
2799 bzero (dev_fd_list + ofds, totfds - ofds);
2802 dev_fd_list[fd] = 1;
2814 for (i = 0; nfds && i < totfds; i++)
2825 #if defined (NOTDEF)
2826 print_dev_fd_list ()
2830 fprintf (stderr, "pid %d: dev_fd_list:", getpid ());
2833 for (i = 0; i < totfds; i++)
2836 fprintf (stderr, " %d", i);
2838 fprintf (stderr, "\n");
2843 make_dev_fd_filename (fd)
2848 ret = xmalloc (sizeof (DEV_FD_PREFIX) + 4);
2849 sprintf (ret, "%s%d", DEV_FD_PREFIX, fd);
2854 #endif /* HAVE_DEV_FD */
2856 /* Return a filename that will open a connection to the process defined by
2857 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
2858 a filename in /dev/fd corresponding to a descriptor that is one of the
2859 ends of the pipe. If not defined, we use named pipes on systems that have
2860 them. Systems without /dev/fd and named pipes are out of luck.
2862 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
2863 use the read end of the pipe and dup that file descriptor to fd 0 in
2864 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
2865 writing or use the write end of the pipe in the child, and dup that
2866 file descriptor to fd 1 in the child. The parent does the opposite. */
2869 process_substitute (string, open_for_read_in_child)
2871 int open_for_read_in_child;
2876 #if defined (HAVE_DEV_FD)
2877 int parent_pipe_fd, child_pipe_fd;
2879 #endif /* HAVE_DEV_FD */
2880 #if defined (JOB_CONTROL)
2881 pid_t old_pipeline_pgrp;
2884 if (!string || !*string || wordexp_only)
2885 return ((char *)NULL);
2887 #if !defined (HAVE_DEV_FD)
2888 pathname = make_named_pipe ();
2889 #else /* HAVE_DEV_FD */
2890 if (pipe (fildes) < 0)
2892 sys_error ("cannot make pipe for process substitution");
2893 return ((char *)NULL);
2895 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
2896 the pipe in the parent, otherwise the read end. */
2897 parent_pipe_fd = fildes[open_for_read_in_child];
2898 child_pipe_fd = fildes[1 - open_for_read_in_child];
2899 /* Move the parent end of the pipe to some high file descriptor, to
2900 avoid clashes with FDs used by the script. */
2901 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
2903 pathname = make_dev_fd_filename (parent_pipe_fd);
2904 #endif /* HAVE_DEV_FD */
2908 sys_error ("cannot make pipe for process substitution");
2909 return ((char *)NULL);
2912 old_pid = last_made_pid;
2914 #if defined (JOB_CONTROL)
2915 old_pipeline_pgrp = pipeline_pgrp;
2916 pipeline_pgrp = shell_pgrp;
2918 cleanup_the_pipeline ();
2922 #endif /* JOB_CONTROL */
2924 pid = make_child ((char *)NULL, 1);
2927 reset_terminating_signals (); /* XXX */
2928 /* Cancel traps, in trap.c. */
2929 restore_original_signals ();
2930 setup_async_signals ();
2931 subshell_environment = SUBSHELL_COMSUB;
2934 #if defined (JOB_CONTROL)
2935 set_sigchld_handler ();
2936 stop_making_children ();
2937 pipeline_pgrp = old_pipeline_pgrp;
2938 #endif /* JOB_CONTROL */
2942 sys_error ("cannot make child for process substitution");
2944 #if defined (HAVE_DEV_FD)
2945 close (parent_pipe_fd);
2946 close (child_pipe_fd);
2947 #endif /* HAVE_DEV_FD */
2948 return ((char *)NULL);
2953 #if defined (JOB_CONTROL)
2954 restore_pipeline (1);
2957 last_made_pid = old_pid;
2959 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
2961 #endif /* JOB_CONTROL && PGRP_PIPE */
2963 #if defined (HAVE_DEV_FD)
2964 close (child_pipe_fd);
2965 #endif /* HAVE_DEV_FD */
2970 set_sigint_handler ();
2972 #if defined (JOB_CONTROL)
2973 set_job_control (0);
2974 #endif /* JOB_CONTROL */
2976 #if !defined (HAVE_DEV_FD)
2977 /* Open the named pipe in the child. */
2978 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
2981 sys_error ("cannot open named pipe %s for %s", pathname,
2982 open_for_read_in_child ? "reading" : "writing");
2985 #else /* HAVE_DEV_FD */
2987 #endif /* HAVE_DEV_FD */
2989 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
2991 sys_error ("cannot duplicate named pipe %s as fd %d", pathname,
2992 open_for_read_in_child ? 0 : 1);
2998 /* Need to close any files that this process has open to pipes inherited
3000 if (current_fds_to_close)
3002 close_fd_bitmap (current_fds_to_close);
3003 current_fds_to_close = (struct fd_bitmap *)NULL;
3006 #if defined (HAVE_DEV_FD)
3007 /* Make sure we close the parent's end of the pipe and clear the slot
3008 in the fd list so it is not closed later, if reallocated by, for
3009 instance, pipe(2). */
3010 close (parent_pipe_fd);
3011 dev_fd_list[parent_pipe_fd] = 0;
3012 #endif /* HAVE_DEV_FD */
3014 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
3016 #if !defined (HAVE_DEV_FD)
3017 /* Make sure we close the named pipe in the child before we exit. */
3018 close (open_for_read_in_child ? 0 : 1);
3019 #endif /* !HAVE_DEV_FD */
3024 #endif /* PROCESS_SUBSTITUTION */
3026 /***********************************/
3028 /* Command Substitution */
3030 /***********************************/
3033 read_comsub (fd, quoted)
3036 char *istring, buf[128], *bufp;
3037 int bufn, istring_index, istring_size, c;
3039 istring = (char *)NULL;
3040 istring_index = istring_size = bufn = 0;
3042 /* Read the output of the command through the pipe. */
3049 while ((bufn = read (fd, buf, sizeof(buf))) < 0 && errno == EINTR)
3057 /* Add the character to ISTRING, possibly after resizing it. */
3058 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
3060 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
3061 istring[istring_index++] = CTLESC;
3063 istring[istring_index++] = c;
3067 istring[istring_index] = '\0';
3069 /* If we read no output, just return now and save ourselves some
3071 if (istring_index == 0)
3074 return (char *)NULL;
3077 /* Strip trailing newlines from the output of the command. */
3078 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
3080 while (istring_index > 0)
3082 if (istring[istring_index - 1] == '\n')
3086 /* If the newline was quoted, remove the quoting char. */
3087 if (istring[istring_index - 1] == CTLESC)
3093 istring[istring_index] = '\0';
3096 strip_trailing (istring, istring_index - 1, 1);
3101 /* Perform command substitution on STRING. This returns a string,
3104 command_substitute (string, quoted)
3108 pid_t pid, old_pid, old_pipeline_pgrp;
3110 int result, fildes[2];
3112 istring = (char *)NULL;
3114 /* Don't fork () if there is no need to. In the case of no command to
3115 run, just return NULL. */
3116 if (!string || !*string || (string[0] == '\n' && !string[1]))
3117 return ((char *)NULL);
3119 if (wordexp_only && read_but_dont_execute)
3121 last_command_exit_value = 125;
3122 jump_to_top_level (EXITPROG);
3125 /* Pipe the output of executing STRING into the current shell. */
3126 if (pipe (fildes) < 0)
3128 sys_error ("cannot make pipes for command substitution");
3132 old_pid = last_made_pid;
3133 #if defined (JOB_CONTROL)
3134 old_pipeline_pgrp = pipeline_pgrp;
3135 pipeline_pgrp = shell_pgrp;
3136 cleanup_the_pipeline ();
3139 pid = make_child ((char *)NULL, 0);
3141 /* Reset the signal handlers in the child, but don't free the
3143 reset_signal_handlers ();
3145 #if defined (JOB_CONTROL)
3146 set_sigchld_handler ();
3147 stop_making_children ();
3148 pipeline_pgrp = old_pipeline_pgrp;
3149 #endif /* JOB_CONTROL */
3153 sys_error ("cannot make child for command substitution");
3159 return ((char *)NULL);
3164 set_sigint_handler (); /* XXX */
3165 #if defined (JOB_CONTROL)
3166 set_job_control (0);
3168 if (dup2 (fildes[1], 1) < 0)
3170 sys_error ("command_substitute: cannot duplicate pipe as fd 1");
3171 exit (EXECUTION_FAILURE);
3174 /* If standard output is closed in the parent shell
3175 (such as after `exec >&-'), file descriptor 1 will be
3176 the lowest available file descriptor, and end up in
3177 fildes[0]. This can happen for stdin and stderr as well,
3178 but stdout is more important -- it will cause no output
3179 to be generated from this command. */
3180 if ((fildes[1] != fileno (stdin)) &&
3181 (fildes[1] != fileno (stdout)) &&
3182 (fildes[1] != fileno (stderr)))
3185 if ((fildes[0] != fileno (stdin)) &&
3186 (fildes[0] != fileno (stdout)) &&
3187 (fildes[0] != fileno (stderr)))
3190 /* The currently executing shell is not interactive. */
3193 /* This is a subshell environment. */
3194 subshell_environment = SUBSHELL_COMSUB;
3196 /* Command substitution does not inherit the -e flag. */
3197 exit_immediately_on_error = 0;
3199 remove_quoted_escapes (string);
3201 startup_state = 2; /* see if we can avoid a fork */
3202 /* Give command substitution a place to jump back to on failure,
3203 so we don't go back up to main (). */
3204 result = setjmp (top_level);
3206 if (result == EXITPROG)
3207 exit (last_command_exit_value);
3209 exit (EXECUTION_FAILURE);
3211 exit (parse_and_execute (string, "command substitution", SEVAL_NOHIST));
3215 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
3217 #endif /* JOB_CONTROL && PGRP_PIPE */
3221 istring = read_comsub (fildes[0], quoted);
3225 current_command_subst_pid = pid;
3226 last_command_exit_value = wait_for (pid);
3227 last_command_subst_pid = pid;
3228 last_made_pid = old_pid;
3230 #if defined (JOB_CONTROL)
3231 /* If last_command_exit_value > 128, then the substituted command
3232 was terminated by a signal. If that signal was SIGINT, then send
3233 SIGINT to ourselves. This will break out of loops, for instance. */
3234 if (last_command_exit_value == (128 + SIGINT))
3235 kill (getpid (), SIGINT);
3237 /* wait_for gives the terminal back to shell_pgrp. If some other
3238 process group should have it, give it away to that group here.
3239 pipeline_pgrp is non-zero only while we are constructing a
3240 pipline, so what we are concerned about is whether or not that
3241 pipeline was started in the background. A pipeline started in
3242 the background should never get the tty back here. */
3244 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
3246 if (interactive && pipeline_pgrp != (pid_t)0 && subshell_environment != SUBSHELL_ASYNC)
3248 give_terminal_to (pipeline_pgrp);
3249 #endif /* JOB_CONTROL */
3255 /********************************************************
3257 * Utility functions for parameter expansion *
3259 ********************************************************/
3261 /* Utility functions to manage arrays and their contents for expansion */
3263 #if defined (ARRAY_VARS)
3265 valid_array_reference (name)
3271 t = strchr (name, '[');
3275 r = legal_identifier (name);
3279 /* Check for a properly-terminated non-blank subscript. */
3280 len = skipsubscript (t, 0);
3281 if (t[len] != ']' || len == 1)
3283 for (r = 1; r < len; r++)
3284 if (whitespace (t[r]) == 0)
3291 /* Expand the array index beginning at S and extending LEN characters. */
3293 array_expand_index (s, len)
3300 exp = xmalloc (len);
3301 strncpy (exp, s, len - 1);
3302 exp[len - 1] = '\0';
3303 t = maybe_expand_string (exp, 0, expand_string);
3304 this_command_name = (char *)NULL;
3305 val = evalexp (t, &expok);
3309 jump_to_top_level (DISCARD);
3313 /* Return the variable specified by S without any subscript. If non-null,
3314 return the index of the start of the subscript in *SUBP. If non-null,
3315 the length of the subscript is returned in *LENP. */
3317 array_variable_part (s, subp, lenp)
3325 t = strchr (s, '[');
3327 ni = skipsubscript (s, ind);
3328 if (ni <= ind + 1 || s[ni] != ']')
3330 report_error ("%s: bad array subscript", s);
3331 return ((SHELL_VAR *)NULL);
3335 var = find_variable (s);
3346 array_value_internal (s, quoted, allow_all)
3348 int quoted, allow_all;
3351 char *retval, *t, *temp;
3352 WORD_LIST *l, *list;
3355 var = array_variable_part (s, &t, &len);
3358 return (char *)NULL;
3360 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
3362 if (array_p (var) == 0 || allow_all == 0)
3364 report_error ("%s: bad array subscript", s);
3365 return ((char *)NULL);
3367 l = array_to_word_list (array_cell (var));
3368 if (l == (WORD_LIST *)NULL)
3369 return ((char *) NULL);
3372 if (t[0] == '*') /* ${name[*]} */
3373 retval = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
3374 else /* ${name[@]} */
3375 retval = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
3377 if (t[0] == '*' && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
3379 temp = string_list_dollar_star (l);
3380 retval = quote_string (temp);
3383 else /* ${name[@]} or unquoted ${name[*]} */
3384 retval = string_list_dollar_at (l, quoted);
3391 ind = array_expand_index (t, len);
3394 report_error ("%s: bad array subscript", var->name);
3395 return ((char *)NULL);
3397 if (array_p (var) == 0)
3398 return (ind == 0 ? savestring (value_cell (var)) : (char *)NULL);
3399 retval = array_reference (array_cell (var), ind);
3401 retval = quote_escapes (retval);
3408 array_value (s, quoted)
3412 return (array_value_internal (s, quoted, 1));
3415 /* Return the value of the array indexing expression S as a single string.
3416 If ALLOW_ALL is 0, do not allow `@' and `*' subscripts. This is used
3417 by other parts of the shell such as the arithmetic expression evaluator
3420 get_array_value (s, allow_all)
3424 return (array_value_internal (s, 0, allow_all));
3428 array_length_reference (s)
3436 var = array_variable_part (s, &t, &len);
3438 /* If unbound variables should generate an error, report one and return
3440 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
3444 report_error ("%s: unbound variable", s);
3450 else if (array_p (var) == 0)
3453 array = array_cell (var);
3455 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
3456 return (array_num_elements (array));
3458 ind = array_expand_index (t, len);
3461 report_error ("%s: bad array subscript", t);
3464 t = array_reference (array, ind);
3469 #endif /* ARRAY_VARS */
3472 valid_brace_expansion_word (name, var_is_special)
3476 if (digit (*name) && all_digits (name))
3478 else if (var_is_special)
3480 #if defined (ARRAY_VARS)
3481 else if (valid_array_reference (name))
3483 #endif /* ARRAY_VARS */
3484 else if (legal_identifier (name))
3490 /* Parameter expand NAME, and return a new string which is the expansion,
3491 or NULL if there was no expansion.
3492 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
3493 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
3494 NAME was found inside of a double-quoted expression. */
3496 parameter_brace_expand_word (name, var_is_special, quoted)
3498 int var_is_special, quoted;
3505 /* Handle multiple digit arguments, as in ${11}. */
3508 arg_index = atoi (name);
3509 temp = get_dollar_var_value (arg_index);
3511 else if (var_is_special) /* ${@} */
3514 tt = xmalloc (2 + strlen (name));
3515 tt[sindex = 0] = '$';
3516 strcpy (tt + 1, name);
3518 l = expand_string_leave_quoted (tt, quoted);
3520 temp = string_list (l);
3523 temp = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
3524 (int *)NULL, (int *)NULL, 0);
3528 #if defined (ARRAY_VARS)
3529 else if (valid_array_reference (name))
3531 temp = array_value (name, quoted);
3534 else if (var = find_variable (name))
3536 if (var && invisible_p (var) == 0)
3538 #if defined (ARRAY_VARS)
3539 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
3541 temp = value_cell (var);
3545 temp = quote_escapes (temp);
3547 if (tempvar_p (var))
3548 dispose_variable (var);
3551 temp = (char *)NULL;
3554 temp = (char *)NULL;
3559 /* Expand an indirect reference to a variable: ${!NAME} expands to the
3560 value of the variable whose name is the value of NAME. */
3562 parameter_brace_expand_indir (name, var_is_special, quoted)
3564 int var_is_special, quoted;
3568 t = parameter_brace_expand_word (name, var_is_special, quoted);
3571 temp = parameter_brace_expand_word (t, t[0] == '@' && t[1] == '\0', quoted);
3576 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
3577 depending on the value of C, the separating character. C can be one of
3578 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
3579 between double quotes. */
3581 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
3583 int c, quoted, *qdollaratp, *hasdollarat;
3586 char *t, *t1, *temp;
3589 temp = (*value == '~' || (strchr (value, '~') && unquoted_substring ("=~", value)))
3590 ? bash_tilde_expand (value)
3591 : savestring (value);
3593 /* If the entire expression is between double quotes, we want to treat
3594 the value as a double-quoted string, with the exception that we strip
3595 embedded unescaped double quotes. */
3596 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *temp)
3599 t = string_extract_double_quoted (temp, &hasdol, 1);
3605 /* XXX was 0 not quoted */
3606 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
3609 *hasdollarat = hasdol || (l && l->next);
3613 /* The expansion of TEMP returned something. We need to treat things
3614 slightly differently if HASDOL is non-zero. */
3615 temp = string_list (l);
3616 /* If l->next is not null, we know that TEMP contained "$@", since that
3617 is the only expansion that creates more than one word. */
3618 if ((hasdol && quoted) || l->next)
3622 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
3624 /* The brace expansion occurred between double quotes and there was
3625 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
3626 it does not expand to anything. In this case, we want to return
3627 a quoted empty string. */
3633 temp = (char *)NULL;
3635 if (c == '-' || c == '+')
3639 t = temp ? savestring (temp) : savestring ("");
3640 t1 = dequote_string (t);
3642 bind_variable (name, t1);
3647 /* Deal with the right hand side of a ${name:?value} expansion in the case
3648 that NAME is null or not set. If VALUE is non-null it is expanded and
3649 used as the error message to print, otherwise a standard message is
3652 parameter_brace_expand_error (name, value)
3658 if (value && *value)
3660 l = expand_string (value, 0);
3661 temp = string_list (l);
3662 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
3667 report_error ("%s: parameter null or not set", name);
3669 /* Free the data we have allocated during this expansion, since we
3670 are about to longjmp out. */
3675 /* Return 1 if NAME is something for which parameter_brace_expand_length is
3678 valid_length_expression (name)
3681 return (!name[1] || /* ${#} */
3682 ((name[1] == '@' || name[1] == '*') && !name[2]) || /* ${#@}, ${#*} */
3683 (member (name[1], "-?$!#") && !name[2]) || /* ${#-}, etc. */
3684 (digit (name[1]) && all_digits (name + 1)) || /* ${#11} */
3685 #if defined (ARRAY_VARS)
3686 valid_array_reference (name + 1) || /* ${#a[7]} */
3688 legal_identifier (name + 1)); /* ${#PS1} */
3691 /* Handle the parameter brace expansion that requires us to return the
3692 length of a parameter. */
3694 parameter_brace_expand_length (name)
3700 #if defined (ARRAY_VARS)
3704 if (name[1] == '\0') /* ${#} */
3705 number = number_of_args ();
3706 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
3707 number = number_of_args ();
3708 else if (member (name[1], "-?$!#") && name[2] == '\0')
3710 /* Take the lengths of some of the shell's special parameters. */
3714 t = which_set_flags ();
3717 t = itos (last_command_exit_value);
3720 t = itos (dollar_dollar_pid);
3723 if (last_asynchronous_pid == NO_PID)
3726 t = itos ((int)last_asynchronous_pid);
3729 t = itos (number_of_args ());
3732 number = STRLEN (t);
3735 #if defined (ARRAY_VARS)
3736 else if (valid_array_reference (name + 1))
3737 number = array_length_reference (name + 1);
3738 #endif /* ARRAY_VARS */
3743 if (digit (name[1])) /* ${#1} */
3745 t = get_dollar_var_value (atoi (name + 1));
3746 number = STRLEN (t);
3749 #if defined (ARRAY_VARS)
3750 else if ((var = find_variable (name + 1)) && array_p (var))
3752 t = array_reference (array_cell (var), 0);
3753 number = STRLEN (t);
3758 newname = savestring (name);
3760 list = expand_string (newname, Q_DOUBLE_QUOTES);
3761 t = list ? string_list (list) : (char *)NULL;
3764 dispose_words (list);
3766 number = STRLEN (t);
3774 /* Verify and limit the start and end of the desired substring. If
3775 VTYPE == 0, a regular shell variable is being used; if it is 1,
3776 then the positional parameters are being used; if it is 2, then
3777 VALUE is really a pointer to an array variable that should be used.
3778 Return value is 1 if both values were OK, 0 if there was a problem
3779 with an invalid expression, or -1 if the values were out of range. */
3781 verify_substring_values (value, substr, vtype, e1p, e2p)
3782 char *value, *substr;
3783 int vtype, *e1p, *e2p;
3787 #if defined (ARRAY_VARS)
3791 t = strchr (substr, ':');
3794 temp1 = maybe_expand_string (substr, Q_DOUBLE_QUOTES, expand_string);
3795 *e1p = evalexp (temp1, &expok);
3803 case VT_ARRAYMEMBER:
3804 len = strlen (value);
3807 len = number_of_args () + 1;
3809 #if defined (ARRAY_VARS)
3812 len = array_num_elements (a) + 1;
3817 if (*e1p < 0) /* negative offsets count from end */
3820 if (*e1p >= len || *e1p < 0)
3826 temp1 = maybe_expand_string (t, Q_DOUBLE_QUOTES, expand_string);
3828 *e2p = evalexp (temp1, &expok);
3834 internal_error ("%s: substring expression < 0", t);
3837 *e2p += *e1p; /* want E2 chars starting at E1 */
3847 /* Return the type of variable specified by VARNAME (simple variable,
3848 positional param, or array variable). Also return the value specified
3849 by VARNAME (value of a variable or a reference to an array element). */
3851 get_var_and_type (varname, value, varp, valp)
3852 char *varname, *value;
3858 #if defined (ARRAY_VARS)
3862 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0'; /* VT_POSPARMS */
3863 *varp = (SHELL_VAR *)NULL;
3865 #if defined (ARRAY_VARS)
3866 if (valid_array_reference (varname))
3868 v = array_variable_part (varname, &temp, (int *)0);
3869 if (v && array_p (v))
3871 if ((temp[0] == '@' || temp[0] == '*') && temp[1] == ']')
3873 vtype = VT_ARRAYVAR;
3874 *valp = (char *)array_cell (v);
3878 vtype = VT_ARRAYMEMBER;
3879 *valp = array_value (varname, 1);
3886 else if ((v = find_variable (varname)) && array_p (v))
3888 vtype = VT_VARIABLE;
3890 *valp = array_reference (array_cell (v), 0);
3899 /******************************************************/
3901 /* Functions to extract substrings of variable values */
3903 /******************************************************/
3905 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
3906 is `@', use the positional parameters; otherwise, use the value of
3907 VARNAME. If VARNAME is an array variable, use the array elements. */
3910 parameter_brace_substring (varname, value, substr, quoted)
3911 char *varname, *value, *substr;
3914 int e1, e2, vtype, r;
3919 return ((char *)NULL);
3921 this_command_name = varname;
3923 vtype = get_var_and_type (varname, value, &v, &val);
3925 return ((char *)NULL);
3927 r = verify_substring_values (val, substr, vtype, &e1, &e2);
3930 if (val && vtype == VT_ARRAYMEMBER)
3932 return ((r == 0) ? &expand_param_error : (char *)NULL);
3938 case VT_ARRAYMEMBER:
3939 temp = quoted ? quoted_substring (value, e1, e2) : substring (value, e1, e2);
3942 temp = pos_params (varname, e1, e2, quoted);
3944 #if defined (ARRAY_VARS)
3946 temp = array_subrange (array_cell (v), e1, e2, quoted);
3954 /****************************************************************/
3956 /* Functions to perform pattern substitution on variable values */
3958 /****************************************************************/
3961 pat_subst (string, pat, rep, mflags)
3962 char *string, *pat, *rep;
3965 char *ret, *s, *e, *str;
3966 int rsize, rptr, l, replen, mtype;
3968 mtype = mflags & MATCH_TYPEMASK;
3971 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
3972 * with REP and return the result.
3973 * 2. A null pattern with mtype == MATCH_END means to append REP to
3974 * STRING and return the result.
3976 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
3978 replen = STRLEN (rep);
3979 l = strlen (string);
3980 ret = xmalloc (replen + l + 2);
3981 if (mtype == MATCH_BEG)
3984 strcpy (ret + replen, string);
3988 strcpy (ret, string);
3989 strcpy (ret + l, rep);
3994 ret = xmalloc (rsize = 64);
3997 for (replen = STRLEN (rep), rptr = 0, str = string;;)
3999 if (match_pattern (str, pat, mtype, &s, &e) == 0)
4002 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
4004 /* OK, now copy the leading unmatched portion of the string (from
4005 str to s) to ret starting at rptr (the current offset). Then copy
4006 the replacement string at ret + rptr + (s - str). Increment
4007 rptr (if necessary) and str and go on. */
4010 strncpy (ret + rptr, str, l);
4015 strncpy (ret + rptr, rep, replen);
4018 str = e; /* e == end of match */
4019 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
4023 /* Now copy the unmatched portion of the input string */
4026 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
4027 strcpy (ret + rptr, str);
4035 /* Do pattern match and replacement on the positional parameters. */
4037 pos_params_pat_subst (string, pat, rep, mflags)
4038 char *string, *pat, *rep;
4041 WORD_LIST *save, *params;
4045 save = params = list_rest_of_args ();
4047 return ((char *)NULL);
4049 for ( ; params; params = params->next)
4051 ret = pat_subst (params->word->word, pat, rep, mflags);
4052 w = make_bare_word (ret);
4053 dispose_word (params->word);
4058 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
4059 dispose_words (save);
4064 /* Perform pattern substitution on VALUE, which is the expansion of
4065 VARNAME. PATSUB is an expression supplying the pattern to match
4066 and the string to substitute. QUOTED is a flags word containing
4067 the type of quoting currently in effect. */
4069 parameter_brace_patsub (varname, value, patsub, quoted)
4070 char *varname, *value, *patsub;
4074 char *val, *temp, *pat, *rep, *p;
4078 return ((char *)NULL);
4080 this_command_name = varname;
4082 vtype = get_var_and_type (varname, value, &v, &val);
4084 return ((char *)NULL);
4089 mflags |= MATCH_GLOBREP;
4093 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4094 mflags |= MATCH_QUOTED;
4096 if (rep = quoted_strchr (patsub, '/', ST_BACKSL))
4101 if (rep && *rep == '\0')
4104 /* Expand PAT and REP for command, variable and parameter, arithmetic,
4105 and process substitution. Also perform quote removal. Do not
4106 perform word splitting or filename generation. */
4108 pat = maybe_expand_string (patsub, quoted, expand_string_unsplit);
4110 pat = maybe_expand_string (patsub, (quoted & ~Q_DOUBLE_QUOTES), expand_string_unsplit);
4114 if ((mflags & MATCH_QUOTED) == 0)
4115 rep = maybe_expand_string (rep, quoted, expand_string_unsplit);
4117 rep = expand_string_to_string (rep, quoted, expand_string_unsplit);
4121 if (pat && pat[0] == '#')
4123 mflags |= MATCH_BEG;
4126 else if (pat && pat[0] == '%')
4128 mflags |= MATCH_END;
4132 mflags |= MATCH_ANY;
4134 /* OK, we now want to substitute REP for PAT in VAL. If
4135 flags & MATCH_GLOBREP is non-zero, the substitution is done
4136 everywhere, otherwise only the first occurrence of PAT is
4141 case VT_ARRAYMEMBER:
4142 temp = pat_subst (val, p, rep, mflags);
4145 temp = pos_params_pat_subst (val, p, rep, mflags);
4147 #if defined (ARRAY_VARS)
4149 temp = array_pat_subst (array_cell (v), p, rep, mflags);
4154 if (val && v && array_p (v) && vtype == VT_ARRAYMEMBER)
4163 /****************************************************************/
4165 /* Functions to perform parameter expansion on a string */
4167 /****************************************************************/
4169 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
4171 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
4173 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
4175 int check_nullness, var_is_set, var_is_null, var_is_special;
4176 int want_substring, want_indir, want_patsub;
4177 char *name, *value, *temp, *temp1;
4178 int t_index, sindex, c, number;
4180 value = (char *)NULL;
4181 var_is_set = var_is_null = var_is_special = check_nullness = 0;
4182 want_substring = want_indir = want_patsub = 0;
4186 name = string_extract (string, &t_index, "#%:-=?+/}", 1);
4188 /* If the name really consists of a special variable, then make sure
4189 that we have the entire name. We don't allow indirect references
4190 to special variables except `#', `?', `@' and `*'. */
4191 if ((sindex == t_index &&
4192 (string[t_index] == '-' ||
4193 string[t_index] == '?' ||
4194 string[t_index] == '#')) ||
4195 (sindex == t_index - 1 && string[sindex] == '!' &&
4196 (string[t_index] == '#' ||
4197 string[t_index] == '?' ||
4198 string[t_index] == '@' ||
4199 string[t_index] == '*')))
4203 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
4204 name = xmalloc (3 + (strlen (temp1)));
4205 *name = string[sindex];
4206 if (string[sindex] == '!')
4208 /* indirect reference of $#, $?, $@, or $* */
4209 name[1] = string[sindex + 1];
4210 strcpy (name + 2, temp1);
4213 strcpy (name + 1, temp1);
4218 /* Find out what character ended the variable name. Then
4219 do the appropriate thing. */
4220 if (c = string[sindex])
4223 /* If c is followed by one of the valid parameter expansion
4224 characters, move past it as normal. If not, assume that
4225 a substring specification is being given, and do not move
4227 if (c == ':' && member (string[sindex], "-=?+"))
4230 if (c = string[sindex])
4233 else if (c == ':' && string[sindex] != RBRACE)
4235 else if (c == '/' && string[sindex] != RBRACE)
4238 /* Catch the valid and invalid brace expressions that made it through the
4240 /* ${#-} is a valid expansion and means to take the length of $-.
4241 Similarly for ${#?} and ${##}... */
4242 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4243 member (c, "-?#") && string[sindex] == RBRACE)
4245 name = xrealloc (name, 3);
4248 c = string[sindex++];
4251 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
4252 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4253 member (c, "%:=+/") && string[sindex] == RBRACE)
4255 temp = (char *)NULL;
4256 goto bad_substitution;
4259 /* Indirect expansion begins with a `!'. A valid indirect expansion is
4260 either a variable name, one of the positional parameters or a special
4261 variable that expands to one of the positional parameters. */
4262 want_indir = *name == '!' &&
4263 (legal_variable_starter (name[1]) || digit (name[1]) || member (name[1], "#?@*"));
4265 /* Determine the value of this variable. */
4267 /* Check for special variables, directly referenced. */
4268 if ((digit (*name) && all_digits (name)) ||
4269 (name[1] == '\0' && member (*name, "#-?$!@*")) ||
4270 (want_indir && name[2] == '\0' && member (name[1], "#?@*")))
4273 /* Check for special expansion things, like the length of a parameter */
4274 if (*name == '#' && name[1])
4276 /* If we are not pointing at the character just after the
4277 closing brace, then we haven't gotten all of the name.
4278 Since it begins with a special character, this is a bad
4279 substitution. Also check NAME for validity before trying
4281 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
4283 temp = (char *)NULL;
4284 goto bad_substitution;
4287 number = parameter_brace_expand_length (name);
4291 return ((number < 0) ? &expand_param_error : itos (number));
4294 /* ${@} is identical to $@. */
4295 if (name[0] == '@' && name[1] == '\0')
4297 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4298 *quoted_dollar_atp = 1;
4300 if (contains_dollar_at)
4301 *contains_dollar_at = 1;
4304 /* Make sure that NAME is valid before trying to go on. */
4305 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
4306 var_is_special) == 0)
4308 temp = (char *)NULL;
4309 goto bad_substitution;
4313 temp = parameter_brace_expand_indir (name + 1, var_is_special, quoted);
4315 temp = parameter_brace_expand_word (name, var_is_special, quoted);
4317 #if defined (ARRAY_VARS)
4319 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && valid_array_reference (name))
4321 if (valid_array_reference (name))
4324 temp1 = strchr (name, '[');
4325 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4327 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4328 *quoted_dollar_atp = 1;
4329 if (contains_dollar_at)
4330 *contains_dollar_at = 1;
4332 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4333 which should result in separate words even when IFS is unset. */
4334 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4336 if (contains_dollar_at)
4337 *contains_dollar_at = 1;
4342 var_is_set = temp != (char *)0;
4343 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
4345 /* Get the rest of the stuff inside the braces. */
4346 if (c && c != RBRACE)
4348 /* Extract the contents of the ${ ... } expansion
4349 according to the Posix.2 rules. */
4350 value = extract_dollar_brace_string (string, &sindex, quoted);
4351 if (string[sindex] == RBRACE)
4354 goto bad_substitution;
4357 value = (char *)NULL;
4361 /* If this is a substring spec, process it and add the result. */
4364 temp1 = parameter_brace_substring (name, temp, value, quoted);
4370 else if (want_patsub)
4372 temp1 = parameter_brace_patsub (name, temp, value, quoted);
4379 /* Do the right thing based on which character ended the variable name. */
4385 report_error ("%s: bad substitution", string ? string : "??");
4389 return &expand_param_error;
4392 if (var_is_set == 0 && unbound_vars_is_error)
4394 report_error ("%s: unbound variable", name);
4398 last_command_exit_value = EXECUTION_FAILURE;
4399 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4403 case '#': /* ${param#[#]pattern} */
4404 case '%': /* ${param%[%]pattern} */
4405 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
4410 if ((name[0] == '@' || name[0] == '*') && name[1] == '\0')
4411 temp1 = parameter_list_remove_pattern (value, name[0], c, quoted);
4412 #if defined (ARRAY_VARS)
4413 else if (valid_array_reference (name))
4414 temp1 = array_remove_pattern (value, name, temp, c, quoted);
4417 temp1 = parameter_brace_remove_pattern (value, temp, c, quoted);
4427 if (var_is_set && var_is_null == 0)
4429 /* We don't want the value of the named variable for
4430 anything, just the value of the right hand side. */
4436 temp = parameter_brace_expand_rhs (name, value, c,
4439 contains_dollar_at);
4443 temp = (char *)NULL;
4449 /* Otherwise do nothing; just use the value in TEMP. */
4451 else /* VAR not set or VAR is NULL. */
4454 temp = (char *)NULL;
4455 if (c == '=' && var_is_special)
4457 report_error ("$%s: cannot assign in this way", name);
4460 return &expand_param_error;
4464 parameter_brace_expand_error (name, value);
4465 return (interactive ? &expand_param_error : &expand_param_fatal);
4468 temp = parameter_brace_expand_rhs (name, value, c, quoted,
4470 contains_dollar_at);
4479 /* Expand a single ${xxx} expansion. The braces are optional. When
4480 the braces are used, parameter_brace_expand() does the work,
4481 possibly calling param_expand recursively. */
4483 param_expand (string, sindex, quoted, expanded_something,
4484 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
4487 int *sindex, quoted, *expanded_something, *contains_dollar_at;
4488 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
4491 int zindex, number, c, t_index, expok;
4493 WORD_LIST *list, *tlist;
4496 c = string[++zindex];
4498 temp = (char *)NULL;
4500 /* Do simple cases first. Switch on what follows '$'. */
4514 temp1 = dollar_vars[digit_value (c)];
4515 if (unbound_vars_is_error && temp1 == (char *)NULL)
4517 report_error ("$%c: unbound variable", c);
4518 last_command_exit_value = EXECUTION_FAILURE;
4519 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4521 temp = temp1 ? savestring (temp1) : (char *)NULL;
4524 /* $$ -- pid of the invoking shell. */
4526 temp = itos (dollar_dollar_pid);
4529 /* $# -- number of positional parameters. */
4531 temp = itos (number_of_args ());
4534 /* $? -- return value of the last synchronous command. */
4536 temp = itos (last_command_exit_value);
4539 /* $- -- flags supplied to the shell on invocation or by `set'. */
4541 temp = which_set_flags ();
4544 /* $! -- Pid of the last asynchronous command. */
4546 /* If no asynchronous pids have been created, expand to nothing.
4547 If `set -u' has been executed, and no async processes have
4548 been created, this is an expansion error. */
4549 if (last_asynchronous_pid == NO_PID)
4551 if (expanded_something)
4552 *expanded_something = 0;
4553 temp = (char *)NULL;
4554 if (unbound_vars_is_error)
4556 report_error ("$%c: unbound variable", c);
4557 last_command_exit_value = EXECUTION_FAILURE;
4558 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4562 temp = itos ((int)last_asynchronous_pid);
4565 /* The only difference between this and $@ is when the arg is quoted. */
4566 case '*': /* `$*' */
4567 list = list_rest_of_args ();
4569 /* If there are no command-line arguments, this should just
4570 disappear if there are other characters in the expansion,
4571 even if it's quoted. */
4572 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
4573 temp = (char *)NULL;
4574 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4576 /* If we have "$*" we want to make a string of the positional
4577 parameters, separated by the first character of $IFS, and
4578 quote the whole string, including the separators. If IFS
4579 is unset, the parameters are separated by ' '; if $IFS is
4580 null, the parameters are concatenated. */
4581 temp = string_list_dollar_star (list);
4582 temp1 = quote_string (temp);
4588 /* If the $* is not quoted it is identical to $@ */
4589 temp = string_list_dollar_at (list, quoted);
4590 if (contains_dollar_at)
4591 *contains_dollar_at = 1;
4594 dispose_words (list);
4597 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
4598 means that we have to turn quoting off after we split into
4599 the individually quoted arguments so that the final split
4600 on the first character of $IFS is still done. */
4601 case '@': /* `$@' */
4602 list = list_rest_of_args ();
4604 /* We want to flag the fact that we saw this. We can't turn
4605 off quoting entirely, because other characters in the
4606 string might need it (consider "\"$@\""), but we need some
4607 way to signal that the final split on the first character
4608 of $IFS should be done, even though QUOTED is 1. */
4609 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
4610 *quoted_dollar_at_p = 1;
4611 if (contains_dollar_at)
4612 *contains_dollar_at = 1;
4614 /* We want to separate the positional parameters with the first
4615 character of $IFS in case $IFS is something other than a space.
4616 We also want to make sure that splitting is done no matter what --
4617 according to POSIX.2, this expands to a list of the positional
4618 parameters no matter what IFS is set to. */
4619 temp = string_list_dollar_at (list, quoted);
4621 dispose_words (list);
4625 temp = parameter_brace_expand (string, &zindex, quoted,
4627 contains_dollar_at);
4628 if (temp == &expand_param_error || temp == &expand_param_fatal)
4632 /* quoted nulls should be removed if there is anything else
4634 /* Note that we saw the quoted null so we can add one back at
4635 the end of this function if there are no other characters
4636 in the string, discard TEMP, and go on. */
4637 if (temp && QUOTED_NULL (temp))
4639 if (had_quoted_null_p)
4640 *had_quoted_null_p = 1;
4642 temp = (char *)NULL;
4647 /* Do command or arithmetic substitution. */
4649 /* We have to extract the contents of this paren substitution. */
4650 t_index = zindex + 1;
4651 temp = extract_command_subst (string, &t_index);
4654 /* For Posix.2-style `$(( ))' arithmetic substitution,
4655 extract the expression and pass it to the evaluator. */
4656 if (temp && *temp == LPAREN)
4660 temp2 = savestring (temp1);
4661 t_index = strlen (temp2) - 1;
4663 if (temp2[t_index] != RPAREN)
4669 /* Cut off ending `)' */
4670 temp2[t_index] = '\0';
4672 /* Expand variables found inside the expression. */
4673 temp1 = maybe_expand_string (temp2, Q_DOUBLE_QUOTES, expand_string);
4677 /* No error messages. */
4678 this_command_name = (char *)NULL;
4679 number = evalexp (temp1, &expok);
4684 if (interactive_shell == 0 && posixly_correct)
4686 last_command_exit_value = EXECUTION_FAILURE;
4687 return (&expand_param_fatal);
4690 return (&expand_param_error);
4692 temp = itos (number);
4697 temp1 = command_substitute (temp, quoted);
4702 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
4703 away in a future bash release. */
4705 /* We have to extract the contents of this arithmetic substitution. */
4706 t_index = zindex + 1;
4707 temp = extract_arithmetic_subst (string, &t_index);
4710 /* Do initial variable expansion. */
4711 temp1 = maybe_expand_string (temp, Q_DOUBLE_QUOTES, expand_string);
4716 /* Find the variable in VARIABLE_LIST. */
4717 temp = (char *)NULL;
4719 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
4721 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
4723 /* If this isn't a variable name, then just output the `$'. */
4724 if (temp1 == 0 || *temp1 == '\0')
4730 if (expanded_something)
4731 *expanded_something = 0;
4735 /* If the variable exists, return its value cell. */
4736 var = find_variable (temp1);
4738 if (var && invisible_p (var) == 0 && value_cell (var))
4740 #if defined (ARRAY_VARS)
4743 temp = array_reference (array_cell (var), 0);
4745 temp = quote_escapes (temp);
4749 temp = quote_escapes (value_cell (var));
4751 if (tempvar_p (var)) /* XXX */
4753 dispose_variable (var); /* XXX */
4754 var = (SHELL_VAR *)NULL;
4759 temp = (char *)NULL;
4761 if (unbound_vars_is_error)
4762 report_error ("%s: unbound variable", temp1);
4770 last_command_exit_value = EXECUTION_FAILURE;
4771 return ((unbound_vars_is_error && interactive_shell == 0)
4772 ? &expand_param_fatal
4773 : &expand_param_error);
4784 /* Make a word list which is the result of parameter and variable
4785 expansion, command substitution, arithmetic substitution, and
4786 quote removal of WORD. Return a pointer to a WORD_LIST which is
4787 the result of the expansion. If WORD contains a null word, the
4788 word list returned is also null.
4790 QUOTED contains flag values defined in shell.h.
4792 ISEXP is used to tell expand_word_internal that the word should be
4793 treated as the result of an expansion. This has implications for
4794 how IFS characters in the word are treated.
4796 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
4797 they point to an integer value which receives information about expansion.
4798 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
4799 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
4802 This only does word splitting in the case of $@ expansion. In that
4803 case, we split on ' '. */
4805 /* Values for the local variable quoted_state. */
4807 #define PARTIALLY_QUOTED 1
4808 #define WHOLLY_QUOTED 2
4811 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
4814 int *contains_dollar_at;
4815 int *expanded_something;
4821 /* The intermediate string that we build while expanding. */
4824 /* The current size of the above object. */
4827 /* Index into ISTRING. */
4830 /* Temporary string storage. */
4833 /* The text of WORD. */
4834 register char *string;
4836 /* The index into STRING. */
4839 /* This gets 1 if we see a $@ while quoted. */
4840 int quoted_dollar_at;
4842 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
4843 whether WORD contains no quoting characters, a partially quoted
4844 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
4847 int had_quoted_null;
4850 register int c; /* Current character. */
4851 int number; /* Temporary number value. */
4852 int t_index; /* For calls to string_extract_xxx. */
4856 istring = xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
4857 istring[istring_index = 0] = '\0';
4858 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
4859 quoted_state = UNQUOTED;
4861 string = word->word;
4863 goto finished_with_string;
4865 if (contains_dollar_at)
4866 *contains_dollar_at = 0;
4868 /* Cache a bitmap of characters in IFS for quoting IFS characters that are
4869 not part of an expansion. POSIX.2 says this is a must. */
4871 bzero (ifscmap, sizeof (ifscmap));
4872 for (temp1 = temp; temp1 && *temp1; temp1++)
4874 /* This check compensates for what I think is a parsing problem -- the
4875 end brace matching algorithms for ${...} expressions differ between
4876 parse.y and subst.c. For instance, the parser passes
4877 ${abc:-G { I } K } as one word when it should be three. */
4878 if (*temp1 != ' ' && *temp1 != '\t' && *temp1 != '\n')
4880 ifscmap[*temp1] = 1;
4882 /* Begin the expansion. */
4888 /* Case on toplevel character. */
4892 goto finished_with_string;
4897 temp[1] = c = string[++sindex];
4907 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
4913 #if defined (PROCESS_SUBSTITUTION)
4914 /* Process substitution. */
4918 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || posixly_correct)
4924 t_index = sindex + 1; /* skip past both '<' and LPAREN */
4926 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
4929 /* If the process substitution specification is `<()', we want to
4930 open the pipe for writing in the child and produce output; if
4931 it is `>()', we want to open the pipe for reading in the child
4932 and consume input. */
4933 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
4937 goto dollar_add_string;
4939 #endif /* PROCESS_SUBSTITUTION */
4942 if (expanded_something)
4943 *expanded_something = 1;
4946 temp = param_expand (string, &sindex, quoted, expanded_something,
4947 &has_dollar_at, "ed_dollar_at,
4948 &had_quoted_null, 0);
4950 if (temp == &expand_param_error || temp == &expand_param_fatal)
4954 return ((temp == &expand_param_error) ? &expand_word_error
4955 : &expand_word_fatal);
4957 if (contains_dollar_at && has_dollar_at)
4958 *contains_dollar_at = 1;
4962 case '`': /* Backquoted command substitution. */
4966 if (expanded_something)
4967 *expanded_something = 1;
4969 temp = string_extract (string, &sindex, "`", 0);
4970 de_backslash (temp);
4971 temp1 = command_substitute (temp, quoted);
4974 goto dollar_add_string;
4978 if (string[sindex + 1] == '\n')
4984 c = string[++sindex];
4986 if (quoted & Q_HERE_DOCUMENT)
4987 temp1 = slashify_in_here_document;
4988 else if (quoted & Q_DOUBLE_QUOTES)
4989 temp1 = slashify_in_quotes;
4993 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && member (c, temp1) == 0)
4996 temp[0] = '\\'; temp[1] = c; temp[2] = '\0';
4999 /* This character is quoted, so add it in quoted mode. */
5000 temp = make_quoted_char (c);
5007 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5011 temp = string_extract_double_quoted (string, &sindex, 0);
5013 /* If the quotes surrounded the entire string, then the
5014 whole word was quoted. */
5015 quoted_state = (t_index == 1 && string[sindex] == '\0')
5021 tword = make_word (temp); /* XXX */
5023 temp = (char *)NULL;
5026 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
5028 if (list == &expand_word_error || list == &expand_word_fatal)
5032 /* expand_word_internal has already freed temp_word->word
5033 for us because of the way it prints error messages. */
5034 tword->word = (char *)NULL;
5035 dispose_word (tword);
5039 dispose_word (tword);
5041 /* "$@" (a double-quoted dollar-at) expands into nothing,
5042 not even a NULL word, when there are no positional
5044 if (list == 0 && has_dollar_at)
5050 /* If we get "$@", we know we have expanded something, so we
5051 need to remember it for the final split on $IFS. This is
5052 a special case; it's the only case where a quoted string
5053 can expand into more than one word. It's going to come back
5054 from the above call to expand_word_internal as a list with
5055 a single word, in which all characters are quoted and
5056 separated by blanks. What we want to do is to turn it back
5057 into a list for the next piece of code. */
5059 dequote_list (list);
5064 if (contains_dollar_at)
5065 *contains_dollar_at = 1;
5066 if (expanded_something)
5067 *expanded_something = 1;
5072 /* What we have is "". This is a minor optimization. */
5074 list = (WORD_LIST *)NULL;
5077 /* The code above *might* return a list (consider the case of "$@",
5078 where it returns "$1", "$2", etc.). We can't throw away the
5079 rest of the list, and we have to make sure each word gets added
5080 as quoted. We test on tresult->next: if it is non-NULL, we
5081 quote the whole list, save it to a string with string_list, and
5082 add that string. We don't need to quote the results of this
5083 (and it would be wrong, since that would quote the separators
5084 as well), so we go directly to add_string. */
5089 /* Testing quoted_dollar_at makes sure that "$@" is
5090 split correctly when $IFS does not contain a space. */
5091 temp = quoted_dollar_at
5092 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
5093 : string_list (quote_list (list));
5094 dispose_words (list);
5099 temp = savestring (list->word->word);
5100 dispose_words (list);
5102 /* If the string is not a quoted null string, we want
5103 to remove any embedded unquoted CTLNUL characters.
5104 We do not want to turn quoted null strings back into
5105 the empty string, though. We do this because we
5106 want to remove any quoted nulls from expansions that
5107 contain other characters. For example, if we have
5108 x"$*"y or "x$*y" and there are no positional parameters,
5109 the $* should expand into nothing. */
5110 if (QUOTED_NULL (temp) == 0)
5111 remove_quoted_nulls (temp); /* XXX */
5116 temp = (char *)NULL;
5118 /* We do not want to add quoted nulls to strings that are only
5119 partially quoted; we can throw them away. */
5120 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
5128 temp = quote_string (temp);
5142 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5146 temp = string_extract_single_quoted (string, &sindex);
5148 /* If the entire STRING was surrounded by single quotes,
5149 then the string is wholly quoted. */
5150 quoted_state = (t_index == 1 && string[sindex] == '\0')
5154 /* If all we had was '', it is a null expansion. */
5158 temp = (char *)NULL;
5161 remove_quoted_escapes (temp);
5163 /* We do not want to add quoted nulls to strings that are only
5164 partially quoted; such nulls are discarded. */
5165 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
5168 goto add_quoted_string;
5172 /* This is the fix for " $@ " */
5173 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && ifscmap[c]))
5175 temp = make_quoted_char (c);
5176 goto dollar_add_string;
5180 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
5181 DEFAULT_ARRAY_SIZE);
5182 istring[istring_index++] = c;
5183 istring[istring_index] = '\0';
5185 /* Next character. */
5190 finished_with_string:
5191 /* OK, we're ready to return. If we have a quoted string, and
5192 quoted_dollar_at is not set, we do no splitting at all; otherwise
5193 we split on ' '. The routines that call this will handle what to
5194 do if nothing has been expanded. */
5196 /* Partially and wholly quoted strings which expand to the empty
5197 string are retained as an empty arguments. Unquoted strings
5198 which expand to the empty string are discarded. The single
5199 exception is the case of expanding "$@" when there are no
5200 positional parameters. In that case, we discard the expansion. */
5202 /* Because of how the code that handles "" and '' in partially
5203 quoted strings works, we need to make ISTRING into a QUOTED_NULL
5204 if we saw quoting characters, but the expansion was empty.
5205 "" and '' are tossed away before we get to this point when
5206 processing partially quoted strings. This makes "" and $xxx""
5207 equivalent when xxx is unset. We also look to see whether we
5208 saw a quoted null from a ${} expansion and add one back if we
5211 /* If we expand to nothing and there were no single or double quotes
5212 in the word, we throw it away. Otherwise, we return a NULL word.
5213 The single exception is for $@ surrounded by double quotes when
5214 there are no positional parameters. In that case, we also throw
5217 if (*istring == '\0')
5219 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
5221 istring[0] = CTLNUL;
5223 tword = make_bare_word (istring);
5224 list = make_word_list (tword, (WORD_LIST *)NULL);
5225 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5226 tword->flags |= W_QUOTED;
5228 /* According to sh, ksh, and Posix.2, if a word expands into nothing
5229 and a double-quoted "$@" appears anywhere in it, then the entire
5231 else if (quoted_state == UNQUOTED || quoted_dollar_at)
5232 list = (WORD_LIST *)NULL;
5236 tword = make_bare_word (istring);
5237 list = make_word_list (tword, (WORD_LIST *)NULL);
5238 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5239 tword->flags |= W_QUOTED;
5243 else if (word->flags & W_NOSPLIT)
5245 tword = make_bare_word (istring);
5246 list = make_word_list (tword, (WORD_LIST *)NULL);
5247 if (word->flags & W_ASSIGNMENT)
5248 tword->flags |= W_ASSIGNMENT; /* XXX */
5249 if (word->flags & W_NOGLOB)
5250 tword->flags |= W_NOGLOB; /* XXX */
5251 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5252 tword->flags |= W_QUOTED;
5258 ifs_chars = (quoted_dollar_at || has_dollar_at) ? getifs () : (char *)NULL;
5260 /* If we have $@, we need to split the results no matter what. If
5261 IFS is unset or NULL, string_list_dollar_at has separated the
5262 positional parameters with a space, so we split on space (we have
5263 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
5264 string_list_dollar_at has separated the positional parameters
5265 with the first character of $IFS, so we split on $IFS. */
5266 if (has_dollar_at && ifs_chars)
5267 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
5270 tword = make_bare_word (istring);
5271 list = make_word_list (tword, (WORD_LIST *)NULL);
5272 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
5273 tword->flags |= W_QUOTED;
5274 if (word->flags & W_ASSIGNMENT)
5275 tword->flags |= W_ASSIGNMENT;
5276 if (word->flags & W_NOGLOB)
5277 tword->flags |= W_NOGLOB;
5285 /* **************************************************************** */
5287 /* Functions for Quote Removal */
5289 /* **************************************************************** */
5291 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
5292 backslash quoting rules for within double quotes. */
5294 string_quote_removal (string, quoted)
5298 char *r, *result_string, *temp;
5299 int sindex, tindex, c, dquote;
5301 /* The result can be no longer than the original string. */
5302 r = result_string = xmalloc (strlen (string) + 1);
5304 for (dquote = sindex = 0; c = string[sindex];)
5309 c = string[++sindex];
5310 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && member (c, slashify_in_quotes) == 0)
5320 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
5326 tindex = sindex + 1;
5327 temp = string_extract_single_quoted (string, &tindex);
5338 dquote = 1 - dquote;
5344 return (result_string);
5349 /* Perform quote removal on word WORD. This allocates and returns a new
5352 word_quote_removal (word, quoted)
5359 t = string_quote_removal (word->word, quoted);
5360 w = make_bare_word (t);
5365 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
5366 the members of the list are treated as if they are surrounded by
5367 double quotes. Return a new list, or NULL if LIST is NULL. */
5369 word_list_quote_removal (list, quoted)
5373 WORD_LIST *result, *t, *tresult;
5375 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5377 tresult = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
5378 tresult->word = word_quote_removal (t->word, quoted);
5379 tresult->next = (WORD_LIST *)NULL;
5380 result = (WORD_LIST *) list_append (result, tresult);
5386 /*******************************************
5388 * Functions to perform word splitting *
5390 *******************************************/
5397 ifs = find_variable ("IFS");
5398 /* If IFS is unset, it defaults to " \t\n". */
5399 return (ifs ? value_cell (ifs) : " \t\n");
5402 /* This splits a single word into a WORD LIST on $IFS, but only if the word
5403 is not quoted. list_string () performs quote removal for us, even if we
5404 don't do any splitting. */
5415 ifs = find_variable ("IFS");
5416 /* If IFS is unset, it defaults to " \t\n". */
5417 ifs_chars = ifs ? value_cell (ifs) : " \t\n";
5419 if ((w->flags & W_QUOTED) || !ifs_chars)
5422 result = list_string (w->word, ifs_chars, w->flags & W_QUOTED);
5424 if (ifs && tempvar_p (ifs)) /* XXX */
5425 dispose_variable (ifs); /* XXX */
5428 result = (WORD_LIST *)NULL;
5433 /* Perform word splitting on LIST and return the RESULT. It is possible
5434 to return (WORD_LIST *)NULL. */
5436 word_list_split (list)
5439 WORD_LIST *result, *t, *tresult;
5441 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5443 tresult = word_split (t->word);
5444 result = (WORD_LIST *) list_append (result, tresult);
5449 /**************************************************
5451 * Functions to expand an entire WORD_LIST *
5453 **************************************************/
5455 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
5456 ELIST, and set ELIST to the new list. */
5457 #define PREPEND_LIST(nlist, elist) \
5458 do { nlist->next = elist; elist = nlist; } while (0)
5460 static WORD_LIST *varlist = (WORD_LIST *)NULL;
5462 /* Separate out any initial variable assignments from TLIST. If set -k has
5463 been executed, remove all assignment statements from TLIST. Initial
5464 variable assignments and other environment assignments are placed
5467 separate_out_assignments (tlist)
5470 register WORD_LIST *vp, *lp;
5473 return ((WORD_LIST *)NULL);
5476 dispose_words (varlist); /* Clean up after previous error */
5478 varlist = (WORD_LIST *)NULL;
5481 /* Separate out variable assignments at the start of the command.
5482 Loop invariant: vp->next == lp
5484 lp = list of words left after assignment statements skipped
5485 tlist = original list of words
5487 while (lp && (lp->word->flags & W_ASSIGNMENT))
5493 /* If lp != tlist, we have some initial assignment statements. */
5494 /* We make VARLIST point to the list of assignment words and
5495 TLIST point to the remaining words. */
5499 /* ASSERT(vp->next == lp); */
5500 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
5501 tlist = lp; /* remainder of word list */
5504 /* vp == end of variable list */
5505 /* tlist == remainder of original word list without variable assignments */
5507 /* All the words in tlist were assignment statements */
5508 return ((WORD_LIST *)NULL);
5510 /* ASSERT(tlist != NULL); */
5511 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
5513 /* If the -k option is in effect, we need to go through the remaining
5514 words, separate out the assignment words, and place them on VARLIST. */
5515 if (place_keywords_in_env)
5517 WORD_LIST *tp; /* tp == running pointer into tlist */
5522 /* Loop Invariant: tp->next == lp */
5523 /* Loop postcondition: tlist == word list without assignment statements */
5526 if (lp->word->flags & W_ASSIGNMENT)
5528 /* Found an assignment statement, add this word to end of
5538 /* Remove the word pointed to by LP from TLIST. */
5539 tp->next = lp->next;
5540 /* ASSERT(vp == lp); */
5541 lp->next = (WORD_LIST *)NULL;
5554 #define WEXP_VARASSIGN 0x001
5555 #define WEXP_BRACEEXP 0x002
5556 #define WEXP_TILDEEXP 0x004
5557 #define WEXP_PARAMEXP 0x008
5558 #define WEXP_PATHEXP 0x010
5560 /* All of the expansions, including variable assignments at the start of
5562 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5564 /* All of the expansions except variable assignments at the start of
5566 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
5568 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
5569 expansion, command substitution, arithmetic expansion, word splitting, and
5571 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
5573 /* Take the list of words in LIST and do the various substitutions. Return
5574 a new list of words which is the expanded list, and without things like
5575 variable assignments. */
5581 return (expand_word_list_internal (list, WEXP_ALL));
5584 /* Same as expand_words (), but doesn't hack variable or environment
5587 expand_words_no_vars (list)
5590 return (expand_word_list_internal (list, WEXP_NOVARS));
5594 expand_words_shellexp (list)
5597 return (expand_word_list_internal (list, WEXP_SHELLEXP));
5601 glob_expand_word_list (tlist, eflags)
5605 char **glob_array, *temp_string;
5606 register int glob_index;
5607 WORD_LIST *glob_list, *output_list, *disposables, *next;
5610 output_list = disposables = (WORD_LIST *)NULL;
5611 glob_array = (char **)NULL;
5614 /* For each word, either globbing is attempted or the word is
5615 added to orig_list. If globbing succeeds, the results are
5616 added to orig_list and the word (tlist) is added to the list
5617 of disposable words. If globbing fails and failed glob
5618 expansions are left unchanged (the shell default), the
5619 original word is added to orig_list. If globbing fails and
5620 failed glob expansions are removed, the original word is
5621 added to the list of disposable words. orig_list ends up
5622 in reverse order and requires a call to reverse_list to
5623 be set right. After all words are examined, the disposable
5627 /* If the word isn't an assignment and contains an unquoted
5628 pattern matching character, then glob it. */
5630 if ((tlist->word->flags & W_ASSIGNMENT) == 0 &&
5632 if ((tlist->word->flags & W_NOGLOB) == 0 &&
5634 unquoted_glob_pattern_p (tlist->word->word))
5636 glob_array = shell_glob_filename (tlist->word->word);
5638 /* Handle error cases.
5639 I don't think we should report errors like "No such file
5640 or directory". However, I would like to report errors
5641 like "Read failed". */
5643 if (GLOB_FAILED (glob_array))
5645 glob_array = (char **) xmalloc (sizeof (char *));
5646 glob_array[0] = (char *)NULL;
5649 /* Dequote the current word in case we have to use it. */
5650 if (glob_array[0] == NULL)
5652 temp_string = dequote_string (tlist->word->word);
5653 free (tlist->word->word);
5654 tlist->word->word = temp_string;
5657 /* Make the array into a word list. */
5658 glob_list = (WORD_LIST *)NULL;
5659 for (glob_index = 0; glob_array[glob_index]; glob_index++)
5661 tword = make_bare_word (glob_array[glob_index]);
5662 tword->flags |= W_GLOBEXP; /* XXX */
5663 glob_list = make_word_list (tword, glob_list);
5668 output_list = (WORD_LIST *)list_append (glob_list, output_list);
5669 PREPEND_LIST (tlist, disposables);
5671 else if (allow_null_glob_expansion == 0)
5673 /* Failed glob expressions are left unchanged. */
5674 PREPEND_LIST (tlist, output_list);
5678 /* Failed glob expressions are removed. */
5679 PREPEND_LIST (tlist, disposables);
5684 /* Dequote the string. */
5685 temp_string = dequote_string (tlist->word->word);
5686 free (tlist->word->word);
5687 tlist->word->word = temp_string;
5688 PREPEND_LIST (tlist, output_list);
5691 free_array (glob_array);
5692 glob_array = (char **)NULL;
5698 dispose_words (disposables);
5701 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5703 return (output_list);
5706 #if defined (BRACE_EXPANSION)
5708 brace_expand_word_list (tlist, eflags)
5712 register char **expansions;
5714 WORD_LIST *disposables, *output_list, *next;
5718 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
5722 /* Only do brace expansion if the word has a brace character. If
5723 not, just add the word list element to BRACES and continue. In
5724 the common case, at least when running shell scripts, this will
5725 degenerate to a bunch of calls to `strchr', and then what is
5726 basically a reversal of TLIST into BRACES, which is corrected
5727 by a call to reverse_list () on BRACES when the end of TLIST
5729 if (strchr (tlist->word->word, LBRACE))
5731 expansions = brace_expand (tlist->word->word);
5733 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
5735 w = make_word (temp_string);
5736 /* If brace expansion didn't change the word, preserve
5737 the flags. We may want to preserve the flags
5738 unconditionally someday -- XXX */
5739 if (STREQ (temp_string, tlist->word->word))
5740 w->flags = tlist->word->flags;
5741 output_list = make_word_list (w, output_list);
5742 free (expansions[eindex]);
5746 /* Add TLIST to the list of words to be freed after brace
5747 expansion has been performed. */
5748 PREPEND_LIST (tlist, disposables);
5751 PREPEND_LIST (tlist, output_list);
5755 dispose_words (disposables);
5758 output_list = REVERSE_LIST (output_list, WORD_LIST *);
5760 return (output_list);
5765 shell_expand_word_list (tlist, eflags)
5769 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
5770 int expanded_something, has_dollar_at;
5773 /* We do tilde expansion all the time. This is what 1003.2 says. */
5774 new_list = (WORD_LIST *)NULL;
5775 for (orig_list = tlist; tlist; tlist = next)
5777 temp_string = tlist->word->word;
5781 /* Posix.2 section 3.6.1 says that tildes following `=' in words
5782 which are not assignment statements are not expanded. We do
5783 this only if POSIXLY_CORRECT is enabled. Essentially, we do
5784 tilde expansion on unquoted assignment statements (flags include
5785 W_ASSIGNMENT but not W_QUOTED). */
5786 if (temp_string[0] == '~' ||
5787 (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
5788 posixly_correct == 0 &&
5789 strchr (temp_string, '~') &&
5790 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string))))
5792 tlist->word->word = bash_tilde_expand (temp_string);
5796 expanded_something = 0;
5797 expanded = expand_word_internal
5798 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
5800 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
5802 /* By convention, each time this error is returned,
5803 tlist->word->word has already been freed. */
5804 tlist->word->word = (char *)NULL;
5806 /* Dispose our copy of the original list. */
5807 dispose_words (orig_list);
5808 /* Dispose the new list we're building. */
5809 dispose_words (new_list);
5811 if (expanded == &expand_word_error)
5812 jump_to_top_level (DISCARD);
5814 jump_to_top_level (FORCE_EOF);
5817 /* Don't split words marked W_NOSPLIT. */
5818 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
5820 temp_list = word_list_split (expanded);
5821 dispose_words (expanded);
5825 /* If no parameter expansion, command substitution, process
5826 substitution, or arithmetic substitution took place, then
5827 do not do word splitting. We still have to remove quoted
5828 null characters from the result. */
5829 word_list_remove_quoted_nulls (expanded);
5830 temp_list = expanded;
5833 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
5834 new_list = (WORD_LIST *)list_append (expanded, new_list);
5838 dispose_words (orig_list);
5841 new_list = REVERSE_LIST (new_list, WORD_LIST *);
5846 /* The workhorse for expand_words () and expand_words_no_vars ().
5847 First arg is LIST, a WORD_LIST of words.
5848 Second arg EFLAGS is a flags word controlling which expansions are
5851 This does all of the substitutions: brace expansion, tilde expansion,
5852 parameter expansion, command substitution, arithmetic expansion,
5853 process substitution, word splitting, and pathname expansion, according
5854 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
5855 set, or for which no expansion is done, do not undergo word splitting.
5856 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
5858 expand_word_list_internal (list, eflags)
5862 WORD_LIST *new_list, *temp_list;
5866 return ((WORD_LIST *)NULL);
5868 new_list = copy_word_list (list);
5870 if (eflags & WEXP_VARASSIGN)
5872 new_list = separate_out_assignments (new_list);
5877 /* All the words were variable assignments, so they are placed
5878 into the shell's environment. */
5879 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5881 this_command_name = (char *)NULL; /* no arithmetic errors */
5882 tint = do_assignment (temp_list->word->word);
5883 /* Variable assignment errors in non-interactive shells
5884 running in Posix.2 mode cause the shell to exit. */
5885 if (tint == 0 && interactive_shell == 0 && posixly_correct)
5887 last_command_exit_value = EXECUTION_FAILURE;
5888 jump_to_top_level (FORCE_EOF);
5891 dispose_words (varlist);
5892 varlist = (WORD_LIST *)NULL;
5894 return ((WORD_LIST *)NULL);
5898 /* Begin expanding the words that remain. The expansions take place on
5899 things that aren't really variable assignments. */
5901 #if defined (BRACE_EXPANSION)
5902 /* Do brace expansion on this word if there are any brace characters
5904 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
5905 new_list = brace_expand_word_list (new_list, eflags);
5906 #endif /* BRACE_EXPANSION */
5908 /* Perform the `normal' shell expansions: tilde expansion, parameter and
5909 variable substitution, command substitution, arithmetic expansion,
5910 and word splitting. */
5911 new_list = shell_expand_word_list (new_list, eflags);
5913 /* Okay, we're almost done. Now let's just do some filename
5917 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
5918 /* Glob expand the word list unless globbing has been disabled. */
5919 new_list = glob_expand_word_list (new_list, eflags);
5921 /* Dequote the words, because we're not performing globbing. */
5922 new_list = dequote_list (new_list);
5925 if ((eflags & WEXP_VARASSIGN) && varlist)
5927 Function *assign_func;
5929 /* If the remainder of the words expand to nothing, Posix.2 requires
5930 that the variable and environment assignments affect the shell's
5932 assign_func = new_list ? assign_in_env : do_assignment;
5934 for (temp_list = varlist; temp_list; temp_list = temp_list->next)
5936 this_command_name = (char *)NULL;
5937 tint = (*assign_func) (temp_list->word->word);
5938 /* Variable assignment errors in non-interactive shells running
5939 in Posix.2 mode cause the shell to exit. */
5940 if (tint == 0 && assign_func == do_assignment &&
5941 interactive_shell == 0 && posixly_correct)
5943 last_command_exit_value = EXECUTION_FAILURE;
5944 jump_to_top_level (FORCE_EOF);
5948 dispose_words (varlist);
5949 varlist = (WORD_LIST *)NULL;
5953 tint = list_length (new_list) + 1;
5954 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
5955 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
5956 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
5957 glob_argv_flags[tint] = '\0';