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 #if defined (READLINE)
54 # include "bashline.h"
55 # include <readline/readline.h>
57 # include <tilde/tilde.h>
61 # include "bashhist.h"
62 # include <readline/history.h>
65 #include <glob/fnmatch.h>
71 /* The size that strings change by. */
72 #define DEFAULT_INITIAL_ARRAY_SIZE 112
73 #define DEFAULT_ARRAY_SIZE 128
79 #define VT_ARRAYMEMBER 3
81 /* Flags for quoted_strchr */
82 #define ST_BACKSL 0x01
83 #define ST_CTLESC 0x02
85 /* How to quote character C. */
86 static char *make_quoted_char ();
88 /* Process ID of the last command executed within command substitution. */
89 pid_t last_command_subst_pid
= NO_PID
;
91 /* Extern functions and variables from different files. */
92 extern int last_command_exit_value
, interactive
, interactive_shell
;
93 extern int subshell_environment
, startup_state
;
94 extern int dollar_dollar_pid
;
95 extern int posixly_correct
;
96 extern int eof_encountered
, eof_encountered_limit
, ignoreeof
;
97 extern char *this_command_name
;
98 extern struct fd_bitmap
*current_fds_to_close
;
99 #if defined (READLINE)
100 extern int no_line_editing
;
101 extern int hostname_list_initialized
;
104 extern void getopts_reset ();
106 /* Non-zero means to allow unmatched globbed filenames to expand to
108 int allow_null_glob_expansion
;
110 /* Variables to keep track of which words in an expanded word list (the
111 output of expand_word_list_internal) are the result of globbing
112 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c. */
113 char *glob_argv_flags
;
114 static int glob_argv_flags_size
;
116 static WORD_LIST expand_word_error
, expand_word_fatal
;
117 static char expand_param_error
, expand_param_fatal
;
119 static WORD_LIST
*expand_string_internal ();
120 static WORD_LIST
*expand_word_internal (), *expand_word_list_internal ();
121 static WORD_LIST
*expand_string_leave_quoted ();
122 static WORD_LIST
*expand_string_for_rhs ();
123 static WORD_LIST
*word_list_split ();
124 static WORD_LIST
*quote_list (), *dequote_list ();
125 static int unquoted_substring (), unquoted_member ();
126 static int do_assignment_internal ();
127 static char *string_extract_verbatim (), *string_extract ();
128 static char *string_extract_double_quoted (), *string_extract_single_quoted ();
129 static 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
);
225 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
226 The parser passes CTLNUL as CTLESC CTLNUL. */
228 /* The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
229 This is necessary to make unquoted CTLESC and CTLNUL characters in the
230 data stream pass through properly.
231 Here we remove doubled CTLESC characters inside quoted strings before
232 quoting the entire string, so we do not double the number of CTLESC
235 remove_quoted_escapes (string
)
245 t1
= t
= xmalloc (strlen (string
) + 1);
246 for (docopy
= 0, s
= string
; *s
; s
++, t1
++)
248 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
))
262 /* Quote escape characters in string s, but no other characters. This is
263 used to protect CTLESC and CTLNUL in variable values from the rest of
264 the word expansion process after the variable is expanded. */
266 quote_escapes (string
)
269 register char *s
, *t
;
272 result
= xmalloc ((strlen (string
) * 2) + 1);
273 for (s
= string
, t
= result
; *s
; )
275 if (*s
== CTLESC
|| *s
== CTLNUL
)
283 #ifdef INCLUDE_UNUSED
285 dequote_escapes (string
)
288 register char *s
, *t
;
291 result
= xmalloc (strlen (string
) + 1);
292 for (s
= string
, t
= result
; *s
; )
294 if (*s
== CTLESC
&& (s
[1] == CTLESC
|| s
[1] == CTLNUL
))
307 /* Extract a substring from STRING, starting at SINDEX and ending with
308 one of the characters in CHARLIST. Don't make the ending character
309 part of the string. Leave SINDEX pointing at the ending character.
310 Understand about backslashes in the string. If VARNAME is non-zero,
311 and array variables have been compiled into the shell, everything
312 between a `[' and a corresponding `]' is skipped over. */
314 string_extract (string
, sindex
, charlist
, varname
)
315 char *string
, *charlist
;
316 int *sindex
, varname
;
321 for (i
= *sindex
; c
= string
[i
]; i
++)
328 #if defined (ARRAY_VARS)
329 else if (varname
&& c
== '[')
332 /* If this is an array subscript, skip over it and continue. */
333 ni
= skipsubscript (string
, i
);
334 if (string
[ni
] == ']')
338 else if (MEMBER (c
, charlist
))
342 temp
= xmalloc (1 + c
);
343 strncpy (temp
, string
+ *sindex
, c
);
349 /* Extract the contents of STRING as if it is enclosed in double quotes.
350 SINDEX, when passed in, is the offset of the character immediately
351 following the opening double quote; on exit, SINDEX is left pointing after
352 the closing double quote. If STRIPDQ is non-zero, unquoted double
353 quotes are stripped and the string is terminated by a null byte.
354 Backslashes between the embedded double quotes are processed. If STRIPDQ
355 is zero, an unquoted `"' terminates the string. */
357 string_extract_double_quoted (string
, sindex
, stripdq
)
359 int *sindex
, stripdq
;
362 char *temp
, *ret
; /* The new string we return. */
363 int pass_next
, backquote
, si
; /* State variables for the machine. */
366 pass_next
= backquote
= dquote
= 0;
367 temp
= xmalloc (1 + strlen (string
) - *sindex
);
369 for (j
= 0, i
= *sindex
; c
= string
[i
]; i
++)
371 /* Process a character that was quoted by a backslash. */
376 ``The backslash shall retain its special meaning as an escape
377 character only when followed by one of the characters:
380 If STRIPDQ is zero, we handle the double quotes here and let
381 expand_word_internal handle the rest. If STRIPDQ is non-zero,
382 we have already been through one round of backslash stripping,
383 and want to strip these backslashes only if DQUOTE is non-zero,
384 indicating that we are inside an embedded double-quoted string. */
386 /* If we are in an embedded quoted string, then don't strip
387 backslashes before characters for which the backslash
388 retains its special meaning, but remove backslashes in
389 front of other characters. If we are not in an
390 embedded quoted string, don't strip backslashes at all.
391 This mess is necessary because the string was already
392 surrounded by double quotes (and sh has some really weird
394 The returned string will be run through expansion as if
395 it were double-quoted. */
396 if ((stripdq
== 0 && c
!= '"') ||
397 (stripdq
&& ((dquote
&& strchr (slashify_in_quotes
, c
)) || dquote
== 0)))
404 /* A backslash protects the next character. The code just above
405 handles preserving the backslash in front of any character but
413 /* Inside backquotes, ``the portion of the quoted string from the
414 initial backquote and the characters up to the next backquote
415 that is not preceded by a backslash, having escape characters
416 removed, defines that command''. */
432 /* Pass everything between `$(' and the matching `)' or a quoted
433 ${ ... } pair through according to the Posix.2 specification. */
434 if (c
== '$' && ((string
[i
+ 1] == '(') || (string
[i
+ 1] == '{')))
437 if (string
[i
+ 1] == '(')
438 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")");
440 ret
= extract_dollar_brace_string (string
, &si
, 1);
443 temp
[j
++] = string
[i
+ 1];
445 for (t
= 0; ret
[t
]; t
++, j
++)
447 temp
[j
++] = string
[si
];
454 /* Add any character but a double quote to the quoted string we're
473 /* Point to after the closing quote. */
481 /* This should really be another option to string_extract_double_quoted. */
483 skip_double_quoted (string
, sind
)
489 int pass_next
, backquote
, si
;
491 pass_next
= backquote
= 0;
493 for (j
= 0, i
= sind
; c
= string
[i
]; i
++)
516 else if (c
== '$' && ((string
[i
+ 1] == '(') || (string
[i
+ 1] == '{')))
519 if (string
[i
+ 1] == '(')
520 ret
= extract_delimited_string (string
, &si
, "$(", "(", ")");
522 ret
= extract_dollar_brace_string (string
, &si
, 0);
540 /* Extract the contents of STRING as if it is enclosed in single quotes.
541 SINDEX, when passed in, is the offset of the character immediately
542 following the opening single quote; on exit, SINDEX is left pointing after
543 the closing single quote. */
545 string_extract_single_quoted (string
, sindex
)
552 for (i
= *sindex
; string
[i
] && string
[i
] != '\''; i
++)
557 strncpy (t
, string
+ *sindex
, j
);
568 skip_single_quoted (string
, sind
)
574 for (i
= sind
; string
[i
] && string
[i
] != '\''; i
++)
581 /* Just like string_extract, but doesn't hack backslashes or any of
582 that other stuff. Obeys quoting. Used to do splitting on $IFS. */
584 string_extract_verbatim (string
, sindex
, charlist
)
585 char *string
, *charlist
;
588 register int i
= *sindex
;
592 if (charlist
[0] == '\'' && charlist
[1] == '\0')
594 temp
= string_extract_single_quoted (string
, sindex
);
595 --*sindex
; /* leave *sindex at separator character */
599 for (i
= *sindex
; c
= string
[i
]; i
++)
607 if (MEMBER (c
, charlist
))
612 temp
= xmalloc (1 + c
);
613 strncpy (temp
, string
+ *sindex
, c
);
620 /* Extract the $( construct in STRING, and return a new string.
621 Start extracting at (SINDEX) as if we had just seen "$(".
622 Make (SINDEX) get the position of the matching ")". */
624 extract_command_subst (string
, sindex
)
628 return (extract_delimited_string (string
, sindex
, "$(", "(", ")"));
631 /* Extract the $[ construct in STRING, and return a new string.
632 Start extracting at (SINDEX) as if we had just seen "$[".
633 Make (SINDEX) get the position of the matching "]". */
635 extract_arithmetic_subst (string
, sindex
)
639 return (extract_delimited_string (string
, sindex
, "$[", "[", "]"));
642 #if defined (PROCESS_SUBSTITUTION)
643 /* Extract the <( or >( construct in STRING, and return a new string.
644 Start extracting at (SINDEX) as if we had just seen "<(".
645 Make (SINDEX) get the position of the matching ")". */
647 extract_process_subst (string
, starter
, sindex
)
652 return (extract_delimited_string (string
, sindex
, starter
, "(", ")"));
654 #endif /* PROCESS_SUBSTITUTION */
656 #if defined (ARRAY_VARS)
658 extract_array_assignment_list (string
, sindex
)
662 return (extract_delimited_string (string
, sindex
, "(", (char *)NULL
, ")"));
666 /* Extract and create a new string from the contents of STRING, a
667 character string delimited with OPENER and CLOSER. SINDEX is
668 the address of an int describing the current offset in STRING;
669 it should point to just after the first OPENER found. On exit,
670 SINDEX gets the position of the last character of the matching CLOSER.
671 If OPENER is more than a single character, ALT_OPENER, if non-null,
672 contains a character string that can also match CLOSER and thus
673 needs to be skipped. */
675 extract_delimited_string (string
, sindex
, opener
, alt_opener
, closer
)
678 char *opener
, *alt_opener
, *closer
;
682 int pass_character
, nesting_level
;
683 int len_closer
, len_opener
, len_alt_opener
;
685 len_opener
= STRLEN (opener
);
686 len_alt_opener
= STRLEN (alt_opener
);
687 len_closer
= STRLEN (closer
);
694 while (nesting_level
)
701 if (pass_character
) /* previous char was backslash */
716 if (c
== '\\' && delimiter
== '"' &&
717 (member (string
[i
], slashify_in_quotes
)))
727 /* Process a nested OPENER. */
728 if (STREQN (string
+ i
, opener
, len_opener
))
731 t
= extract_delimited_string (string
, &si
, opener
, alt_opener
, closer
);
737 /* Process a nested ALT_OPENER */
738 if (len_alt_opener
&& STREQN (string
+ i
, alt_opener
, len_alt_opener
))
740 si
= i
+ len_alt_opener
;
741 t
= extract_delimited_string (string
, &si
, alt_opener
, alt_opener
, closer
);
747 /* If the current substring terminates the delimited string, decrement
748 the nesting level. */
749 if (STREQN (string
+ i
, closer
, len_closer
))
751 i
+= len_closer
- 1; /* move to last char of the closer */
753 if (nesting_level
== 0)
757 /* Pass old-style command substitution through verbatim. */
761 t
= string_extract (string
, &si
, "`", 0);
767 /* Pass single-quoted strings through verbatim. */
771 i
= skip_single_quoted (string
, si
);
775 /* Pass embedded double-quoted strings through verbatim as well. */
779 i
= skip_double_quoted (string
, si
);
783 i
++; /* move past this character, which was not special. */
786 si
= i
- *sindex
- len_closer
+ 1;
787 result
= xmalloc (1 + si
);
788 strncpy (result
, string
+ *sindex
, si
);
792 if (c
== 0 && nesting_level
)
794 report_error ("bad substitution: no `%s' in %s", closer
, string
);
796 jump_to_top_level (DISCARD
);
802 /* Extract a parameter expansion expression within ${ and } from STRING.
803 Obey the Posix.2 rules for finding the ending `}': count braces while
804 skipping over enclosed quoted strings and command substitutions.
805 SINDEX is the address of an int describing the current offset in STRING;
806 it should point to just after the first `{' found. On exit, SINDEX
807 gets the position of the matching `}'. QUOTED is non-zero if this
808 occurs inside double quotes. */
809 /* XXX -- this is very similar to extract_delimited_string -- XXX */
811 extract_dollar_brace_string (string
, sindex
, quoted
)
815 register int i
, c
, l
;
816 int pass_character
, nesting_level
, si
;
823 for (i
= *sindex
; (c
= string
[i
]); i
++)
837 /* Backslashes quote the next character. */
844 if (string
[i
] == '$' && string
[i
+1] == '{')
854 if (nesting_level
== 0)
859 /* Pass the contents of old-style command substitutions through
864 t
= string_extract (string
, &si
, "`", 0);
870 /* Pass the contents of new-style command substitutions through
872 if (string
[i
] == '$' && string
[i
+1] == '(')
875 t
= extract_delimited_string (string
, &si
, "$(", "(", ")");
881 /* Pass the contents of single-quoted strings through verbatim. */
885 i
= skip_single_quoted (string
, si
);
886 /* skip_single_quoted leaves index one past close quote */
891 /* Pass embedded double-quoted strings through verbatim as well. */
895 /* skip_double_quoted leaves index one past close quote */
896 i
= skip_double_quoted (string
, si
);
903 result
= xmalloc (1 + l
);
904 strncpy (result
, string
+ *sindex
, l
);
908 if (c
== 0 && nesting_level
)
910 report_error ("bad substitution: no ending `}' in %s", string
);
912 jump_to_top_level (DISCARD
);
918 /* Remove backslashes which are quoting backquotes from STRING. Modifies
919 STRING, and returns a pointer to it. */
921 de_backslash (string
)
926 for (i
= 0, l
= strlen (string
); i
< l
; i
++)
927 if (string
[i
] == '\\' && (string
[i
+ 1] == '`' || string
[i
+ 1] == '\\' ||
928 string
[i
+ 1] == '$'))
929 strcpy (string
+ i
, string
+ i
+ 1); /* XXX - should be memmove */
934 /* Replace instances of \! in a string with !. */
936 unquote_bang (string
)
942 temp
= xmalloc (1 + strlen (string
));
944 for (i
= 0, j
= 0; (temp
[j
] = string
[i
]); i
++, j
++)
946 if (string
[i
] == '\\' && string
[i
+ 1] == '!')
952 strcpy (string
, temp
);
957 #if defined (READLINE)
958 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
959 an unclosed quoted string), or if the character at EINDEX is quoted
962 char_is_quoted (string
, eindex
)
966 int i
, pass_next
, quoted
;
968 for (i
= pass_next
= quoted
= 0; i
<= eindex
; i
++)
973 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
977 else if (string
[i
] == '\'' || string
[i
] == '"')
979 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, ++i
)
980 : skip_double_quoted (string
, ++i
);
983 i
--; /* the skip functions increment past the closing quote. */
985 else if (string
[i
] == '\\')
995 unclosed_pair (string
, eindex
, openstr
)
1000 int i
, pass_next
, openc
, olen
;
1002 olen
= strlen (openstr
);
1003 for (i
= pass_next
= openc
= 0; i
<= eindex
; i
++)
1008 if (i
>= eindex
) /* XXX was if (i >= eindex - 1) */
1012 else if (STREQN (string
+ i
, openstr
, olen
))
1017 else if (string
[i
] == '\'' || string
[i
] == '"')
1019 i
= (string
[i
] == '\'') ? skip_single_quoted (string
, i
)
1020 : skip_double_quoted (string
, i
);
1024 else if (string
[i
] == '\\')
1032 #endif /* READLINE */
1036 /* Extract the name of the variable to bind to from the assignment string. */
1038 assignment_name (string
)
1044 offset
= assignment (string
);
1046 return (char *)NULL
;
1047 temp
= xmalloc (offset
+ 1);
1048 strncpy (temp
, string
, offset
);
1049 temp
[offset
] = '\0';
1054 /* Return a single string of all the words in LIST. SEP is the separator
1055 to put between individual elements of LIST in the output string. */
1057 string_list_internal (list
, sep
)
1061 register WORD_LIST
*t
;
1063 int word_len
, sep_len
, result_size
;
1066 return ((char *)NULL
);
1068 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1069 sep_len
= STRLEN (sep
);
1072 for (t
= list
; t
; t
= t
->next
)
1075 result_size
+= sep_len
;
1076 result_size
+= strlen (t
->word
->word
);
1079 r
= result
= xmalloc (result_size
+ 1);
1081 for (t
= list
; t
; t
= t
->next
)
1083 if (t
!= list
&& sep_len
)
1087 FASTCOPY (sep
, r
, sep_len
);
1094 word_len
= strlen (t
->word
->word
);
1095 FASTCOPY (t
->word
->word
, r
, word_len
);
1103 /* Return a single string of all the words present in LIST, separating
1104 each word with a space. */
1109 return (string_list_internal (list
, " "));
1112 /* Return a single string of all the words present in LIST, obeying the
1113 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1114 expansion [of $*] appears within a double quoted string, it expands
1115 to a single field with the value of each parameter separated by the
1116 first character of the IFS variable, or by a <space> if IFS is unset." */
1118 string_list_dollar_star (list
)
1123 ifs
= get_string_value ("IFS");
1126 else if (*ifs
== '\0')
1133 return (string_list_internal (list
, sep
));
1136 /* Return the list of words present in STRING. Separate the string into
1137 words at any of the characters found in SEPARATORS. If QUOTED is
1138 non-zero then word in the list will have its quoted flag set, otherwise
1139 the quoted flag is left as make_word () deemed fit.
1141 This obeys the P1003.2 word splitting semantics. If `separators' is
1142 exactly <space><tab><newline>, then the splitting algorithm is that of
1143 the Bourne shell, which treats any sequence of characters from `separators'
1144 as a delimiter. If IFS is unset, which results in `separators' being set
1145 to "", no splitting occurs. If separators has some other value, the
1146 following rules are applied (`IFS white space' means zero or more
1147 occurrences of <space>, <tab>, or <newline>, as long as those characters
1148 are in `separators'):
1150 1) IFS white space is ignored at the start and the end of the
1152 2) Each occurrence of a character in `separators' that is not
1153 IFS white space, along with any adjacent occurrences of
1154 IFS white space delimits a field.
1155 3) Any nonzero-length sequence of IFS white space delimits a field.
1158 /* BEWARE! list_string strips null arguments. Don't call it twice and
1159 expect to have "" preserved! */
1161 /* Perform quoted null character removal on STRING. We don't allow any
1162 quoted null characters in the middle or at the ends of strings because
1163 of how expand_word_internal works. remove_quoted_nulls () turns
1164 STRING into an empty string iff it only consists of a quoted null,
1165 and removes all unquoted CTLNUL characters. */
1167 #define remove_quoted_nulls(string) \
1168 do { if (QUOTED_NULL (string)) string[0] ='\0'; } while (0)
1171 remove_quoted_nulls (string
)
1176 nstr
= savestring (string
);
1178 for (p
= nstr
, s
= string
; *s
; s
++)
1182 *p
++ = *s
++; /* CTLESC */
1185 *p
++ = *s
; /* quoted char */
1193 strcpy (string
, nstr
);
1197 /* Perform quoted null character removal on each element of LIST.
1198 This modifies LIST. */
1200 word_list_remove_quoted_nulls (list
)
1203 register WORD_LIST
*t
;
1205 for (t
= list
; t
; t
= t
->next
)
1206 remove_quoted_nulls (t
->word
->word
);
1209 /* This performs word splitting and quoted null character removal on
1211 #define issep(c) (member ((c), separators))
1214 list_string (string
, separators
, quoted
)
1215 register char *string
, *separators
;
1220 char *current_word
, *s
;
1221 int sindex
, sh_style_split
;
1223 if (!string
|| !*string
)
1224 return ((WORD_LIST
*)NULL
);
1227 separators
&& *separators
&& (STREQ (separators
, " \t\n"));
1229 /* Remove sequences of whitespace at the beginning of STRING, as
1230 long as those characters appear in IFS. Do not do this if
1231 STRING is quoted or if there are no separator characters. */
1232 if (!quoted
|| !separators
|| !*separators
)
1234 for (s
= string
; *s
&& spctabnl (*s
) && issep (*s
); s
++);
1237 return ((WORD_LIST
*)NULL
);
1242 /* OK, now STRING points to a word that does not begin with white space.
1243 The splitting algorithm is:
1244 extract a word, stopping at a separator
1245 skip sequences of spc, tab, or nl as long as they are separators
1246 This obeys the field splitting rules in Posix.2. */
1247 for (result
= (WORD_LIST
*)NULL
, sindex
= 0; string
[sindex
]; )
1249 current_word
= string_extract_verbatim (string
, &sindex
, separators
);
1250 if (current_word
== 0)
1253 /* If we have a quoted empty string, add a quoted null argument. We
1254 want to preserve the quoted null character iff this is a quoted
1255 empty string; otherwise the quoted null characters are removed
1257 if (QUOTED_NULL (current_word
))
1259 t
= make_bare_word ("");
1260 t
->flags
|= W_QUOTED
;
1262 t
->word
= make_quoted_char ('\0');
1263 result
= make_word_list (t
, result
);
1265 else if (current_word
[0] != '\0')
1267 /* If we have something, then add it regardless. However,
1268 perform quoted null character removal on the current word. */
1269 remove_quoted_nulls (current_word
);
1270 result
= make_word_list (make_word (current_word
), result
);
1271 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
))
1272 result
->word
->flags
|= W_QUOTED
;
1275 /* If we're not doing sequences of separators in the traditional
1276 Bourne shell style, then add a quoted null argument. */
1277 else if (!sh_style_split
&& !spctabnl (string
[sindex
]))
1279 t
= make_bare_word ("");
1280 t
->flags
|= W_QUOTED
;
1282 t
->word
= make_quoted_char ('\0');
1283 result
= make_word_list (t
, result
);
1286 free (current_word
);
1288 /* Move past the current separator character. */
1292 /* Now skip sequences of space, tab, or newline characters if they are
1293 in the list of separators. */
1294 while (string
[sindex
] && spctabnl (string
[sindex
]) && issep (string
[sindex
]))
1297 return (REVERSE_LIST (result
, WORD_LIST
*));
1300 /* Parse a single word from STRING, using SEPARATORS to separate fields.
1301 ENDPTR is set to the first character after the word. This is used by
1303 XXX - this function is very similar to list_string; they should be
1306 get_word_from_string (stringp
, separators
, endptr
)
1307 char **stringp
, *separators
, **endptr
;
1311 int sindex
, sh_style_split
;
1313 if (!stringp
|| !*stringp
|| !**stringp
)
1314 return ((char *)NULL
);
1319 separators
&& *separators
&& (STREQ (separators
, " \t\n"));
1321 /* Remove sequences of whitespace at the beginning of STRING, as
1322 long as those characters appear in IFS. */
1323 if (sh_style_split
|| !separators
|| !*separators
)
1325 for (; *s
&& spctabnl (*s
) && issep (*s
); s
++);
1327 /* If the string is nothing but whitespace, update it and return. */
1333 return ((char *)NULL
);
1337 /* OK, S points to a word that does not begin with white space.
1338 Now extract a word, stopping at a separator, save a pointer to
1339 the first character after the word, then skip sequences of spc,
1340 tab, or nl as long as they are separators.
1342 This obeys the field splitting rules in Posix.2. */
1344 current_word
= string_extract_verbatim (s
, &sindex
, separators
);
1346 /* Set ENDPTR to the first character after the end of the word. */
1348 *endptr
= s
+ sindex
;
1350 /* Move past the current separator character. */
1354 /* Now skip sequences of space, tab, or newline characters if they are
1355 in the list of separators. */
1356 while (s
[sindex
] && spctabnl (s
[sindex
]) && issep (s
[sindex
]))
1359 /* Update STRING to point to the next field. */
1360 *stringp
= s
+ sindex
;
1361 return (current_word
);
1364 /* Remove IFS white space at the end of STRING. Start at the end
1365 of the string and walk backwards until the beginning of the string
1366 or we find a character that's not IFS white space and not CTLESC.
1367 Only let CTLESC escape a white space character if SAW_ESCAPE is
1370 strip_trailing_ifs_whitespace (string
, separators
, saw_escape
)
1371 char *string
, *separators
;
1376 s
= string
+ STRLEN (string
) - 1;
1377 while (s
> string
&& ((spctabnl (*s
) && issep (*s
)) ||
1378 (saw_escape
&& *s
== CTLESC
&& spctabnl (s
[1]))))
1385 #if defined (ARRAY_VARS)
1387 list_string_with_quotes (string
)
1392 int c
, i
, tokstart
, len
;
1394 for (s
= string
; s
&& *s
&& spctabnl (*s
); s
++)
1396 if (s
== 0 || *s
== 0)
1397 return ((WORD_LIST
*)NULL
);
1400 list
= (WORD_LIST
*)NULL
;
1411 i
= skip_single_quoted (s
, ++i
);
1413 i
= skip_double_quoted (s
, ++i
);
1414 else if (c
== 0 || spctabnl (c
))
1416 /* We have found the end of a token. Make a word out of it and
1417 add it to the word list. */
1419 token
= xmalloc (len
+ 1);
1420 strncpy (token
, s
+ tokstart
, len
);
1422 list
= make_word_list (make_word (token
), list
);
1424 while (spctabnl (s
[i
]))
1432 i
++; /* normal character */
1434 return (REVERSE_LIST (list
, WORD_LIST
*));
1436 #endif /* ARRAY_VARS */
1439 #if defined (PROCESS_SUBSTITUTION)
1440 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC)
1442 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
1445 /* If there are any characters in STRING that require full expansion,
1446 then call FUNC to expand STRING; otherwise just perform quote
1447 removal if necessary. This returns a new string. */
1449 maybe_expand_string (string
, quoted
, func
)
1452 WORD_LIST
*(*func
)();
1458 for (i
= saw_quote
= 0; string
[i
]; i
++)
1460 if (EXP_CHAR (string
[i
]))
1462 else if (string
[i
] == '\'' || string
[i
] == '\\' || string
[i
] == '"')
1468 list
= (*func
) (string
, quoted
);
1471 ret
= string_list (list
);
1472 dispose_words (list
);
1477 else if (saw_quote
&& ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) == 0))
1478 ret
= string_quote_removal (string
, quoted
);
1480 ret
= savestring (string
);
1484 static inline char *
1485 expand_string_to_string (string
, quoted
, func
)
1488 WORD_LIST
*(*func
)();
1493 if (string
== 0 || *string
== '\0')
1494 return ((char *)NULL
);
1496 list
= (*func
) (string
, quoted
);
1499 ret
= string_list (list
);
1500 dispose_words (list
);
1508 #if defined (ARRAY_VARS)
1510 do_array_element_assignment (name
, value
)
1517 t
= strchr (name
, '[');
1519 return ((SHELL_VAR
*)NULL
);
1521 ni
= skipsubscript (name
, ind
);
1522 if ((ALL_ELEMENT_SUB (t
[1]) && t
[2] == ']') || (ni
<= ind
+ 1))
1524 report_error ("%s: bad array subscript", name
);
1525 return ((SHELL_VAR
*)NULL
);
1528 ind
= array_expand_index (t
, ni
- ind
);
1531 t
[-1] = '['; /* restore original name */
1532 report_error ("%s: bad array subscript", name
);
1533 return ((SHELL_VAR
*)NULL
);
1535 entry
= bind_array_variable (name
, ind
, value
);
1536 t
[-1] = '['; /* restore original name */
1539 #endif /* ARRAY_VARS */
1541 /* Given STRING, an assignment string, get the value of the right side
1542 of the `=', and bind it to the left side. If EXPAND is true, then
1543 perform parameter expansion, command substitution, and arithmetic
1544 expansion on the right-hand side. Perform tilde expansion in any
1545 case. Do not perform word splitting on the result of expansion. */
1547 do_assignment_internal (string
, expand
)
1554 #if defined (ARRAY_VARS)
1556 int ni
, assign_list
= 0;
1559 offset
= assignment (string
);
1560 name
= savestring (string
);
1561 value
= (char *)NULL
;
1563 if (name
[offset
] == '=')
1568 temp
= name
+ offset
+ 1;
1570 #if defined (ARRAY_VARS)
1571 if (expand
&& temp
[0] == '(' && strchr (temp
, ')'))
1573 assign_list
= ni
= 1;
1574 value
= extract_delimited_string (temp
, &ni
, "(", (char *)NULL
, ")");
1579 /* Perform tilde expansion. */
1580 if (expand
&& temp
[0])
1582 temp
= (strchr (temp
, '~') && unquoted_member ('~', temp
))
1583 ? bash_tilde_expand (temp
)
1584 : savestring (temp
);
1586 value
= maybe_expand_string (temp
, 0, expand_string_unsplit
);
1590 value
= savestring (temp
);
1595 value
= xmalloc (1);
1599 if (echo_command_at_execute
)
1600 #if defined (ARRAY_VARS)
1602 fprintf (stderr
, "%s%s=(%s)\n", indirection_level_string (), name
, value
);
1605 fprintf (stderr
, "%s%s=%s\n", indirection_level_string (), name
, value
);
1607 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
1609 #if defined (ARRAY_VARS)
1610 if (t
= strchr (name
, '['))
1614 report_error ("%s: cannot assign list to array member", name
);
1617 entry
= do_array_element_assignment (name
, value
);
1621 else if (assign_list
)
1622 entry
= assign_array_from_string (name
, value
);
1624 #endif /* ARRAY_VARS */
1625 entry
= bind_variable (name
, value
);
1627 stupidly_hack_special_variables (name
);
1630 entry
->attributes
&= ~att_invisible
;
1632 /* Return 1 if the assignment seems to have been performed correctly. */
1633 ASSIGN_RETURN (entry
? ((entry
->attributes
& att_readonly
) == 0) : 0);
1636 /* Perform the assignment statement in STRING, and expand the
1637 right side by doing command and parameter expansion. */
1639 do_assignment (string
)
1642 return do_assignment_internal (string
, 1);
1645 /* Given STRING, an assignment string, get the value of the right side
1646 of the `=', and bind it to the left side. Do not do command and
1647 parameter substitution on the right hand side. */
1649 do_assignment_no_expand (string
)
1652 return do_assignment_internal (string
, 0);
1655 /* Most of the substitutions must be done in parallel. In order
1656 to avoid using tons of unclear goto's, I have some functions
1657 for manipulating malloc'ed strings. They all take INDX, a
1658 pointer to an integer which is the offset into the string
1659 where manipulation is taking place. They also take SIZE, a
1660 pointer to an integer which is the current length of the
1661 character array for this string. */
1663 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
1664 of space allocated to TARGET. SOURCE can be NULL, in which
1665 case nothing happens. Gets rid of SOURCE by freeing it.
1666 Returns TARGET in case the location has changed. */
1668 sub_append_string (source
, target
, indx
, size
)
1669 char *source
, *target
;
1676 srclen
= STRLEN (source
);
1677 if (srclen
>= (int)(*size
- *indx
))
1680 n
= (n
+ DEFAULT_ARRAY_SIZE
) - (n
% DEFAULT_ARRAY_SIZE
);
1681 target
= xrealloc (target
, (*size
= n
));
1684 FASTCOPY (source
, target
+ *indx
, srclen
);
1686 target
[*indx
] = '\0';
1695 /* Append the textual representation of NUMBER to TARGET.
1696 INDX and SIZE are as in SUB_APPEND_STRING. */
1698 sub_append_number (number
, target
, indx
, size
)
1699 int number
, *indx
, *size
;
1704 temp
= itos (number
);
1705 return (sub_append_string (temp
, target
, indx
, size
));
1709 /* Return the word list that corresponds to `$*'. */
1711 list_rest_of_args ()
1713 register WORD_LIST
*list
, *args
;
1716 /* Break out of the loop as soon as one of the dollar variables is null. */
1717 for (i
= 1, list
= (WORD_LIST
*)NULL
; i
< 10 && dollar_vars
[i
]; i
++)
1718 list
= make_word_list (make_bare_word (dollar_vars
[i
]), list
);
1720 for (args
= rest_of_args
; args
; args
= args
->next
)
1721 list
= make_word_list (make_bare_word (args
->word
->word
), list
);
1723 return (REVERSE_LIST (list
, WORD_LIST
*));
1729 register WORD_LIST
*list
;
1732 for (n
= 0; n
< 9 && dollar_vars
[n
+1]; n
++)
1734 for (list
= rest_of_args
; list
; list
= list
->next
)
1739 /* Make a single large string out of the dollar digit variables,
1740 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
1741 case of "$*" with respect to IFS. */
1743 string_rest_of_args (dollar_star
)
1746 register WORD_LIST
*list
;
1749 list
= list_rest_of_args ();
1750 string
= dollar_star
? string_list_dollar_star (list
) : string_list (list
);
1751 dispose_words (list
);
1755 /***************************************************
1757 * Functions to Expand a String *
1759 ***************************************************/
1760 /* Call expand_word_internal to expand W and handle error returns.
1761 A convenience function for functions that don't want to handle
1762 any errors or free any memory before aborting. */
1764 call_expand_word_internal (w
, q
, c
, e
)
1770 result
= expand_word_internal (w
, q
, c
, e
);
1771 if (result
== &expand_word_error
)
1773 /* By convention, each time this error is returned, w->word has
1774 already been freed. */
1775 w
->word
= (char *)NULL
;
1776 jump_to_top_level (DISCARD
);
1779 else if (result
== &expand_word_fatal
)
1780 jump_to_top_level (FORCE_EOF
);
1786 /* Perform parameter expansion, command substitution, and arithmetic
1787 expansion on STRING, as if it were a word. Leave the result quoted. */
1789 expand_string_internal (string
, quoted
)
1796 if (string
== 0 || *string
== 0)
1797 return ((WORD_LIST
*)NULL
);
1799 bzero ((char *)&td
, sizeof (td
));
1801 tresult
= call_expand_word_internal (&td
, quoted
, (int *)NULL
, (int *)NULL
);
1805 /* Expand STRING by performing parameter expansion, command substitution,
1806 and arithmetic expansion. Dequote the resulting WORD_LIST before
1807 returning it, but do not perform word splitting. The call to
1808 remove_quoted_nulls () is in here because word splitting normally
1809 takes care of quote removal. */
1811 expand_string_unsplit (string
, quoted
)
1817 if (!string
|| !*string
)
1818 return ((WORD_LIST
*)NULL
);
1820 value
= expand_string_internal (string
, quoted
);
1824 remove_quoted_nulls (value
->word
->word
);
1825 dequote_list (value
);
1830 /* Expand STRING just as if you were expanding a word, but do not dequote
1831 the resultant WORD_LIST. This is called only from within this file,
1832 and is used to correctly preserve quoted characters when expanding
1833 things like ${1+"$@"}. This does parameter expansion, command
1834 subsitution, arithmetic expansion, and word splitting. */
1836 expand_string_leave_quoted (string
, quoted
)
1843 if (string
== 0 || *string
== '\0')
1844 return ((WORD_LIST
*)NULL
);
1846 tlist
= expand_string_internal (string
, quoted
);
1850 tresult
= word_list_split (tlist
);
1851 dispose_words (tlist
);
1854 return ((WORD_LIST
*)NULL
);
1857 /* This does not perform word splitting or dequote the WORD_LIST
1860 expand_string_for_rhs (string
, quoted
, dollar_at_p
, has_dollar_at
)
1862 int quoted
, *dollar_at_p
, *has_dollar_at
;
1867 if (string
== 0 || *string
== '\0')
1868 return (WORD_LIST
*)NULL
;
1870 bzero ((char *)&td
, sizeof (td
));
1872 tresult
= call_expand_word_internal (&td
, quoted
, dollar_at_p
, has_dollar_at
);
1876 /* Expand STRING just as if you were expanding a word. This also returns
1877 a list of words. Note that filename globbing is *NOT* done for word
1878 or string expansion, just when the shell is expanding a command. This
1879 does parameter expansion, command substitution, arithmetic expansion,
1880 and word splitting. Dequote the resultant WORD_LIST before returning. */
1882 expand_string (string
, quoted
)
1888 if (!string
|| !*string
)
1889 return ((WORD_LIST
*)NULL
);
1891 result
= expand_string_leave_quoted (string
, quoted
);
1892 return (result
? dequote_list (result
) : result
);
1895 /***************************************************
1897 * Functions to handle quoting chars *
1899 ***************************************************/
1906 register WORD_LIST
*tlist
;
1908 for (tlist
= list
; tlist
; tlist
= tlist
->next
)
1910 s
= dequote_string (tlist
->word
->word
);
1911 free (tlist
->word
->word
);
1912 tlist
->word
->word
= s
;
1918 make_quoted_char (c
)
1938 /* Quote STRING. Return a new string. */
1940 quote_string (string
)
1948 result
= xmalloc (2);
1954 result
= xmalloc ((strlen (string
) * 2) + 1);
1956 for (t
= result
; *string
; )
1966 /* De-quoted quoted characters in STRING. */
1968 dequote_string (string
)
1974 result
= xmalloc (strlen (string
) + 1);
1976 if (QUOTED_NULL (string
))
1982 /* If no character in the string can be quoted, don't bother examining
1983 each character. Just return a copy of the string passed to us. */
1984 if (strchr (string
, CTLESC
) == NULL
) /* XXX */
1986 strcpy (result
, string
); /* XXX */
1987 return (result
); /* XXX */
1990 for (t
= result
; *string
; string
++, t
++)
1992 if (*string
== CTLESC
)
2007 /* Quote the entire WORD_LIST list. */
2012 register WORD_LIST
*w
;
2015 for (w
= list
; w
; w
= w
->next
)
2018 w
->word
->word
= quote_string (t
);
2020 w
->word
->flags
|= W_QUOTED
;
2025 /* **************************************************************** */
2027 /* Functions for Removing Patterns */
2029 /* **************************************************************** */
2031 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
2032 can have one of 4 values:
2033 RP_LONG_LEFT remove longest matching portion at start of PARAM
2034 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
2035 RP_LONG_RIGHT remove longest matching portion at end of PARAM
2036 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
2039 #define RP_LONG_LEFT 1
2040 #define RP_SHORT_LEFT 2
2041 #define RP_LONG_RIGHT 3
2042 #define RP_SHORT_RIGHT 4
2045 remove_pattern (param
, pattern
, op
)
2046 char *param
, *pattern
;
2051 register char *p
, *ret
, c
;
2053 if (param
== NULL
|| *param
== '\0')
2055 if (pattern
== NULL
|| *pattern
== '\0') /* minor optimization */
2056 return (savestring (param
));
2058 len
= STRLEN (param
);
2063 case RP_LONG_LEFT
: /* remove longest match at start */
2064 for (p
= end
; p
>= param
; p
--)
2067 if (fnmatch (pattern
, param
, 0) != FNM_NOMATCH
)
2070 return (savestring (p
));
2076 case RP_SHORT_LEFT
: /* remove shortest match at start */
2077 for (p
= param
; p
<= end
; p
++)
2080 if (fnmatch (pattern
, param
, 0) != FNM_NOMATCH
)
2083 return (savestring (p
));
2089 case RP_LONG_RIGHT
: /* remove longest match at end */
2090 for (p
= param
; p
<= end
; p
++)
2092 if (fnmatch (pattern
, p
, 0) != FNM_NOMATCH
)
2095 ret
= savestring (param
);
2102 case RP_SHORT_RIGHT
: /* remove shortest match at end */
2103 for (p
= end
; p
>= param
; p
--)
2105 if (fnmatch (pattern
, p
, 0) != FNM_NOMATCH
)
2108 ret
= savestring (param
);
2115 return (savestring (param
)); /* no match, return original string */
2118 /* Return 1 of the first character of STRING could match the first
2119 character of pattern PAT. Used to avoid n2 calls to fnmatch(). */
2121 match_pattern_char (pat
, string
)
2137 return (*string
== c
);
2139 return (*string
== *pat
);
2141 return (*string
!= '\0');
2146 for (np
= pat
; *np
!= ']'; np
++);
2148 return (*string
== '[');
2149 if (neg
= (*pat
== '!' || *pat
== '^'))
2151 for ( ; (c1
= *pat
++) != ']'; )
2157 if (*pat
!= '-' || pat
[1] == '\0' || pat
[1] == ']')
2158 return (neg
? *string
!= c1
: *string
== c1
);
2159 if (c1
<= *string
&& *string
<= pat
[1])
2164 return (*string
!= '\0');
2169 /* Match PAT anywhere in STRING and return the match boundaries.
2170 This returns 1 in case of a successful match, 0 otherwise. SP
2171 and EP are pointers into the string where the match begins and
2172 ends, respectively. MTYPE controls what kind of match is attempted.
2173 MATCH_BEG and MATCH_END anchor the match at the beginning and end
2174 of the string, respectively. The longest match is returned. */
2176 match_pattern (string
, pat
, mtype
, sp
, ep
)
2182 register char *p
, *p1
;
2185 if (string
== 0 || *string
== 0 || pat
== 0 || *pat
== 0)
2188 end
= string
+ STRLEN (string
);
2193 for (p
= string
; p
<= end
; p
++)
2195 if (match_pattern_char (pat
, p
))
2197 for (p1
= end
; p1
>= p
; p1
--)
2199 c
= *p1
; *p1
= '\0';
2200 if (fnmatch (pat
, p
, 0) == 0)
2214 if (match_pattern_char (pat
, string
) == 0)
2216 for (p
= end
; p
>= string
; p
--)
2219 if (fnmatch (pat
, string
, 0) == 0)
2231 for (p
= string
; p
<= end
; p
++)
2232 if (fnmatch (pat
, p
, 0) == 0)
2244 /*******************************************
2246 * Functions to expand WORD_DESCs *
2248 *******************************************/
2250 /* Expand WORD, performing word splitting on the result. This does
2251 parameter expansion, command substitution, arithmetic expansion,
2252 word splitting, and quote removal. */
2255 expand_word (word
, quoted
)
2259 WORD_LIST
*result
, *tresult
;
2261 tresult
= call_expand_word_internal (word
, quoted
, (int *)NULL
, (int *)NULL
);
2262 result
= word_list_split (tresult
);
2263 dispose_words (tresult
);
2264 return (result
? dequote_list (result
) : result
);
2267 /* Expand WORD, but do not perform word splitting on the result. This
2268 does parameter expansion, command substitution, arithmetic expansion,
2269 and quote removal. */
2271 expand_word_no_split (word
, quoted
)
2277 result
= call_expand_word_internal (word
, quoted
, (int *)NULL
, (int *)NULL
);
2278 return (result
? dequote_list (result
) : result
);
2281 /* Perform shell expansions on WORD, but do not perform word splitting or
2282 quote removal on the result. */
2284 expand_word_leave_quoted (word
, quoted
)
2288 return (call_expand_word_internal (word
, quoted
, (int *)NULL
, (int *)NULL
));
2291 /* Return the value of a positional parameter. This handles values > 10. */
2293 get_dollar_var_value (ind
)
2300 temp
= dollar_vars
[ind
] ? savestring (dollar_vars
[ind
]) : (char *)NULL
;
2301 else /* We want something like ${11} */
2304 for (p
= rest_of_args
; p
&& ind
--; p
= p
->next
)
2306 temp
= p
? savestring (p
->word
->word
) : (char *)NULL
;
2311 #if defined (PROCESS_SUBSTITUTION)
2313 /* **************************************************************** */
2315 /* Hacking Process Substitution */
2317 /* **************************************************************** */
2319 #if !defined (HAVE_DEV_FD)
2320 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
2321 of FIFOs the shell has open. unlink_fifo_list will walk the list and
2322 unlink all of them. add_fifo_list adds the name of an open FIFO to the
2323 list. NFIFO is a count of the number of FIFOs in the list. */
2324 #define FIFO_INCR 20
2325 extern char *mktemp ();
2327 static char **fifo_list
= (char **)NULL
;
2329 static int fifo_list_size
;
2332 add_fifo_list (pathname
)
2335 if (nfifo
>= fifo_list_size
- 1)
2337 fifo_list_size
+= FIFO_INCR
;
2338 fifo_list
= (char **)xrealloc (fifo_list
,
2339 fifo_list_size
* sizeof (char *));
2342 fifo_list
[nfifo
++] = savestring (pathname
);
2353 unlink (fifo_list
[nfifo
]);
2354 free (fifo_list
[nfifo
]);
2355 fifo_list
[nfifo
] = (char *)NULL
;
2365 tname
= mktemp (savestring ("/tmp/sh-np-XXXXXX"));
2366 if (mkfifo (tname
, 0600) < 0)
2369 return ((char *)NULL
);
2372 add_fifo_list (tname
);
2376 #else /* HAVE_DEV_FD */
2378 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
2379 has open to children. NFDS is a count of the number of bits currently
2380 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
2382 static char *dev_fd_list
= (char *)NULL
;
2384 static int totfds
; /* The highest possible number of open files. */
2390 if (!dev_fd_list
|| fd
>= totfds
)
2395 totfds
= getdtablesize ();
2396 if (totfds
< 0 || totfds
> 256)
2401 dev_fd_list
= xrealloc (dev_fd_list
, totfds
);
2402 bzero (dev_fd_list
+ ofds
, totfds
- ofds
);
2405 dev_fd_list
[fd
] = 1;
2417 for (i
= 0; nfds
&& i
< totfds
; i
++)
2428 #if defined (NOTDEF)
2429 print_dev_fd_list ()
2433 fprintf (stderr
, "pid %d: dev_fd_list:", getpid ());
2436 for (i
= 0; i
< totfds
; i
++)
2439 fprintf (stderr
, " %d", i
);
2441 fprintf (stderr
, "\n");
2446 make_dev_fd_filename (fd
)
2451 ret
= xmalloc (sizeof (DEV_FD_PREFIX
) + 4);
2452 sprintf (ret
, "%s%d", DEV_FD_PREFIX
, fd
);
2457 #endif /* HAVE_DEV_FD */
2459 /* Return a filename that will open a connection to the process defined by
2460 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
2461 a filename in /dev/fd corresponding to a descriptor that is one of the
2462 ends of the pipe. If not defined, we use named pipes on systems that have
2463 them. Systems without /dev/fd and named pipes are out of luck.
2465 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
2466 use the read end of the pipe and dup that file descriptor to fd 0 in
2467 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
2468 writing or use the write end of the pipe in the child, and dup that
2469 file descriptor to fd 1 in the child. The parent does the opposite. */
2472 process_substitute (string
, open_for_read_in_child
)
2474 int open_for_read_in_child
;
2479 #if defined (HAVE_DEV_FD)
2480 int parent_pipe_fd
, child_pipe_fd
;
2482 #endif /* HAVE_DEV_FD */
2483 #if defined (JOB_CONTROL)
2484 pid_t old_pipeline_pgrp
;
2487 if (!string
|| !*string
)
2488 return ((char *)NULL
);
2490 #if !defined (HAVE_DEV_FD)
2491 pathname
= make_named_pipe ();
2492 #else /* HAVE_DEV_FD */
2493 if (pipe (fildes
) < 0)
2495 sys_error ("cannot make pipe for process substitution");
2496 return ((char *)NULL
);
2498 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
2499 the pipe in the parent, otherwise the read end. */
2500 parent_pipe_fd
= fildes
[open_for_read_in_child
];
2501 child_pipe_fd
= fildes
[1 - open_for_read_in_child
];
2502 /* Move the parent end of the pipe to some high file descriptor, to
2503 avoid clashes with FDs used by the script. */
2504 parent_pipe_fd
= move_to_high_fd (parent_pipe_fd
, 1, 64);
2506 pathname
= make_dev_fd_filename (parent_pipe_fd
);
2507 #endif /* HAVE_DEV_FD */
2511 sys_error ("cannot make pipe for process substitution");
2512 return ((char *)NULL
);
2515 old_pid
= last_made_pid
;
2517 #if defined (JOB_CONTROL)
2518 old_pipeline_pgrp
= pipeline_pgrp
;
2519 pipeline_pgrp
= shell_pgrp
;
2521 cleanup_the_pipeline ();
2525 #endif /* JOB_CONTROL */
2527 pid
= make_child ((char *)NULL
, 1);
2530 reset_terminating_signals (); /* XXX */
2531 /* Cancel traps, in trap.c. */
2532 restore_original_signals ();
2533 setup_async_signals ();
2534 subshell_environment
= SUBSHELL_COMSUB
;
2537 #if defined (JOB_CONTROL)
2538 set_sigchld_handler ();
2539 stop_making_children ();
2540 pipeline_pgrp
= old_pipeline_pgrp
;
2541 #endif /* JOB_CONTROL */
2545 sys_error ("cannot make child for process substitution");
2547 #if defined (HAVE_DEV_FD)
2548 close (parent_pipe_fd
);
2549 close (child_pipe_fd
);
2550 #endif /* HAVE_DEV_FD */
2551 return ((char *)NULL
);
2556 #if defined (JOB_CONTROL)
2557 restore_pipeline (1);
2560 last_made_pid
= old_pid
;
2562 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
2564 #endif /* JOB_CONTROL && PGRP_PIPE */
2566 #if defined (HAVE_DEV_FD)
2567 close (child_pipe_fd
);
2568 #endif /* HAVE_DEV_FD */
2573 set_sigint_handler ();
2575 #if defined (JOB_CONTROL)
2576 set_job_control (0);
2577 #endif /* JOB_CONTROL */
2579 #if !defined (HAVE_DEV_FD)
2580 /* Open the named pipe in the child. */
2581 fd
= open (pathname
, open_for_read_in_child
? O_RDONLY
|O_NONBLOCK
: O_WRONLY
);
2584 sys_error ("cannot open named pipe %s for %s", pathname
,
2585 open_for_read_in_child
? "reading" : "writing");
2588 #else /* HAVE_DEV_FD */
2590 #endif /* HAVE_DEV_FD */
2592 if (dup2 (fd
, open_for_read_in_child
? 0 : 1) < 0)
2594 sys_error ("cannot duplicate named pipe %s as fd %d", pathname
,
2595 open_for_read_in_child
? 0 : 1);
2601 /* Need to close any files that this process has open to pipes inherited
2603 if (current_fds_to_close
)
2605 close_fd_bitmap (current_fds_to_close
);
2606 current_fds_to_close
= (struct fd_bitmap
*)NULL
;
2609 #if defined (HAVE_DEV_FD)
2610 /* Make sure we close the parent's end of the pipe and clear the slot
2611 in the fd list so it is not closed later, if reallocated by, for
2612 instance, pipe(2). */
2613 close (parent_pipe_fd
);
2614 dev_fd_list
[parent_pipe_fd
] = 0;
2615 #endif /* HAVE_DEV_FD */
2617 result
= parse_and_execute (string
, "process substitution", (SEVAL_NONINT
|SEVAL_NOHIST
));
2619 #if !defined (HAVE_DEV_FD)
2620 /* Make sure we close the named pipe in the child before we exit. */
2621 close (open_for_read_in_child
? 0 : 1);
2622 #endif /* !HAVE_DEV_FD */
2627 #endif /* PROCESS_SUBSTITUTION */
2630 read_comsub (fd
, quoted
)
2633 char *istring
, buf
[128], *bufp
;
2634 int bufn
, istring_index
, istring_size
, c
;
2636 istring
= (char *)NULL
;
2637 istring_index
= istring_size
= bufn
= 0;
2639 /* Read the output of the command through the pipe. */
2646 while ((bufn
= read (fd
, buf
, sizeof(buf
))) < 0 && errno
== EINTR
)
2654 /* Add the character to ISTRING, possibly after resizing it. */
2655 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 2, istring_size
, DEFAULT_ARRAY_SIZE
);
2657 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || c
== CTLESC
|| c
== CTLNUL
)
2658 istring
[istring_index
++] = CTLESC
;
2660 istring
[istring_index
++] = c
;
2664 istring
[istring_index
] = '\0';
2666 /* If we read no output, just return now and save ourselves some
2668 if (istring_index
== 0)
2671 return (char *)NULL
;
2674 /* Strip trailing newlines from the output of the command. */
2675 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
2677 while (istring_index
> 0)
2679 if (istring
[istring_index
- 1] == '\n')
2683 /* If the newline was quoted, remove the quoting char. */
2684 if (istring
[istring_index
- 1] == CTLESC
)
2690 istring
[istring_index
] = '\0';
2693 strip_trailing (istring
, istring_index
- 1, 1);
2698 /* Perform command substitution on STRING. This returns a string,
2701 command_substitute (string
, quoted
)
2705 pid_t pid
, old_pid
, old_pipeline_pgrp
;
2707 int result
, fildes
[2];
2709 istring
= (char *)NULL
;
2711 /* Don't fork () if there is no need to. In the case of no command to
2712 run, just return NULL. */
2713 if (!string
|| !*string
|| (string
[0] == '\n' && !string
[1]))
2714 return ((char *)NULL
);
2716 /* Pipe the output of executing STRING into the current shell. */
2717 if (pipe (fildes
) < 0)
2719 sys_error ("cannot make pipes for command substitution");
2723 old_pid
= last_made_pid
;
2724 #if defined (JOB_CONTROL)
2725 old_pipeline_pgrp
= pipeline_pgrp
;
2726 pipeline_pgrp
= shell_pgrp
;
2727 cleanup_the_pipeline ();
2730 pid
= make_child ((char *)NULL
, 0);
2732 /* Reset the signal handlers in the child, but don't free the
2734 reset_signal_handlers ();
2736 #if defined (JOB_CONTROL)
2737 set_sigchld_handler ();
2738 stop_making_children ();
2739 pipeline_pgrp
= old_pipeline_pgrp
;
2740 #endif /* JOB_CONTROL */
2744 sys_error ("cannot make child for command substitution");
2750 return ((char *)NULL
);
2755 set_sigint_handler (); /* XXX */
2756 #if defined (JOB_CONTROL)
2757 set_job_control (0);
2759 if (dup2 (fildes
[1], 1) < 0)
2761 sys_error ("command_substitute: cannot duplicate pipe as fd 1");
2762 exit (EXECUTION_FAILURE
);
2765 /* If standard output is closed in the parent shell
2766 (such as after `exec >&-'), file descriptor 1 will be
2767 the lowest available file descriptor, and end up in
2768 fildes[0]. This can happen for stdin and stderr as well,
2769 but stdout is more important -- it will cause no output
2770 to be generated from this command. */
2771 if ((fildes
[1] != fileno (stdin
)) &&
2772 (fildes
[1] != fileno (stdout
)) &&
2773 (fildes
[1] != fileno (stderr
)))
2776 if ((fildes
[0] != fileno (stdin
)) &&
2777 (fildes
[0] != fileno (stdout
)) &&
2778 (fildes
[0] != fileno (stderr
)))
2781 /* The currently executing shell is not interactive. */
2784 /* This is a subshell environment. */
2785 subshell_environment
= SUBSHELL_COMSUB
;
2787 /* Command substitution does not inherit the -e flag. */
2788 exit_immediately_on_error
= 0;
2790 remove_quoted_escapes (string
);
2792 startup_state
= 2; /* see if we can avoid a fork */
2793 /* Give command substitution a place to jump back to on failure,
2794 so we don't go back up to main (). */
2795 result
= setjmp (top_level
);
2797 if (result
== EXITPROG
)
2798 exit (last_command_exit_value
);
2800 exit (EXECUTION_FAILURE
);
2802 exit (parse_and_execute (string
, "command substitution", SEVAL_NOHIST
));
2806 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
2808 #endif /* JOB_CONTROL && PGRP_PIPE */
2812 istring
= read_comsub (fildes
[0], quoted
);
2816 last_command_exit_value
= wait_for (pid
);
2817 last_command_subst_pid
= pid
;
2818 last_made_pid
= old_pid
;
2820 #if defined (JOB_CONTROL)
2821 /* If last_command_exit_value > 128, then the substituted command
2822 was terminated by a signal. If that signal was SIGINT, then send
2823 SIGINT to ourselves. This will break out of loops, for instance. */
2824 if (last_command_exit_value
== (128 + SIGINT
))
2825 kill (getpid (), SIGINT
);
2827 /* wait_for gives the terminal back to shell_pgrp. If some other
2828 process group should have it, give it away to that group here. */
2829 if (interactive
&& pipeline_pgrp
!= (pid_t
)0)
2830 give_terminal_to (pipeline_pgrp
);
2831 #endif /* JOB_CONTROL */
2837 /********************************************************
2839 * Utility functions for parameter expansion *
2841 ********************************************************/
2844 getpatspec (c
, value
)
2849 return ((*value
== '#') ? RP_LONG_LEFT
: RP_SHORT_LEFT
);
2851 return ((*value
== '%') ? RP_LONG_RIGHT
: RP_SHORT_RIGHT
);
2854 /* Posix.2 says that the WORD should be run through tilde expansion,
2855 parameter expansion, command substitution and arithmetic expansion.
2856 This leaves the result quoted, so quote_string_for_globbing () has
2857 to be called to fix it up for fnmatch (). If QUOTED is non-zero,
2858 it means that the entire expression was enclosed in double quotes.
2859 This means that quoting characters in the pattern do not make any
2860 special pattern characters quoted. For example, the `*' in the
2861 following retains its special meaning: "${foo#'*'}". */
2863 getpattern (value
, quoted
, expandpat
)
2865 int quoted
, expandpat
;
2871 tword
= strchr (value
, '~') ? bash_tilde_expand (value
) : savestring (value
);
2873 /* expand_string_internal () leaves WORD quoted and does not perform
2875 if (expandpat
&& (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *tword
)
2878 pat
= string_extract_double_quoted (tword
, &i
, 1);
2883 /* There is a problem here: how to handle single or double quotes in the
2884 pattern string when the whole expression is between double quotes? */
2886 l
= *tword
? expand_string_for_rhs (tword
, quoted
, (int *)NULL
, (int *)NULL
)
2888 l
= *tword
? expand_string_for_rhs (tword
,
2889 (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? Q_NOQUOTE
: quoted
,
2890 (int *)NULL
, (int *)NULL
)
2894 pat
= string_list (l
);
2898 tword
= quote_string_for_globbing (pat
, 1);
2905 /* Handle removing a pattern from a string as a result of ${name%[%]value}
2906 or ${name#[#]value}. */
2908 parameter_brace_remove_pattern (value
, temp
, c
, quoted
)
2913 char *pattern
, *tword
;
2915 patspec
= getpatspec (c
, value
);
2916 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
2919 pattern
= getpattern (value
, quoted
, 1);
2921 tword
= remove_pattern (temp
, pattern
, patspec
);
2928 list_remove_pattern (list
, pattern
, patspec
, type
, quoted
)
2931 int patspec
, type
, quoted
;
2937 for (new = (WORD_LIST
*)NULL
, l
= list
; l
; l
= l
->next
)
2939 tword
= remove_pattern (l
->word
->word
, pattern
, patspec
);
2940 w
= make_bare_word (tword
);
2942 new = make_word_list (w
, new);
2945 l
= REVERSE_LIST (new, WORD_LIST
*);
2947 tword
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? string_list_dollar_star (l
) : string_list (l
);
2949 tword
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (l
) : l
);
2956 parameter_list_remove_pattern (value
, type
, c
, quoted
)
2958 int type
, c
, quoted
;
2961 char *pattern
, *ret
;
2964 patspec
= getpatspec (c
, value
);
2965 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
2968 pattern
= getpattern (value
, quoted
, 1);
2970 list
= list_rest_of_args ();
2971 ret
= list_remove_pattern (list
, pattern
, patspec
, type
, quoted
);
2972 dispose_words (list
);
2977 #if defined (ARRAY_VARS)
2979 array_remove_pattern (value
, aspec
, aval
, c
, quoted
)
2980 char *value
, *aspec
, *aval
; /* AVAL == evaluated ASPEC */
2988 char *ret
, *t
, *pattern
;
2991 var
= array_variable_part (aspec
, &t
, &len
);
2993 return ((char *)NULL
);
2995 patspec
= getpatspec (c
, value
);
2996 if (patspec
== RP_LONG_LEFT
|| patspec
== RP_LONG_RIGHT
)
2999 pattern
= getpattern (value
, quoted
, 1);
3001 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
3003 if (array_p (var
) == 0)
3005 report_error ("%s: bad array subscript", aspec
);
3007 return ((char *)NULL
);
3009 l
= array_to_word_list (array_cell (var
));
3011 return ((char *)NULL
);
3012 ret
= list_remove_pattern (l
, pattern
, patspec
, t
[0], quoted
);
3018 ind
= array_expand_index (t
, len
);
3021 report_error ("%s: bad array subscript", aspec
);
3023 return ((char *)NULL
);
3025 if (array_p (var
) == 0 && ind
!= 0)
3026 return ((char *)NULL
);
3028 t
= array_p (var
) ? array_reference (array_cell (var
), ind
) : value_cell (var
);
3029 ret
= remove_pattern (t
, pattern
, patspec
);
3031 ret
= remove_pattern (aval
, pattern
, patspec
);
3035 t
= quote_escapes (ret
);
3046 valid_array_reference (name
)
3052 t
= strchr (name
, '[');
3056 r
= legal_identifier (name
);
3060 /* Check for a properly-terminated non-blank subscript. */
3061 len
= skipsubscript (t
, 0);
3062 if (t
[len
] != ']' || len
== 1)
3064 for (r
= 1; r
< len
; r
++)
3065 if (whitespace (t
[r
]) == 0)
3072 /* Expand the array index beginning at S and extending LEN characters. */
3074 array_expand_index (s
, len
)
3081 exp
= xmalloc (len
);
3082 strncpy (exp
, s
, len
- 1);
3083 exp
[len
- 1] = '\0';
3084 t
= maybe_expand_string (exp
, 0, expand_string
);
3085 this_command_name
= (char *)NULL
;
3086 val
= evalexp (t
, &expok
);
3090 jump_to_top_level (DISCARD
);
3094 /* Return the variable specified by S without any subscript. If non-null,
3095 return the index of the start of the subscript in *SUBP. If non-null,
3096 the length of the subscript is returned in *LENP. */
3098 array_variable_part (s
, subp
, lenp
)
3106 t
= strchr (s
, '[');
3108 ni
= skipsubscript (s
, ind
);
3109 if (ni
<= ind
+ 1 || s
[ni
] != ']')
3111 report_error ("%s: bad array subscript", s
);
3112 return ((SHELL_VAR
*)NULL
);
3116 var
= find_variable (s
);
3127 array_value_internal (s
, quoted
, allow_all
)
3129 int quoted
, allow_all
;
3136 var
= array_variable_part (s
, &t
, &len
);
3139 return (char *)NULL
;
3141 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
3143 if (array_p (var
) == 0 || allow_all
== 0)
3145 report_error ("%s: bad array subscript", s
);
3146 return ((char *)NULL
);
3148 l
= array_to_word_list (array_cell (var
));
3149 if (l
== (WORD_LIST
*)NULL
)
3150 return ((char *) NULL
);
3152 if (t
[0] == '*') /* ${name[*]} */
3153 retval
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? string_list_dollar_star (l
) : string_list (l
);
3154 else /* ${name[@]} */
3155 retval
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (l
) : l
);
3161 ind
= array_expand_index (t
, len
);
3164 report_error ("%s: bad array subscript", var
->name
);
3165 return ((char *)NULL
);
3167 if (array_p (var
) == 0)
3168 return (ind
== 0 ? savestring (value_cell (var
)) : (char *)NULL
);
3169 retval
= array_reference (array_cell (var
), ind
);
3171 retval
= quote_escapes (retval
);
3178 array_value (s
, quoted
)
3182 return (array_value_internal (s
, quoted
, 1));
3185 /* Return the value of the array indexing expression S as a single string.
3186 If ALLOW_ALL is 0, do not allow `@' and `*' subscripts. This is used
3187 by other parts of the shell such as the arithmetic expression evaluator
3190 get_array_value (s
, allow_all
)
3194 return (array_value_internal (s
, 0, allow_all
));
3198 array_length_reference (s
)
3206 var
= array_variable_part (s
, &t
, &len
);
3208 /* If unbound variables should generate an error, report one and return
3210 if ((var
== 0 || array_p (var
) == 0) && unbound_vars_is_error
)
3214 report_error ("%s: unbound variable", s
);
3220 else if (array_p (var
) == 0)
3223 array
= array_cell (var
);
3225 if (ALL_ELEMENT_SUB (t
[0]) && t
[1] == ']')
3226 return (array_num_elements (array
));
3228 ind
= array_expand_index (t
, len
);
3231 report_error ("%s: bad array subscript", t
);
3234 t
= array_reference (array
, ind
);
3239 #endif /* ARRAY_VARS */
3242 valid_brace_expansion_word (name
, var_is_special
)
3246 if (digit (*name
) && all_digits (name
))
3248 else if (var_is_special
)
3250 #if defined (ARRAY_VARS)
3251 else if (valid_array_reference (name
))
3253 #endif /* ARRAY_VARS */
3254 else if (legal_identifier (name
))
3260 /* Parameter expand NAME, and return a new string which is the expansion,
3261 or NULL if there was no expansion.
3262 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
3263 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
3264 NAME was found inside of a double-quoted expression. */
3266 parameter_brace_expand_word (name
, var_is_special
, quoted
)
3268 int var_is_special
, quoted
;
3275 /* Handle multiple digit arguments, as in ${11}. */
3278 arg_index
= atoi (name
);
3279 temp
= get_dollar_var_value (arg_index
);
3281 else if (var_is_special
) /* ${@} */
3283 tt
= xmalloc (2 + strlen (name
));
3285 strcpy (tt
+ 1, name
);
3286 l
= expand_string_leave_quoted (tt
, quoted
);
3288 temp
= string_list (l
);
3291 #if defined (ARRAY_VARS)
3292 else if (valid_array_reference (name
))
3294 temp
= array_value (name
, quoted
);
3297 else if (var
= find_variable (name
))
3299 if (var
&& invisible_p (var
) == 0)
3301 #if defined (ARRAY_VARS)
3302 temp
= array_p (var
) ? array_reference (array_cell (var
), 0) : value_cell (var
);
3304 temp
= value_cell (var
);
3308 temp
= quote_escapes (temp
);
3311 temp
= (char *)NULL
;
3314 temp
= (char *)NULL
;
3319 /* Expand an indirect reference to a variable: ${!NAME} expands to the
3320 value of the variable whose name is the value of NAME. */
3322 parameter_brace_expand_indir (name
, var_is_special
, quoted
)
3324 int var_is_special
, quoted
;
3328 t
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
3331 temp
= parameter_brace_expand_word (t
, t
[0] == '@' && t
[1] == '\0', quoted
);
3336 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
3337 depending on the value of C, the separating character. C can be one of
3338 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
3339 between double quotes. */
3341 parameter_brace_expand_rhs (name
, value
, c
, quoted
, qdollaratp
, hasdollarat
)
3343 int c
, quoted
, *qdollaratp
, *hasdollarat
;
3346 char *t
, *t1
, *temp
;
3349 temp
= (*value
== '~' || (strchr (value
, '~') && unquoted_substring ("=~", value
)))
3350 ? bash_tilde_expand (value
)
3351 : savestring (value
);
3353 /* If the entire expression is between double quotes, we want to treat
3354 the value as a double-quoted string, with the exception that we strip
3355 embedded unescaped double quotes. */
3356 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && *temp
)
3359 t
= string_extract_double_quoted (temp
, &hasdol
, 1);
3365 /* XXX was 0 not quoted */
3366 l
= *temp
? expand_string_for_rhs (temp
, quoted
, &hasdol
, (int *)NULL
)
3369 *hasdollarat
= hasdol
|| (l
&& l
->next
);
3373 /* The expansion of TEMP returned something. We need to treat things
3374 slightly differently if HASDOL is non-zero. */
3375 temp
= string_list (l
);
3376 /* If l->next is not null, we know that TEMP contained "$@", since that
3377 is the only expansion that creates more than one word. */
3378 if ((hasdol
&& quoted
) || l
->next
)
3382 else if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && hasdol
)
3384 /* The brace expansion occurred between double quotes and there was
3385 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
3386 it does not expand to anything. In this case, we want to return
3387 a quoted empty string. */
3393 temp
= (char *)NULL
;
3395 if (c
== '-' || c
== '+')
3399 t
= temp
? savestring (temp
) : savestring ("");
3400 t1
= dequote_string (t
);
3402 bind_variable (name
, t1
);
3407 /* Deal with the right hand side of a ${name:?value} expansion in the case
3408 that NAME is null or not set. If VALUE is non-null it is expanded and
3409 used as the error message to print, otherwise a standard message is
3412 parameter_brace_expand_error (name
, value
)
3418 if (value
&& *value
)
3420 l
= expand_string (value
, 0);
3421 temp
= string_list (l
);
3422 report_error ("%s: %s", name
, temp
? temp
: ""); /* XXX was value not "" */
3427 report_error ("%s: parameter null or not set", name
);
3429 /* Free the data we have allocated during this expansion, since we
3430 are about to longjmp out. */
3435 /* Return 1 if NAME is something for which parameter_brace_expand_length is
3438 valid_length_expression (name
)
3441 return (!name
[1] || /* ${#} */
3442 ((name
[1] == '@' || name
[1] == '*') && !name
[2]) || /* ${#@}, ${#*} */
3443 (digit (name
[1]) && all_digits (name
+ 1)) || /* ${#11} */
3444 #if defined (ARRAY_VARS)
3445 valid_array_reference (name
+ 1) || /* ${#a[7]} */
3447 legal_identifier (name
+ 1)); /* ${#PS1} */
3450 /* Handle the parameter brace expansion that requires us to return the
3451 length of a parameter. */
3453 parameter_brace_expand_length (name
)
3459 #if defined (ARRAY_VARS)
3463 if (name
[1] == '\0') /* ${#} */
3464 number
= number_of_args ();
3465 #if defined (ARRAY_VARS)
3466 else if (valid_array_reference (name
+ 1))
3467 number
= array_length_reference (name
+ 1);
3468 #endif /* ARRAY_VARS */
3469 else if (name
[1] != '*' && name
[1] != '@')
3473 if (digit (name
[1])) /* ${#1} */
3475 t
= get_dollar_var_value (atoi (name
+ 1));
3476 number
= STRLEN (t
);
3479 #if defined (ARRAY_VARS)
3480 else if ((var
= find_variable (name
+ 1)) && array_p (var
))
3482 t
= array_reference (array_cell (var
), 0);
3483 number
= STRLEN (t
);
3488 newname
= savestring (name
);
3490 list
= expand_string (newname
, Q_DOUBLE_QUOTES
);
3491 t
= list
? string_list (list
) : (char *)NULL
;
3494 dispose_words (list
);
3496 number
= STRLEN (t
);
3500 else /* ${#@} and ${#*} */
3501 number
= number_of_args ();
3506 /* Verify and limit the start and end of the desired substring. If
3507 VTYPE == 0, a regular shell variable is being used; if it is 1,
3508 then the positional paramters are being used; if it is 2, then
3509 VALUE is really a pointer to an array variable that should be used.
3510 Return value is 1 if both values were OK, 0 if there was a problem
3511 with an invalid expression, or -1 if the values were out of range. */
3513 verify_substring_values (value
, substr
, vtype
, e1p
, e2p
)
3514 char *value
, *substr
;
3515 int vtype
, *e1p
, *e2p
;
3519 #if defined (ARRAY_VARS)
3523 t
= strchr (substr
, ':');
3526 temp1
= maybe_expand_string (substr
, Q_DOUBLE_QUOTES
, expand_string
);
3527 *e1p
= evalexp (temp1
, &expok
);
3535 case VT_ARRAYMEMBER
:
3536 len
= strlen (value
);
3539 len
= number_of_args () + 1;
3541 #if defined (ARRAY_VARS)
3544 len
= array_num_elements (a
) + 1;
3549 if (*e1p
< 0) /* negative offsets count from end */
3552 if (*e1p
>= len
|| *e1p
< 0)
3558 temp1
= maybe_expand_string (t
, Q_DOUBLE_QUOTES
, expand_string
);
3560 *e2p
= evalexp (temp1
, &expok
);
3566 internal_error ("%s: substring expression < 0", t
);
3569 *e2p
+= *e1p
; /* want E2 chars starting at E1 */
3579 /* Return a string containing the positional parameters from START to
3580 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
3581 which only makes a difference if QUOTED is non-zero. */
3583 pos_params (string
, start
, end
, quoted
)
3585 int start
, end
, quoted
;
3587 WORD_LIST
*save
, *params
, *h
, *t
;
3591 save
= params
= list_rest_of_args ();
3593 return ((char *)NULL
);
3595 for (i
= 1; params
&& i
< start
; i
++)
3596 params
= params
->next
;
3598 return ((char *)NULL
);
3599 for (h
= t
= params
; params
&& i
< end
; i
++)
3602 params
= params
->next
;
3605 t
->next
= (WORD_LIST
*)NULL
;
3606 if (string
[0] == '*')
3607 ret
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? string_list_dollar_star (h
) : string_list (h
);
3609 ret
= string_list ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) ? quote_list (h
) : h
);
3612 dispose_words (save
);
3616 /* Return the type of variable specified by VARNAME (simple variable,
3617 positional param, or array variable. Also return the value specified
3618 by VARNAME (value of a variable or a reference to an array element). */
3620 get_var_and_type (varname
, value
, varp
, valp
)
3621 char *varname
, *value
;
3627 #if defined (ARRAY_VARS)
3631 vtype
= (varname
[0] == '@' || varname
[0] == '*') && varname
[1] == '\0'; /* VT_POSPARMS */
3632 *varp
= (SHELL_VAR
*)NULL
;
3634 #if defined (ARRAY_VARS)
3635 if (valid_array_reference (varname
))
3637 v
= array_variable_part (varname
, &temp
, (int *)0);
3638 if (v
&& array_p (v
))
3640 if ((temp
[0] == '@' || temp
[0] == '*') && temp
[1] == ']')
3642 vtype
= VT_ARRAYVAR
;
3643 *valp
= (char *)array_cell (v
);
3647 vtype
= VT_ARRAYMEMBER
;
3648 *valp
= array_value (varname
, 1);
3655 else if ((v
= find_variable (varname
)) && array_p (v
))
3657 vtype
= VT_VARIABLE
;
3659 *valp
= array_reference (array_cell (v
), 0);
3668 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
3669 is `@', use the positional parameters; otherwise, use the value of
3670 VARNAME. If VARNAME is an array variable, use the array elements. */
3673 parameter_brace_substring (varname
, value
, substr
, quoted
)
3674 char *varname
, *value
, *substr
;
3677 int e1
, e2
, vtype
, r
;
3682 return ((char *)NULL
);
3684 this_command_name
= varname
;
3686 vtype
= get_var_and_type (varname
, value
, &v
, &val
);
3688 return ((char *)NULL
);
3690 r
= verify_substring_values (val
, substr
, vtype
, &e1
, &e2
);
3693 if (val
&& vtype
== VT_ARRAYMEMBER
)
3695 return ((r
== 0) ? &expand_param_error
: (char *)NULL
);
3701 case VT_ARRAYMEMBER
:
3702 temp
= quoted
? quoted_substring (value
, e1
, e2
) : substring (value
, e1
, e2
);
3705 temp
= pos_params (varname
, e1
, e2
, quoted
);
3707 #if defined (ARRAY_VARS)
3709 temp
= array_subrange (array_cell (v
), e1
, e2
, quoted
);
3718 pat_subst (string
, pat
, rep
, mflags
)
3719 char *string
, *pat
, *rep
;
3722 char *ret
, *s
, *e
, *str
;
3723 int rsize
, rptr
, l
, replen
, mtype
;
3725 ret
= xmalloc (rsize
= 64);
3728 mtype
= mflags
& MATCH_TYPEMASK
;
3730 for (replen
= STRLEN (rep
), rptr
= 0, str
= string
;;)
3732 if (match_pattern (str
, pat
, mtype
, &s
, &e
) == 0)
3735 RESIZE_MALLOCED_BUFFER (ret
, rptr
, (l
+ replen
), rsize
, 64);
3737 /* OK, now copy the leading unmatched portion of the string (from
3738 str to s) to ret starting at rptr (the current offset). Then copy
3739 the replacement string at ret + rptr + (s - str). Increment
3740 rptr (if necessary) and str and go on. */
3743 strncpy (ret
+ rptr
, str
, l
);
3748 strncpy (ret
+ rptr
, rep
, replen
);
3751 str
= e
; /* e == end of match */
3752 if (((mflags
& MATCH_GLOBREP
) == 0) || mtype
!= MATCH_ANY
)
3756 /* Now copy the unmatched portion of the input string */
3759 RESIZE_MALLOCED_BUFFER (ret
, rptr
, STRLEN(str
) + 1, rsize
, 64);
3760 strcpy (ret
+ rptr
, str
);
3768 /* Do pattern match and replacement on the positional parameters. */
3770 pos_params_pat_subst (string
, pat
, rep
, mflags
)
3771 char *string
, *pat
, *rep
;
3774 WORD_LIST
*save
, *params
;
3778 save
= params
= list_rest_of_args ();
3780 return ((char *)NULL
);
3782 for ( ; params
; params
= params
->next
)
3784 ret
= pat_subst (params
->word
->word
, pat
, rep
, mflags
);
3785 w
= make_bare_word (ret
);
3786 dispose_word (params
->word
);
3791 ret
= string_list ((mflags
& MATCH_QUOTED
) ? quote_list (save
) : save
);
3792 dispose_words (save
);
3798 parameter_brace_patsub (varname
, value
, patsub
, quoted
)
3799 char *varname
, *value
, *patsub
;
3803 char *val
, *temp
, *pat
, *rep
, *p
;
3807 return ((char *)NULL
);
3809 this_command_name
= varname
;
3811 vtype
= get_var_and_type (varname
, value
, &v
, &val
);
3813 return ((char *)NULL
);
3818 mflags
|= MATCH_GLOBREP
;
3822 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
3823 mflags
|= MATCH_QUOTED
;
3825 if (rep
= quoted_strchr (patsub
, '/', ST_BACKSL
))
3830 if (rep
&& *rep
== '\0')
3833 /* Expand PAT and REP for command, variable and parameter, arithmetic,
3834 and process substitution. Also perform quote removal. Do not
3835 perform word splitting or filename generation. */
3836 pat
= maybe_expand_string (patsub
, quoted
, expand_string_unsplit
);
3839 if ((mflags
& MATCH_QUOTED
) == 0)
3840 rep
= maybe_expand_string (rep
, quoted
, expand_string_unsplit
);
3842 rep
= expand_string_to_string (rep
, quoted
, expand_string_unsplit
);
3846 if (pat
&& pat
[0] == '#')
3848 mflags
|= MATCH_BEG
;
3851 else if (pat
&& pat
[0] == '%')
3853 mflags
|= MATCH_END
;
3857 mflags
|= MATCH_ANY
;
3859 /* OK, we now want to substitute REP for PAT in VAL. If GLOBAL is 1,
3860 the substitution is done everywhere, otherwise only the first
3861 occurrence of PAT is replaced. */
3865 case VT_ARRAYMEMBER
:
3866 temp
= pat_subst (val
, p
, rep
, mflags
);
3869 temp
= pos_params_pat_subst (val
, p
, rep
, mflags
);
3871 #if defined (ARRAY_VARS)
3873 temp
= array_pat_subst (array_cell (v
), p
, rep
, mflags
);
3878 if (val
&& v
&& array_p (v
) && vtype
== VT_ARRAYMEMBER
)
3887 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
3889 parameter_brace_expand (string
, indexp
, quoted
, quoted_dollar_atp
, contains_dollar_at
)
3891 int *indexp
, quoted
, *quoted_dollar_atp
, *contains_dollar_at
;
3893 int check_nullness
, var_is_set
, var_is_null
, var_is_special
;
3894 int want_substring
, want_indir
, want_patsub
;
3895 char *name
, *value
, *temp
, *temp1
;
3896 int t_index
, sindex
, c
, number
;
3900 name
= string_extract (string
, &t_index
, "#%:-=?+/}", 1);
3901 value
= (char *)NULL
;
3902 var_is_set
= var_is_null
= var_is_special
= check_nullness
= 0;
3903 want_substring
= want_indir
= want_patsub
= 0;
3905 /* If the name really consists of a special variable, then
3906 make sure that we have the entire name. Handle indirect
3907 references to special variables here, too. */
3908 if ((sindex
== t_index
||
3909 ((sindex
== t_index
- 1) && string
[sindex
] == '!')) &&
3910 (string
[t_index
] == '-' ||
3911 string
[t_index
] == '?' ||
3912 string
[t_index
] == '#'))
3916 temp1
= string_extract (string
, &t_index
, "#%:-=?+/}", 0);
3917 name
= xmalloc (3 + (strlen (temp1
)));
3918 *name
= string
[sindex
];
3919 if (string
[sindex
] == '!')
3921 /* indirect ref. of special variable */
3922 name
[1] = string
[sindex
+ 1];
3923 strcpy (name
+ 2, temp1
);
3926 strcpy (name
+ 1, temp1
);
3931 /* Find out what character ended the variable name. Then
3932 do the appropriate thing. */
3933 if (c
= string
[sindex
])
3936 /* If c is followed by one of the valid parameter expansion
3937 characters, move past it as normal. If not, assume that
3938 a substring specification is being given, and do not move
3940 if (c
== ':' && member (string
[sindex
], "-=?+"))
3943 if (c
= string
[sindex
])
3951 want_indir
= *name
== '!';
3953 /* Determine the value of this variable. */
3955 /* Check for special variables, directly and indirectly
3957 if ((digit (*name
) && all_digits (name
)) ||
3958 (name
[1] == '\0' && member (*name
, "#-?$!@*")) ||
3959 (want_indir
&& name
[2] == '\0' && member (name
[1], "#-?$!@*")))
3962 /* Check for special expansion things. */
3963 if (*name
== '#') /* length of a parameter */
3965 /* Take the lengths of some of the shell's special
3967 if (string
[sindex
] == '}' && name
[1] == '\0' &&
3968 check_nullness
== 0 && member (c
, "-?$!#"))
3974 temp1
= which_set_flags ();
3977 temp1
= itos (last_command_exit_value
);
3980 temp1
= itos (dollar_dollar_pid
);
3983 if (last_asynchronous_pid
== NO_PID
)
3984 temp1
= (char *)NULL
;
3986 temp1
= itos ((int)last_asynchronous_pid
);
3989 temp1
= itos (number_of_args ());
3992 number
= STRLEN (temp1
);
3994 *indexp
= ++sindex
; /* { string[sindex] == '}' */
3995 return (itos (number
));
3998 /* Don't allow things like ${#:-foo} to go by; they are
3999 errors. If we are not pointing at the character just
4000 after the closing brace, then we haven't gotten all of
4001 the name. Since it begins with a special character,
4002 this is a bad substitution. Explicitly check for ${#:},
4003 which the rules do not catch. Also check NAME for
4004 validity before trying to go on. */
4005 if (string
[sindex
- 1] != '}' ||
4006 member (c
, "?-=+") ||
4007 (name
[1] == '\0' && c
== '}' && check_nullness
) ||
4008 (valid_length_expression (name
) == 0))
4010 temp
= (char *)NULL
;
4011 goto bad_substitution
;
4014 number
= parameter_brace_expand_length (name
);
4018 return ((number
< 0) ? &expand_param_error
: itos (number
));
4021 /* ${@} is identical to $@. */
4022 if (name
[0] == '@' && name
[1] == '\0')
4024 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4025 *quoted_dollar_atp
= 1;
4027 if (contains_dollar_at
)
4028 *contains_dollar_at
= 1;
4031 /* Make sure that NAME is valid before trying to go on. */
4032 if (valid_brace_expansion_word (want_indir
? name
+ 1 : name
,
4033 var_is_special
) == 0)
4035 temp
= (char *)NULL
;
4036 goto bad_substitution
;
4040 temp
= parameter_brace_expand_indir (name
+ 1, var_is_special
, quoted
);
4042 temp
= parameter_brace_expand_word (name
, var_is_special
, quoted
);
4044 #if defined (ARRAY_VARS)
4045 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && valid_array_reference (name
))
4047 temp1
= strchr (name
, '[');
4048 if (temp1
&& temp1
[1] == '@' && temp1
[2] == ']')
4050 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && quoted_dollar_atp
)
4051 *quoted_dollar_atp
= 1;
4052 if (contains_dollar_at
)
4053 *contains_dollar_at
= 1;
4058 var_is_set
= temp
!= (char *)0;
4059 var_is_null
= check_nullness
&& (var_is_set
== 0 || *temp
== 0);
4061 /* Get the rest of the stuff inside the braces. */
4064 /* Extract the contents of the ${ ... } expansion
4065 according to the Posix.2 rules. */
4066 value
= extract_dollar_brace_string (string
, &sindex
, quoted
);
4068 if (string
[sindex
] == '}')
4071 goto bad_substitution
;
4074 value
= (char *)NULL
;
4078 /* If this is a substring spec, process it and add the result. */
4081 temp1
= parameter_brace_substring (name
, temp
, value
, quoted
);
4087 else if (want_patsub
)
4089 temp1
= parameter_brace_patsub (name
, temp
, value
, quoted
);
4096 /* Do the right thing based on which character ended the variable name. */
4102 report_error ("%s: bad substitution", string
? string
: "??");
4106 return &expand_param_error
;
4110 if (var_is_set
== 0 && unbound_vars_is_error
)
4112 report_error ("%s: unbound variable", name
);
4116 last_command_exit_value
= EXECUTION_FAILURE
;
4117 return (interactive_shell
? &expand_param_error
: &expand_param_fatal
);
4121 case '#': /* ${param#[#]pattern} */
4122 case '%': /* ${param%[%]pattern} */
4123 if (value
== 0 || *value
== '\0' || temp
== 0 || *temp
== '\0')
4128 if ((name
[0] == '@' || name
[0] == '*') && name
[1] == '\0')
4129 temp1
= parameter_list_remove_pattern (value
, name
[0], c
, quoted
);
4130 #if defined (ARRAY_VARS)
4131 else if (valid_array_reference (name
))
4132 temp1
= array_remove_pattern (value
, name
, temp
, c
, quoted
);
4135 temp1
= parameter_brace_remove_pattern (value
, temp
, c
, quoted
);
4145 if (var_is_set
&& var_is_null
== 0)
4147 /* We don't want the value of the named variable for
4148 anything, just the value of the right hand side. */
4154 temp
= parameter_brace_expand_rhs (name
, value
, c
,
4157 contains_dollar_at
);
4161 temp
= (char *)NULL
;
4167 /* Otherwise do nothing; just use the value in TEMP. */
4169 else /* VAR not set or VAR is NULL. */
4172 temp
= (char *)NULL
;
4173 if (c
== '=' && var_is_special
)
4175 report_error ("$%s: cannot assign in this way", name
);
4178 return &expand_param_error
;
4182 parameter_brace_expand_error (name
, value
);
4183 return (interactive
? &expand_param_error
: &expand_param_fatal
);
4186 temp
= parameter_brace_expand_rhs (name
, value
, c
, quoted
,
4188 contains_dollar_at
);
4197 /* Make a word list which is the parameter and variable expansion,
4198 command substitution, arithmetic substitution, and quote removed
4199 expansion of WORD. Return a pointer to a WORD_LIST which is the
4200 result of the expansion. If WORD contains a null word, the word
4201 list returned is also null.
4203 QUOTED contains flag values defined in shell.h.
4205 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
4206 they point to an integer value which receives information about expansion.
4207 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
4208 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
4211 This only does word splitting in the case of $@ expansion. In that
4212 case, we split on ' '. */
4214 /* Values for the local variable quoted_state. */
4216 #define PARTIALLY_QUOTED 1
4217 #define WHOLLY_QUOTED 2
4220 expand_word_internal (word
, quoted
, contains_dollar_at
, expanded_something
)
4223 int *contains_dollar_at
;
4224 int *expanded_something
;
4230 /* The intermediate string that we build while expanding. */
4233 /* The current size of the above object. */
4236 /* Index into ISTRING. */
4239 /* Temporary string storage. */
4242 /* The text of WORD. */
4243 register char *string
;
4245 /* The index into STRING. */
4248 /* This gets 1 if we see a $@ while quoted. */
4249 int quoted_dollar_at
;
4251 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
4252 whether WORD contains no quoting characters, a partially quoted
4253 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
4256 int had_quoted_null
;
4260 register int c
; /* Current character. */
4261 int number
; /* Temporary number value. */
4262 int t_index
; /* For calls to string_extract_xxx. */
4264 istring
= xmalloc (istring_size
= DEFAULT_INITIAL_ARRAY_SIZE
);
4265 istring
[istring_index
= 0] = '\0';
4267 quoted_dollar_at
= had_quoted_null
= 0;
4268 quoted_state
= UNQUOTED
;
4270 string
= word
->word
;
4272 goto finished_with_string
;
4274 if (contains_dollar_at
)
4275 *contains_dollar_at
= 0;
4277 /* Begin the expansion. */
4283 /* Case on toplevel character. */
4287 goto finished_with_string
;
4292 temp
[1] = c
= string
[++sindex
];
4300 #if defined (PROCESS_SUBSTITUTION)
4301 /* Process substitution. */
4305 if (string
[++sindex
] != '(' || (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || posixly_correct
)
4311 t_index
= sindex
+ 1; /* skip past both '<' and '(' */
4313 temp1
= extract_process_subst (string
, (c
== '<') ? "<(" : ">(", &t_index
);
4316 /* If the process substitution specification is `<()', we want to
4317 open the pipe for writing in the child and produce output; if
4318 it is `>()', we want to open the pipe for reading in the child
4319 and consume input. */
4320 temp
= temp1
? process_substitute (temp1
, (c
== '>')) : (char *)0;
4324 goto dollar_add_string
;
4326 #endif /* PROCESS_SUBSTITUTION */
4328 /* See about breaking this into a separate function:
4330 param_expand (string, sindex, quoted, expanded_something,
4331 contains_dollar_at, quoted_dollar_at)
4333 int *sindex, quoted, *expanded_something, *contains_dollar_at;
4334 int *quoted_dollar_at;
4338 if (expanded_something
)
4339 *expanded_something
= 1;
4341 c
= string
[++sindex
];
4343 /* Do simple cases first. Switch on what follows '$'. */
4357 temp1
= dollar_vars
[digit_value (c
)];
4358 if (unbound_vars_is_error
&& temp1
== (char *)NULL
)
4360 report_error ("$%c: unbound variable", c
);
4363 last_command_exit_value
= EXECUTION_FAILURE
;
4364 return (interactive_shell
? &expand_word_error
: &expand_word_fatal
);
4366 temp
= temp1
? savestring (temp1
) : (char *)NULL
;
4367 goto dollar_add_string
;
4369 /* $$ -- pid of the invoking shell. */
4371 number
= dollar_dollar_pid
;
4374 temp
= itos (number
);
4376 if (string
[sindex
]) sindex
++;
4378 /* Add TEMP to ISTRING. */
4382 istring
= sub_append_string
4383 (temp
, istring
, &istring_index
, &istring_size
);
4389 /* $# -- number of positional parameters. */
4391 number
= number_of_args ();
4394 /* $? -- return value of the last synchronous command. */
4396 number
= last_command_exit_value
;
4399 /* $- -- flags supplied to the shell on invocation or
4402 temp
= which_set_flags ();
4403 goto dollar_add_string
;
4405 /* $! -- Pid of the last asynchronous command. */
4407 number
= (int)last_asynchronous_pid
;
4409 /* If no asynchronous pids have been created, expand
4411 if (number
== (int)NO_PID
)
4415 if (expanded_something
)
4416 *expanded_something
= 0;
4421 /* The only difference between this and $@ is when the
4423 case '*': /* `$*' */
4424 temp
= string_rest_of_args (quoted
);
4426 /* If there are no command-line arguments, this should just
4427 disappear if there are other characters in the expansion,
4428 even if it's quoted. */
4429 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && temp
&& *temp
== '\0')
4432 temp
= (char *)NULL
;
4434 /* In the case of a quoted string, quote the entire arg-list.
4435 "$1 $2 $3". Otherwise quote the special escape characters. */
4439 temp
= (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4440 ? quote_string (temp
)
4441 : quote_escapes (temp
);
4444 goto dollar_add_string
;
4446 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
4447 means that we have to turn quoting off after we split into
4448 the individually quoted arguments so that the final split
4449 on the first character of $IFS is still done. */
4450 case '@': /* `$@' */
4451 list
= list_rest_of_args ();
4453 /* We want to flag the fact that we saw this. We can't turn
4454 off quoting entirely, because other characters in the
4455 string might need it (consider "\"$@\""), but we need some
4456 way to signal that the final split on the first character
4457 of $IFS should be done, even though QUOTED is 1. */
4458 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4459 quoted_dollar_at
= 1;
4460 if (contains_dollar_at
)
4461 *contains_dollar_at
= 1;
4462 temp
= string_list (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && list
) ? quote_list (list
) : list
);
4463 /* If the expansion is not quoted, protect any special escape
4464 characters in the expansion by quoting them. */
4465 if (temp
&& quoted
== 0)
4468 temp
= quote_escapes (temp
);
4471 dispose_words (list
);
4472 goto dollar_add_string
;
4475 temp
= parameter_brace_expand (string
, &sindex
, quoted
,
4477 contains_dollar_at
);
4478 if (temp
== &expand_param_error
|| temp
== &expand_param_fatal
)
4482 return (temp
== &expand_param_error
) ? &expand_word_error
4483 : &expand_word_fatal
;
4486 /* quoted nulls should be removed if there is anything else
4488 /* Note that we saw the quoted null so we can add one back at
4489 the end of this function if there are no other characters
4490 in the string, discard TEMP, and go on. */
4491 if (temp
&& QUOTED_NULL (temp
))
4493 had_quoted_null
= 1;
4501 /* Do command or arithmetic substitution. */
4503 /* We have to extract the contents of this paren substitution. */
4504 t_index
= sindex
+ 1;
4505 temp
= extract_command_subst (string
, &t_index
);
4508 /* For Posix.2-style `$(( ))' arithmetic substitution,
4509 extract the expression and pass it to the evaluator. */
4510 if (temp
&& *temp
== '(')
4514 temp2
= savestring (temp1
);
4515 t_index
= strlen (temp2
) - 1;
4517 if (temp2
[t_index
] != ')')
4521 report_error ("%s: bad arithmetic substitution", temp
);
4525 return (&expand_word_error
);
4531 /* Cut off ending `)' */
4532 temp2
[t_index
] = '\0';
4534 /* Expand variables found inside the expression. */
4535 temp1
= maybe_expand_string (temp2
, Q_DOUBLE_QUOTES
, expand_string
);
4538 /* No error messages. */
4539 this_command_name
= (char *)NULL
;
4540 number
= evalexp (temp1
, &expok
);
4547 return (&expand_word_error
);
4553 temp1
= command_substitute (temp
, quoted
);
4556 goto dollar_add_string
;
4558 /* Do straight arithmetic substitution. */
4560 /* We have to extract the contents of this
4561 arithmetic substitution. */
4562 t_index
= sindex
+ 1;
4563 temp
= extract_arithmetic_subst (string
, &t_index
);
4566 /* Do initial variable expansion. */
4567 temp1
= maybe_expand_string (temp
, Q_DOUBLE_QUOTES
, expand_string
);
4569 /* No error messages. */
4570 this_command_name
= (char *)NULL
;
4571 number
= evalexp (temp1
, &expok
);
4578 return (&expand_word_error
);
4583 /* Find the variable in VARIABLE_LIST. */
4584 temp
= (char *)NULL
;
4586 for (t_index
= sindex
;
4587 (c
= string
[sindex
]) && legal_variable_char (c
);
4589 temp1
= substring (string
, t_index
, sindex
);
4591 /* If this isn't a variable name, then just output the `$'. */
4592 if (temp1
== 0 || *temp1
== '\0')
4598 if (expanded_something
)
4599 *expanded_something
= 0;
4603 /* If the variable exists, return its value cell. */
4604 var
= find_variable (temp1
);
4606 if (var
&& invisible_p (var
) == 0 && value_cell (var
))
4608 #if defined (ARRAY_VARS)
4611 temp
= array_reference (array_cell (var
), 0);
4613 temp
= quote_escapes (temp
);
4617 temp
= quote_escapes (value_cell (var
));
4622 temp
= (char *)NULL
;
4624 if (unbound_vars_is_error
)
4625 report_error ("%s: unbound variable", temp1
);
4634 last_command_exit_value
= EXECUTION_FAILURE
;
4636 return ((unbound_vars_is_error
&& interactive_shell
== 0)
4637 ? &expand_word_fatal
4638 : &expand_word_error
);
4640 break; /* End case '$': */
4642 case '`': /* Backquoted command substitution. */
4646 if (expanded_something
)
4647 *expanded_something
= 1;
4649 temp
= string_extract (string
, &sindex
, "`", 0);
4650 de_backslash (temp
);
4651 temp1
= command_substitute (temp
, quoted
);
4654 goto dollar_add_string
;
4658 if (string
[sindex
+ 1] == '\n')
4664 c
= string
[++sindex
];
4666 if (quoted
& Q_HERE_DOCUMENT
)
4667 temp1
= slashify_in_here_document
;
4668 else if (quoted
& Q_DOUBLE_QUOTES
)
4669 temp1
= slashify_in_quotes
;
4673 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) && member (c
, temp1
) == 0)
4676 temp
[0] = '\\'; temp
[1] = c
; temp
[2] = '\0';
4679 /* This character is quoted, so add it in quoted mode. */
4680 temp
= make_quoted_char (c
);
4687 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
|Q_NOQUOTE
))
4691 temp
= string_extract_double_quoted (string
, &sindex
, 0);
4693 /* If the quotes surrounded the entire string, then the
4694 whole word was quoted. */
4695 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
4703 tword
= make_word (temp
); /* XXX */
4705 temp
= (char *)NULL
;
4707 list
= expand_word_internal (tword
, Q_DOUBLE_QUOTES
, &dollar_at_flag
, (int *)NULL
);
4709 if (list
== &expand_word_error
|| list
== &expand_word_fatal
)
4713 /* expand_word_internal has already freed temp_word->word
4714 for us because of the way it prints error messages. */
4715 tword
->word
= (char *)NULL
;
4716 dispose_word (tword
);
4720 dispose_word (tword
);
4722 /* "$@" (a double-quoted dollar-at) expands into nothing,
4723 not even a NULL word, when there are no positional
4725 if (list
== 0 && dollar_at_flag
)
4731 /* If we get "$@", we know we have expanded something, so we
4732 need to remember it for the final split on $IFS. This is
4733 a special case; it's the only case where a quoted string
4734 can expand into more than one word. It's going to come back
4735 from the above call to expand_word_internal as a list with
4736 a single word, in which all characters are quoted and
4737 separated by blanks. What we want to do is to turn it back
4738 into a list for the next piece of code. */
4740 dequote_list (list
);
4745 if (contains_dollar_at
)
4746 *contains_dollar_at
= 1;
4747 if (expanded_something
)
4748 *expanded_something
= 1;
4753 /* What we have is "". This is a minor optimization. */
4755 list
= (WORD_LIST
*)NULL
;
4758 /* The code above *might* return a list (consider the case of "$@",
4759 where it returns "$1", "$2", etc.). We can't throw away the
4760 rest of the list, and we have to make sure each word gets added
4761 as quoted. We test on tresult->next: if it is non-NULL, we
4762 quote the whole list, save it to a string with string_list, and
4763 add that string. We don't need to quote the results of this
4764 (and it would be wrong, since that would quote the separators
4765 as well), so we go directly to add_string. */
4770 temp
= string_list (quote_list (list
));
4771 dispose_words (list
);
4776 temp
= savestring (list
->word
->word
);
4777 dispose_words (list
);
4781 temp
= (char *)NULL
;
4783 /* We do not want to add quoted nulls to strings that are only
4784 partially quoted; we can throw them away. */
4785 if (temp
== 0 && quoted_state
== PARTIALLY_QUOTED
)
4796 temp
= quote_string (temp
);
4810 if (quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
|Q_NOQUOTE
))
4814 temp
= string_extract_single_quoted (string
, &sindex
);
4816 /* If the entire STRING was surrounded by single quotes,
4817 then the string is wholly quoted. */
4818 quoted_state
= (t_index
== 1 && string
[sindex
] == '\0')
4822 /* If all we had was '', it is a null expansion. */
4826 temp
= (char *)NULL
;
4829 remove_quoted_escapes (temp
);
4831 /* We do not want to add quoted nulls to strings that are only
4832 partially quoted; such nulls are discarded. */
4833 if (temp
== 0 && (quoted_state
== PARTIALLY_QUOTED
))
4836 goto add_quoted_string
;
4840 /* This is the fix for " $@ " */
4841 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4843 temp
= make_quoted_char (c
);
4844 goto dollar_add_string
;
4848 RESIZE_MALLOCED_BUFFER (istring
, istring_index
, 1, istring_size
,
4849 DEFAULT_ARRAY_SIZE
);
4850 istring
[istring_index
++] = c
;
4851 istring
[istring_index
] = '\0';
4853 /* Next character. */
4858 finished_with_string
:
4859 /* OK, we're ready to return. If we have a quoted string, and
4860 quoted_dollar_at is not set, we do no splitting at all; otherwise
4861 we split on ' '. The routines that call this will handle what to
4862 do if nothing has been expanded. */
4864 /* Partially and wholly quoted strings which expand to the empty
4865 string are retained as an empty arguments. Unquoted strings
4866 which expand to the empty string are discarded. The single
4867 exception is the case of expanding "$@" when there are no
4868 positional parameters. In that case, we discard the expansion. */
4870 /* Because of how the code that handles "" and '' in partially
4871 quoted strings works, we need to make ISTRING into a QUOTED_NULL
4872 if we saw quoting characters, but the expansion was empty.
4873 "" and '' are tossed away before we get to this point when
4874 processing partially quoted strings. This makes "" and $xxx""
4875 equivalent when xxx is unset. We also look to see whether we
4876 saw a quoted null from a ${} expansion and add one back if we
4879 /* If we expand to nothing and there were no single or double quotes
4880 in the word, we throw it away. Otherwise, we return a NULL word.
4881 The single exception is for $@ surrounded by double quotes when
4882 there are no positional parameters. In that case, we also throw
4885 if (*istring
== '\0')
4887 if (quoted_dollar_at
== 0 && (had_quoted_null
|| quoted_state
== PARTIALLY_QUOTED
))
4889 istring
[0] = CTLNUL
;
4891 tword
= make_bare_word (istring
);
4892 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
4893 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4894 tword
->flags
|= W_QUOTED
;
4896 /* According to sh, ksh, and Posix.2, if a word expands into nothing
4897 and a double-quoted "$@" appears anywhere in it, then the entire
4899 else if (quoted_state
== UNQUOTED
|| quoted_dollar_at
)
4900 list
= (WORD_LIST
*)NULL
;
4904 tword
= make_bare_word (istring
);
4905 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
4906 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4907 tword
->flags
|= W_QUOTED
;
4911 else if (word
->flags
& W_NOSPLIT
)
4913 tword
= make_bare_word (istring
);
4914 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
4915 if (word
->flags
& W_ASSIGNMENT
)
4916 tword
->flags
|= W_ASSIGNMENT
; /* XXX */
4917 if (quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
))
4918 tword
->flags
|= W_QUOTED
;
4924 if (quoted_dollar_at
)
4926 var
= find_variable ("IFS");
4927 ifs_chars
= var
? value_cell (var
) : " \t\n";
4930 ifs_chars
= (char *)NULL
;
4932 /* According to Posix.2, "$@" expands to a single word if
4933 IFS="" and the positional parameters are not empty. */
4934 if (quoted_dollar_at
&& ifs_chars
&& *ifs_chars
)
4936 list
= list_string (istring
, " ", 1);
4940 tword
= make_bare_word (istring
);
4941 list
= make_word_list (tword
, (WORD_LIST
*)NULL
);
4942 if ((quoted
& (Q_DOUBLE_QUOTES
|Q_HERE_DOCUMENT
)) || (quoted_state
== WHOLLY_QUOTED
))
4943 tword
->flags
|= W_QUOTED
;
4944 if (word
->flags
& W_ASSIGNMENT
)
4945 tword
->flags
|= W_ASSIGNMENT
;
4953 /* **************************************************************** */
4955 /* Functions for Quote Removal */
4957 /* **************************************************************** */
4959 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
4960 backslash quoting rules for within double quotes. */
4962 string_quote_removal (string
, quoted
)
4966 char *r
, *result_string
, *temp
;
4967 int sindex
, tindex
, c
, dquote
;
4969 /* The result can be no longer than the original string. */
4970 r
= result_string
= xmalloc (strlen (string
) + 1);
4972 for (dquote
= sindex
= 0; c
= string
[sindex
];)
4977 c
= string
[++sindex
];
4978 if (((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
) && member (c
, slashify_in_quotes
) == 0)
4988 if ((quoted
& (Q_HERE_DOCUMENT
|Q_DOUBLE_QUOTES
)) || dquote
)
4994 tindex
= sindex
+ 1;
4995 temp
= string_extract_single_quoted (string
, &tindex
);
5006 dquote
= 1 - dquote
;
5012 return (result_string
);
5017 /* Perform quote removal on word WORD. This allocates and returns a new
5020 word_quote_removal (word
, quoted
)
5027 t
= string_quote_removal (word
->word
, quoted
);
5028 w
= make_bare_word (t
);
5033 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
5034 the members of the list are treated as if they are surrounded by
5035 double quotes. Return a new list, or NULL if LIST is NULL. */
5037 word_list_quote_removal (list
, quoted
)
5041 WORD_LIST
*result
, *t
, *tresult
;
5043 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
5045 tresult
= (WORD_LIST
*)xmalloc (sizeof (WORD_LIST
));
5046 tresult
->word
= word_quote_removal (t
->word
, quoted
);
5047 tresult
->next
= (WORD_LIST
*)NULL
;
5048 result
= (WORD_LIST
*) list_append (result
, tresult
);
5054 /* Return 1 if CHARACTER appears in an unquoted portion of
5055 STRING. Return 0 otherwise. */
5057 unquoted_member (character
, string
)
5063 for (sindex
= 0; c
= string
[sindex
]; )
5081 sindex
= skip_single_quoted (string
, ++sindex
);
5085 sindex
= skip_double_quoted (string
, ++sindex
);
5092 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
5094 unquoted_substring (substr
, string
)
5095 char *substr
, *string
;
5097 int sindex
, c
, sublen
;
5099 if (substr
== 0 || *substr
== '\0')
5102 sublen
= strlen (substr
);
5103 for (sindex
= 0; c
= string
[sindex
]; )
5105 if (STREQN (string
+ sindex
, substr
, sublen
))
5118 sindex
= skip_single_quoted (string
, ++sindex
);
5122 sindex
= skip_double_quoted (string
, ++sindex
);
5133 /*******************************************
5135 * Functions to perform word splitting *
5137 *******************************************/
5139 /* This splits a single word into a WORD LIST on $IFS, but only if the word
5140 is not quoted. list_string () performs quote removal for us, even if we
5141 don't do any splitting. */
5152 ifs
= find_variable ("IFS");
5153 /* If IFS is unset, it defaults to " \t\n". */
5154 ifs_chars
= ifs
? value_cell (ifs
) : " \t\n";
5156 if ((w
->flags
& W_QUOTED
) || !ifs_chars
)
5159 result
= list_string (w
->word
, ifs_chars
, w
->flags
& W_QUOTED
);
5162 result
= (WORD_LIST
*)NULL
;
5167 /* Perform word splitting on LIST and return the RESULT. It is possible
5168 to return (WORD_LIST *)NULL. */
5170 word_list_split (list
)
5173 WORD_LIST
*result
, *t
, *tresult
;
5175 for (t
= list
, result
= (WORD_LIST
*)NULL
; t
; t
= t
->next
)
5177 tresult
= word_split (t
->word
);
5178 result
= (WORD_LIST
*) list_append (result
, tresult
);
5183 /**************************************************
5185 * Functions to expand an entire WORD_LIST *
5187 **************************************************/
5189 static WORD_LIST
*varlist
= (WORD_LIST
*)NULL
;
5191 /* Separate out any initial variable assignments from TLIST. If set -k has
5192 been executed, remove all assignment statements from TLIST. Initial
5193 variable assignments and other environment assignments are placed
5196 separate_out_assignments (tlist
)
5199 register WORD_LIST
*vp
, *lp
;
5202 return ((WORD_LIST
*)NULL
);
5204 varlist
= (WORD_LIST
*)NULL
;
5207 /* Separate out variable assignments at the start of the command.
5208 Loop invariant: vp->next == lp
5210 lp = list of words left after assignment statements skipped
5211 tlist = original list of words
5213 while (lp
&& (lp
->word
->flags
& W_ASSIGNMENT
))
5219 /* If lp != tlist, we have some initial assignment statements. */
5220 /* We make VARLIST point to the list of assignment words and
5221 TLIST point to the remaining words. */
5225 /* ASSERT(vp->next == lp); */
5226 vp
->next
= (WORD_LIST
*)NULL
; /* terminate variable list */
5227 tlist
= lp
; /* remainder of word list */
5230 /* vp == end of variable list */
5231 /* tlist == remainder of original word list without variable assignments */
5233 /* All the words in tlist were assignment statements */
5234 return ((WORD_LIST
*)NULL
);
5236 /* ASSERT(tlist != NULL); */
5237 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
5239 /* If the -k option is in effect, we need to go through the remaining
5240 words, separate out the assignment words, and place them on VARLIST. */
5241 if (place_keywords_in_env
)
5243 WORD_LIST
*tp
; /* tp == running pointer into tlist */
5248 /* Loop Invariant: tp->next == lp */
5249 /* Loop postcondition: tlist == word list without assignment statements */
5252 if (lp
->word
->flags
& W_ASSIGNMENT
)
5254 /* Found an assignment statement, add this word to end of
5264 /* Remove the word pointed to by LP from TLIST. */
5265 tp
->next
= lp
->next
;
5266 /* ASSERT(vp == lp); */
5267 lp
->next
= (WORD_LIST
*)NULL
;
5280 /* Take the list of words in LIST and do the various substitutions. Return
5281 a new list of words which is the expanded list, and without things like
5282 variable assignments. */
5288 return (expand_word_list_internal (list
, 1));
5291 /* Same as expand_words (), but doesn't hack variable or environment
5294 expand_words_no_vars (list
)
5297 return (expand_word_list_internal (list
, 0));
5300 /* The workhorse for expand_words () and expand_words_no_vars ().
5301 First arg is LIST, a WORD_LIST of words.
5302 Second arg DO_VARS is non-zero if you want to do environment and
5303 variable assignments, else zero.
5305 This does all of the substitutions: brace expansion, tilde expansion,
5306 parameter expansion, command substitution, arithmetic expansion,
5307 process substitution, word splitting, and pathname expansion. Words
5308 with the W_QUOTED or W_NOSPLIT bits set, or for which no expansion
5309 is done, do not undergo word splitting. Words with the W_ASSIGNMENT
5310 bit set do not undergo pathname expansion. */
5312 expand_word_list_internal (list
, do_vars
)
5316 WORD_LIST
*tlist
, *new_list
, *next
, *temp_list
, *orig_list
, *disposables
;
5321 return ((WORD_LIST
*)NULL
);
5323 tlist
= copy_word_list (list
);
5327 tlist
= separate_out_assignments (tlist
);
5332 /* All the words were variable assignments, so they are placed
5333 into the shell's environment. */
5334 for (new_list
= varlist
; new_list
; new_list
= new_list
->next
)
5336 this_command_name
= (char *)NULL
; /* no arithmetic errors */
5337 tint
= do_assignment (new_list
->word
->word
);
5338 /* Variable assignment errors in non-interactive shells
5339 running in Posix.2 mode cause the shell to exit. */
5340 if (tint
== 0 && interactive_shell
== 0 && posixly_correct
)
5342 last_command_exit_value
= EXECUTION_FAILURE
;
5343 jump_to_top_level (FORCE_EOF
);
5346 dispose_words (varlist
);
5347 varlist
= (WORD_LIST
*)NULL
;
5349 return ((WORD_LIST
*)NULL
);
5353 /* Begin expanding the words that remain. The expansions take place on
5354 things that aren't really variable assignments. */
5356 #if defined (BRACE_EXPANSION)
5357 /* Do brace expansion on this word if there are any brace characters
5359 if (brace_expansion
&& tlist
)
5361 register char **expansions
;
5366 for (braces
= disposables
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
5370 /* Only do brace expansion if the word has a brace character. If
5371 not, just add the word list element to BRACES and continue. In
5372 the common case, at least when running shell scripts, this will
5373 degenerate to a bunch of calls to `strchr', and then what is
5374 basically a reversal of TLIST into BRACES, which is corrected
5375 by a call to reverse_list () on BRACES when the end of TLIST
5377 if (strchr (tlist
->word
->word
, '{'))
5379 expansions
= brace_expand (tlist
->word
->word
);
5381 for (eindex
= 0; temp_string
= expansions
[eindex
]; eindex
++)
5383 w
= make_word (temp_string
);
5384 /* If brace expansion didn't change the word, preserve
5385 the flags. We may want to preserve the flags
5386 unconditionally someday -- XXX */
5387 if (STREQ (temp_string
, tlist
->word
->word
))
5388 w
->flags
= tlist
->word
->flags
;
5389 braces
= make_word_list (w
, braces
);
5390 free (expansions
[eindex
]);
5394 /* Add TLIST to the list of words to be freed after brace
5395 expansion has been performed. */
5396 tlist
->next
= disposables
;
5397 disposables
= tlist
;
5401 tlist
->next
= braces
;
5406 dispose_words (disposables
);
5407 tlist
= REVERSE_LIST (braces
, WORD_LIST
*);
5409 #endif /* BRACE_EXPANSION */
5411 /* We do tilde expansion all the time. This is what 1003.2 says. */
5412 for (orig_list
= tlist
, new_list
= (WORD_LIST
*)NULL
; tlist
; tlist
= next
)
5414 WORD_LIST
*expanded
;
5415 int expanded_something
, has_dollar_at
;
5417 temp_string
= tlist
->word
->word
;
5421 /* Posix.2 section 3.6.1 says that tildes following `=' in words
5422 which are not assignment statements are not expanded. We do
5423 this only if POSIXLY_CORRECT is enabled. Essentially, we do
5424 tilde expansion on unquoted assignment statements (flags include
5425 W_ASSIGNMENT but not W_QUOTED). */
5426 if (temp_string
[0] == '~' ||
5427 (((tlist
->word
->flags
& (W_ASSIGNMENT
|W_QUOTED
)) == W_ASSIGNMENT
) &&
5428 posixly_correct
== 0 &&
5429 strchr (temp_string
, '~') &&
5430 (unquoted_substring ("=~", temp_string
) || unquoted_substring (":~", temp_string
))))
5432 tlist
->word
->word
= bash_tilde_expand (temp_string
);
5436 expanded_something
= 0;
5437 expanded
= expand_word_internal
5438 (tlist
->word
, 0, &has_dollar_at
, &expanded_something
);
5440 if (expanded
== &expand_word_error
|| expanded
== &expand_word_fatal
)
5442 /* By convention, each time this error is returned,
5443 tlist->word->word has already been freed. */
5444 tlist
->word
->word
= (char *)NULL
;
5446 /* Dispose our copy of the original list. */
5447 dispose_words (orig_list
);
5448 /* Dispose the new list we're building. */
5449 dispose_words (new_list
);
5451 if (expanded
== &expand_word_error
)
5452 jump_to_top_level (DISCARD
);
5454 jump_to_top_level (FORCE_EOF
);
5457 /* Don't split words marked W_NOSPLIT. */
5458 if (expanded_something
&& (tlist
->word
->flags
& W_NOSPLIT
) == 0)
5460 temp_list
= word_list_split (expanded
);
5461 dispose_words (expanded
);
5465 /* If no parameter expansion, command substitution, process
5466 substitution, or arithmetic substitution took place, then
5467 do not do word splitting. We still have to remove quoted
5468 null characters from the result. */
5469 word_list_remove_quoted_nulls (expanded
);
5470 temp_list
= expanded
;
5473 /* In the most common cases, t will be a list containing only one
5474 element, so the call to reverse_list would be wasted. */
5475 expanded
= REVERSE_LIST (temp_list
, WORD_LIST
*);
5476 new_list
= (WORD_LIST
*)list_append (expanded
, new_list
);
5479 new_list
= REVERSE_LIST (new_list
, WORD_LIST
*);
5481 dispose_words (orig_list
);
5483 /* Okay, we're almost done. Now let's just do some filename
5488 register int glob_index
;
5489 WORD_LIST
*glob_list
;
5492 orig_list
= disposables
= (WORD_LIST
*)NULL
;
5495 /* orig_list == output list, despite the name. */
5496 if (disallow_filename_globbing
== 0)
5498 glob_array
= (char **)NULL
;
5501 /* For each word, either globbing is attempted or the word is
5502 added to orig_list. If globbing succeeds, the results are
5503 added to orig_list and the word (tlist) is added to the list
5504 of disposable words. If globbing fails and failed glob
5505 expansions are left unchanged (the shell default), the
5506 original word is added to orig_list. If globbing fails and
5507 failed glob expansions are removed, the original word is
5508 added to the list of disposable words. orig_list ends up
5509 in reverse order and requires a call to reverse_list to
5510 be set right. After all words are examined, the disposable
5514 /* If the word isn't an assignment and contains an unquoted
5515 pattern matching character, then glob it. */
5517 if ((tlist
->word
->flags
& (W_QUOTED
|W_ASSIGNMENT
)) == 0 &&
5519 if ((tlist
->word
->flags
& W_ASSIGNMENT
) == 0 &&
5521 unquoted_glob_pattern_p (tlist
->word
->word
))
5523 glob_array
= shell_glob_filename (tlist
->word
->word
);
5525 /* Handle error cases.
5526 I don't think we should report errors like "No such file
5527 or directory". However, I would like to report errors
5528 like "Read failed". */
5530 if (GLOB_FAILED (glob_array
))
5532 glob_array
= (char **) xmalloc (sizeof (char *));
5533 glob_array
[0] = (char *)NULL
;
5536 /* Dequote the current word in case we have to use it. */
5537 if (glob_array
[0] == NULL
)
5539 temp_string
= dequote_string (tlist
->word
->word
);
5540 free (tlist
->word
->word
);
5541 tlist
->word
->word
= temp_string
;
5544 /* Make the array into a word list. */
5545 glob_list
= (WORD_LIST
*)NULL
;
5546 for (glob_index
= 0; glob_array
[glob_index
]; glob_index
++)
5548 tword
= make_bare_word (glob_array
[glob_index
]);
5549 tword
->flags
|= W_GLOBEXP
; /* XXX */
5550 glob_list
= make_word_list (tword
, glob_list
);
5555 orig_list
= (WORD_LIST
*)list_append (glob_list
, orig_list
);
5556 tlist
->next
= disposables
;
5557 disposables
= tlist
;
5559 else if (allow_null_glob_expansion
== 0)
5561 /* Failed glob expressions are left unchanged. */
5562 tlist
->next
= orig_list
;
5567 /* Failed glob expressions are removed. */
5568 tlist
->next
= disposables
;
5569 disposables
= tlist
;
5574 /* Dequote the string. */
5575 temp_string
= dequote_string (tlist
->word
->word
);
5576 free (tlist
->word
->word
);
5577 tlist
->word
->word
= temp_string
;
5578 tlist
->next
= orig_list
;
5582 free_array (glob_array
);
5583 glob_array
= (char **)NULL
;
5589 dispose_words (disposables
);
5591 new_list
= REVERSE_LIST (orig_list
, WORD_LIST
*);
5595 /* Dequote the words, because we're not performing globbing. */
5596 for (temp_list
= new_list
; temp_list
; temp_list
= temp_list
->next
)
5598 temp_string
= dequote_string (temp_list
->word
->word
);
5599 free (temp_list
->word
->word
);
5600 temp_list
->word
->word
= temp_string
;
5607 Function
*assign_func
;
5609 /* If the remainder of the words expand to nothing, Posix.2 requires
5610 that the variable and environment assignments affect the shell's
5612 assign_func
= new_list
? assign_in_env
: do_assignment
;
5614 for (temp_list
= varlist
; temp_list
; temp_list
= temp_list
->next
)
5616 this_command_name
= (char *)NULL
;
5617 tint
= (*assign_func
) (temp_list
->word
->word
);
5618 /* Variable assignment errors in non-interactive shells running
5619 in Posix.2 mode cause the shell to exit. */
5620 if (tint
== 0 && assign_func
== do_assignment
&&
5621 interactive_shell
== 0 && posixly_correct
)
5623 last_command_exit_value
= EXECUTION_FAILURE
;
5624 jump_to_top_level (FORCE_EOF
);
5628 dispose_words (varlist
);
5629 varlist
= (WORD_LIST
*)NULL
;
5632 tint
= list_length (new_list
) + 1;
5633 RESIZE_MALLOCED_BUFFER (glob_argv_flags
, 0, tint
, glob_argv_flags_size
, 16);
5634 for (tint
= 0, tlist
= new_list
; tlist
; tlist
= tlist
->next
)
5635 glob_argv_flags
[tint
++] = (tlist
->word
->flags
& W_GLOBEXP
) ? '1' : '0';
5636 glob_argv_flags
[tint
] = '\0';
5641 /*************************************************
5643 * Functions to manage special variables *
5645 *************************************************/
5647 /* An alist of name.function for each special variable. Most of the
5648 functions don't do much, and in fact, this would be faster with a
5649 switch statement, but by the end of this file, I am sick of switch
5652 #define SET_INT_VAR(name, intvar) intvar = find_variable (name) != 0
5654 struct name_and_function
{
5656 VFunction
*function
;
5657 } special_vars
[] = {
5658 { "PATH", sv_path
},
5659 { "MAIL", sv_mail
},
5660 { "MAILPATH", sv_mail
},
5661 { "MAILCHECK", sv_mail
},
5663 { "POSIXLY_CORRECT", sv_strict_posix
},
5664 { "GLOBIGNORE", sv_globignore
},
5666 /* Variables which only do something special when READLINE is defined. */
5667 #if defined (READLINE)
5668 { "TERM", sv_terminal
},
5669 { "TERMCAP", sv_terminal
},
5670 { "TERMINFO", sv_terminal
},
5671 { "HOSTFILE", sv_hostfile
},
5672 #endif /* READLINE */
5674 /* Variables which only do something special when HISTORY is defined. */
5675 #if defined (HISTORY)
5676 { "HISTIGNORE", sv_histignore
},
5677 { "HISTSIZE", sv_histsize
},
5678 { "HISTFILESIZE", sv_histsize
},
5679 { "HISTCONTROL", sv_history_control
},
5680 # if defined (BANG_HISTORY)
5681 { "histchars", sv_histchars
},
5682 # endif /* BANG_HISTORY */
5683 #endif /* HISTORY */
5685 { "IGNOREEOF", sv_ignoreeof
},
5686 { "ignoreeof", sv_ignoreeof
},
5688 { "OPTIND", sv_optind
},
5689 { "OPTERR", sv_opterr
},
5691 { "TEXTDOMAIN", sv_locale
},
5692 { "TEXTDOMAINDIR", sv_locale
},
5693 { "LC_ALL", sv_locale
},
5694 { "LC_COLLATE", sv_locale
},
5695 { "LC_CTYPE", sv_locale
},
5696 { "LC_MESSAGES", sv_locale
},
5697 { "LANG", sv_locale
},
5699 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
5703 { (char *)0, (VFunction
*)0 }
5706 /* The variable in NAME has just had its state changed. Check to see if it
5707 is one of the special ones where something special happens. */
5709 stupidly_hack_special_variables (name
)
5714 for (i
= 0; special_vars
[i
].name
; i
++)
5716 if (STREQ (special_vars
[i
].name
, name
))
5718 (*(special_vars
[i
].function
)) (name
);
5724 /* What to do just after the PATH variable has changed. */
5730 flush_hashed_filenames ();
5733 /* What to do just after one of the MAILxxxx variables has changed. NAME
5734 is the name of the variable. This is called with NAME set to one of
5735 MAIL, MAILCHECK, or MAILPATH. */
5740 /* If the time interval for checking the files has changed, then
5741 reset the mail timer. Otherwise, one of the pathname vars
5742 to the users mailbox has changed, so rebuild the array of
5744 if (name
[4] == 'C') /* if (strcmp (name, "MAILCHECK") == 0) */
5745 reset_mail_timer ();
5749 remember_mail_dates ();
5753 /* What to do when GLOBIGNORE changes. */
5755 sv_globignore (name
)
5758 setup_glob_ignore (name
);
5761 #if defined (READLINE)
5762 /* What to do just after one of the TERMxxx variables has changed.
5763 If we are an interactive shell, then try to reset the terminal
5764 information in readline. */
5769 if (interactive_shell
&& no_line_editing
== 0)
5770 rl_reset_terminal (get_string_value ("TERM"));
5777 hostname_list_initialized
= 0;
5779 #endif /* READLINE */
5781 #if defined (HISTORY)
5782 /* What to do after the HISTSIZE or HISTFILESIZE variables change.
5783 If there is a value for this HISTSIZE (and it is numeric), then stifle
5784 the history. Otherwise, if there is NO value for this variable,
5785 unstifle the history. If name is HISTFILESIZE, and its value is
5786 numeric, truncate the history file to hold no more than that many
5795 temp
= get_string_value (name
);
5799 if (legal_number (temp
, &num
))
5803 stifle_history (num
);
5804 num
= where_history ();
5805 if (history_lines_this_session
> num
)
5806 history_lines_this_session
= num
;
5810 history_truncate_file (get_string_value ("HISTFILE"), (int)num
);
5811 if (num
<= history_lines_in_file
)
5812 history_lines_in_file
= num
;
5816 else if (name
[4] == 'S')
5817 unstifle_history ();
5820 /* What to do after the HISTIGNORE variable changes. */
5822 sv_histignore (name
)
5825 setup_history_ignore (name
);
5828 /* What to do after the HISTCONTROL variable changes. */
5830 sv_history_control (name
)
5835 history_control
= 0;
5836 temp
= get_string_value (name
);
5838 if (temp
&& *temp
&& STREQN (temp
, "ignore", 6))
5840 if (temp
[6] == 's') /* ignorespace */
5841 history_control
= 1;
5842 else if (temp
[6] == 'd') /* ignoredups */
5843 history_control
= 2;
5844 else if (temp
[6] == 'b') /* ignoreboth */
5845 history_control
= 3;
5849 #if defined (BANG_HISTORY)
5850 /* Setting/unsetting of the history expansion character. */
5857 temp
= get_string_value (name
);
5860 history_expansion_char
= *temp
;
5861 if (temp
[0] && temp
[1])
5863 history_subst_char
= temp
[1];
5865 history_comment_char
= temp
[2];
5870 history_expansion_char
= '!';
5871 history_subst_char
= '^';
5872 history_comment_char
= '#';
5875 #endif /* BANG_HISTORY */
5876 #endif /* HISTORY */
5878 #if defined (HAVE_TZSET) && defined (PROMPT_STRING_DECODE)
5887 /* If the variable exists, then the value of it can be the number
5888 of times we actually ignore the EOF. The default is small,
5889 (smaller than csh, anyway). */
5897 eof_encountered
= 0;
5899 tmp_var
= find_variable (name
);
5900 ignoreeof
= tmp_var
!= 0;
5901 temp
= tmp_var
? value_cell (tmp_var
) : (char *)NULL
;
5903 eof_encountered_limit
= (*temp
&& all_digits (temp
)) ? atoi (temp
) : 10;
5904 set_shellopts (); /* make sure `ignoreeof' is/is not in $SHELLOPTS */
5914 tt
= get_string_value ("OPTIND");
5919 /* According to POSIX, setting OPTIND=1 resets the internal state
5921 if (s
< 0 || s
== 1)
5935 tt
= get_string_value ("OPTERR");
5936 sh_opterr
= (tt
&& *tt
) ? atoi (tt
) : 1;
5940 sv_strict_posix (name
)
5943 SET_INT_VAR (name
, posixly_correct
);
5944 posix_initialize (posixly_correct
);
5945 #if defined (READLINE)
5946 if (interactive_shell
)
5947 posix_readline_initialize (posixly_correct
);
5948 #endif /* READLINE */
5949 set_shellopts (); /* make sure `posix' is/is not in $SHELLOPTS */
5958 v
= get_string_value (name
);
5959 if (name
[0] == 'L' && name
[1] == 'A') /* LANG */
5962 set_locale_var (name
, v
); /* LC_*, TEXTDOMAIN* */