]> git.ipfire.org Git - thirdparty/bash.git/blob - subst.c
Imported from ../bash-2.05a.tar.gz.
[thirdparty/bash.git] / subst.c
1 /* subst.c -- The part of the shell that does parameter, command, and
2 globbing substitutions. */
3
4 /* ``Have a little faith, there's magic in the night. You ain't a
5 beauty, but, hey, you're alright.'' */
6
7 /* Copyright (C) 1987,1989 Free Software Foundation, Inc.
8
9 This file is part of GNU Bash, the Bourne Again SHell.
10
11 Bash is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
14 version.
15
16 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 for more details.
20
21 You should have received a copy of the GNU General Public License along
22 with Bash; see the file COPYING. If not, write to the Free Software
23 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24
25 #include "config.h"
26
27 #include "bashtypes.h"
28 #include <stdio.h>
29 #include "chartypes.h"
30 #include <pwd.h>
31 #include <signal.h>
32 #include <errno.h>
33
34 #if defined (HAVE_UNISTD_H)
35 # include <unistd.h>
36 #endif
37
38 #include "bashansi.h"
39 #include "posixstat.h"
40
41 #include "shell.h"
42 #include "flags.h"
43 #include "jobs.h"
44 #include "execute_cmd.h"
45 #include "filecntl.h"
46 #include "trap.h"
47 #include "pathexp.h"
48 #include "mailcheck.h"
49
50 #include "builtins/getopt.h"
51 #include "builtins/common.h"
52
53 #include <tilde/tilde.h>
54 #include <glob/strmatch.h>
55
56 #if !defined (errno)
57 extern int errno;
58 #endif /* !errno */
59
60 /* The size that strings change by. */
61 #define DEFAULT_INITIAL_ARRAY_SIZE 112
62 #define DEFAULT_ARRAY_SIZE 128
63
64 /* Variable types. */
65 #define VT_VARIABLE 0
66 #define VT_POSPARMS 1
67 #define VT_ARRAYVAR 2
68 #define VT_ARRAYMEMBER 3
69
70 /* Flags for quoted_strchr */
71 #define ST_BACKSL 0x01
72 #define ST_CTLESC 0x02
73
74 /* These defs make it easier to use the editor. */
75 #define LBRACE '{'
76 #define RBRACE '}'
77 #define LPAREN '('
78 #define RPAREN ')'
79
80 /* Evaluates to 1 if C is one of the shell's special parameters whose length
81 can be taken, but is also one of the special expansion characters. */
82 #define VALID_SPECIAL_LENGTH_PARAM(c) \
83 ((c) == '-' || (c) == '?' || (c) == '#')
84
85 /* Evaluates to 1 if C is one of the shell's special parameters for which an
86 indirect variable reference may be made. */
87 #define VALID_INDIR_PARAM(c) \
88 ((c) == '#' || (c) == '?' || (c) == '@' || (c) == '*')
89
90 /* Evaluates to 1 if C is one of the OP characters that follows the parameter
91 in ${parameter[:]OPword}. */
92 #define VALID_PARAM_EXPAND_CHAR(c) \
93 ((c) == '-' || (c) == '=' || (c) == '?' || (c) == '+')
94
95 /* Evaluates to 1 if this is one of the shell's special variables. */
96 #define SPECIAL_VAR(name, wi) \
97 ((DIGIT (*name) && all_digits (name)) || \
98 (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \
99 (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))
100
101 /* An expansion function that takes a string and a quoted flag and returns
102 a WORD_LIST *. Used as the type of the third argument to
103 expand_string_if_necessary(). */
104 typedef WORD_LIST *EXPFUNC __P((char *, int));
105
106 /* Process ID of the last command executed within command substitution. */
107 pid_t last_command_subst_pid = NO_PID;
108 pid_t current_command_subst_pid = NO_PID;
109
110 /* Extern functions and variables from different files. */
111 extern int last_command_exit_value;
112 extern int subshell_environment, startup_state;
113 extern int return_catch_flag, return_catch_value;
114 extern pid_t dollar_dollar_pid;
115 extern int posixly_correct;
116 extern char *this_command_name;
117 extern struct fd_bitmap *current_fds_to_close;
118 extern int wordexp_only;
119
120 /* Non-zero means to allow unmatched globbed filenames to expand to
121 a null file. */
122 int allow_null_glob_expansion;
123
124 #if 0
125 /* Variables to keep track of which words in an expanded word list (the
126 output of expand_word_list_internal) are the result of globbing
127 expansions. GLOB_ARGV_FLAGS is used by execute_cmd.c.
128 (CURRENTLY UNUSED). */
129 char *glob_argv_flags;
130 static int glob_argv_flags_size;
131 #endif
132
133 static WORD_LIST expand_word_error, expand_word_fatal;
134 static char expand_param_error, expand_param_fatal;
135
136 /* Tell the expansion functions to not longjmp back to top_level on fatal
137 errors. Enabled when doing completion and prompt string expansion. */
138 static int no_longjmp_on_fatal_error = 0;
139
140 /* Set by expand_word_unsplit; used to inhibit splitting and re-joining
141 $* on $IFS, primarily when doing assignment statements. */
142 static int expand_no_split_dollar_star = 0;
143
144 /* Used to hold a list of variable assignments preceding a command. Global
145 so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a
146 SIGCHLD trap. */
147 WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;
148
149 /* A WORD_LIST of words to be expanded by expand_word_list_internal,
150 without any leading variable assignments. */
151 static WORD_LIST *garglist = (WORD_LIST *)NULL;
152
153 static char *quoted_substring __P((char *, int, int));
154 static inline char *quoted_strchr __P((char *, int, int));
155
156 static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));
157 static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));
158 static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
159 static WORD_LIST *expand_string_internal __P((char *, int));
160 static WORD_LIST *expand_string_leave_quoted __P((char *, int));
161 static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));
162
163 static char *remove_quoted_escapes __P((char *));
164 static WORD_LIST *list_quote_escapes __P((WORD_LIST *));
165 static char *make_quoted_char __P((int));
166 static WORD_LIST *quote_list __P((WORD_LIST *));
167 static WORD_LIST *dequote_list __P((WORD_LIST *));
168 static void remove_quoted_nulls __P((char *));
169
170 static int unquoted_substring __P((char *, char *));
171 static int unquoted_member __P((int, char *));
172
173 static int do_assignment_internal __P((const char *, int));
174
175 static char *string_extract_verbatim __P((char *, int *, char *));
176 static char *string_extract __P((char *, int *, char *, int));
177 static char *string_extract_double_quoted __P((char *, int *, int));
178 static char *string_extract_single_quoted __P((char *, int *));
179 static inline int skip_single_quoted __P((char *, int));
180 static int skip_double_quoted __P((char *, int));
181 static char *extract_delimited_string __P((char *, int *, char *, char *, char *));
182 static char *extract_dollar_brace_string __P((char *, int *, int));
183
184 static char *string_list_internal __P((WORD_LIST *, char *));
185 static char *pos_params __P((char *, int, int, int));
186
187 static char *remove_pattern __P((char *, char *, int));
188 static int match_pattern_char __P((char *, char *));
189 static int match_pattern __P((char *, char *, int, char **, char **));
190 static int getpatspec __P((int, char *));
191 static char *getpattern __P((char *, int, int));
192 static char *parameter_brace_remove_pattern __P((char *, char *, int, int));
193 static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));
194 static char *parameter_list_remove_pattern __P((char *, int, int, int));
195 #ifdef ARRAY_VARS
196 static char *array_remove_pattern __P((char *, char *, char *, int, int));
197 #endif
198
199 static char *process_substitute __P((char *, int));
200
201 static char *read_comsub __P((int, int));
202
203 #ifdef ARRAY_VARS
204 static arrayind_t array_length_reference __P((char *));
205 #endif
206
207 static int valid_brace_expansion_word __P((char *, int));
208 static char *parameter_brace_expand_word __P((char *, int, int));
209 static char *parameter_brace_expand_indir __P((char *, int, int));
210 static char *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));
211 static void parameter_brace_expand_error __P((char *, char *));
212
213 static int valid_length_expression __P((char *));
214 static long parameter_brace_expand_length __P((char *));
215
216 static char *skiparith __P((char *, int));
217 static int verify_substring_values __P((char *, char *, int, long *, long *));
218 static int get_var_and_type __P((char *, char *, SHELL_VAR **, char **));
219 static char *parameter_brace_substring __P((char *, char *, char *, int));
220
221 static char *pos_params_pat_subst __P((char *, char *, char *, int));
222
223 static char *parameter_brace_patsub __P((char *, char *, char *, int));
224
225 static char *parameter_brace_expand __P((char *, int *, int, int *, int *));
226 static char *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));
227
228 static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));
229
230 static char *getifs __P((void));
231 static WORD_LIST *word_list_split __P((WORD_LIST *));
232
233 static WORD_LIST *separate_out_assignments __P((WORD_LIST *));
234 static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));
235 #ifdef BRACE_EXPANSION
236 static WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));
237 #endif
238 static WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));
239 static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));
240
241 /* **************************************************************** */
242 /* */
243 /* Utility Functions */
244 /* */
245 /* **************************************************************** */
246
247 /* Cons a new string from STRING starting at START and ending at END,
248 not including END. */
249 char *
250 substring (string, start, end)
251 char *string;
252 int start, end;
253 {
254 register int len;
255 register char *result;
256
257 len = end - start;
258 result = (char *)xmalloc (len + 1);
259 strncpy (result, string + start, len);
260 result[len] = '\0';
261 return (result);
262 }
263
264 static char *
265 quoted_substring (string, start, end)
266 char *string;
267 int start, end;
268 {
269 register int len, l;
270 register char *result, *s, *r;
271
272 len = end - start;
273
274 /* Move to string[start], skipping quoted characters. */
275 for (s = string, l = 0; *s && l < start; )
276 {
277 if (*s == CTLESC)
278 {
279 s++;
280 continue;
281 }
282 l++;
283 if (*s == 0)
284 break;
285 }
286
287 r = result = (char *)xmalloc (2*len + 1); /* save room for quotes */
288
289 /* Copy LEN characters, including quote characters. */
290 s = string + l;
291 for (l = 0; l < len; s++)
292 {
293 if (*s == CTLESC)
294 *r++ = *s++;
295 *r++ = *s;
296 l++;
297 if (*s == 0)
298 break;
299 }
300 *r = '\0';
301 return result;
302 }
303
304 /* Find the first occurrence of character C in string S, obeying shell
305 quoting rules. If (FLAGS & ST_BACKSL) is non-zero, backslash-escaped
306 characters are skipped. If (FLAGS & ST_CTLESC) is non-zero, characters
307 escaped with CTLESC are skipped. */
308 static inline char *
309 quoted_strchr (s, c, flags)
310 char *s;
311 int c, flags;
312 {
313 register char *p;
314
315 for (p = s; *p; p++)
316 {
317 if (((flags & ST_BACKSL) && *p == '\\')
318 || ((flags & ST_CTLESC) && *p == CTLESC))
319 {
320 p++;
321 if (*p == '\0')
322 return ((char *)NULL);
323 continue;
324 }
325 else if (*p == c)
326 return p;
327 }
328 return ((char *)NULL);
329 }
330
331 /* Return 1 if CHARACTER appears in an unquoted portion of
332 STRING. Return 0 otherwise. */
333 static int
334 unquoted_member (character, string)
335 int character;
336 char *string;
337 {
338 int sindex, c;
339
340 for (sindex = 0; c = string[sindex]; )
341 {
342 if (c == character)
343 return (1);
344
345 switch (c)
346 {
347 default:
348 sindex++;
349 break;
350
351 case '\\':
352 sindex++;
353 if (string[sindex])
354 sindex++;
355 break;
356
357 case '\'':
358 sindex = skip_single_quoted (string, ++sindex);
359 break;
360
361 case '"':
362 sindex = skip_double_quoted (string, ++sindex);
363 break;
364 }
365 }
366 return (0);
367 }
368
369 /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */
370 static int
371 unquoted_substring (substr, string)
372 char *substr, *string;
373 {
374 int sindex, c, sublen;
375
376 if (substr == 0 || *substr == '\0')
377 return (0);
378
379 sublen = strlen (substr);
380 for (sindex = 0; c = string[sindex]; )
381 {
382 if (STREQN (string + sindex, substr, sublen))
383 return (1);
384
385 switch (c)
386 {
387 case '\\':
388 sindex++;
389
390 if (string[sindex])
391 sindex++;
392 break;
393
394 case '\'':
395 sindex = skip_single_quoted (string, ++sindex);
396 break;
397
398 case '"':
399 sindex = skip_double_quoted (string, ++sindex);
400 break;
401
402 default:
403 sindex++;
404 break;
405 }
406 }
407 return (0);
408 }
409
410 /* Most of the substitutions must be done in parallel. In order
411 to avoid using tons of unclear goto's, I have some functions
412 for manipulating malloc'ed strings. They all take INDX, a
413 pointer to an integer which is the offset into the string
414 where manipulation is taking place. They also take SIZE, a
415 pointer to an integer which is the current length of the
416 character array for this string. */
417
418 /* Append SOURCE to TARGET at INDEX. SIZE is the current amount
419 of space allocated to TARGET. SOURCE can be NULL, in which
420 case nothing happens. Gets rid of SOURCE by freeing it.
421 Returns TARGET in case the location has changed. */
422 inline char *
423 sub_append_string (source, target, indx, size)
424 char *source, *target;
425 int *indx, *size;
426 {
427 if (source)
428 {
429 int srclen, n;
430
431 srclen = STRLEN (source);
432 if (srclen >= (int)(*size - *indx))
433 {
434 n = srclen + *indx;
435 n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE);
436 target = (char *)xrealloc (target, (*size = n));
437 }
438
439 FASTCOPY (source, target + *indx, srclen);
440 *indx += srclen;
441 target[*indx] = '\0';
442
443 free (source);
444 }
445 return (target);
446 }
447
448 #if 0
449 /* UNUSED */
450 /* Append the textual representation of NUMBER to TARGET.
451 INDX and SIZE are as in SUB_APPEND_STRING. */
452 char *
453 sub_append_number (number, target, indx, size)
454 long number;
455 int *indx, *size;
456 char *target;
457 {
458 char *temp;
459
460 temp = itos (number);
461 return (sub_append_string (temp, target, indx, size));
462 }
463 #endif
464
465 /* Extract a substring from STRING, starting at SINDEX and ending with
466 one of the characters in CHARLIST. Don't make the ending character
467 part of the string. Leave SINDEX pointing at the ending character.
468 Understand about backslashes in the string. If VARNAME is non-zero,
469 and array variables have been compiled into the shell, everything
470 between a `[' and a corresponding `]' is skipped over. */
471 static char *
472 string_extract (string, sindex, charlist, varname)
473 char *string;
474 int *sindex;
475 char *charlist;
476 int varname;
477 {
478 register int c, i;
479 char *temp;
480
481 for (i = *sindex; c = string[i]; i++)
482 {
483 if (c == '\\')
484 if (string[i + 1])
485 i++;
486 else
487 break;
488 #if defined (ARRAY_VARS)
489 else if (varname && c == '[')
490 {
491 int ni;
492 /* If this is an array subscript, skip over it and continue. */
493 ni = skipsubscript (string, i);
494 if (string[ni] == ']')
495 i = ni;
496 }
497 #endif
498 else if (MEMBER (c, charlist))
499 break;
500 }
501
502 temp = substring (string, *sindex, i);
503 *sindex = i;
504 return (temp);
505 }
506
507 /* Extract the contents of STRING as if it is enclosed in double quotes.
508 SINDEX, when passed in, is the offset of the character immediately
509 following the opening double quote; on exit, SINDEX is left pointing after
510 the closing double quote. If STRIPDQ is non-zero, unquoted double
511 quotes are stripped and the string is terminated by a null byte.
512 Backslashes between the embedded double quotes are processed. If STRIPDQ
513 is zero, an unquoted `"' terminates the string. */
514 static inline char *
515 string_extract_double_quoted (string, sindex, stripdq)
516 char *string;
517 int *sindex, stripdq;
518 {
519 int j, i, t;
520 unsigned char c;
521 char *temp, *ret; /* The new string we return. */
522 int pass_next, backquote, si; /* State variables for the machine. */
523 int dquote;
524
525 pass_next = backquote = dquote = 0;
526 temp = (char *)xmalloc (1 + strlen (string) - *sindex);
527
528 for (j = 0, i = *sindex; c = string[i]; i++)
529 {
530 /* Process a character that was quoted by a backslash. */
531 if (pass_next)
532 {
533 /* Posix.2 sez:
534
535 ``The backslash shall retain its special meaning as an escape
536 character only when followed by one of the characters:
537 $ ` " \ <newline>''.
538
539 If STRIPDQ is zero, we handle the double quotes here and let
540 expand_word_internal handle the rest. If STRIPDQ is non-zero,
541 we have already been through one round of backslash stripping,
542 and want to strip these backslashes only if DQUOTE is non-zero,
543 indicating that we are inside an embedded double-quoted string. */
544
545 /* If we are in an embedded quoted string, then don't strip
546 backslashes before characters for which the backslash
547 retains its special meaning, but remove backslashes in
548 front of other characters. If we are not in an
549 embedded quoted string, don't strip backslashes at all.
550 This mess is necessary because the string was already
551 surrounded by double quotes (and sh has some really weird
552 quoting rules).
553 The returned string will be run through expansion as if
554 it were double-quoted. */
555 if ((stripdq == 0 && c != '"') ||
556 (stripdq && ((dquote && (sh_syntaxtab[c] & CBSDQUOTE)) || dquote == 0)))
557 temp[j++] = '\\';
558 temp[j++] = c;
559 pass_next = 0;
560 continue;
561 }
562
563 /* A backslash protects the next character. The code just above
564 handles preserving the backslash in front of any character but
565 a double quote. */
566 if (c == '\\')
567 {
568 pass_next++;
569 continue;
570 }
571
572 /* Inside backquotes, ``the portion of the quoted string from the
573 initial backquote and the characters up to the next backquote
574 that is not preceded by a backslash, having escape characters
575 removed, defines that command''. */
576 if (backquote)
577 {
578 if (c == '`')
579 backquote = 0;
580 temp[j++] = c;
581 continue;
582 }
583
584 if (c == '`')
585 {
586 temp[j++] = c;
587 backquote++;
588 continue;
589 }
590
591 /* Pass everything between `$(' and the matching `)' or a quoted
592 ${ ... } pair through according to the Posix.2 specification. */
593 if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
594 {
595 si = i + 2;
596 if (string[i + 1] == LPAREN)
597 ret = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
598 else
599 ret = extract_dollar_brace_string (string, &si, 1);
600
601 temp[j++] = '$';
602 temp[j++] = string[i + 1];
603
604 for (t = 0; ret[t]; t++, j++)
605 temp[j] = ret[t];
606 temp[j++] = string[si];
607
608 i = si;
609 free (ret);
610 continue;
611 }
612
613 /* Add any character but a double quote to the quoted string we're
614 accumulating. */
615 if (c != '"')
616 {
617 temp[j++] = c;
618 continue;
619 }
620
621 /* c == '"' */
622 if (stripdq)
623 {
624 dquote ^= 1;
625 continue;
626 }
627
628 break;
629 }
630 temp[j] = '\0';
631
632 /* Point to after the closing quote. */
633 if (c)
634 i++;
635 *sindex = i;
636
637 return (temp);
638 }
639
640 /* This should really be another option to string_extract_double_quoted. */
641 static int
642 skip_double_quoted (string, sind)
643 char *string;
644 int sind;
645 {
646 int c, i;
647 char *ret;
648 int pass_next, backquote, si;
649
650 pass_next = backquote = 0;
651
652 for (i = sind; c = string[i]; i++)
653 {
654 if (pass_next)
655 {
656 pass_next = 0;
657 continue;
658 }
659 else if (c == '\\')
660 {
661 pass_next++;
662 continue;
663 }
664 else if (backquote)
665 {
666 if (c == '`')
667 backquote = 0;
668 continue;
669 }
670 else if (c == '`')
671 {
672 backquote++;
673 continue;
674 }
675 else if (c == '$' && ((string[i + 1] == LPAREN) || (string[i + 1] == LBRACE)))
676 {
677 si = i + 2;
678 if (string[i + 1] == LPAREN)
679 ret = extract_delimited_string (string, &si, "$(", "(", ")");
680 else
681 ret = extract_dollar_brace_string (string, &si, 0);
682
683 i = si;
684 free (ret);
685 continue;
686 }
687 else if (c != '"')
688 continue;
689 else
690 break;
691 }
692
693 if (c)
694 i++;
695
696 return (i);
697 }
698
699 /* Extract the contents of STRING as if it is enclosed in single quotes.
700 SINDEX, when passed in, is the offset of the character immediately
701 following the opening single quote; on exit, SINDEX is left pointing after
702 the closing single quote. */
703 static inline char *
704 string_extract_single_quoted (string, sindex)
705 char *string;
706 int *sindex;
707 {
708 register int i;
709 char *t;
710
711 for (i = *sindex; string[i] && string[i] != '\''; i++)
712 ;
713
714 t = substring (string, *sindex, i);
715
716 if (string[i])
717 i++;
718 *sindex = i;
719
720 return (t);
721 }
722
723 static inline int
724 skip_single_quoted (string, sind)
725 char *string;
726 int sind;
727 {
728 register int c;
729
730 for (c = sind; string[c] && string[c] != '\''; c++)
731 ;
732 if (string[c])
733 c++;
734 return c;
735 }
736
737 /* Just like string_extract, but doesn't hack backslashes or any of
738 that other stuff. Obeys CTLESC quoting. Used to do splitting on $IFS. */
739 static char *
740 string_extract_verbatim (string, sindex, charlist)
741 char *string;
742 int *sindex;
743 char *charlist;
744 {
745 register int i = *sindex;
746 int c;
747 char *temp;
748
749 if (charlist[0] == '\'' && charlist[1] == '\0')
750 {
751 temp = string_extract_single_quoted (string, sindex);
752 --*sindex; /* leave *sindex at separator character */
753 return temp;
754 }
755
756 for (i = *sindex; c = string[i]; i++)
757 {
758 if (c == CTLESC)
759 {
760 i++;
761 continue;
762 }
763
764 if (MEMBER (c, charlist))
765 break;
766 }
767
768 temp = substring (string, *sindex, i);
769 *sindex = i;
770
771 return (temp);
772 }
773
774 /* Extract the $( construct in STRING, and return a new string.
775 Start extracting at (SINDEX) as if we had just seen "$(".
776 Make (SINDEX) get the position of the matching ")". */
777 char *
778 extract_command_subst (string, sindex)
779 char *string;
780 int *sindex;
781 {
782 return (extract_delimited_string (string, sindex, "$(", "(", ")"));
783 }
784
785 /* Extract the $[ construct in STRING, and return a new string. (])
786 Start extracting at (SINDEX) as if we had just seen "$[".
787 Make (SINDEX) get the position of the matching "]". */
788 char *
789 extract_arithmetic_subst (string, sindex)
790 char *string;
791 int *sindex;
792 {
793 return (extract_delimited_string (string, sindex, "$[", "[", "]")); /*]*/
794 }
795
796 #if defined (PROCESS_SUBSTITUTION)
797 /* Extract the <( or >( construct in STRING, and return a new string.
798 Start extracting at (SINDEX) as if we had just seen "<(".
799 Make (SINDEX) get the position of the matching ")". */ /*))*/
800 char *
801 extract_process_subst (string, starter, sindex)
802 char *string;
803 char *starter;
804 int *sindex;
805 {
806 return (extract_delimited_string (string, sindex, starter, "(", ")"));
807 }
808 #endif /* PROCESS_SUBSTITUTION */
809
810 #if defined (ARRAY_VARS)
811 char *
812 extract_array_assignment_list (string, sindex)
813 char *string;
814 int *sindex;
815 {
816 return (extract_delimited_string (string, sindex, "(", (char *)NULL, ")"));
817 }
818 #endif
819
820 /* Extract and create a new string from the contents of STRING, a
821 character string delimited with OPENER and CLOSER. SINDEX is
822 the address of an int describing the current offset in STRING;
823 it should point to just after the first OPENER found. On exit,
824 SINDEX gets the position of the last character of the matching CLOSER.
825 If OPENER is more than a single character, ALT_OPENER, if non-null,
826 contains a character string that can also match CLOSER and thus
827 needs to be skipped. */
828 static char *
829 extract_delimited_string (string, sindex, opener, alt_opener, closer)
830 char *string;
831 int *sindex;
832 char *opener, *alt_opener, *closer;
833 {
834 int i, c, si;
835 char *t, *result;
836 int pass_character, nesting_level;
837 int len_closer, len_opener, len_alt_opener;
838
839 len_opener = STRLEN (opener);
840 len_alt_opener = STRLEN (alt_opener);
841 len_closer = STRLEN (closer);
842
843 pass_character = 0;
844
845 nesting_level = 1;
846 i = *sindex;
847
848 while (nesting_level)
849 {
850 c = string[i];
851
852 if (c == 0)
853 break;
854
855 if (pass_character) /* previous char was backslash */
856 {
857 pass_character = 0;
858 i++;
859 continue;
860 }
861
862 if (c == CTLESC)
863 {
864 pass_character++;
865 i++;
866 continue;
867 }
868
869 if (c == '\\')
870 {
871 pass_character++;
872 i++;
873 continue;
874 }
875
876 /* Process a nested OPENER. */
877 if (STREQN (string + i, opener, len_opener))
878 {
879 si = i + len_opener;
880 t = extract_delimited_string (string, &si, opener, alt_opener, closer);
881 i = si + 1;
882 FREE (t);
883 continue;
884 }
885
886 /* Process a nested ALT_OPENER */
887 if (len_alt_opener && STREQN (string + i, alt_opener, len_alt_opener))
888 {
889 si = i + len_alt_opener;
890 t = extract_delimited_string (string, &si, alt_opener, alt_opener, closer);
891 i = si + 1;
892 FREE (t);
893 continue;
894 }
895
896 /* If the current substring terminates the delimited string, decrement
897 the nesting level. */
898 if (STREQN (string + i, closer, len_closer))
899 {
900 i += len_closer - 1; /* move to last char of the closer */
901 nesting_level--;
902 if (nesting_level == 0)
903 break;
904 }
905
906 /* Pass old-style command substitution through verbatim. */
907 if (c == '`')
908 {
909 si = i + 1;
910 t = string_extract (string, &si, "`", 0);
911 i = si + 1;
912 FREE (t);
913 continue;
914 }
915
916 /* Pass single-quoted strings through verbatim. */
917 if (c == '\'')
918 {
919 si = i + 1;
920 i = skip_single_quoted (string, si);
921 continue;
922 }
923
924 /* Pass embedded double-quoted strings through verbatim as well. */
925 if (c == '"')
926 {
927 si = i + 1;
928 i = skip_double_quoted (string, si);
929 continue;
930 }
931
932 i++; /* move past this character, which was not special. */
933 }
934
935 #if 0
936 if (c == 0 && nesting_level)
937 #else
938 if (c == 0 && nesting_level && no_longjmp_on_fatal_error == 0)
939 #endif
940 {
941 report_error ("bad substitution: no `%s' in %s", closer, string);
942 last_command_exit_value = EXECUTION_FAILURE;
943 jump_to_top_level (DISCARD);
944 }
945
946 si = i - *sindex - len_closer + 1;
947 result = (char *)xmalloc (1 + si);
948 strncpy (result, string + *sindex, si);
949 result[si] = '\0';
950 *sindex = i;
951
952 return (result);
953 }
954
955 /* Extract a parameter expansion expression within ${ and } from STRING.
956 Obey the Posix.2 rules for finding the ending `}': count braces while
957 skipping over enclosed quoted strings and command substitutions.
958 SINDEX is the address of an int describing the current offset in STRING;
959 it should point to just after the first `{' found. On exit, SINDEX
960 gets the position of the matching `}'. QUOTED is non-zero if this
961 occurs inside double quotes. */
962 /* XXX -- this is very similar to extract_delimited_string -- XXX */
963 static char *
964 extract_dollar_brace_string (string, sindex, quoted)
965 char *string;
966 int *sindex, quoted;
967 {
968 register int i, c;
969 int pass_character, nesting_level, si;
970 char *result, *t;
971
972 pass_character = 0;
973
974 nesting_level = 1;
975
976 for (i = *sindex; (c = string[i]); i++)
977 {
978 if (pass_character)
979 {
980 pass_character = 0;
981 continue;
982 }
983
984 /* CTLESCs and backslashes quote the next character. */
985 if (c == CTLESC || c == '\\')
986 {
987 pass_character++;
988 continue;
989 }
990
991 if (string[i] == '$' && string[i+1] == LBRACE)
992 {
993 nesting_level++;
994 i++;
995 continue;
996 }
997
998 if (c == RBRACE)
999 {
1000 nesting_level--;
1001 if (nesting_level == 0)
1002 break;
1003 continue;
1004 }
1005
1006 /* Pass the contents of old-style command substitutions through
1007 verbatim. */
1008 if (c == '`')
1009 {
1010 si = i + 1;
1011 t = string_extract (string, &si, "`", 0);
1012 i = si;
1013 free (t);
1014 continue;
1015 }
1016
1017 /* Pass the contents of new-style command substitutions and
1018 arithmetic substitutions through verbatim. */
1019 if (string[i] == '$' && string[i+1] == LPAREN)
1020 {
1021 si = i + 2;
1022 t = extract_delimited_string (string, &si, "$(", "(", ")"); /*)*/
1023 i = si;
1024 free (t);
1025 continue;
1026 }
1027
1028 /* Pass the contents of single-quoted and double-quoted strings
1029 through verbatim. */
1030 if (c == '\'' || c == '"')
1031 {
1032 si = i + 1;
1033 i = (c == '\'') ? skip_single_quoted (string, si)
1034 : skip_double_quoted (string, si);
1035 /* skip_XXX_quoted leaves index one past close quote */
1036 i--;
1037 continue;
1038 }
1039 }
1040
1041 if (c == 0 && nesting_level && no_longjmp_on_fatal_error == 0)
1042 {
1043 report_error ("bad substitution: no ending `}' in %s", string);
1044 last_command_exit_value = EXECUTION_FAILURE;
1045 jump_to_top_level (DISCARD);
1046 }
1047
1048 result = substring (string, *sindex, i);
1049 *sindex = i;
1050
1051 return (result);
1052 }
1053
1054 /* Remove backslashes which are quoting backquotes from STRING. Modifies
1055 STRING, and returns a pointer to it. */
1056 char *
1057 de_backslash (string)
1058 char *string;
1059 {
1060 register int i, l;
1061
1062 for (i = 0, l = strlen (string); i < l; i++)
1063 if (string[i] == '\\' && (string[i + 1] == '`' || string[i + 1] == '\\' ||
1064 string[i + 1] == '$'))
1065 strcpy (string + i, string + i + 1); /* XXX - should be memmove */
1066 return (string);
1067 }
1068
1069 #if 0
1070 /*UNUSED*/
1071 /* Replace instances of \! in a string with !. */
1072 void
1073 unquote_bang (string)
1074 char *string;
1075 {
1076 register int i, j;
1077 register char *temp;
1078
1079 temp = (char *)xmalloc (1 + strlen (string));
1080
1081 for (i = 0, j = 0; (temp[j] = string[i]); i++, j++)
1082 {
1083 if (string[i] == '\\' && string[i + 1] == '!')
1084 {
1085 temp[j] = '!';
1086 i++;
1087 }
1088 }
1089 strcpy (string, temp);
1090 free (temp);
1091 }
1092 #endif
1093
1094 #if defined (READLINE)
1095 /* Return 1 if the portion of STRING ending at EINDEX is quoted (there is
1096 an unclosed quoted string), or if the character at EINDEX is quoted
1097 by a backslash. NO_LONGJMP_ON_FATAL_ERROR is used to flag that the various
1098 single and double-quoted string parsing functions should not return an
1099 error if there are unclosed quotes or braces. */
1100
1101 #define CQ_RETURN(x) do { no_longjmp_on_fatal_error = 0; return (x); } while (0)
1102
1103 int
1104 char_is_quoted (string, eindex)
1105 char *string;
1106 int eindex;
1107 {
1108 int i, pass_next;
1109
1110 no_longjmp_on_fatal_error = 1;
1111 for (i = pass_next = 0; i <= eindex; i++)
1112 {
1113 if (pass_next)
1114 {
1115 pass_next = 0;
1116 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1117 CQ_RETURN(1);
1118 continue;
1119 }
1120 else if (string[i] == '\'' || string[i] == '"')
1121 {
1122 i = (string[i] == '\'') ? skip_single_quoted (string, ++i)
1123 : skip_double_quoted (string, ++i);
1124 if (i > eindex)
1125 CQ_RETURN(1);
1126 i--; /* the skip functions increment past the closing quote. */
1127 }
1128 else if (string[i] == '\\')
1129 {
1130 pass_next = 1;
1131 continue;
1132 }
1133 }
1134 CQ_RETURN(0);
1135 }
1136
1137 int
1138 unclosed_pair (string, eindex, openstr)
1139 char *string;
1140 int eindex;
1141 char *openstr;
1142 {
1143 int i, pass_next, openc, olen;
1144
1145 olen = strlen (openstr);
1146 for (i = pass_next = openc = 0; i <= eindex; i++)
1147 {
1148 if (pass_next)
1149 {
1150 pass_next = 0;
1151 if (i >= eindex) /* XXX was if (i >= eindex - 1) */
1152 return 0;
1153 continue;
1154 }
1155 else if (STREQN (string + i, openstr, olen))
1156 {
1157 openc = 1 - openc;
1158 i += olen - 1;
1159 }
1160 else if (string[i] == '\'' || string[i] == '"')
1161 {
1162 i = (string[i] == '\'') ? skip_single_quoted (string, i)
1163 : skip_double_quoted (string, i);
1164 if (i > eindex)
1165 return 0;
1166 }
1167 else if (string[i] == '\\')
1168 {
1169 pass_next = 1;
1170 continue;
1171 }
1172 }
1173 return (openc);
1174 }
1175
1176 /* Skip characters in STRING until we find a character in DELIMS, and return
1177 the index of that character. START is the index into string at which we
1178 begin. This is similar in spirit to strpbrk, but it returns an index into
1179 STRING and takes a starting index. This little piece of code knows quite
1180 a lot of shell syntax. It's very similar to skip_double_quoted and other
1181 functions of that ilk. */
1182 int
1183 skip_to_delim (string, start, delims)
1184 char *string;
1185 int start;
1186 char *delims;
1187 {
1188 int i, pass_next, backq, si;
1189 char *temp;
1190
1191 no_longjmp_on_fatal_error = 1;
1192 for (i = start, pass_next = backq = 0; string[i]; i++)
1193 {
1194 if (pass_next)
1195 {
1196 pass_next = 0;
1197 if (string[i] == 0)
1198 CQ_RETURN(i);
1199 continue;
1200 }
1201 else if (string[i] == '\\')
1202 {
1203 pass_next = 1;
1204 continue;
1205 }
1206 else if (backq)
1207 {
1208 if (string[i] == '`')
1209 backq = 0;
1210 continue;
1211 }
1212 else if (string[i] == '`')
1213 {
1214 backq = 1;
1215 continue;
1216 }
1217 else if (string[i] == '\'' || string[i] == '"')
1218 {
1219 i = (string[i] == '\'') ? skip_single_quoted (string, ++i)
1220 : skip_double_quoted (string, ++i);
1221 i--; /* the skip functions increment past the closing quote. */
1222 }
1223 else if (string[i] == '$' && (string[i+1] == LPAREN || string[i+1] == LBRACE))
1224 {
1225 si = i + 2;
1226 if (string[si] == '\0')
1227 CQ_RETURN(si);
1228
1229 if (string[i+1] == LPAREN)
1230 temp = extract_delimited_string (string, &si, "$(", "(", ")"); /* ) */
1231 else
1232 temp = extract_dollar_brace_string (string, &si, 0);
1233 i = si;
1234 free (temp);
1235 if (string[i] == '\0') /* don't increment i past EOS in loop */
1236 break;
1237 continue;
1238 }
1239 else if (member (string[i], delims))
1240 break;
1241 }
1242 CQ_RETURN(i);
1243 }
1244
1245 /* Split STRING (length SLEN) at DELIMS, and return a WORD_LIST with the
1246 individual words. If DELIMS is NULL, the current value of $IFS is used
1247 to split the string. SENTINEL is an index to look for. NWP, if non-NULL
1248 gets the number of words in the returned list. CWP, if non-NULL, gets
1249 the index of the word containing SENTINEL. Non-whitespace chars in
1250 DELIMS delimit separate fields. */
1251 WORD_LIST *
1252 split_at_delims (string, slen, delims, sentinel, nwp, cwp)
1253 char *string;
1254 int slen;
1255 char *delims;
1256 int sentinel;
1257 int *nwp, *cwp;
1258 {
1259 int ts, te, i, nw, cw;
1260 char *token, *d, *d2;
1261 WORD_LIST *ret, *tl;
1262
1263 if (string == 0 || *string == '\0')
1264 {
1265 if (nwp)
1266 *nwp = 0;
1267 if (cwp)
1268 *cwp = 0;
1269 return ((WORD_LIST *)NULL);
1270 }
1271
1272 d = (delims == 0) ? getifs () : delims;
1273
1274 /* Make d2 the non-whitespace characters in delims */
1275 d2 = 0;
1276 if (delims)
1277 {
1278 d2 = (char *)xmalloc (strlen (delims) + 1);
1279 for (i = ts = 0; delims[i]; i++)
1280 {
1281 if (whitespace(delims[i]) == 0)
1282 d2[ts++] = delims[i];
1283 }
1284 d2[ts] = '\0';
1285 }
1286
1287 ret = (WORD_LIST *)NULL;
1288
1289 for (i = 0; member (string[i], d) && (whitespace(string[i]) || string[i] == '\n'); i++)
1290 ;
1291 if (string[i] == '\0')
1292 return (ret);
1293
1294 ts = i;
1295 nw = 0;
1296 cw = -1;
1297 while (1)
1298 {
1299 te = skip_to_delim (string, ts, d);
1300
1301 /* If we have a non-whitespace delimiter character, use it to make a
1302 separate field. This is just about what $IFS splitting does and
1303 is closer to the behavior of the shell parser. */
1304 if (ts == te && d2 && member (string[ts], d2))
1305 {
1306 te = ts + 1;
1307 while (member (string[te], d2))
1308 te++;
1309 }
1310
1311 token = substring (string, ts, te);
1312
1313 ret = add_string_to_list (token, ret);
1314 free (token);
1315 nw++;
1316
1317 if (sentinel >= ts && sentinel <= te)
1318 cw = nw;
1319
1320 /* If the cursor is at whitespace just before word start, set the
1321 sentinel word to the current word. */
1322 if (cwp && cw == -1 && sentinel == ts-1)
1323 cw = nw;
1324
1325 /* If the cursor is at whitespace between two words, make a new, empty
1326 word, add it before (well, after, since the list is in reverse order)
1327 the word we just added, and set the current word to that one. */
1328 if (cwp && cw == -1 && sentinel < ts)
1329 {
1330 tl = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
1331 tl->word = make_word ("");
1332 tl->next = ret->next;
1333 ret->next = tl;
1334 cw = nw;
1335 nw++;
1336 }
1337
1338 if (string[te] == 0)
1339 break;
1340
1341 i = te /* + member (string[te], d) */;
1342 while (member (string[i], d) && whitespace(string[i]))
1343 i++;
1344
1345 if (string[i])
1346 ts = i;
1347 else
1348 break;
1349 }
1350
1351 /* Special case for SENTINEL at the end of STRING. If we haven't found
1352 the word containing SENTINEL yet, and the index we're looking for is at
1353 the end of STRING, add an additional null argument and set the current
1354 word pointer to that. */
1355 if (cwp && cw == -1 && sentinel >= slen)
1356 {
1357 if (whitespace (string[sentinel - 1]))
1358 {
1359 token = "";
1360 ret = add_string_to_list (token, ret);
1361 nw++;
1362 }
1363 cw = nw;
1364 }
1365
1366 if (nwp)
1367 *nwp = nw;
1368 if (cwp)
1369 *cwp = cw;
1370
1371 return (REVERSE_LIST (ret, WORD_LIST *));
1372 }
1373 #endif /* READLINE */
1374
1375 #if 0
1376 /* UNUSED */
1377 /* Extract the name of the variable to bind to from the assignment string. */
1378 char *
1379 assignment_name (string)
1380 char *string;
1381 {
1382 int offset;
1383 char *temp;
1384
1385 offset = assignment (string);
1386 if (offset == 0)
1387 return (char *)NULL;
1388 temp = substring (string, 0, offset);
1389 return (temp);
1390 }
1391 #endif
1392
1393 /* **************************************************************** */
1394 /* */
1395 /* Functions to convert strings to WORD_LISTs and vice versa */
1396 /* */
1397 /* **************************************************************** */
1398
1399 /* Return a single string of all the words in LIST. SEP is the separator
1400 to put between individual elements of LIST in the output string. */
1401 static char *
1402 string_list_internal (list, sep)
1403 WORD_LIST *list;
1404 char *sep;
1405 {
1406 register WORD_LIST *t;
1407 char *result, *r;
1408 int word_len, sep_len, result_size;
1409
1410 if (list == 0)
1411 return ((char *)NULL);
1412
1413 /* This is nearly always called with either sep[0] == 0 or sep[1] == 0. */
1414 sep_len = STRLEN (sep);
1415 result_size = 0;
1416
1417 for (t = list; t; t = t->next)
1418 {
1419 if (t != list)
1420 result_size += sep_len;
1421 result_size += strlen (t->word->word);
1422 }
1423
1424 r = result = (char *)xmalloc (result_size + 1);
1425
1426 for (t = list; t; t = t->next)
1427 {
1428 if (t != list && sep_len)
1429 {
1430 if (sep_len > 1)
1431 {
1432 FASTCOPY (sep, r, sep_len);
1433 r += sep_len;
1434 }
1435 else
1436 *r++ = sep[0];
1437 }
1438
1439 word_len = strlen (t->word->word);
1440 FASTCOPY (t->word->word, r, word_len);
1441 r += word_len;
1442 }
1443
1444 *r = '\0';
1445 return (result);
1446 }
1447
1448 /* Return a single string of all the words present in LIST, separating
1449 each word with a space. */
1450 char *
1451 string_list (list)
1452 WORD_LIST *list;
1453 {
1454 return (string_list_internal (list, " "));
1455 }
1456
1457 /* Return a single string of all the words present in LIST, obeying the
1458 quoting rules for "$*", to wit: (P1003.2, draft 11, 3.5.2) "If the
1459 expansion [of $*] appears within a double quoted string, it expands
1460 to a single field with the value of each parameter separated by the
1461 first character of the IFS variable, or by a <space> if IFS is unset." */
1462 char *
1463 string_list_dollar_star (list)
1464 WORD_LIST *list;
1465 {
1466 char *ifs, sep[2];
1467
1468 ifs = get_string_value ("IFS");
1469
1470 sep[0] = (ifs == 0) ? ' ' : *ifs;
1471 sep[1] = '\0';
1472
1473 return (string_list_internal (list, sep));
1474 }
1475
1476 /* Turn $@ into a string. If (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
1477 is non-zero, the $@ appears within double quotes, and we should quote
1478 the list before converting it into a string. If IFS is unset, and the
1479 word is not quoted, we just need to quote CTLESC and CTLNUL characters
1480 in the words in the list, because the default value of $IFS is
1481 <space><tab><newline>, IFS characters in the words in the list should
1482 also be split. If IFS is null, and the word is not quoted, we need
1483 to quote the words in the list to preserve the positional parameters
1484 exactly. */
1485 char *
1486 string_list_dollar_at (list, quoted)
1487 WORD_LIST *list;
1488 int quoted;
1489 {
1490 char *ifs, sep[2];
1491 WORD_LIST *tlist;
1492
1493 ifs = get_string_value ("IFS");
1494
1495 sep[0] = (ifs == 0 || *ifs == 0) ? ' ' : *ifs;
1496 sep[1] = '\0';
1497
1498 tlist = ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (ifs && *ifs == 0))
1499 ? quote_list (list)
1500 : list_quote_escapes (list);
1501 return (string_list_internal (tlist, sep));
1502 }
1503
1504 /* Return the list of words present in STRING. Separate the string into
1505 words at any of the characters found in SEPARATORS. If QUOTED is
1506 non-zero then word in the list will have its quoted flag set, otherwise
1507 the quoted flag is left as make_word () deemed fit.
1508
1509 This obeys the P1003.2 word splitting semantics. If `separators' is
1510 exactly <space><tab><newline>, then the splitting algorithm is that of
1511 the Bourne shell, which treats any sequence of characters from `separators'
1512 as a delimiter. If IFS is unset, which results in `separators' being set
1513 to "", no splitting occurs. If separators has some other value, the
1514 following rules are applied (`IFS white space' means zero or more
1515 occurrences of <space>, <tab>, or <newline>, as long as those characters
1516 are in `separators'):
1517
1518 1) IFS white space is ignored at the start and the end of the
1519 string.
1520 2) Each occurrence of a character in `separators' that is not
1521 IFS white space, along with any adjacent occurrences of
1522 IFS white space delimits a field.
1523 3) Any nonzero-length sequence of IFS white space delimits a field.
1524 */
1525
1526 /* BEWARE! list_string strips null arguments. Don't call it twice and
1527 expect to have "" preserved! */
1528
1529 /* This performs word splitting and quoted null character removal on
1530 STRING. */
1531 #define issep(c) (member ((c), separators))
1532
1533 WORD_LIST *
1534 list_string (string, separators, quoted)
1535 register char *string, *separators;
1536 int quoted;
1537 {
1538 WORD_LIST *result;
1539 WORD_DESC *t;
1540 char *current_word, *s;
1541 int sindex, sh_style_split, whitesep;
1542
1543 if (!string || !*string)
1544 return ((WORD_LIST *)NULL);
1545
1546 sh_style_split =
1547 separators && *separators && (STREQ (separators, " \t\n"));
1548
1549 /* Remove sequences of whitespace at the beginning of STRING, as
1550 long as those characters appear in IFS. Do not do this if
1551 STRING is quoted or if there are no separator characters. */
1552 if (!quoted || !separators || !*separators)
1553 {
1554 for (s = string; *s && spctabnl (*s) && issep (*s); s++);
1555
1556 if (!*s)
1557 return ((WORD_LIST *)NULL);
1558
1559 string = s;
1560 }
1561
1562 /* OK, now STRING points to a word that does not begin with white space.
1563 The splitting algorithm is:
1564 extract a word, stopping at a separator
1565 skip sequences of spc, tab, or nl as long as they are separators
1566 This obeys the field splitting rules in Posix.2. */
1567 for (result = (WORD_LIST *)NULL, sindex = 0; string[sindex]; )
1568 {
1569 current_word = string_extract_verbatim (string, &sindex, separators);
1570 if (current_word == 0)
1571 break;
1572
1573 /* If we have a quoted empty string, add a quoted null argument. We
1574 want to preserve the quoted null character iff this is a quoted
1575 empty string; otherwise the quoted null characters are removed
1576 below. */
1577 if (QUOTED_NULL (current_word))
1578 {
1579 t = make_bare_word ("");
1580 t->flags |= W_QUOTED;
1581 free (t->word);
1582 t->word = make_quoted_char ('\0');
1583 result = make_word_list (t, result);
1584 }
1585 else if (current_word[0] != '\0')
1586 {
1587 /* If we have something, then add it regardless. However,
1588 perform quoted null character removal on the current word. */
1589 remove_quoted_nulls (current_word);
1590 result = add_string_to_list (current_word, result);
1591 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT))
1592 result->word->flags |= W_QUOTED;
1593 }
1594
1595 /* If we're not doing sequences of separators in the traditional
1596 Bourne shell style, then add a quoted null argument. */
1597 else if (!sh_style_split && !spctabnl (string[sindex]))
1598 {
1599 t = make_bare_word ("");
1600 t->flags |= W_QUOTED;
1601 free (t->word);
1602 t->word = make_quoted_char ('\0');
1603 result = make_word_list (t, result);
1604 }
1605
1606 free (current_word);
1607
1608 /* Note whether or not the separator is IFS whitespace, used later. */
1609 whitesep = string[sindex] && spctabnl (string[sindex]);
1610
1611 /* Move past the current separator character. */
1612 if (string[sindex])
1613 sindex++;
1614
1615 /* Now skip sequences of space, tab, or newline characters if they are
1616 in the list of separators. */
1617 while (string[sindex] && spctabnl (string[sindex]) && issep (string[sindex]))
1618 sindex++;
1619
1620 /* If the first separator was IFS whitespace and the current character is
1621 a non-whitespace IFS character, it should be part of the current field
1622 delimiter, not a separate delimiter that would result in an empty field.
1623 Look at POSIX.2, 3.6.5, (3)(b). */
1624 if (string[sindex] && whitesep && issep (string[sindex]) && !spctabnl (string[sindex]))
1625 sindex++;
1626 }
1627 return (REVERSE_LIST (result, WORD_LIST *));
1628 }
1629
1630 /* Parse a single word from STRING, using SEPARATORS to separate fields.
1631 ENDPTR is set to the first character after the word. This is used by
1632 the `read' builtin.
1633 XXX - this function is very similar to list_string; they should be
1634 combined - XXX */
1635 char *
1636 get_word_from_string (stringp, separators, endptr)
1637 char **stringp, *separators, **endptr;
1638 {
1639 register char *s;
1640 char *current_word;
1641 int sindex, sh_style_split, whitesep;
1642
1643 if (!stringp || !*stringp || !**stringp)
1644 return ((char *)NULL);
1645
1646 s = *stringp;
1647
1648 sh_style_split =
1649 separators && *separators && (STREQ (separators, " \t\n"));
1650
1651 /* Remove sequences of whitespace at the beginning of STRING, as
1652 long as those characters appear in IFS. */
1653 if (sh_style_split || !separators || !*separators)
1654 {
1655 for (; *s && spctabnl (*s) && issep (*s); s++);
1656
1657 /* If the string is nothing but whitespace, update it and return. */
1658 if (!*s)
1659 {
1660 *stringp = s;
1661 if (endptr)
1662 *endptr = s;
1663 return ((char *)NULL);
1664 }
1665 }
1666
1667 /* OK, S points to a word that does not begin with white space.
1668 Now extract a word, stopping at a separator, save a pointer to
1669 the first character after the word, then skip sequences of spc,
1670 tab, or nl as long as they are separators.
1671
1672 This obeys the field splitting rules in Posix.2. */
1673 sindex = 0;
1674 current_word = string_extract_verbatim (s, &sindex, separators);
1675
1676 /* Set ENDPTR to the first character after the end of the word. */
1677 if (endptr)
1678 *endptr = s + sindex;
1679
1680 /* Note whether or not the separator is IFS whitespace, used later. */
1681 whitesep = s[sindex] && spctabnl (s[sindex]);
1682
1683 /* Move past the current separator character. */
1684 if (s[sindex])
1685 sindex++;
1686
1687 /* Now skip sequences of space, tab, or newline characters if they are
1688 in the list of separators. */
1689 while (s[sindex] && spctabnl (s[sindex]) && issep (s[sindex]))
1690 sindex++;
1691
1692 /* If the first separator was IFS whitespace and the current character is
1693 a non-whitespace IFS character, it should be part of the current field
1694 delimiter, not a separate delimiter that would result in an empty field.
1695 Look at POSIX.2, 3.6.5, (3)(b). */
1696 if (s[sindex] && whitesep && issep (s[sindex]) && !spctabnl (s[sindex]))
1697 sindex++;
1698
1699 /* Update STRING to point to the next field. */
1700 *stringp = s + sindex;
1701 return (current_word);
1702 }
1703
1704 /* Remove IFS white space at the end of STRING. Start at the end
1705 of the string and walk backwards until the beginning of the string
1706 or we find a character that's not IFS white space and not CTLESC.
1707 Only let CTLESC escape a white space character if SAW_ESCAPE is
1708 non-zero. */
1709 char *
1710 strip_trailing_ifs_whitespace (string, separators, saw_escape)
1711 char *string, *separators;
1712 int saw_escape;
1713 {
1714 char *s;
1715
1716 s = string + STRLEN (string) - 1;
1717 while (s > string && ((spctabnl (*s) && issep (*s)) ||
1718 (saw_escape && *s == CTLESC && spctabnl (s[1]))))
1719 s--;
1720 *++s = '\0';
1721 return string;
1722 }
1723
1724 #if 0
1725 /* UNUSED */
1726 /* Split STRING into words at whitespace. Obeys shell-style quoting with
1727 backslashes, single and double quotes. */
1728 WORD_LIST *
1729 list_string_with_quotes (string)
1730 char *string;
1731 {
1732 WORD_LIST *list;
1733 char *token, *s;
1734 int c, i, tokstart, len;
1735
1736 for (s = string; s && *s && spctabnl (*s); s++)
1737 ;
1738 if (s == 0 || *s == 0)
1739 return ((WORD_LIST *)NULL);
1740
1741 tokstart = i = 0;
1742 list = (WORD_LIST *)NULL;
1743 while (1)
1744 {
1745 c = s[i];
1746 if (c == '\\')
1747 {
1748 i++;
1749 if (s[i])
1750 i++;
1751 }
1752 else if (c == '\'')
1753 i = skip_single_quoted (s, ++i);
1754 else if (c == '"')
1755 i = skip_double_quoted (s, ++i);
1756 else if (c == 0 || spctabnl (c))
1757 {
1758 /* We have found the end of a token. Make a word out of it and
1759 add it to the word list. */
1760 token = substring (s, tokstart, i);
1761 list = add_string_to_list (token, list);
1762 free (token);
1763 while (spctabnl (s[i]))
1764 i++;
1765 if (s[i])
1766 tokstart = i;
1767 else
1768 break;
1769 }
1770 else
1771 i++; /* normal character */
1772 }
1773 return (REVERSE_LIST (list, WORD_LIST *));
1774 }
1775 #endif
1776
1777 /********************************************************/
1778 /* */
1779 /* Functions to perform assignment statements */
1780 /* */
1781 /********************************************************/
1782
1783 /* Given STRING, an assignment string, get the value of the right side
1784 of the `=', and bind it to the left side. If EXPAND is true, then
1785 perform parameter expansion, command substitution, and arithmetic
1786 expansion on the right-hand side. Perform tilde expansion in any
1787 case. Do not perform word splitting on the result of expansion. */
1788 static int
1789 do_assignment_internal (string, expand)
1790 const char *string;
1791 int expand;
1792 {
1793 int offset;
1794 char *name, *value;
1795 SHELL_VAR *entry;
1796 #if defined (ARRAY_VARS)
1797 char *t;
1798 int ni, assign_list = 0;
1799 #endif
1800
1801 offset = assignment (string);
1802 name = savestring (string);
1803 value = (char *)NULL;
1804
1805 if (name[offset] == '=')
1806 {
1807 char *temp;
1808
1809 name[offset] = 0;
1810 temp = name + offset + 1;
1811
1812 #if defined (ARRAY_VARS)
1813 if (expand && temp[0] == LPAREN && strchr (temp, RPAREN))
1814 {
1815 assign_list = ni = 1;
1816 value = extract_delimited_string (temp, &ni, "(", (char *)NULL, ")");
1817 }
1818 else
1819 #endif
1820
1821 /* Perform tilde expansion. */
1822 if (expand && temp[0])
1823 {
1824 temp = (strchr (temp, '~') && unquoted_member ('~', temp))
1825 ? bash_tilde_expand (temp)
1826 : savestring (temp);
1827
1828 value = expand_string_if_necessary (temp, 0, expand_string_unsplit);
1829 free (temp);
1830 }
1831 else
1832 value = savestring (temp);
1833 }
1834
1835 if (value == 0)
1836 {
1837 value = (char *)xmalloc (1);
1838 value[0] = '\0';
1839 }
1840
1841 if (echo_command_at_execute)
1842 {
1843 #if defined (ARRAY_VARS)
1844 if (assign_list)
1845 fprintf (stderr, "%s%s=(%s)\n", indirection_level_string (), name, value);
1846 else
1847 #endif
1848 fprintf (stderr, "%s%s=%s\n", indirection_level_string (), name, value);
1849 }
1850
1851 #define ASSIGN_RETURN(r) do { FREE (value); free (name); return (r); } while (0)
1852
1853 #if defined (ARRAY_VARS)
1854 if (t = strchr (name, '[')) /*]*/
1855 {
1856 if (assign_list)
1857 {
1858 report_error ("%s: cannot assign list to array member", name);
1859 ASSIGN_RETURN (0);
1860 }
1861 entry = assign_array_element (name, value);
1862 if (entry == 0)
1863 ASSIGN_RETURN (0);
1864 }
1865 else if (assign_list)
1866 entry = assign_array_from_string (name, value);
1867 else
1868 #endif /* ARRAY_VARS */
1869 entry = bind_variable (name, value);
1870
1871 stupidly_hack_special_variables (name);
1872
1873 if (entry)
1874 VUNSETATTR (entry, att_invisible);
1875
1876 /* Return 1 if the assignment seems to have been performed correctly. */
1877 ASSIGN_RETURN (entry ? ((readonly_p (entry) == 0) && noassign_p (entry) == 0) : 0);
1878 }
1879
1880 /* Perform the assignment statement in STRING, and expand the
1881 right side by doing command and parameter expansion. */
1882 int
1883 do_assignment (string)
1884 const char *string;
1885 {
1886 return do_assignment_internal (string, 1);
1887 }
1888
1889 /* Given STRING, an assignment string, get the value of the right side
1890 of the `=', and bind it to the left side. Do not do command and
1891 parameter substitution on the right hand side. */
1892 int
1893 do_assignment_no_expand (string)
1894 const char *string;
1895 {
1896 return do_assignment_internal (string, 0);
1897 }
1898
1899 /***************************************************
1900 * *
1901 * Functions to manage the positional parameters *
1902 * *
1903 ***************************************************/
1904
1905 /* Return the word list that corresponds to `$*'. */
1906 WORD_LIST *
1907 list_rest_of_args ()
1908 {
1909 register WORD_LIST *list, *args;
1910 int i;
1911
1912 /* Break out of the loop as soon as one of the dollar variables is null. */
1913 for (i = 1, list = (WORD_LIST *)NULL; i < 10 && dollar_vars[i]; i++)
1914 list = make_word_list (make_bare_word (dollar_vars[i]), list);
1915
1916 for (args = rest_of_args; args; args = args->next)
1917 list = make_word_list (make_bare_word (args->word->word), list);
1918
1919 return (REVERSE_LIST (list, WORD_LIST *));
1920 }
1921
1922 int
1923 number_of_args ()
1924 {
1925 register WORD_LIST *list;
1926 int n;
1927
1928 for (n = 0; n < 9 && dollar_vars[n+1]; n++)
1929 ;
1930 for (list = rest_of_args; list; list = list->next)
1931 n++;
1932 return n;
1933 }
1934
1935 /* Return the value of a positional parameter. This handles values > 10. */
1936 char *
1937 get_dollar_var_value (ind)
1938 long ind;
1939 {
1940 char *temp;
1941 WORD_LIST *p;
1942
1943 if (ind < 10)
1944 temp = dollar_vars[ind] ? savestring (dollar_vars[ind]) : (char *)NULL;
1945 else /* We want something like ${11} */
1946 {
1947 ind -= 10;
1948 for (p = rest_of_args; p && ind--; p = p->next)
1949 ;
1950 temp = p ? savestring (p->word->word) : (char *)NULL;
1951 }
1952 return (temp);
1953 }
1954
1955 /* Make a single large string out of the dollar digit variables,
1956 and the rest_of_args. If DOLLAR_STAR is 1, then obey the special
1957 case of "$*" with respect to IFS. */
1958 char *
1959 string_rest_of_args (dollar_star)
1960 int dollar_star;
1961 {
1962 register WORD_LIST *list;
1963 char *string;
1964
1965 list = list_rest_of_args ();
1966 string = dollar_star ? string_list_dollar_star (list) : string_list (list);
1967 dispose_words (list);
1968 return (string);
1969 }
1970
1971 /* Return a string containing the positional parameters from START to
1972 END, inclusive. If STRING[0] == '*', we obey the rules for $*,
1973 which only makes a difference if QUOTED is non-zero. */
1974 static char *
1975 pos_params (string, start, end, quoted)
1976 char *string;
1977 int start, end, quoted;
1978 {
1979 WORD_LIST *save, *params, *h, *t;
1980 char *ret;
1981 int i;
1982
1983 /* see if we can short-circuit. if start == end, we want 0 parameters. */
1984 if (start == end)
1985 return ((char *)NULL);
1986
1987 save = params = list_rest_of_args ();
1988 if (save == 0)
1989 return ((char *)NULL);
1990
1991 for (i = 1; params && i < start; i++)
1992 params = params->next;
1993 if (params == 0)
1994 return ((char *)NULL);
1995 for (h = t = params; params && i < end; i++)
1996 {
1997 t = params;
1998 params = params->next;
1999 }
2000
2001 t->next = (WORD_LIST *)NULL;
2002 if (string[0] == '*')
2003 ret = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (h) : string_list (h);
2004 else
2005 ret = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (h) : h);
2006 if (t != params)
2007 t->next = params;
2008
2009 dispose_words (save);
2010 return (ret);
2011 }
2012
2013 /******************************************************************/
2014 /* */
2015 /* Functions to expand strings to strings or WORD_LISTs */
2016 /* */
2017 /******************************************************************/
2018
2019 #if defined (PROCESS_SUBSTITUTION)
2020 #define EXP_CHAR(s) (s == '$' || s == '`' || s == '<' || s == '>' || s == CTLESC)
2021 #else
2022 #define EXP_CHAR(s) (s == '$' || s == '`' || s == CTLESC)
2023 #endif
2024
2025 /* If there are any characters in STRING that require full expansion,
2026 then call FUNC to expand STRING; otherwise just perform quote
2027 removal if necessary. This returns a new string. */
2028 static char *
2029 expand_string_if_necessary (string, quoted, func)
2030 char *string;
2031 int quoted;
2032 EXPFUNC *func;
2033 {
2034 WORD_LIST *list;
2035 int i, saw_quote;
2036 char *ret;
2037
2038 for (i = saw_quote = 0; string[i]; i++)
2039 {
2040 if (EXP_CHAR (string[i]))
2041 break;
2042 else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"')
2043 saw_quote = 1;
2044 }
2045
2046 if (string[i])
2047 {
2048 list = (*func) (string, quoted);
2049 if (list)
2050 {
2051 ret = string_list (list);
2052 dispose_words (list);
2053 }
2054 else
2055 ret = (char *)NULL;
2056 }
2057 else if (saw_quote && ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) == 0))
2058 ret = string_quote_removal (string, quoted);
2059 else
2060 ret = savestring (string);
2061 return ret;
2062 }
2063
2064 static inline char *
2065 expand_string_to_string_internal (string, quoted, func)
2066 char *string;
2067 int quoted;
2068 EXPFUNC *func;
2069 {
2070 WORD_LIST *list;
2071 char *ret;
2072
2073 if (string == 0 || *string == '\0')
2074 return ((char *)NULL);
2075
2076 list = (*func) (string, quoted);
2077 if (list)
2078 {
2079 ret = string_list (list);
2080 dispose_words (list);
2081 }
2082 else
2083 ret = (char *)NULL;
2084
2085 return (ret);
2086 }
2087
2088 char *
2089 expand_string_to_string (string, quoted)
2090 char *string;
2091 int quoted;
2092 {
2093 return (expand_string_to_string_internal (string, quoted, expand_string));
2094 }
2095
2096 char *
2097 expand_string_unsplit_to_string (string, quoted)
2098 char *string;
2099 int quoted;
2100 {
2101 return (expand_string_to_string_internal (string, quoted, expand_string_unsplit));
2102 }
2103
2104 #if defined (COND_COMMAND)
2105 /* Just remove backslashes in STRING. Returns a new string. */
2106 char *
2107 remove_backslashes (string)
2108 char *string;
2109 {
2110 char *r, *ret, *s;
2111
2112 r = ret = (char *)xmalloc (strlen (string) + 1);
2113 for (s = string; s && *s; )
2114 {
2115 if (*s == '\\')
2116 s++;
2117 if (*s == 0)
2118 break;
2119 *r++ = *s++;
2120 }
2121 *r = '\0';
2122 return ret;
2123 }
2124
2125 /* This needs better error handling. */
2126 /* Expand W for use as an argument to a unary or binary operator in a
2127 [[...]] expression. If SPECIAL is nonzero, this is the rhs argument
2128 to the != or == operator, and should be treated as a pattern. In
2129 this case, we quote the string specially for the globbing code. The
2130 caller is responsible for removing the backslashes if the unquoted
2131 words is needed later. */
2132 char *
2133 cond_expand_word (w, special)
2134 WORD_DESC *w;
2135 int special;
2136 {
2137 char *r, *p;
2138 WORD_LIST *l;
2139
2140 if (w->word == 0 || w->word[0] == '\0')
2141 return ((char *)NULL);
2142
2143 if (strchr (w->word, '~') && unquoted_member ('~', w->word))
2144 {
2145 p = bash_tilde_expand (w->word);
2146 free (w->word);
2147 w->word = p;
2148 }
2149
2150 l = call_expand_word_internal (w, 0, 0, (int *)0, (int *)0);
2151 if (l)
2152 {
2153 if (special == 0)
2154 {
2155 dequote_list (l);
2156 r = string_list (l);
2157 }
2158 else
2159 {
2160 p = string_list (l);
2161 r = quote_string_for_globbing (p, QGLOB_CVTNULL);
2162 free (p);
2163 }
2164 dispose_words (l);
2165 }
2166 else
2167 r = (char *)NULL;
2168
2169 return r;
2170 }
2171 #endif
2172
2173 /* Call expand_word_internal to expand W and handle error returns.
2174 A convenience function for functions that don't want to handle
2175 any errors or free any memory before aborting. */
2176 static WORD_LIST *
2177 call_expand_word_internal (w, q, i, c, e)
2178 WORD_DESC *w;
2179 int q, i, *c, *e;
2180 {
2181 WORD_LIST *result;
2182
2183 result = expand_word_internal (w, q, i, c, e);
2184 if (result == &expand_word_error || result == &expand_word_fatal)
2185 {
2186 expand_no_split_dollar_star = 0; /* XXX */
2187 /* By convention, each time this error is returned, w->word has
2188 already been freed (it sometimes may not be in the fatal case,
2189 but that doesn't result in a memory leak because we're going
2190 to exit in most cases). */
2191 w->word = (char *)NULL;
2192 last_command_exit_value = EXECUTION_FAILURE;
2193 jump_to_top_level ((result == &expand_word_error) ? DISCARD : FORCE_EOF);
2194 /* NOTREACHED */
2195 }
2196 else
2197 return (result);
2198 }
2199
2200 /* Perform parameter expansion, command substitution, and arithmetic
2201 expansion on STRING, as if it were a word. Leave the result quoted. */
2202 static WORD_LIST *
2203 expand_string_internal (string, quoted)
2204 char *string;
2205 int quoted;
2206 {
2207 WORD_DESC td;
2208 WORD_LIST *tresult;
2209
2210 if (string == 0 || *string == 0)
2211 return ((WORD_LIST *)NULL);
2212
2213 td.flags = 0;
2214 td.word = savestring (string);
2215
2216 tresult = call_expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2217
2218 FREE (td.word);
2219 return (tresult);
2220 }
2221
2222 /* Expand STRING by performing parameter expansion, command substitution,
2223 and arithmetic expansion. Dequote the resulting WORD_LIST before
2224 returning it, but do not perform word splitting. The call to
2225 remove_quoted_nulls () is in here because word splitting normally
2226 takes care of quote removal. */
2227 WORD_LIST *
2228 expand_string_unsplit (string, quoted)
2229 char *string;
2230 int quoted;
2231 {
2232 WORD_LIST *value;
2233
2234 if (string == 0 || *string == '\0')
2235 return ((WORD_LIST *)NULL);
2236
2237 expand_no_split_dollar_star = 1;
2238 value = expand_string_internal (string, quoted);
2239 expand_no_split_dollar_star = 0;
2240
2241 if (value)
2242 {
2243 if (value->word)
2244 remove_quoted_nulls (value->word->word);
2245 dequote_list (value);
2246 }
2247 return (value);
2248 }
2249
2250
2251 /* Expand one of the PS? prompt strings. This is a sort of combination of
2252 expand_string_unsplit and expand_string_internal, but returns the
2253 passed string when an error occurs. Might want to trap other calls
2254 to jump_to_top_level here so we don't endlessly loop. */
2255 WORD_LIST *
2256 expand_prompt_string (string, quoted)
2257 char *string;
2258 int quoted;
2259 {
2260 WORD_LIST *value;
2261 WORD_DESC td;
2262
2263 if (string == 0 || *string == 0)
2264 return ((WORD_LIST *)NULL);
2265
2266 td.flags = 0;
2267 td.word = savestring (string);
2268
2269 no_longjmp_on_fatal_error = 1;
2270 value = expand_word_internal (&td, quoted, 0, (int *)NULL, (int *)NULL);
2271 no_longjmp_on_fatal_error = 0;
2272
2273 if (value == &expand_word_error || value == &expand_word_fatal)
2274 {
2275 value = make_word_list (make_bare_word (string), (WORD_LIST *)NULL);
2276 return value;
2277 }
2278 FREE (td.word);
2279 if (value)
2280 {
2281 if (value->word)
2282 remove_quoted_nulls (value->word->word);
2283 dequote_list (value);
2284 }
2285 return (value);
2286 }
2287
2288 /* Expand STRING just as if you were expanding a word, but do not dequote
2289 the resultant WORD_LIST. This is called only from within this file,
2290 and is used to correctly preserve quoted characters when expanding
2291 things like ${1+"$@"}. This does parameter expansion, command
2292 substitution, arithmetic expansion, and word splitting. */
2293 static WORD_LIST *
2294 expand_string_leave_quoted (string, quoted)
2295 char *string;
2296 int quoted;
2297 {
2298 WORD_LIST *tlist;
2299 WORD_LIST *tresult;
2300
2301 if (string == 0 || *string == '\0')
2302 return ((WORD_LIST *)NULL);
2303
2304 tlist = expand_string_internal (string, quoted);
2305
2306 if (tlist)
2307 {
2308 tresult = word_list_split (tlist);
2309 dispose_words (tlist);
2310 return (tresult);
2311 }
2312 return ((WORD_LIST *)NULL);
2313 }
2314
2315 /* This does not perform word splitting or dequote the WORD_LIST
2316 it returns. */
2317 static WORD_LIST *
2318 expand_string_for_rhs (string, quoted, dollar_at_p, has_dollar_at)
2319 char *string;
2320 int quoted, *dollar_at_p, *has_dollar_at;
2321 {
2322 WORD_DESC td;
2323 WORD_LIST *tresult;
2324
2325 if (string == 0 || *string == '\0')
2326 return (WORD_LIST *)NULL;
2327
2328 td.flags = 0;
2329 td.word = string;
2330 tresult = call_expand_word_internal (&td, quoted, 1, dollar_at_p, has_dollar_at);
2331 return (tresult);
2332 }
2333
2334 /* Expand STRING just as if you were expanding a word. This also returns
2335 a list of words. Note that filename globbing is *NOT* done for word
2336 or string expansion, just when the shell is expanding a command. This
2337 does parameter expansion, command substitution, arithmetic expansion,
2338 and word splitting. Dequote the resultant WORD_LIST before returning. */
2339 WORD_LIST *
2340 expand_string (string, quoted)
2341 char *string;
2342 int quoted;
2343 {
2344 WORD_LIST *result;
2345
2346 if (string == 0 || *string == '\0')
2347 return ((WORD_LIST *)NULL);
2348
2349 result = expand_string_leave_quoted (string, quoted);
2350 return (result ? dequote_list (result) : result);
2351 }
2352
2353 /***************************************************
2354 * *
2355 * Functions to handle quoting chars *
2356 * *
2357 ***************************************************/
2358
2359 /* Conventions:
2360
2361 A string with s[0] == CTLNUL && s[1] == 0 is a quoted null string.
2362 The parser passes CTLNUL as CTLESC CTLNUL. */
2363
2364 /* The parser passes us CTLESC as CTLESC CTLESC and CTLNUL as CTLESC CTLNUL.
2365 This is necessary to make unquoted CTLESC and CTLNUL characters in the
2366 data stream pass through properly.
2367 Here we remove doubled CTLESC characters inside quoted strings before
2368 quoting the entire string, so we do not double the number of CTLESC
2369 characters. */
2370 static char *
2371 remove_quoted_escapes (string)
2372 char *string;
2373 {
2374 register char *s;
2375 int docopy;
2376 char *t, *t1;
2377
2378 if (string == NULL)
2379 return (string);
2380
2381 t1 = t = (char *)xmalloc (strlen (string) + 1);
2382 for (docopy = 0, s = string; *s; s++, t1++)
2383 {
2384 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2385 {
2386 s++;
2387 docopy = 1;
2388 }
2389 *t1 = *s;
2390 }
2391 *t1 = '\0';
2392 if (docopy)
2393 strcpy (string, t);
2394 free (t);
2395 return (string);
2396 }
2397
2398 /* Quote escape characters in string s, but no other characters. This is
2399 used to protect CTLESC and CTLNUL in variable values from the rest of
2400 the word expansion process after the variable is expanded. */
2401 char *
2402 quote_escapes (string)
2403 char *string;
2404 {
2405 register char *s, *t;
2406 char *result;
2407
2408 result = (char *)xmalloc ((strlen (string) * 2) + 1);
2409 for (s = string, t = result; *s; )
2410 {
2411 if (*s == CTLESC || *s == CTLNUL)
2412 *t++ = CTLESC;
2413 *t++ = *s++;
2414 }
2415 *t = '\0';
2416 return (result);
2417 }
2418
2419 static WORD_LIST *
2420 list_quote_escapes (list)
2421 WORD_LIST *list;
2422 {
2423 register WORD_LIST *w;
2424 char *t;
2425
2426 for (w = list; w; w = w->next)
2427 {
2428 t = w->word->word;
2429 w->word->word = quote_escapes (t);
2430 free (t);
2431 }
2432 return list;
2433 }
2434
2435 #if 0
2436 /* UNUSED */
2437 static char *
2438 dequote_escapes (string)
2439 char *string;
2440 {
2441 register char *s, *t;
2442 char *result;
2443
2444 result = (char *)xmalloc (strlen (string) + 1);
2445 for (s = string, t = result; *s; )
2446 {
2447 if (*s == CTLESC && (s[1] == CTLESC || s[1] == CTLNUL))
2448 {
2449 s++;
2450 if (*s == '\0')
2451 break;
2452 }
2453 *t++ = *s++;
2454 }
2455 *t = '\0';
2456 return result;
2457 }
2458 #endif
2459
2460 static WORD_LIST *
2461 dequote_list (list)
2462 WORD_LIST *list;
2463 {
2464 register char *s;
2465 register WORD_LIST *tlist;
2466
2467 for (tlist = list; tlist; tlist = tlist->next)
2468 {
2469 s = dequote_string (tlist->word->word);
2470 free (tlist->word->word);
2471 tlist->word->word = s;
2472 }
2473 return list;
2474 }
2475
2476 /* Return a new string with the quoted representation of character C. */
2477 static char *
2478 make_quoted_char (c)
2479 int c;
2480 {
2481 char *temp;
2482
2483 temp = (char *)xmalloc (3);
2484 if (c == 0)
2485 {
2486 temp[0] = CTLNUL;
2487 temp[1] = '\0';
2488 }
2489 else
2490 {
2491 temp[0] = CTLESC;
2492 temp[1] = c;
2493 temp[2] = '\0';
2494 }
2495 return (temp);
2496 }
2497
2498 /* Quote STRING. Return a new string. */
2499 char *
2500 quote_string (string)
2501 char *string;
2502 {
2503 register char *t;
2504 char *result;
2505
2506 if (*string == 0)
2507 {
2508 result = (char *)xmalloc (2);
2509 result[0] = CTLNUL;
2510 result[1] = '\0';
2511 }
2512 else
2513 {
2514 result = (char *)xmalloc ((strlen (string) * 2) + 1);
2515
2516 for (t = result; *string; )
2517 {
2518 *t++ = CTLESC;
2519 *t++ = *string++;
2520 }
2521 *t = '\0';
2522 }
2523 return (result);
2524 }
2525
2526 /* De-quoted quoted characters in STRING. */
2527 char *
2528 dequote_string (string)
2529 char *string;
2530 {
2531 register char *t;
2532 char *result;
2533
2534 result = (char *)xmalloc (strlen (string) + 1);
2535
2536 if (QUOTED_NULL (string))
2537 {
2538 result[0] = '\0';
2539 return (result);
2540 }
2541
2542 /* If no character in the string can be quoted, don't bother examining
2543 each character. Just return a copy of the string passed to us. */
2544 if (strchr (string, CTLESC) == NULL) /* XXX */
2545 { /* XXX */
2546 strcpy (result, string); /* XXX */
2547 return (result); /* XXX */
2548 }
2549
2550 for (t = result; *string; string++, t++)
2551 {
2552 if (*string == CTLESC)
2553 {
2554 string++;
2555
2556 if (!*string)
2557 break;
2558 }
2559
2560 *t = *string;
2561 }
2562
2563 *t = '\0';
2564 return (result);
2565 }
2566
2567 /* Quote the entire WORD_LIST list. */
2568 static WORD_LIST *
2569 quote_list (list)
2570 WORD_LIST *list;
2571 {
2572 register WORD_LIST *w;
2573 char *t;
2574
2575 for (w = list; w; w = w->next)
2576 {
2577 t = w->word->word;
2578 w->word->word = quote_string (t);
2579 free (t);
2580 w->word->flags |= W_QUOTED;
2581 }
2582 return list;
2583 }
2584
2585 /* Perform quoted null character removal on STRING. We don't allow any
2586 quoted null characters in the middle or at the ends of strings because
2587 of how expand_word_internal works. remove_quoted_nulls () turns
2588 STRING into an empty string iff it only consists of a quoted null,
2589 and removes all unquoted CTLNUL characters. */
2590 /*
2591 #define remove_quoted_nulls(string) \
2592 do { if (QUOTED_NULL (string)) string[0] ='\0'; } while (0)
2593 */
2594 static void
2595 remove_quoted_nulls (string)
2596 char *string;
2597 {
2598 char *nstr, *s, *p;
2599
2600 nstr = savestring (string);
2601 nstr[0] = '\0';
2602 for (p = nstr, s = string; *s; s++)
2603 {
2604 if (*s == CTLESC)
2605 {
2606 *p++ = *s++; /* CTLESC */
2607 if (*s == 0)
2608 break;
2609 *p++ = *s; /* quoted char */
2610 continue;
2611 }
2612 if (*s == CTLNUL)
2613 continue;
2614 *p++ = *s;
2615 }
2616 *p = '\0';
2617 strcpy (string, nstr);
2618 free (nstr);
2619 }
2620
2621 /* Perform quoted null character removal on each element of LIST.
2622 This modifies LIST. */
2623 void
2624 word_list_remove_quoted_nulls (list)
2625 WORD_LIST *list;
2626 {
2627 register WORD_LIST *t;
2628
2629 for (t = list; t; t = t->next)
2630 remove_quoted_nulls (t->word->word);
2631 }
2632
2633 /* **************************************************************** */
2634 /* */
2635 /* Functions for Matching and Removing Patterns */
2636 /* */
2637 /* **************************************************************** */
2638
2639 /* Remove the portion of PARAM matched by PATTERN according to OP, where OP
2640 can have one of 4 values:
2641 RP_LONG_LEFT remove longest matching portion at start of PARAM
2642 RP_SHORT_LEFT remove shortest matching portion at start of PARAM
2643 RP_LONG_RIGHT remove longest matching portion at end of PARAM
2644 RP_SHORT_RIGHT remove shortest matching portion at end of PARAM
2645 */
2646
2647 #define RP_LONG_LEFT 1
2648 #define RP_SHORT_LEFT 2
2649 #define RP_LONG_RIGHT 3
2650 #define RP_SHORT_RIGHT 4
2651
2652 static char *
2653 remove_pattern (param, pattern, op)
2654 char *param, *pattern;
2655 int op;
2656 {
2657 register int len;
2658 register char *end;
2659 register char *p, *ret, c;
2660
2661 if (param == NULL || *param == '\0')
2662 return (param);
2663 if (pattern == NULL || *pattern == '\0') /* minor optimization */
2664 return (savestring (param));
2665
2666 len = STRLEN (param);
2667 end = param + len;
2668
2669 switch (op)
2670 {
2671 case RP_LONG_LEFT: /* remove longest match at start */
2672 for (p = end; p >= param; p--)
2673 {
2674 c = *p; *p = '\0';
2675 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2676 {
2677 *p = c;
2678 return (savestring (p));
2679 }
2680 *p = c;
2681 }
2682 break;
2683
2684 case RP_SHORT_LEFT: /* remove shortest match at start */
2685 for (p = param; p <= end; p++)
2686 {
2687 c = *p; *p = '\0';
2688 if (strmatch (pattern, param, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2689 {
2690 *p = c;
2691 return (savestring (p));
2692 }
2693 *p = c;
2694 }
2695 break;
2696
2697 case RP_LONG_RIGHT: /* remove longest match at end */
2698 for (p = param; p <= end; p++)
2699 {
2700 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2701 {
2702 c = *p; *p = '\0';
2703 ret = savestring (param);
2704 *p = c;
2705 return (ret);
2706 }
2707 }
2708 break;
2709
2710 case RP_SHORT_RIGHT: /* remove shortest match at end */
2711 for (p = end; p >= param; p--)
2712 {
2713 if (strmatch (pattern, p, FNMATCH_EXTFLAG) != FNM_NOMATCH)
2714 {
2715 c = *p; *p = '\0';
2716 ret = savestring (param);
2717 *p = c;
2718 return (ret);
2719 }
2720 }
2721 break;
2722 }
2723 return (savestring (param)); /* no match, return original string */
2724 }
2725
2726 /* Return 1 of the first character of STRING could match the first
2727 character of pattern PAT. Used to avoid n2 calls to strmatch(). */
2728 static int
2729 match_pattern_char (pat, string)
2730 char *pat, *string;
2731 {
2732 char c;
2733
2734 if (*string == 0)
2735 return (0);
2736
2737 switch (c = *pat++)
2738 {
2739 default:
2740 return (*string == c);
2741 case '\\':
2742 return (*string == *pat);
2743 case '?':
2744 return (*pat == LPAREN ? 1 : (*string != '\0'));
2745 case '*':
2746 return (1);
2747 case '+':
2748 case '!':
2749 case '@':
2750 return (*pat == LPAREN ? 1 : (*string == c));
2751 case '[':
2752 return (*string != '\0');
2753 }
2754 }
2755
2756 /* Match PAT anywhere in STRING and return the match boundaries.
2757 This returns 1 in case of a successful match, 0 otherwise. SP
2758 and EP are pointers into the string where the match begins and
2759 ends, respectively. MTYPE controls what kind of match is attempted.
2760 MATCH_BEG and MATCH_END anchor the match at the beginning and end
2761 of the string, respectively. The longest match is returned. */
2762 static int
2763 match_pattern (string, pat, mtype, sp, ep)
2764 char *string, *pat;
2765 int mtype;
2766 char **sp, **ep;
2767 {
2768 int c;
2769 register char *p, *p1;
2770 char *end;
2771
2772 if (string == 0 || *string == 0 || pat == 0 || *pat == 0)
2773 return (0);
2774
2775 end = string + STRLEN (string);
2776
2777 switch (mtype)
2778 {
2779 case MATCH_ANY:
2780 for (p = string; p <= end; p++)
2781 {
2782 if (match_pattern_char (pat, p))
2783 {
2784 for (p1 = end; p1 >= p; p1--)
2785 {
2786 c = *p1; *p1 = '\0';
2787 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2788 {
2789 *p1 = c;
2790 *sp = p;
2791 *ep = p1;
2792 return 1;
2793 }
2794 *p1 = c;
2795 }
2796 }
2797 }
2798 return (0);
2799
2800 case MATCH_BEG:
2801 if (match_pattern_char (pat, string) == 0)
2802 return (0);
2803 for (p = end; p >= string; p--)
2804 {
2805 c = *p; *p = '\0';
2806 if (strmatch (pat, string, FNMATCH_EXTFLAG) == 0)
2807 {
2808 *p = c;
2809 *sp = string;
2810 *ep = p;
2811 return 1;
2812 }
2813 *p = c;
2814 }
2815 return (0);
2816
2817 case MATCH_END:
2818 for (p = string; p <= end; p++)
2819 if (strmatch (pat, p, FNMATCH_EXTFLAG) == 0)
2820 {
2821 *sp = p;
2822 *ep = end;
2823 return 1;
2824 }
2825 return (0);
2826 }
2827
2828 return (0);
2829 }
2830
2831 static int
2832 getpatspec (c, value)
2833 int c;
2834 char *value;
2835 {
2836 if (c == '#')
2837 return ((*value == '#') ? RP_LONG_LEFT : RP_SHORT_LEFT);
2838 else /* c == '%' */
2839 return ((*value == '%') ? RP_LONG_RIGHT : RP_SHORT_RIGHT);
2840 }
2841
2842 /* Posix.2 says that the WORD should be run through tilde expansion,
2843 parameter expansion, command substitution and arithmetic expansion.
2844 This leaves the result quoted, so quote_string_for_globbing () has
2845 to be called to fix it up for strmatch (). If QUOTED is non-zero,
2846 it means that the entire expression was enclosed in double quotes.
2847 This means that quoting characters in the pattern do not make any
2848 special pattern characters quoted. For example, the `*' in the
2849 following retains its special meaning: "${foo#'*'}". */
2850 static char *
2851 getpattern (value, quoted, expandpat)
2852 char *value;
2853 int quoted, expandpat;
2854 {
2855 char *pat, *tword;
2856 WORD_LIST *l;
2857 int i;
2858
2859 tword = strchr (value, '~') ? bash_tilde_expand (value) : savestring (value);
2860
2861 /* expand_string_internal () leaves WORD quoted and does not perform
2862 word splitting. */
2863 if (expandpat && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *tword)
2864 {
2865 i = 0;
2866 pat = string_extract_double_quoted (tword, &i, 1);
2867 free (tword);
2868 tword = pat;
2869 }
2870
2871 /* There is a problem here: how to handle single or double quotes in the
2872 pattern string when the whole expression is between double quotes? */
2873 #if 0
2874 l = *tword ? expand_string_for_rhs (tword, quoted, (int *)NULL, (int *)NULL)
2875 #else
2876 l = *tword ? expand_string_for_rhs (tword,
2877 (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? Q_NOQUOTE : quoted,
2878 (int *)NULL, (int *)NULL)
2879 #endif
2880 : (WORD_LIST *)0;
2881 free (tword);
2882 pat = string_list (l);
2883 dispose_words (l);
2884 if (pat)
2885 {
2886 tword = quote_string_for_globbing (pat, QGLOB_CVTNULL);
2887 free (pat);
2888 pat = tword;
2889 }
2890 return (pat);
2891 }
2892
2893 /* Handle removing a pattern from a string as a result of ${name%[%]value}
2894 or ${name#[#]value}. */
2895 static char *
2896 parameter_brace_remove_pattern (value, temp, c, quoted)
2897 char *value, *temp;
2898 int c, quoted;
2899 {
2900 int patspec;
2901 char *pattern, *tword;
2902
2903 patspec = getpatspec (c, value);
2904 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2905 value++;
2906
2907 pattern = getpattern (value, quoted, 1);
2908
2909 tword = remove_pattern (temp, pattern, patspec);
2910
2911 FREE (pattern);
2912 return (tword);
2913 }
2914
2915 static char *
2916 list_remove_pattern (list, pattern, patspec, type, quoted)
2917 WORD_LIST *list;
2918 char *pattern;
2919 int patspec, type, quoted;
2920 {
2921 WORD_LIST *new, *l;
2922 WORD_DESC *w;
2923 char *tword;
2924
2925 for (new = (WORD_LIST *)NULL, l = list; l; l = l->next)
2926 {
2927 tword = remove_pattern (l->word->word, pattern, patspec);
2928 w = make_bare_word (tword);
2929 free (tword);
2930 new = make_word_list (w, new);
2931 }
2932
2933 l = REVERSE_LIST (new, WORD_LIST *);
2934 if (type == '*')
2935 tword = (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? string_list_dollar_star (l) : string_list (l);
2936 else
2937 tword = string_list ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) ? quote_list (l) : l);
2938
2939 dispose_words (l);
2940 return (tword);
2941 }
2942
2943 static char *
2944 parameter_list_remove_pattern (value, type, c, quoted)
2945 char *value;
2946 int type, c, quoted;
2947 {
2948 int patspec;
2949 char *pattern, *ret;
2950 WORD_LIST *list;
2951
2952 patspec = getpatspec (c, value);
2953 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2954 value++;
2955
2956 pattern = getpattern (value, quoted, 1);
2957
2958 list = list_rest_of_args ();
2959 ret = list_remove_pattern (list, pattern, patspec, type, quoted);
2960 dispose_words (list);
2961 FREE (pattern);
2962 return (ret);
2963 }
2964
2965 #if defined (ARRAY_VARS)
2966 static char *
2967 array_remove_pattern (value, aspec, aval, c, quoted)
2968 char *value, *aspec, *aval; /* AVAL == evaluated ASPEC */
2969 int c, quoted;
2970 {
2971 SHELL_VAR *var;
2972 int len, patspec;
2973 char *ret, *t, *pattern;
2974 WORD_LIST *l;
2975
2976 var = array_variable_part (aspec, &t, &len);
2977 if (var == 0)
2978 return ((char *)NULL);
2979
2980 patspec = getpatspec (c, value);
2981 if (patspec == RP_LONG_LEFT || patspec == RP_LONG_RIGHT)
2982 value++;
2983
2984 pattern = getpattern (value, quoted, 1);
2985
2986 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
2987 {
2988 if (array_p (var) == 0)
2989 {
2990 report_error ("%s: bad array subscript", aspec);
2991 FREE (pattern);
2992 return ((char *)NULL);
2993 }
2994 l = array_to_word_list (array_cell (var));
2995 if (l == 0)
2996 return ((char *)NULL);
2997 ret = list_remove_pattern (l, pattern, patspec, t[0], quoted);
2998 dispose_words (l);
2999 }
3000 else
3001 {
3002 ret = remove_pattern (aval, pattern, patspec);
3003 if (ret)
3004 {
3005 t = quote_escapes (ret);
3006 free (ret);
3007 ret = t;
3008 }
3009 }
3010
3011 FREE (pattern);
3012 return ret;
3013 }
3014 #endif /* ARRAY_VARS */
3015
3016 /*******************************************
3017 * *
3018 * Functions to expand WORD_DESCs *
3019 * *
3020 *******************************************/
3021
3022 /* Expand WORD, performing word splitting on the result. This does
3023 parameter expansion, command substitution, arithmetic expansion,
3024 word splitting, and quote removal. */
3025
3026 WORD_LIST *
3027 expand_word (word, quoted)
3028 WORD_DESC *word;
3029 int quoted;
3030 {
3031 WORD_LIST *result, *tresult;
3032
3033 tresult = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
3034 result = word_list_split (tresult);
3035 dispose_words (tresult);
3036 return (result ? dequote_list (result) : result);
3037 }
3038
3039 /* Expand WORD, but do not perform word splitting on the result. This
3040 does parameter expansion, command substitution, arithmetic expansion,
3041 and quote removal. */
3042 WORD_LIST *
3043 expand_word_unsplit (word, quoted)
3044 WORD_DESC *word;
3045 int quoted;
3046 {
3047 WORD_LIST *result;
3048
3049 expand_no_split_dollar_star = 1;
3050 result = call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL);
3051 expand_no_split_dollar_star = 0;
3052
3053 return (result ? dequote_list (result) : result);
3054 }
3055
3056 /* Perform shell expansions on WORD, but do not perform word splitting or
3057 quote removal on the result. */
3058 WORD_LIST *
3059 expand_word_leave_quoted (word, quoted)
3060 WORD_DESC *word;
3061 int quoted;
3062 {
3063 return (call_expand_word_internal (word, quoted, 0, (int *)NULL, (int *)NULL));
3064 }
3065
3066 #if defined (PROCESS_SUBSTITUTION)
3067
3068 /*****************************************************************/
3069 /* */
3070 /* Hacking Process Substitution */
3071 /* */
3072 /*****************************************************************/
3073
3074 #if !defined (HAVE_DEV_FD)
3075 /* Named pipes must be removed explicitly with `unlink'. This keeps a list
3076 of FIFOs the shell has open. unlink_fifo_list will walk the list and
3077 unlink all of them. add_fifo_list adds the name of an open FIFO to the
3078 list. NFIFO is a count of the number of FIFOs in the list. */
3079 #define FIFO_INCR 20
3080
3081 struct temp_fifo {
3082 char *file;
3083 pid_t proc;
3084 };
3085
3086 static struct temp_fifo *fifo_list = (struct temp_fifo *)NULL;
3087 static int nfifo;
3088 static int fifo_list_size;
3089
3090 static void
3091 add_fifo_list (pathname)
3092 char *pathname;
3093 {
3094 if (nfifo >= fifo_list_size - 1)
3095 {
3096 fifo_list_size += FIFO_INCR;
3097 fifo_list = (struct temp_fifo *)xrealloc (fifo_list,
3098 fifo_list_size * sizeof (struct temp_fifo));
3099 }
3100
3101 fifo_list[nfifo].file = savestring (pathname);
3102 nfifo++;
3103 }
3104
3105 void
3106 unlink_fifo_list ()
3107 {
3108 int saved, i, j;
3109
3110 if (nfifo == 0)
3111 return;
3112
3113 for (i = saved = 0; i < nfifo; i++)
3114 {
3115 if ((fifo_list[i].proc == -1) || (kill(fifo_list[i].proc, 0) == -1))
3116 {
3117 unlink (fifo_list[i].file);
3118 free (fifo_list[i].file);
3119 fifo_list[i].file = (char *)NULL;
3120 fifo_list[i].proc = -1;
3121 }
3122 else
3123 saved++;
3124 }
3125
3126 /* If we didn't remove some of the FIFOs, compact the list. */
3127 if (saved)
3128 {
3129 for (i = j = 0; i < nfifo; i++)
3130 if (fifo_list[i].file)
3131 {
3132 fifo_list[j].file = fifo_list[i].file;
3133 fifo_list[j].proc = fifo_list[i].proc;
3134 j++;
3135 }
3136 nfifo = j;
3137 }
3138 else
3139 nfifo = 0;
3140 }
3141
3142 static char *
3143 make_named_pipe ()
3144 {
3145 char *tname;
3146
3147 tname = sh_mktmpname ("sh-np", MT_USERANDOM);
3148 if (mkfifo (tname, 0600) < 0)
3149 {
3150 free (tname);
3151 return ((char *)NULL);
3152 }
3153
3154 add_fifo_list (tname);
3155 return (tname);
3156 }
3157
3158 #else /* HAVE_DEV_FD */
3159
3160 /* DEV_FD_LIST is a bitmap of file descriptors attached to pipes the shell
3161 has open to children. NFDS is a count of the number of bits currently
3162 set in DEV_FD_LIST. TOTFDS is a count of the highest possible number
3163 of open files. */
3164 static char *dev_fd_list = (char *)NULL;
3165 static int nfds;
3166 static int totfds; /* The highest possible number of open files. */
3167
3168 static void
3169 add_fifo_list (fd)
3170 int fd;
3171 {
3172 if (!dev_fd_list || fd >= totfds)
3173 {
3174 int ofds;
3175
3176 ofds = totfds;
3177 totfds = getdtablesize ();
3178 if (totfds < 0 || totfds > 256)
3179 totfds = 256;
3180 if (fd > totfds)
3181 totfds = fd + 2;
3182
3183 dev_fd_list = (char *)xrealloc (dev_fd_list, totfds);
3184 bzero (dev_fd_list + ofds, totfds - ofds);
3185 }
3186
3187 dev_fd_list[fd] = 1;
3188 nfds++;
3189 }
3190
3191 void
3192 unlink_fifo_list ()
3193 {
3194 register int i;
3195
3196 if (nfds == 0)
3197 return;
3198
3199 for (i = 0; nfds && i < totfds; i++)
3200 if (dev_fd_list[i])
3201 {
3202 close (i);
3203 dev_fd_list[i] = 0;
3204 nfds--;
3205 }
3206
3207 nfds = 0;
3208 }
3209
3210 #if defined (NOTDEF)
3211 print_dev_fd_list ()
3212 {
3213 register int i;
3214
3215 fprintf (stderr, "pid %ld: dev_fd_list:", (long)getpid ());
3216 fflush (stderr);
3217
3218 for (i = 0; i < totfds; i++)
3219 {
3220 if (dev_fd_list[i])
3221 fprintf (stderr, " %d", i);
3222 }
3223 fprintf (stderr, "\n");
3224 }
3225 #endif /* NOTDEF */
3226
3227 static char *
3228 make_dev_fd_filename (fd)
3229 int fd;
3230 {
3231 char *ret, intbuf[INT_STRLEN_BOUND (int) + 1], *p;
3232
3233 ret = (char *)xmalloc (sizeof (DEV_FD_PREFIX) + 4);
3234
3235 strcpy (ret, DEV_FD_PREFIX);
3236 p = inttostr (fd, intbuf, sizeof (intbuf));
3237 strcpy (ret + sizeof (DEV_FD_PREFIX) - 1, p);
3238
3239 add_fifo_list (fd);
3240 return (ret);
3241 }
3242
3243 #endif /* HAVE_DEV_FD */
3244
3245 /* Return a filename that will open a connection to the process defined by
3246 executing STRING. HAVE_DEV_FD, if defined, means open a pipe and return
3247 a filename in /dev/fd corresponding to a descriptor that is one of the
3248 ends of the pipe. If not defined, we use named pipes on systems that have
3249 them. Systems without /dev/fd and named pipes are out of luck.
3250
3251 OPEN_FOR_READ_IN_CHILD, if 1, means open the named pipe for reading or
3252 use the read end of the pipe and dup that file descriptor to fd 0 in
3253 the child. If OPEN_FOR_READ_IN_CHILD is 0, we open the named pipe for
3254 writing or use the write end of the pipe in the child, and dup that
3255 file descriptor to fd 1 in the child. The parent does the opposite. */
3256
3257 static char *
3258 process_substitute (string, open_for_read_in_child)
3259 char *string;
3260 int open_for_read_in_child;
3261 {
3262 char *pathname;
3263 int fd, result;
3264 pid_t old_pid, pid;
3265 #if defined (HAVE_DEV_FD)
3266 int parent_pipe_fd, child_pipe_fd;
3267 int fildes[2];
3268 #endif /* HAVE_DEV_FD */
3269 #if defined (JOB_CONTROL)
3270 pid_t old_pipeline_pgrp;
3271 #endif
3272
3273 if (!string || !*string || wordexp_only)
3274 return ((char *)NULL);
3275
3276 #if !defined (HAVE_DEV_FD)
3277 pathname = make_named_pipe ();
3278 #else /* HAVE_DEV_FD */
3279 if (pipe (fildes) < 0)
3280 {
3281 sys_error ("cannot make pipe for process substitution");
3282 return ((char *)NULL);
3283 }
3284 /* If OPEN_FOR_READ_IN_CHILD == 1, we want to use the write end of
3285 the pipe in the parent, otherwise the read end. */
3286 parent_pipe_fd = fildes[open_for_read_in_child];
3287 child_pipe_fd = fildes[1 - open_for_read_in_child];
3288 /* Move the parent end of the pipe to some high file descriptor, to
3289 avoid clashes with FDs used by the script. */
3290 parent_pipe_fd = move_to_high_fd (parent_pipe_fd, 1, 64);
3291
3292 pathname = make_dev_fd_filename (parent_pipe_fd);
3293 #endif /* HAVE_DEV_FD */
3294
3295 if (!pathname)
3296 {
3297 sys_error ("cannot make pipe for process substitution");
3298 return ((char *)NULL);
3299 }
3300
3301 old_pid = last_made_pid;
3302
3303 #if defined (JOB_CONTROL)
3304 old_pipeline_pgrp = pipeline_pgrp;
3305 pipeline_pgrp = shell_pgrp;
3306 save_pipeline (1);
3307 #endif /* JOB_CONTROL */
3308
3309 pid = make_child ((char *)NULL, 1);
3310 if (pid == 0)
3311 {
3312 reset_terminating_signals (); /* XXX */
3313 /* Cancel traps, in trap.c. */
3314 restore_original_signals ();
3315 setup_async_signals ();
3316 subshell_environment |= SUBSHELL_COMSUB;
3317 }
3318
3319 #if defined (JOB_CONTROL)
3320 set_sigchld_handler ();
3321 stop_making_children ();
3322 pipeline_pgrp = old_pipeline_pgrp;
3323 #endif /* JOB_CONTROL */
3324
3325 if (pid < 0)
3326 {
3327 sys_error ("cannot make child for process substitution");
3328 free (pathname);
3329 #if defined (HAVE_DEV_FD)
3330 close (parent_pipe_fd);
3331 close (child_pipe_fd);
3332 #endif /* HAVE_DEV_FD */
3333 return ((char *)NULL);
3334 }
3335
3336 if (pid > 0)
3337 {
3338 #if defined (JOB_CONTROL)
3339 restore_pipeline (1);
3340 #endif
3341
3342 #if !defined (HAVE_DEV_FD)
3343 fifo_list[nfifo-1].proc = pid;
3344 #endif
3345
3346 last_made_pid = old_pid;
3347
3348 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
3349 close_pgrp_pipe ();
3350 #endif /* JOB_CONTROL && PGRP_PIPE */
3351
3352 #if defined (HAVE_DEV_FD)
3353 close (child_pipe_fd);
3354 #endif /* HAVE_DEV_FD */
3355
3356 return (pathname);
3357 }
3358
3359 set_sigint_handler ();
3360
3361 #if defined (JOB_CONTROL)
3362 set_job_control (0);
3363 #endif /* JOB_CONTROL */
3364
3365 #if !defined (HAVE_DEV_FD)
3366 /* Open the named pipe in the child. */
3367 fd = open (pathname, open_for_read_in_child ? O_RDONLY|O_NONBLOCK : O_WRONLY);
3368 if (fd < 0)
3369 {
3370 sys_error ("cannot open named pipe %s for %s", pathname,
3371 open_for_read_in_child ? "reading" : "writing");
3372 exit (127);
3373 }
3374 if (open_for_read_in_child)
3375 {
3376 if (sh_unset_nodelay_mode (fd) < 0)
3377 {
3378 sys_error ("cannout reset nodelay mode for fd %d", fd);
3379 exit (127);
3380 }
3381 }
3382 #else /* HAVE_DEV_FD */
3383 fd = child_pipe_fd;
3384 #endif /* HAVE_DEV_FD */
3385
3386 if (dup2 (fd, open_for_read_in_child ? 0 : 1) < 0)
3387 {
3388 sys_error ("cannot duplicate named pipe %s as fd %d", pathname,
3389 open_for_read_in_child ? 0 : 1);
3390 exit (127);
3391 }
3392
3393 if (fd != (open_for_read_in_child ? 0 : 1))
3394 close (fd);
3395
3396 /* Need to close any files that this process has open to pipes inherited
3397 from its parent. */
3398 if (current_fds_to_close)
3399 {
3400 close_fd_bitmap (current_fds_to_close);
3401 current_fds_to_close = (struct fd_bitmap *)NULL;
3402 }
3403
3404 #if defined (HAVE_DEV_FD)
3405 /* Make sure we close the parent's end of the pipe and clear the slot
3406 in the fd list so it is not closed later, if reallocated by, for
3407 instance, pipe(2). */
3408 close (parent_pipe_fd);
3409 dev_fd_list[parent_pipe_fd] = 0;
3410 #endif /* HAVE_DEV_FD */
3411
3412 result = parse_and_execute (string, "process substitution", (SEVAL_NONINT|SEVAL_NOHIST));
3413
3414 #if !defined (HAVE_DEV_FD)
3415 /* Make sure we close the named pipe in the child before we exit. */
3416 close (open_for_read_in_child ? 0 : 1);
3417 #endif /* !HAVE_DEV_FD */
3418
3419 exit (result);
3420 /*NOTREACHED*/
3421 }
3422 #endif /* PROCESS_SUBSTITUTION */
3423
3424 /***********************************/
3425 /* */
3426 /* Command Substitution */
3427 /* */
3428 /***********************************/
3429
3430 static char *
3431 read_comsub (fd, quoted)
3432 int fd, quoted;
3433 {
3434 char *istring, buf[128], *bufp;
3435 int istring_index, istring_size, c;
3436 ssize_t bufn;
3437
3438 istring = (char *)NULL;
3439 istring_index = istring_size = bufn = 0;
3440
3441 #ifdef __CYGWIN__
3442 setmode (fd, O_TEXT); /* we don't want CR/LF, we want Unix-style */
3443 #endif
3444
3445 /* Read the output of the command through the pipe. */
3446 while (1)
3447 {
3448 if (fd < 0)
3449 break;
3450 if (--bufn <= 0)
3451 {
3452 bufn = zread (fd, buf, sizeof (buf));
3453 if (bufn <= 0)
3454 break;
3455 bufp = buf;
3456 }
3457 c = *bufp++;
3458
3459 if (c == 0)
3460 {
3461 #if 0
3462 internal_warning ("read_comsub: ignored null byte in input");
3463 #endif
3464 continue;
3465 }
3466
3467 /* Add the character to ISTRING, possibly after resizing it. */
3468 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size, DEFAULT_ARRAY_SIZE);
3469
3470 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || c == CTLESC || c == CTLNUL)
3471 istring[istring_index++] = CTLESC;
3472
3473 istring[istring_index++] = c;
3474
3475 #if 0
3476 #if defined (__CYGWIN__)
3477 if (c == '\n' && istring_index > 1 && istring[istring_index - 2] == '\r')
3478 {
3479 istring_index--;
3480 istring[istring_index - 1] = '\n';
3481 }
3482 #endif
3483 #endif
3484 }
3485
3486 if (istring)
3487 istring[istring_index] = '\0';
3488
3489 /* If we read no output, just return now and save ourselves some
3490 trouble. */
3491 if (istring_index == 0)
3492 {
3493 FREE (istring);
3494 return (char *)NULL;
3495 }
3496
3497 /* Strip trailing newlines from the output of the command. */
3498 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
3499 {
3500 while (istring_index > 0)
3501 {
3502 if (istring[istring_index - 1] == '\n')
3503 {
3504 --istring_index;
3505
3506 /* If the newline was quoted, remove the quoting char. */
3507 if (istring[istring_index - 1] == CTLESC)
3508 --istring_index;
3509 }
3510 else
3511 break;
3512 }
3513 istring[istring_index] = '\0';
3514 }
3515 else
3516 strip_trailing (istring, istring_index - 1, 1);
3517
3518 return istring;
3519 }
3520
3521 /* Perform command substitution on STRING. This returns a string,
3522 possibly quoted. */
3523 char *
3524 command_substitute (string, quoted)
3525 char *string;
3526 int quoted;
3527 {
3528 pid_t pid, old_pid, old_pipeline_pgrp;
3529 char *istring;
3530 int result, fildes[2], function_value;
3531
3532 istring = (char *)NULL;
3533
3534 /* Don't fork () if there is no need to. In the case of no command to
3535 run, just return NULL. */
3536 if (!string || !*string || (string[0] == '\n' && !string[1]))
3537 return ((char *)NULL);
3538
3539 if (wordexp_only && read_but_dont_execute)
3540 {
3541 last_command_exit_value = 125;
3542 jump_to_top_level (EXITPROG);
3543 }
3544
3545 /* We're making the assumption here that the command substitution will
3546 eventually run a command from the file system. Since we'll run
3547 maybe_make_export_env in this subshell before executing that command,
3548 the parent shell and any other shells it starts will have to remake
3549 the environment. If we make it before we fork, other shells won't
3550 have to. Don't bother if we have any temporary variable assignments,
3551 though, because the export environment will be remade after this
3552 command completes anyway, but do it if all the words to be expanded
3553 are variable assignments. */
3554 if (subst_assign_varlist == 0 || garglist == 0)
3555 maybe_make_export_env (); /* XXX */
3556
3557 /* Pipe the output of executing STRING into the current shell. */
3558 if (pipe (fildes) < 0)
3559 {
3560 sys_error ("cannot make pipes for command substitution");
3561 goto error_exit;
3562 }
3563
3564 old_pid = last_made_pid;
3565 #if defined (JOB_CONTROL)
3566 old_pipeline_pgrp = pipeline_pgrp;
3567 /* Don't reset the pipeline pgrp if we're already a subshell in a pipeline. */
3568 if ((subshell_environment & SUBSHELL_PIPE) == 0)
3569 pipeline_pgrp = shell_pgrp;
3570 cleanup_the_pipeline ();
3571 #endif
3572
3573 pid = make_child ((char *)NULL, 0);
3574 if (pid == 0)
3575 /* Reset the signal handlers in the child, but don't free the
3576 trap strings. */
3577 reset_signal_handlers ();
3578
3579 #if defined (JOB_CONTROL)
3580 set_sigchld_handler ();
3581 stop_making_children ();
3582 pipeline_pgrp = old_pipeline_pgrp;
3583 #else
3584 stop_making_children ();
3585 #endif /* JOB_CONTROL */
3586
3587 if (pid < 0)
3588 {
3589 sys_error ("cannot make child for command substitution");
3590 error_exit:
3591
3592 FREE (istring);
3593 close (fildes[0]);
3594 close (fildes[1]);
3595 return ((char *)NULL);
3596 }
3597
3598 if (pid == 0)
3599 {
3600 set_sigint_handler (); /* XXX */
3601
3602 if (dup2 (fildes[1], 1) < 0)
3603 {
3604 sys_error ("command_substitute: cannot duplicate pipe as fd 1");
3605 exit (EXECUTION_FAILURE);
3606 }
3607
3608 /* If standard output is closed in the parent shell
3609 (such as after `exec >&-'), file descriptor 1 will be
3610 the lowest available file descriptor, and end up in
3611 fildes[0]. This can happen for stdin and stderr as well,
3612 but stdout is more important -- it will cause no output
3613 to be generated from this command. */
3614 if ((fildes[1] != fileno (stdin)) &&
3615 (fildes[1] != fileno (stdout)) &&
3616 (fildes[1] != fileno (stderr)))
3617 close (fildes[1]);
3618
3619 if ((fildes[0] != fileno (stdin)) &&
3620 (fildes[0] != fileno (stdout)) &&
3621 (fildes[0] != fileno (stderr)))
3622 close (fildes[0]);
3623
3624 /* The currently executing shell is not interactive. */
3625 interactive = 0;
3626
3627 /* This is a subshell environment. */
3628 subshell_environment |= SUBSHELL_COMSUB;
3629
3630 /* When not in POSIX mode, command substitution does not inherit
3631 the -e flag. */
3632 if (posixly_correct == 0)
3633 exit_immediately_on_error = 0;
3634
3635 remove_quoted_escapes (string);
3636
3637 startup_state = 2; /* see if we can avoid a fork */
3638 /* Give command substitution a place to jump back to on failure,
3639 so we don't go back up to main (). */
3640 result = setjmp (top_level);
3641
3642 /* If we're running a command substitution inside a shell function,
3643 trap `return' so we don't return from the function in the subshell
3644 and go off to never-never land. */
3645 if (result == 0 && return_catch_flag)
3646 function_value = setjmp (return_catch);
3647 else
3648 function_value = 0;
3649
3650 if (result == EXITPROG)
3651 exit (last_command_exit_value);
3652 else if (result)
3653 exit (EXECUTION_FAILURE);
3654 else if (function_value)
3655 exit (return_catch_value);
3656 else
3657 exit (parse_and_execute (string, "command substitution", SEVAL_NOHIST));
3658 }
3659 else
3660 {
3661 #if defined (JOB_CONTROL) && defined (PGRP_PIPE)
3662 close_pgrp_pipe ();
3663 #endif /* JOB_CONTROL && PGRP_PIPE */
3664
3665 close (fildes[1]);
3666
3667 istring = read_comsub (fildes[0], quoted);
3668
3669 close (fildes[0]);
3670
3671 current_command_subst_pid = pid;
3672 last_command_exit_value = wait_for (pid);
3673 last_command_subst_pid = pid;
3674 last_made_pid = old_pid;
3675
3676 #if defined (JOB_CONTROL)
3677 /* If last_command_exit_value > 128, then the substituted command
3678 was terminated by a signal. If that signal was SIGINT, then send
3679 SIGINT to ourselves. This will break out of loops, for instance. */
3680 if (last_command_exit_value == (128 + SIGINT))
3681 kill (getpid (), SIGINT);
3682
3683 /* wait_for gives the terminal back to shell_pgrp. If some other
3684 process group should have it, give it away to that group here.
3685 pipeline_pgrp is non-zero only while we are constructing a
3686 pipline, so what we are concerned about is whether or not that
3687 pipeline was started in the background. A pipeline started in
3688 the background should never get the tty back here. */
3689 #if 0
3690 if (interactive && pipeline_pgrp != (pid_t)0 && pipeline_pgrp != last_asynchronous_pid)
3691 #else
3692 if (interactive && pipeline_pgrp != (pid_t)0 && (subshell_environment & SUBSHELL_ASYNC) == 0)
3693 #endif
3694 give_terminal_to (pipeline_pgrp, 0);
3695 #endif /* JOB_CONTROL */
3696
3697 return (istring);
3698 }
3699 }
3700
3701 /********************************************************
3702 * *
3703 * Utility functions for parameter expansion *
3704 * *
3705 ********************************************************/
3706
3707 #if defined (ARRAY_VARS)
3708
3709 static arrayind_t
3710 array_length_reference (s)
3711 char *s;
3712 {
3713 int len;
3714 arrayind_t ind;
3715 char *t, c;
3716 ARRAY *array;
3717 SHELL_VAR *var;
3718
3719 var = array_variable_part (s, &t, &len);
3720
3721 /* If unbound variables should generate an error, report one and return
3722 failure. */
3723 if ((var == 0 || array_p (var) == 0) && unbound_vars_is_error)
3724 {
3725 c = *--t;
3726 *t = '\0';
3727 report_error ("%s: unbound variable", s);
3728 *t = c;
3729 return (-1);
3730 }
3731 else if (var == 0)
3732 return 0;
3733
3734 /* We support a couple of expansions for variables that are not arrays.
3735 We'll return the length of the value for v[0], and 1 for v[@] or
3736 v[*]. Return 0 for everything else. */
3737
3738 array = array_p (var) ? array_cell (var) : (ARRAY *)NULL;
3739
3740 if (ALL_ELEMENT_SUB (t[0]) && t[1] == ']')
3741 return (array_p (var) ? array_num_elements (array) : 1);
3742
3743 ind = array_expand_index (t, len);
3744 if (ind < 0)
3745 {
3746 report_error ("%s: bad array subscript", t);
3747 return (-1);
3748 }
3749
3750 if (array_p (var))
3751 t = array_reference (array, ind);
3752 else
3753 t = (ind == 0) ? value_cell (var) : (char *)NULL;
3754
3755 len = STRLEN (t);
3756 return (len);
3757 }
3758 #endif /* ARRAY_VARS */
3759
3760 static int
3761 valid_brace_expansion_word (name, var_is_special)
3762 char *name;
3763 int var_is_special;
3764 {
3765 if (DIGIT (*name) && all_digits (name))
3766 return 1;
3767 else if (var_is_special)
3768 return 1;
3769 #if defined (ARRAY_VARS)
3770 else if (valid_array_reference (name))
3771 return 1;
3772 #endif /* ARRAY_VARS */
3773 else if (legal_identifier (name))
3774 return 1;
3775 else
3776 return 0;
3777 }
3778
3779 /* Parameter expand NAME, and return a new string which is the expansion,
3780 or NULL if there was no expansion.
3781 VAR_IS_SPECIAL is non-zero if NAME is one of the special variables in
3782 the shell, e.g., "@", "$", "*", etc. QUOTED, if non-zero, means that
3783 NAME was found inside of a double-quoted expression. */
3784 static char *
3785 parameter_brace_expand_word (name, var_is_special, quoted)
3786 char *name;
3787 int var_is_special, quoted;
3788 {
3789 char *temp, *tt;
3790 long arg_index;
3791 SHELL_VAR *var;
3792 #if 0
3793 WORD_LIST *l;
3794 #endif
3795
3796 /* Handle multiple digit arguments, as in ${11}. */
3797
3798 if (legal_number (name, &arg_index))
3799 temp = get_dollar_var_value (arg_index);
3800 else if (var_is_special) /* ${@} */
3801 {
3802 int sindex;
3803 tt = (char *)xmalloc (2 + strlen (name));
3804 tt[sindex = 0] = '$';
3805 strcpy (tt + 1, name);
3806 #if 0
3807 l = expand_string_leave_quoted (tt, quoted);
3808 free (tt);
3809 temp = string_list (l);
3810 dispose_words (l);
3811 #else
3812 temp = param_expand (tt, &sindex, quoted, (int *)NULL, (int *)NULL,
3813 (int *)NULL, (int *)NULL, 0);
3814 free (tt);
3815 #endif
3816 }
3817 #if defined (ARRAY_VARS)
3818 else if (valid_array_reference (name))
3819 {
3820 temp = array_value (name, quoted);
3821 }
3822 #endif
3823 else if (var = find_variable (name))
3824 {
3825 if (var && invisible_p (var) == 0)
3826 {
3827 #if defined (ARRAY_VARS)
3828 temp = array_p (var) ? array_reference (array_cell (var), 0) : value_cell (var);
3829 #else
3830 temp = value_cell (var);
3831 #endif
3832
3833 if (temp)
3834 temp = quote_escapes (temp);
3835
3836 if (tempvar_p (var))
3837 dispose_variable (var);
3838 }
3839 else
3840 temp = (char *)NULL;
3841 }
3842 else
3843 temp = (char *)NULL;
3844
3845 return (temp);
3846 }
3847
3848 /* Expand an indirect reference to a variable: ${!NAME} expands to the
3849 value of the variable whose name is the value of NAME. */
3850 static char *
3851 parameter_brace_expand_indir (name, var_is_special, quoted)
3852 char *name;
3853 int var_is_special, quoted;
3854 {
3855 char *temp, *t;
3856
3857 t = parameter_brace_expand_word (name, var_is_special, quoted);
3858 if (t == 0)
3859 return (t);
3860 #if 0
3861 temp = parameter_brace_expand_word (t, t[0] == '@' && t[1] == '\0', quoted);
3862 #else
3863 temp = parameter_brace_expand_word (t, SPECIAL_VAR(t, 0), quoted);
3864 #endif
3865 free (t);
3866 return temp;
3867 }
3868
3869 /* Expand the right side of a parameter expansion of the form ${NAMEcVALUE},
3870 depending on the value of C, the separating character. C can be one of
3871 "-", "+", or "=". QUOTED is true if the entire brace expression occurs
3872 between double quotes. */
3873 static char *
3874 parameter_brace_expand_rhs (name, value, c, quoted, qdollaratp, hasdollarat)
3875 char *name, *value;
3876 int c, quoted, *qdollaratp, *hasdollarat;
3877 {
3878 WORD_LIST *l;
3879 char *t, *t1, *temp;
3880 int hasdol;
3881
3882 temp = (*value == '~' || (strchr (value, '~') && unquoted_substring ("=~", value)))
3883 ? bash_tilde_expand (value)
3884 : savestring (value);
3885
3886 /* If the entire expression is between double quotes, we want to treat
3887 the value as a double-quoted string, with the exception that we strip
3888 embedded unescaped double quotes. */
3889 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && *temp)
3890 {
3891 hasdol = 0;
3892 t = string_extract_double_quoted (temp, &hasdol, 1);
3893 free (temp);
3894 temp = t;
3895 }
3896
3897 hasdol = 0;
3898 /* XXX was 0 not quoted */
3899 l = *temp ? expand_string_for_rhs (temp, quoted, &hasdol, (int *)NULL)
3900 : (WORD_LIST *)0;
3901 if (hasdollarat)
3902 *hasdollarat = hasdol || (l && l->next);
3903 free (temp);
3904 if (l)
3905 {
3906 /* The expansion of TEMP returned something. We need to treat things
3907 slightly differently if HASDOL is non-zero. */
3908 temp = string_list (l);
3909 /* If l->next is not null, we know that TEMP contained "$@", since that
3910 is the only expansion that creates more than one word. */
3911 if ((hasdol && quoted) || l->next)
3912 *qdollaratp = 1;
3913 dispose_words (l);
3914 }
3915 else if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && hasdol)
3916 {
3917 /* The brace expansion occurred between double quotes and there was
3918 a $@ in TEMP. It does not matter if the $@ is quoted, as long as
3919 it does not expand to anything. In this case, we want to return
3920 a quoted empty string. */
3921 temp = (char *)xmalloc (2);
3922 temp[0] = CTLNUL;
3923 temp[1] = '\0';
3924 }
3925 else
3926 temp = (char *)NULL;
3927
3928 if (c == '-' || c == '+')
3929 return (temp);
3930
3931 /* c == '=' */
3932 t = temp ? savestring (temp) : savestring ("");
3933 t1 = dequote_string (t);
3934 free (t);
3935 bind_variable (name, t1);
3936 free (t1);
3937 return (temp);
3938 }
3939
3940 /* Deal with the right hand side of a ${name:?value} expansion in the case
3941 that NAME is null or not set. If VALUE is non-null it is expanded and
3942 used as the error message to print, otherwise a standard message is
3943 printed. */
3944 static void
3945 parameter_brace_expand_error (name, value)
3946 char *name, *value;
3947 {
3948 WORD_LIST *l;
3949 char *temp;
3950
3951 if (value && *value)
3952 {
3953 temp = (*value == '~' || (strchr (value, '~') && unquoted_substring ("=~", value)))
3954 ? bash_tilde_expand (value)
3955 : savestring (value);
3956
3957 l = expand_string (temp, 0);
3958 FREE (temp);
3959 temp = string_list (l);
3960 report_error ("%s: %s", name, temp ? temp : ""); /* XXX was value not "" */
3961 FREE (temp);
3962 dispose_words (l);
3963 }
3964 else
3965 report_error ("%s: parameter null or not set", name);
3966
3967 /* Free the data we have allocated during this expansion, since we
3968 are about to longjmp out. */
3969 free (name);
3970 FREE (value);
3971 }
3972
3973 /* Return 1 if NAME is something for which parameter_brace_expand_length is
3974 OK to do. */
3975 static int
3976 valid_length_expression (name)
3977 char *name;
3978 {
3979 return (name[1] == '\0' || /* ${#} */
3980 ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0') || /* special param */
3981 (DIGIT (name[1]) && all_digits (name + 1)) || /* ${#11} */
3982 #if defined (ARRAY_VARS)
3983 valid_array_reference (name + 1) || /* ${#a[7]} */
3984 #endif
3985 legal_identifier (name + 1)); /* ${#PS1} */
3986 }
3987
3988 /* Handle the parameter brace expansion that requires us to return the
3989 length of a parameter. */
3990 static long
3991 parameter_brace_expand_length (name)
3992 char *name;
3993 {
3994 char *t, *newname;
3995 long number, arg_index;
3996 WORD_LIST *list;
3997 #if defined (ARRAY_VARS)
3998 SHELL_VAR *var;
3999 #endif
4000
4001 if (name[1] == '\0') /* ${#} */
4002 number = number_of_args ();
4003 else if ((name[1] == '@' || name[1] == '*') && name[2] == '\0') /* ${#@}, ${#*} */
4004 number = number_of_args ();
4005 else if ((sh_syntaxtab[(unsigned char) name[1]] & CSPECVAR) && name[2] == '\0')
4006 {
4007 /* Take the lengths of some of the shell's special parameters. */
4008 switch (name[1])
4009 {
4010 case '-':
4011 t = which_set_flags ();
4012 break;
4013 case '?':
4014 t = itos (last_command_exit_value);
4015 break;
4016 case '$':
4017 t = itos (dollar_dollar_pid);
4018 break;
4019 case '!':
4020 if (last_asynchronous_pid == NO_PID)
4021 t = (char *)NULL;
4022 else
4023 t = itos (last_asynchronous_pid);
4024 break;
4025 case '#':
4026 t = itos (number_of_args ());
4027 break;
4028 }
4029 number = STRLEN (t);
4030 FREE (t);
4031 }
4032 #if defined (ARRAY_VARS)
4033 else if (valid_array_reference (name + 1))
4034 number = array_length_reference (name + 1);
4035 #endif /* ARRAY_VARS */
4036 else
4037 {
4038 number = 0;
4039
4040 if (legal_number (name + 1, &arg_index)) /* ${#1} */
4041 {
4042 t = get_dollar_var_value (arg_index);
4043 number = STRLEN (t);
4044 FREE (t);
4045 }
4046 #if defined (ARRAY_VARS)
4047 else if ((var = find_variable (name + 1)) && array_p (var))
4048 {
4049 t = array_reference (array_cell (var), 0);
4050 number = STRLEN (t);
4051 }
4052 #endif
4053 else /* ${#PS1} */
4054 {
4055 newname = savestring (name);
4056 newname[0] = '$';
4057 list = expand_string (newname, Q_DOUBLE_QUOTES);
4058 t = list ? string_list (list) : (char *)NULL;
4059 free (newname);
4060 if (list)
4061 dispose_words (list);
4062
4063 number = STRLEN (t);
4064 FREE (t);
4065 }
4066 }
4067
4068 return (number);
4069 }
4070
4071 /* Skip characters in SUBSTR until DELIM. SUBSTR is an arithmetic expression,
4072 so we do some ad-hoc parsing of an arithmetic expression to find
4073 the first DELIM, instead of using strchr(3). Two rules:
4074 1. If the substring contains a `(', read until closing `)'.
4075 2. If the substring contains a `?', read past one `:' for each `?'.
4076 */
4077
4078 static char *
4079 skiparith (substr, delim)
4080 char *substr;
4081 int delim;
4082 {
4083 int skipcol, pcount;
4084 char *t;
4085
4086 for (skipcol = pcount = 0, t = substr; *t; t++)
4087 {
4088 /* Balance parens */
4089 if (*t == '(')
4090 {
4091 pcount++;
4092 continue;
4093 }
4094 if (*t == ')' && pcount)
4095 {
4096 pcount--;
4097 continue;
4098 }
4099 if (pcount)
4100 continue;
4101
4102 /* Skip one `:' for each `?' */
4103 if (*t == ':' && skipcol)
4104 {
4105 skipcol--;
4106 continue;
4107 }
4108 if (*t == delim)
4109 break;
4110 if (*t == '?')
4111 {
4112 skipcol++;
4113 continue;
4114 }
4115 }
4116 return t;
4117 }
4118
4119 /* Verify and limit the start and end of the desired substring. If
4120 VTYPE == 0, a regular shell variable is being used; if it is 1,
4121 then the positional parameters are being used; if it is 2, then
4122 VALUE is really a pointer to an array variable that should be used.
4123 Return value is 1 if both values were OK, 0 if there was a problem
4124 with an invalid expression, or -1 if the values were out of range. */
4125 static int
4126 verify_substring_values (value, substr, vtype, e1p, e2p)
4127 char *value, *substr;
4128 int vtype;
4129 long *e1p, *e2p;
4130 {
4131 char *t, *temp1, *temp2;
4132 arrayind_t len;
4133 int expok;
4134 #if defined (ARRAY_VARS)
4135 ARRAY *a;
4136 #endif
4137
4138 /* duplicate behavior of strchr(3) */
4139 t = skiparith (substr, ':');
4140 if (*t && *t == ':')
4141 *t = '\0';
4142 else
4143 t = (char *)0;
4144
4145 temp1 = expand_string_if_necessary (substr, Q_DOUBLE_QUOTES, expand_string);
4146 *e1p = evalexp (temp1, &expok);
4147 free (temp1);
4148 if (expok == 0)
4149 return (0);
4150
4151 len = -1; /* paranoia */
4152 switch (vtype)
4153 {
4154 case VT_VARIABLE:
4155 case VT_ARRAYMEMBER:
4156 len = strlen (value);
4157 break;
4158 case VT_POSPARMS:
4159 len = number_of_args () + 1;
4160 break;
4161 #if defined (ARRAY_VARS)
4162 case VT_ARRAYVAR:
4163 a = (ARRAY *)value;
4164 len = array_num_elements (a) + 1;
4165 break;
4166 #endif
4167 }
4168
4169 if (len == -1) /* paranoia */
4170 return -1;
4171
4172 if (*e1p < 0) /* negative offsets count from end */
4173 *e1p += len;
4174
4175 if (*e1p >= len || *e1p < 0)
4176 return (-1);
4177
4178 if (t)
4179 {
4180 t++;
4181 temp2 = savestring (t);
4182 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
4183 free (temp2);
4184 t[-1] = ':';
4185 *e2p = evalexp (temp1, &expok);
4186 free (temp1);
4187 if (expok == 0)
4188 return (0);
4189 if (*e2p < 0)
4190 {
4191 internal_error ("%s: substring expression < 0", t);
4192 return (0);
4193 }
4194 *e2p += *e1p; /* want E2 chars starting at E1 */
4195 if (*e2p > len)
4196 *e2p = len;
4197 }
4198 else
4199 *e2p = len;
4200
4201 return (1);
4202 }
4203
4204 /* Return the type of variable specified by VARNAME (simple variable,
4205 positional param, or array variable). Also return the value specified
4206 by VARNAME (value of a variable or a reference to an array element). */
4207 static int
4208 get_var_and_type (varname, value, varp, valp)
4209 char *varname, *value;
4210 SHELL_VAR **varp;
4211 char **valp;
4212 {
4213 int vtype;
4214 char *temp;
4215 #if defined (ARRAY_VARS)
4216 SHELL_VAR *v;
4217 #endif
4218
4219 vtype = (varname[0] == '@' || varname[0] == '*') && varname[1] == '\0'; /* VT_POSPARMS */
4220 *varp = (SHELL_VAR *)NULL;
4221
4222 #if defined (ARRAY_VARS)
4223 if (valid_array_reference (varname))
4224 {
4225 v = array_variable_part (varname, &temp, (int *)0);
4226 if (v && array_p (v))
4227 { /* [ */
4228 if (ALL_ELEMENT_SUB (temp[0]) && temp[1] == ']')
4229 {
4230 vtype = VT_ARRAYVAR;
4231 *valp = (char *)array_cell (v);
4232 }
4233 else
4234 {
4235 vtype = VT_ARRAYMEMBER;
4236 *valp = array_value (varname, 1);
4237 }
4238 *varp = v;
4239 }
4240 else
4241 return -1;
4242 }
4243 else if ((v = find_variable (varname)) && array_p (v))
4244 {
4245 vtype = VT_VARIABLE;
4246 *varp = v;
4247 *valp = array_reference (array_cell (v), 0);
4248 }
4249 else
4250 #endif
4251 *valp = value;
4252
4253 return vtype;
4254 }
4255
4256 /******************************************************/
4257 /* */
4258 /* Functions to extract substrings of variable values */
4259 /* */
4260 /******************************************************/
4261
4262 /* Process a variable substring expansion: ${name:e1[:e2]}. If VARNAME
4263 is `@', use the positional parameters; otherwise, use the value of
4264 VARNAME. If VARNAME is an array variable, use the array elements. */
4265
4266 static char *
4267 parameter_brace_substring (varname, value, substr, quoted)
4268 char *varname, *value, *substr;
4269 int quoted;
4270 {
4271 long e1, e2;
4272 int vtype, r;
4273 char *temp, *val;
4274 SHELL_VAR *v;
4275
4276 if (value == 0)
4277 return ((char *)NULL);
4278
4279 this_command_name = varname;
4280
4281 vtype = get_var_and_type (varname, value, &v, &val);
4282 if (vtype == -1)
4283 return ((char *)NULL);
4284
4285 r = verify_substring_values (val, substr, vtype, &e1, &e2);
4286 if (r <= 0)
4287 {
4288 if (val && vtype == VT_ARRAYMEMBER)
4289 free (val);
4290 return ((r == 0) ? &expand_param_error : (char *)NULL);
4291 }
4292
4293 switch (vtype)
4294 {
4295 case VT_VARIABLE:
4296 case VT_ARRAYMEMBER:
4297 temp = quoted ? quoted_substring (value, e1, e2) : substring (value, e1, e2);
4298 if (val && vtype == VT_ARRAYMEMBER)
4299 free (val);
4300 break;
4301 case VT_POSPARMS:
4302 temp = pos_params (varname, e1, e2, quoted);
4303 break;
4304 #if defined (ARRAY_VARS)
4305 case VT_ARRAYVAR:
4306 temp = array_subrange (array_cell (v), e1, e2, quoted);
4307 break;
4308 #endif
4309 default:
4310 temp = (char *)NULL;
4311 }
4312
4313 return temp;
4314 }
4315
4316 /****************************************************************/
4317 /* */
4318 /* Functions to perform pattern substitution on variable values */
4319 /* */
4320 /****************************************************************/
4321
4322 char *
4323 pat_subst (string, pat, rep, mflags)
4324 char *string, *pat, *rep;
4325 int mflags;
4326 {
4327 char *ret, *s, *e, *str;
4328 int rsize, rptr, l, replen, mtype;
4329
4330 mtype = mflags & MATCH_TYPEMASK;
4331
4332 /* Special cases:
4333 * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING
4334 * with REP and return the result.
4335 * 2. A null pattern with mtype == MATCH_END means to append REP to
4336 * STRING and return the result.
4337 */
4338 if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END))
4339 {
4340 replen = STRLEN (rep);
4341 l = strlen (string);
4342 ret = (char *)xmalloc (replen + l + 2);
4343 if (replen == 0)
4344 strcpy (ret, string);
4345 else if (mtype == MATCH_BEG)
4346 {
4347 strcpy (ret, rep);
4348 strcpy (ret + replen, string);
4349 }
4350 else
4351 {
4352 strcpy (ret, string);
4353 strcpy (ret + l, rep);
4354 }
4355 return (ret);
4356 }
4357
4358 ret = (char *)xmalloc (rsize = 64);
4359 ret[0] = '\0';
4360
4361 for (replen = STRLEN (rep), rptr = 0, str = string;;)
4362 {
4363 if (match_pattern (str, pat, mtype, &s, &e) == 0)
4364 break;
4365 l = s - str;
4366 RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64);
4367
4368 /* OK, now copy the leading unmatched portion of the string (from
4369 str to s) to ret starting at rptr (the current offset). Then copy
4370 the replacement string at ret + rptr + (s - str). Increment
4371 rptr (if necessary) and str and go on. */
4372 if (l)
4373 {
4374 strncpy (ret + rptr, str, l);
4375 rptr += l;
4376 }
4377 if (replen)
4378 {
4379 strncpy (ret + rptr, rep, replen);
4380 rptr += replen;
4381 }
4382 if (s == e)
4383 e++; /* avoid infinite recursion on zero-length match */
4384 str = e; /* e == end of match */
4385 if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY)
4386 break;
4387 }
4388
4389 /* Now copy the unmatched portion of the input string */
4390 if (*str)
4391 {
4392 RESIZE_MALLOCED_BUFFER (ret, rptr, STRLEN(str) + 1, rsize, 64);
4393 strcpy (ret + rptr, str);
4394 }
4395 else
4396 ret[rptr] = '\0';
4397
4398 return ret;
4399 }
4400
4401 /* Do pattern match and replacement on the positional parameters. */
4402 static char *
4403 pos_params_pat_subst (string, pat, rep, mflags)
4404 char *string, *pat, *rep;
4405 int mflags;
4406 {
4407 WORD_LIST *save, *params;
4408 WORD_DESC *w;
4409 char *ret;
4410
4411 save = params = list_rest_of_args ();
4412 if (save == 0)
4413 return ((char *)NULL);
4414
4415 for ( ; params; params = params->next)
4416 {
4417 ret = pat_subst (params->word->word, pat, rep, mflags);
4418 w = make_bare_word (ret);
4419 dispose_word (params->word);
4420 params->word = w;
4421 FREE (ret);
4422 }
4423
4424 ret = string_list ((mflags & MATCH_QUOTED) ? quote_list (save) : save);
4425 dispose_words (save);
4426
4427 return (ret);
4428 }
4429
4430 /* Perform pattern substitution on VALUE, which is the expansion of
4431 VARNAME. PATSUB is an expression supplying the pattern to match
4432 and the string to substitute. QUOTED is a flags word containing
4433 the type of quoting currently in effect. */
4434 static char *
4435 parameter_brace_patsub (varname, value, patsub, quoted)
4436 char *varname, *value, *patsub;
4437 int quoted;
4438 {
4439 int vtype, mflags;
4440 char *val, *temp, *pat, *rep, *p, *lpatsub;
4441 SHELL_VAR *v;
4442
4443 if (value == 0)
4444 return ((char *)NULL);
4445
4446 this_command_name = varname;
4447
4448 vtype = get_var_and_type (varname, value, &v, &val);
4449 if (vtype == -1)
4450 return ((char *)NULL);
4451
4452 mflags = 0;
4453 if (*patsub == '/')
4454 {
4455 mflags |= MATCH_GLOBREP;
4456 patsub++;
4457 }
4458 /* Malloc this because expand_string_if_necessary or one of the expansion functions
4459 in its call chain may free it on a substitution error. */
4460 lpatsub = savestring (patsub);
4461
4462 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4463 mflags |= MATCH_QUOTED;
4464
4465 if (rep = quoted_strchr (lpatsub, '/', ST_BACKSL))
4466 *rep++ = '\0';
4467 else
4468 rep = (char *)NULL;
4469
4470 if (rep && *rep == '\0')
4471 rep = (char *)NULL;
4472
4473 /* Expand PAT and REP for command, variable and parameter, arithmetic,
4474 and process substitution. Also perform quote removal. Do not
4475 perform word splitting or filename generation. */
4476 #if 0
4477 pat = expand_string_if_necessary (lpatsub, quoted, expand_string_unsplit);
4478 #else
4479 pat = expand_string_if_necessary (lpatsub, (quoted & ~Q_DOUBLE_QUOTES), expand_string_unsplit);
4480 #endif
4481
4482 if (rep)
4483 {
4484 if ((mflags & MATCH_QUOTED) == 0)
4485 rep = expand_string_if_necessary (rep, quoted, expand_string_unsplit);
4486 else
4487 rep = expand_string_to_string_internal (rep, quoted, expand_string_unsplit);
4488 }
4489
4490 p = pat;
4491 if (pat && pat[0] == '#')
4492 {
4493 mflags |= MATCH_BEG;
4494 p++;
4495 }
4496 else if (pat && pat[0] == '%')
4497 {
4498 mflags |= MATCH_END;
4499 p++;
4500 }
4501 else
4502 mflags |= MATCH_ANY;
4503
4504 /* OK, we now want to substitute REP for PAT in VAL. If
4505 flags & MATCH_GLOBREP is non-zero, the substitution is done
4506 everywhere, otherwise only the first occurrence of PAT is
4507 replaced. */
4508 switch (vtype)
4509 {
4510 case VT_VARIABLE:
4511 case VT_ARRAYMEMBER:
4512 temp = pat_subst (val, p, rep, mflags);
4513 break;
4514 case VT_POSPARMS:
4515 temp = pos_params_pat_subst (val, p, rep, mflags);
4516 break;
4517 #if defined (ARRAY_VARS)
4518 case VT_ARRAYVAR:
4519 temp = array_pat_subst (array_cell (v), p, rep, mflags);
4520 break;
4521 #endif
4522 }
4523
4524 if (val && v && array_p (v) && vtype == VT_ARRAYMEMBER)
4525 free (val);
4526
4527 FREE (pat);
4528 FREE (rep);
4529 free (lpatsub);
4530
4531 return temp;
4532 }
4533
4534 /****************************************************************/
4535 /* */
4536 /* Functions to perform parameter expansion on a string */
4537 /* */
4538 /****************************************************************/
4539
4540 /* ${[#][!]name[[:]#[#]%[%]-=?+[word][:e1[:e2]]]} */
4541 static char *
4542 parameter_brace_expand (string, indexp, quoted, quoted_dollar_atp, contains_dollar_at)
4543 char *string;
4544 int *indexp, quoted, *quoted_dollar_atp, *contains_dollar_at;
4545 {
4546 int check_nullness, var_is_set, var_is_null, var_is_special;
4547 int want_substring, want_indir, want_patsub;
4548 char *name, *value, *temp, *temp1;
4549 int t_index, sindex, c;
4550 long number;
4551
4552 value = (char *)NULL;
4553 var_is_set = var_is_null = var_is_special = check_nullness = 0;
4554 want_substring = want_indir = want_patsub = 0;
4555
4556 sindex = *indexp;
4557 t_index = ++sindex;
4558 name = string_extract (string, &t_index, "#%:-=?+/}", 1);
4559
4560 /* If the name really consists of a special variable, then make sure
4561 that we have the entire name. We don't allow indirect references
4562 to special variables except `#', `?', `@' and `*'. */
4563 if ((sindex == t_index &&
4564 (string[t_index] == '-' ||
4565 string[t_index] == '?' ||
4566 string[t_index] == '#')) ||
4567 (sindex == t_index - 1 && string[sindex] == '!' &&
4568 (string[t_index] == '#' ||
4569 string[t_index] == '?' ||
4570 string[t_index] == '@' ||
4571 string[t_index] == '*')))
4572 {
4573 t_index++;
4574 free (name);
4575 temp1 = string_extract (string, &t_index, "#%:-=?+/}", 0);
4576 name = (char *)xmalloc (3 + (strlen (temp1)));
4577 *name = string[sindex];
4578 if (string[sindex] == '!')
4579 {
4580 /* indirect reference of $#, $?, $@, or $* */
4581 name[1] = string[sindex + 1];
4582 strcpy (name + 2, temp1);
4583 }
4584 else
4585 strcpy (name + 1, temp1);
4586 free (temp1);
4587 }
4588 sindex = t_index;
4589
4590 /* Find out what character ended the variable name. Then
4591 do the appropriate thing. */
4592 if (c = string[sindex])
4593 sindex++;
4594
4595 /* If c is followed by one of the valid parameter expansion
4596 characters, move past it as normal. If not, assume that
4597 a substring specification is being given, and do not move
4598 past it. */
4599 if (c == ':' && VALID_PARAM_EXPAND_CHAR (string[sindex]))
4600 {
4601 check_nullness++;
4602 if (c = string[sindex])
4603 sindex++;
4604 }
4605 else if (c == ':' && string[sindex] != RBRACE)
4606 want_substring = 1;
4607 else if (c == '/' && string[sindex] != RBRACE)
4608 want_patsub = 1;
4609
4610 /* Catch the valid and invalid brace expressions that made it through the
4611 tests above. */
4612 /* ${#-} is a valid expansion and means to take the length of $-.
4613 Similarly for ${#?} and ${##}... */
4614 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4615 VALID_SPECIAL_LENGTH_PARAM (c) && string[sindex] == RBRACE)
4616 {
4617 name = (char *)xrealloc (name, 3);
4618 name[1] = c;
4619 name[2] = '\0';
4620 c = string[sindex++];
4621 }
4622
4623 /* ...but ${#%}, ${#:}, ${#=}, ${#+}, and ${#/} are errors. */
4624 if (name[0] == '#' && name[1] == '\0' && check_nullness == 0 &&
4625 member (c, "%:=+/") && string[sindex] == RBRACE)
4626 {
4627 temp = (char *)NULL;
4628 goto bad_substitution;
4629 }
4630
4631 /* Indirect expansion begins with a `!'. A valid indirect expansion is
4632 either a variable name, one of the positional parameters or a special
4633 variable that expands to one of the positional parameters. */
4634 want_indir = *name == '!' &&
4635 (legal_variable_starter ((unsigned char)name[1]) || DIGIT (name[1])
4636 || VALID_INDIR_PARAM (name[1]));
4637
4638 /* Determine the value of this variable. */
4639
4640 /* Check for special variables, directly referenced. */
4641 if (SPECIAL_VAR (name, want_indir))
4642 var_is_special++;
4643
4644 /* Check for special expansion things, like the length of a parameter */
4645 if (*name == '#' && name[1])
4646 {
4647 /* If we are not pointing at the character just after the
4648 closing brace, then we haven't gotten all of the name.
4649 Since it begins with a special character, this is a bad
4650 substitution. Also check NAME for validity before trying
4651 to go on. */
4652 if (string[sindex - 1] != RBRACE || (valid_length_expression (name) == 0))
4653 {
4654 temp = (char *)NULL;
4655 goto bad_substitution;
4656 }
4657
4658 number = parameter_brace_expand_length (name);
4659 free (name);
4660
4661 *indexp = sindex;
4662 return ((number < 0) ? &expand_param_error : itos (number));
4663 }
4664
4665 /* ${@} is identical to $@. */
4666 if (name[0] == '@' && name[1] == '\0')
4667 {
4668 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4669 *quoted_dollar_atp = 1;
4670
4671 if (contains_dollar_at)
4672 *contains_dollar_at = 1;
4673 }
4674
4675 /* Process ${PREFIX*} expansion. */
4676 if (want_indir && string[sindex - 1] == RBRACE &&
4677 (string[sindex - 2] == '*' || string[sindex - 2] == '@') &&
4678 legal_variable_starter ((unsigned char) name[1]))
4679 {
4680 char **x;
4681 WORD_LIST *xlist;
4682
4683 temp1 = savestring (name + 1);
4684 number = strlen (temp1);
4685 temp1[number - 1] = '\0';
4686 x = all_variables_matching_prefix (temp1);
4687 xlist = argv_to_word_list (x, 1, 0);
4688 if (string[sindex - 2] == '*')
4689 temp = string_list_dollar_star (xlist);
4690 else
4691 {
4692 temp = string_list_dollar_at (xlist, quoted);
4693 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4694 *quoted_dollar_atp = 1;
4695 if (contains_dollar_at)
4696 *contains_dollar_at = 1;
4697 }
4698 free (x);
4699 free (xlist);
4700 free (temp1);
4701 *indexp = sindex;
4702 return (temp);
4703 }
4704
4705 /* Make sure that NAME is valid before trying to go on. */
4706 if (valid_brace_expansion_word (want_indir ? name + 1 : name,
4707 var_is_special) == 0)
4708 {
4709 temp = (char *)NULL;
4710 goto bad_substitution;
4711 }
4712
4713 if (want_indir)
4714 temp = parameter_brace_expand_indir (name + 1, var_is_special, quoted);
4715 else
4716 temp = parameter_brace_expand_word (name, var_is_special, quoted);
4717
4718 #if defined (ARRAY_VARS)
4719 if (valid_array_reference (name))
4720 {
4721 temp1 = strchr (name, '[');
4722 if (temp1 && temp1[1] == '@' && temp1[2] == ']')
4723 {
4724 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4725 *quoted_dollar_atp = 1;
4726 if (contains_dollar_at)
4727 *contains_dollar_at = 1;
4728 } /* [ */
4729 /* ${array[*]}, when unquoted, should be treated like ${array[@]},
4730 which should result in separate words even when IFS is unset. */
4731 if (temp1 && temp1[1] == '*' && temp1[2] == ']' && quoted == 0)
4732 {
4733 if (contains_dollar_at)
4734 *contains_dollar_at = 1;
4735 }
4736 }
4737 #endif
4738
4739 var_is_set = temp != (char *)0;
4740 var_is_null = check_nullness && (var_is_set == 0 || *temp == 0);
4741
4742 /* Get the rest of the stuff inside the braces. */
4743 if (c && c != RBRACE)
4744 {
4745 /* Extract the contents of the ${ ... } expansion
4746 according to the Posix.2 rules. */
4747 value = extract_dollar_brace_string (string, &sindex, quoted);
4748 if (string[sindex] == RBRACE)
4749 sindex++;
4750 else
4751 goto bad_substitution;
4752 }
4753 else
4754 value = (char *)NULL;
4755
4756 *indexp = sindex;
4757
4758 /* If this is a substring spec, process it and add the result. */
4759 if (want_substring)
4760 {
4761 temp1 = parameter_brace_substring (name, temp, value, quoted);
4762 FREE (name);
4763 FREE (value);
4764 FREE (temp);
4765 return (temp1);
4766 }
4767 else if (want_patsub)
4768 {
4769 temp1 = parameter_brace_patsub (name, temp, value, quoted);
4770 FREE (name);
4771 FREE (value);
4772 FREE (temp);
4773 return (temp1);
4774 }
4775
4776 /* Do the right thing based on which character ended the variable name. */
4777 switch (c)
4778 {
4779 default:
4780 case '\0':
4781 bad_substitution:
4782 report_error ("%s: bad substitution", string ? string : "??");
4783 FREE (value);
4784 FREE (temp);
4785 free (name);
4786 return &expand_param_error;
4787
4788 case RBRACE:
4789 if (var_is_set == 0 && unbound_vars_is_error)
4790 {
4791 report_error ("%s: unbound variable", name);
4792 FREE (value);
4793 FREE (temp);
4794 free (name);
4795 last_command_exit_value = EXECUTION_FAILURE;
4796 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4797 }
4798 break;
4799
4800 case '#': /* ${param#[#]pattern} */
4801 case '%': /* ${param%[%]pattern} */
4802 if (value == 0 || *value == '\0' || temp == 0 || *temp == '\0')
4803 {
4804 FREE (value);
4805 break;
4806 }
4807 if ((name[0] == '@' || name[0] == '*') && name[1] == '\0')
4808 temp1 = parameter_list_remove_pattern (value, name[0], c, quoted);
4809 #if defined (ARRAY_VARS)
4810 else if (valid_array_reference (name))
4811 temp1 = array_remove_pattern (value, name, temp, c, quoted);
4812 #endif
4813 else
4814 temp1 = parameter_brace_remove_pattern (value, temp, c, quoted);
4815 free (temp);
4816 free (value);
4817 temp = temp1;
4818 break;
4819
4820 case '-':
4821 case '=':
4822 case '?':
4823 case '+':
4824 if (var_is_set && var_is_null == 0)
4825 {
4826 /* If the operator is `+', we don't want the value of the named
4827 variable for anything, just the value of the right hand side. */
4828
4829 if (c == '+')
4830 {
4831 /* XXX -- if we're double-quoted and the named variable is "$@",
4832 we want to turn off any special handling of "$@" --
4833 we're not using it, so whatever is on the rhs applies. */
4834 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4835 *quoted_dollar_atp = 0;
4836 if (contains_dollar_at)
4837 *contains_dollar_at = 0;
4838
4839 FREE (temp);
4840 if (value)
4841 {
4842 temp = parameter_brace_expand_rhs (name, value, c,
4843 quoted,
4844 quoted_dollar_atp,
4845 contains_dollar_at);
4846 free (value);
4847 }
4848 else
4849 temp = (char *)NULL;
4850 }
4851 else
4852 {
4853 FREE (value);
4854 }
4855 /* Otherwise do nothing; just use the value in TEMP. */
4856 }
4857 else /* VAR not set or VAR is NULL. */
4858 {
4859 FREE (temp);
4860 temp = (char *)NULL;
4861 if (c == '=' && var_is_special)
4862 {
4863 report_error ("$%s: cannot assign in this way", name);
4864 free (name);
4865 free (value);
4866 return &expand_param_error;
4867 }
4868 else if (c == '?')
4869 {
4870 parameter_brace_expand_error (name, value);
4871 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4872 }
4873 else if (c != '+')
4874 {
4875 /* XXX -- if we're double-quoted and the named variable is "$@",
4876 we want to turn off any special handling of "$@" --
4877 we're not using it, so whatever is on the rhs applies. */
4878 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && quoted_dollar_atp)
4879 *quoted_dollar_atp = 0;
4880 if (contains_dollar_at)
4881 *contains_dollar_at = 0;
4882
4883 temp = parameter_brace_expand_rhs (name, value, c, quoted,
4884 quoted_dollar_atp,
4885 contains_dollar_at);
4886 }
4887 free (value);
4888 }
4889
4890 break;
4891 }
4892 free (name);
4893 return (temp);
4894 }
4895
4896 /* Expand a single ${xxx} expansion. The braces are optional. When
4897 the braces are used, parameter_brace_expand() does the work,
4898 possibly calling param_expand recursively. */
4899 static char *
4900 param_expand (string, sindex, quoted, expanded_something,
4901 contains_dollar_at, quoted_dollar_at_p, had_quoted_null_p,
4902 pflags)
4903 char *string;
4904 int *sindex, quoted, *expanded_something, *contains_dollar_at;
4905 int *quoted_dollar_at_p, *had_quoted_null_p, pflags;
4906 {
4907 char *temp, *temp1;
4908 int zindex, t_index, expok;
4909 unsigned char c;
4910 long number;
4911 SHELL_VAR *var;
4912 WORD_LIST *list;
4913
4914 zindex = *sindex;
4915 c = string[++zindex];
4916
4917 temp = (char *)NULL;
4918
4919 /* Do simple cases first. Switch on what follows '$'. */
4920 switch (c)
4921 {
4922 /* $0 .. $9? */
4923 case '0':
4924 case '1':
4925 case '2':
4926 case '3':
4927 case '4':
4928 case '5':
4929 case '6':
4930 case '7':
4931 case '8':
4932 case '9':
4933 temp1 = dollar_vars[TODIGIT (c)];
4934 if (unbound_vars_is_error && temp1 == (char *)NULL)
4935 {
4936 report_error ("$%c: unbound variable", c);
4937 last_command_exit_value = EXECUTION_FAILURE;
4938 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4939 }
4940 temp = temp1 ? savestring (temp1) : (char *)NULL;
4941 break;
4942
4943 /* $$ -- pid of the invoking shell. */
4944 case '$':
4945 temp = itos (dollar_dollar_pid);
4946 break;
4947
4948 /* $# -- number of positional parameters. */
4949 case '#':
4950 temp = itos (number_of_args ());
4951 break;
4952
4953 /* $? -- return value of the last synchronous command. */
4954 case '?':
4955 temp = itos (last_command_exit_value);
4956 break;
4957
4958 /* $- -- flags supplied to the shell on invocation or by `set'. */
4959 case '-':
4960 temp = which_set_flags ();
4961 break;
4962
4963 /* $! -- Pid of the last asynchronous command. */
4964 case '!':
4965 /* If no asynchronous pids have been created, expand to nothing.
4966 If `set -u' has been executed, and no async processes have
4967 been created, this is an expansion error. */
4968 if (last_asynchronous_pid == NO_PID)
4969 {
4970 if (expanded_something)
4971 *expanded_something = 0;
4972 temp = (char *)NULL;
4973 if (unbound_vars_is_error)
4974 {
4975 report_error ("$%c: unbound variable", c);
4976 last_command_exit_value = EXECUTION_FAILURE;
4977 return (interactive_shell ? &expand_param_error : &expand_param_fatal);
4978 }
4979 }
4980 else
4981 temp = itos (last_asynchronous_pid);
4982 break;
4983
4984 /* The only difference between this and $@ is when the arg is quoted. */
4985 case '*': /* `$*' */
4986 list = list_rest_of_args ();
4987
4988 /* If there are no command-line arguments, this should just
4989 disappear if there are other characters in the expansion,
4990 even if it's quoted. */
4991 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && list == 0)
4992 temp = (char *)NULL;
4993 else if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
4994 {
4995 /* If we have "$*" we want to make a string of the positional
4996 parameters, separated by the first character of $IFS, and
4997 quote the whole string, including the separators. If IFS
4998 is unset, the parameters are separated by ' '; if $IFS is
4999 null, the parameters are concatenated. */
5000 temp = string_list_dollar_star (list);
5001 temp1 = quote_string (temp);
5002 free (temp);
5003 temp = temp1;
5004 }
5005 else
5006 {
5007 /* If the $* is not quoted it is identical to $@ */
5008 temp = string_list_dollar_at (list, quoted);
5009 if (expand_no_split_dollar_star == 0 && contains_dollar_at)
5010 *contains_dollar_at = 1;
5011 }
5012
5013 dispose_words (list);
5014 break;
5015
5016 /* When we have "$@" what we want is "$1" "$2" "$3" ... This
5017 means that we have to turn quoting off after we split into
5018 the individually quoted arguments so that the final split
5019 on the first character of $IFS is still done. */
5020 case '@': /* `$@' */
5021 list = list_rest_of_args ();
5022
5023 /* We want to flag the fact that we saw this. We can't turn
5024 off quoting entirely, because other characters in the
5025 string might need it (consider "\"$@\""), but we need some
5026 way to signal that the final split on the first character
5027 of $IFS should be done, even though QUOTED is 1. */
5028 if (quoted_dollar_at_p && (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)))
5029 *quoted_dollar_at_p = 1;
5030 if (contains_dollar_at)
5031 *contains_dollar_at = 1;
5032
5033 /* We want to separate the positional parameters with the first
5034 character of $IFS in case $IFS is something other than a space.
5035 We also want to make sure that splitting is done no matter what --
5036 according to POSIX.2, this expands to a list of the positional
5037 parameters no matter what IFS is set to. */
5038 temp = string_list_dollar_at (list, quoted);
5039
5040 dispose_words (list);
5041 break;
5042
5043 case LBRACE:
5044 temp = parameter_brace_expand (string, &zindex, quoted,
5045 quoted_dollar_at_p,
5046 contains_dollar_at);
5047 if (temp == &expand_param_error || temp == &expand_param_fatal)
5048 return (temp);
5049
5050 /* XXX */
5051 /* Quoted nulls should be removed if there is anything else
5052 in the string. */
5053 /* Note that we saw the quoted null so we can add one back at
5054 the end of this function if there are no other characters
5055 in the string, discard TEMP, and go on. The exception to
5056 this is when we have "${@}" and $1 is '', since $@ needs
5057 special handling. */
5058 if (temp && QUOTED_NULL (temp))
5059 {
5060 if (had_quoted_null_p)
5061 *had_quoted_null_p = 1;
5062 if (*quoted_dollar_at_p == 0)
5063 {
5064 free (temp);
5065 temp = (char *)NULL;
5066 }
5067
5068 }
5069
5070 goto return0;
5071
5072 /* Do command or arithmetic substitution. */
5073 case LPAREN:
5074 /* We have to extract the contents of this paren substitution. */
5075 t_index = zindex + 1;
5076 temp = extract_command_subst (string, &t_index);
5077 zindex = t_index;
5078
5079 /* For Posix.2-style `$(( ))' arithmetic substitution,
5080 extract the expression and pass it to the evaluator. */
5081 if (temp && *temp == LPAREN)
5082 {
5083 char *temp2;
5084 temp1 = temp + 1;
5085 temp2 = savestring (temp1);
5086 t_index = strlen (temp2) - 1;
5087
5088 if (temp2[t_index] != RPAREN)
5089 {
5090 free (temp2);
5091 goto comsub;
5092 }
5093
5094 /* Cut off ending `)' */
5095 temp2[t_index] = '\0';
5096
5097 /* Expand variables found inside the expression. */
5098 temp1 = expand_string_if_necessary (temp2, Q_DOUBLE_QUOTES, expand_string);
5099 free (temp2);
5100
5101 arithsub:
5102 /* No error messages. */
5103 this_command_name = (char *)NULL;
5104 number = evalexp (temp1, &expok);
5105 free (temp);
5106 free (temp1);
5107 if (expok == 0)
5108 {
5109 if (interactive_shell == 0 && posixly_correct)
5110 {
5111 last_command_exit_value = EXECUTION_FAILURE;
5112 return (&expand_param_fatal);
5113 }
5114 else
5115 return (&expand_param_error);
5116 }
5117 temp = itos (number);
5118 break;
5119 }
5120
5121 comsub:
5122 temp1 = command_substitute (temp, quoted);
5123 FREE (temp);
5124 temp = temp1;
5125 break;
5126
5127 /* Do POSIX.2d9-style arithmetic substitution. This will probably go
5128 away in a future bash release. */
5129 case '[':
5130 /* Extract the contents of this arithmetic substitution. */
5131 t_index = zindex + 1;
5132 temp = extract_arithmetic_subst (string, &t_index);
5133 zindex = t_index;
5134
5135 /* Do initial variable expansion. */
5136 temp1 = expand_string_if_necessary (temp, Q_DOUBLE_QUOTES, expand_string);
5137
5138 goto arithsub;
5139
5140 default:
5141 /* Find the variable in VARIABLE_LIST. */
5142 temp = (char *)NULL;
5143
5144 for (t_index = zindex; (c = string[zindex]) && legal_variable_char (c); zindex++)
5145 ;
5146 temp1 = (zindex > t_index) ? substring (string, t_index, zindex) : (char *)NULL;
5147
5148 /* If this isn't a variable name, then just output the `$'. */
5149 if (temp1 == 0 || *temp1 == '\0')
5150 {
5151 FREE (temp1);
5152 temp = (char *)xmalloc (2);
5153 temp[0] = '$';
5154 temp[1] = '\0';
5155 if (expanded_something)
5156 *expanded_something = 0;
5157 goto return0;
5158 }
5159
5160 /* If the variable exists, return its value cell. */
5161 var = find_variable (temp1);
5162
5163 if (var && invisible_p (var) == 0 && value_cell (var))
5164 {
5165 #if defined (ARRAY_VARS)
5166 if (array_p (var))
5167 {
5168 temp = array_reference (array_cell (var), 0);
5169 if (temp)
5170 temp = quote_escapes (temp);
5171 }
5172 else
5173 #endif
5174 temp = quote_escapes (value_cell (var));
5175 free (temp1);
5176 if (tempvar_p (var)) /* XXX */
5177 {
5178 dispose_variable (var); /* XXX */
5179 var = (SHELL_VAR *)NULL;
5180 }
5181 goto return0;
5182 }
5183
5184 temp = (char *)NULL;
5185
5186 if (unbound_vars_is_error)
5187 report_error ("%s: unbound variable", temp1);
5188 else
5189 {
5190 free (temp1);
5191 goto return0;
5192 }
5193
5194 free (temp1);
5195 last_command_exit_value = EXECUTION_FAILURE;
5196 return ((unbound_vars_is_error && interactive_shell == 0)
5197 ? &expand_param_fatal
5198 : &expand_param_error);
5199 }
5200
5201 if (string[zindex])
5202 zindex++;
5203
5204 return0:
5205 *sindex = zindex;
5206 return (temp);
5207 }
5208
5209 /* Make a word list which is the result of parameter and variable
5210 expansion, command substitution, arithmetic substitution, and
5211 quote removal of WORD. Return a pointer to a WORD_LIST which is
5212 the result of the expansion. If WORD contains a null word, the
5213 word list returned is also null.
5214
5215 QUOTED contains flag values defined in shell.h.
5216
5217 ISEXP is used to tell expand_word_internal that the word should be
5218 treated as the result of an expansion. This has implications for
5219 how IFS characters in the word are treated.
5220
5221 CONTAINS_DOLLAR_AT and EXPANDED_SOMETHING are return values; when non-null
5222 they point to an integer value which receives information about expansion.
5223 CONTAINS_DOLLAR_AT gets non-zero if WORD contained "$@", else zero.
5224 EXPANDED_SOMETHING get non-zero if WORD contained any parameter expansions,
5225 else zero.
5226
5227 This only does word splitting in the case of $@ expansion. In that
5228 case, we split on ' '. */
5229
5230 /* Values for the local variable quoted_state. */
5231 #define UNQUOTED 0
5232 #define PARTIALLY_QUOTED 1
5233 #define WHOLLY_QUOTED 2
5234
5235 static WORD_LIST *
5236 expand_word_internal (word, quoted, isexp, contains_dollar_at, expanded_something)
5237 WORD_DESC *word;
5238 int quoted, isexp;
5239 int *contains_dollar_at;
5240 int *expanded_something;
5241 {
5242 WORD_LIST *list;
5243 WORD_DESC *tword;
5244
5245 /* The intermediate string that we build while expanding. */
5246 char *istring;
5247
5248 /* The current size of the above object. */
5249 int istring_size;
5250
5251 /* Index into ISTRING. */
5252 int istring_index;
5253
5254 /* Temporary string storage. */
5255 char *temp, *temp1;
5256
5257 /* The text of WORD. */
5258 register char *string;
5259
5260 /* The index into STRING. */
5261 int sindex;
5262
5263 /* This gets 1 if we see a $@ while quoted. */
5264 int quoted_dollar_at;
5265
5266 /* One of UNQUOTED, PARTIALLY_QUOTED, or WHOLLY_QUOTED, depending on
5267 whether WORD contains no quoting characters, a partially quoted
5268 string (e.g., "xx"ab), or is fully quoted (e.g., "xxab"). */
5269 int quoted_state;
5270
5271 int had_quoted_null;
5272 int has_dollar_at;
5273 int tflag;
5274
5275 register unsigned char c; /* Current character. */
5276 unsigned char uc;
5277 int t_index; /* For calls to string_extract_xxx. */
5278
5279 char ifscmap[256];
5280 char twochars[2];
5281
5282 istring = (char *)xmalloc (istring_size = DEFAULT_INITIAL_ARRAY_SIZE);
5283 istring[istring_index = 0] = '\0';
5284 quoted_dollar_at = had_quoted_null = has_dollar_at = 0;
5285 quoted_state = UNQUOTED;
5286
5287 string = word->word;
5288 if (string == 0)
5289 goto finished_with_string;
5290
5291 if (contains_dollar_at)
5292 *contains_dollar_at = 0;
5293
5294 /* Cache a bitmap of characters in IFS for quoting IFS characters that are
5295 not part of an expansion. POSIX.2 says this is a must. */
5296 temp = getifs ();
5297 bzero (ifscmap, sizeof (ifscmap));
5298 for (temp1 = temp; temp1 && *temp1; temp1++)
5299 #if 0
5300 /* This check compensates for what I think is a parsing problem -- the
5301 end brace matching algorithms for ${...} expressions differ between
5302 parse.y and subst.c. For instance, the parser passes
5303 ${abc:-G { I } K } as one word when it should be three. */
5304 if (*temp1 != ' ' && *temp1 != '\t' && *temp1 != '\n')
5305 #endif
5306 {
5307 uc = *temp1;
5308 ifscmap[uc] = 1;
5309 }
5310
5311 /* Begin the expansion. */
5312
5313 for (sindex = 0; ;)
5314 {
5315 c = string[sindex];
5316
5317 /* Case on toplevel character. */
5318 switch (c)
5319 {
5320 case '\0':
5321 goto finished_with_string;
5322
5323 case CTLESC:
5324 temp = (char *)xmalloc (3);
5325 temp[0] = CTLESC;
5326 temp[1] = c = string[++sindex];
5327 temp[2] = '\0';
5328
5329 dollar_add_string:
5330 if (string[sindex])
5331 sindex++;
5332
5333 add_string:
5334 if (temp)
5335 {
5336 istring = sub_append_string (temp, istring, &istring_index, &istring_size);
5337 temp = (char *)0;
5338 }
5339
5340 break;
5341
5342 #if defined (PROCESS_SUBSTITUTION)
5343 /* Process substitution. */
5344 case '<':
5345 case '>':
5346 {
5347 if (string[++sindex] != LPAREN || (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || posixly_correct)
5348 {
5349 sindex--; /* add_character: label increments sindex */
5350 goto add_character;
5351 }
5352 else
5353 t_index = sindex + 1; /* skip past both '<' and LPAREN */
5354
5355 temp1 = extract_process_subst (string, (c == '<') ? "<(" : ">(", &t_index); /*))*/
5356 sindex = t_index;
5357
5358 /* If the process substitution specification is `<()', we want to
5359 open the pipe for writing in the child and produce output; if
5360 it is `>()', we want to open the pipe for reading in the child
5361 and consume input. */
5362 temp = temp1 ? process_substitute (temp1, (c == '>')) : (char *)0;
5363
5364 FREE (temp1);
5365
5366 goto dollar_add_string;
5367 }
5368 #endif /* PROCESS_SUBSTITUTION */
5369
5370 case '$':
5371 if (expanded_something)
5372 *expanded_something = 1;
5373
5374 has_dollar_at = 0;
5375 temp = param_expand (string, &sindex, quoted, expanded_something,
5376 &has_dollar_at, &quoted_dollar_at,
5377 &had_quoted_null, 0);
5378
5379 if (temp == &expand_param_error || temp == &expand_param_fatal)
5380 {
5381 free (string);
5382 free (istring);
5383 return ((temp == &expand_param_error) ? &expand_word_error
5384 : &expand_word_fatal);
5385 }
5386 if (contains_dollar_at && has_dollar_at)
5387 *contains_dollar_at = 1;
5388 goto add_string;
5389 break;
5390
5391 case '`': /* Backquoted command substitution. */
5392 {
5393 sindex++;
5394
5395 if (expanded_something)
5396 *expanded_something = 1;
5397
5398 temp = string_extract (string, &sindex, "`", 0);
5399 de_backslash (temp);
5400 temp1 = command_substitute (temp, quoted);
5401 FREE (temp);
5402 temp = temp1;
5403 goto dollar_add_string;
5404 }
5405
5406 case '\\':
5407 if (string[sindex + 1] == '\n')
5408 {
5409 sindex += 2;
5410 continue;
5411 }
5412
5413 c = string[++sindex];
5414
5415 if (quoted & Q_HERE_DOCUMENT)
5416 tflag = CBSHDOC;
5417 else if (quoted & Q_DOUBLE_QUOTES)
5418 tflag = CBSDQUOTE;
5419 else
5420 tflag = 0;
5421
5422
5423 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) && ((sh_syntaxtab[c] & tflag) == 0))
5424 {
5425 twochars[0] = '\\';
5426 twochars[1] = c;
5427 }
5428 else if (c == 0)
5429 {
5430 c = CTLNUL;
5431 sindex--; /* add_character: label increments sindex */
5432 goto add_character;
5433 }
5434 else
5435 {
5436 twochars[0] = CTLESC;
5437 twochars[1] = c;
5438 }
5439
5440 sindex++;
5441 add_twochars:
5442 /* BEFORE jumping here, we need to increment sindex if appropriate */
5443 RESIZE_MALLOCED_BUFFER (istring, istring_index, 2, istring_size,
5444 DEFAULT_ARRAY_SIZE);
5445 istring[istring_index++] = twochars[0];
5446 istring[istring_index++] = twochars[1];
5447 istring[istring_index] = '\0';
5448
5449 break;
5450
5451 case '"':
5452 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5453 goto add_character;
5454
5455 t_index = ++sindex;
5456 temp = string_extract_double_quoted (string, &sindex, 0);
5457
5458 /* If the quotes surrounded the entire string, then the
5459 whole word was quoted. */
5460 quoted_state = (t_index == 1 && string[sindex] == '\0')
5461 ? WHOLLY_QUOTED
5462 : PARTIALLY_QUOTED;
5463
5464 if (temp && *temp)
5465 {
5466 tword = make_word (temp); /* XXX */
5467 free (temp);
5468 temp = (char *)NULL;
5469
5470 has_dollar_at = 0;
5471 list = expand_word_internal (tword, Q_DOUBLE_QUOTES, 0, &has_dollar_at, (int *)NULL);
5472
5473 if (list == &expand_word_error || list == &expand_word_fatal)
5474 {
5475 free (istring);
5476 free (string);
5477 /* expand_word_internal has already freed temp_word->word
5478 for us because of the way it prints error messages. */
5479 tword->word = (char *)NULL;
5480 dispose_word (tword);
5481 return list;
5482 }
5483
5484 dispose_word (tword);
5485
5486 /* "$@" (a double-quoted dollar-at) expands into nothing,
5487 not even a NULL word, when there are no positional
5488 parameters. */
5489 if (list == 0 && has_dollar_at)
5490 {
5491 quoted_dollar_at++;
5492 break;
5493 }
5494
5495 /* If we get "$@", we know we have expanded something, so we
5496 need to remember it for the final split on $IFS. This is
5497 a special case; it's the only case where a quoted string
5498 can expand into more than one word. It's going to come back
5499 from the above call to expand_word_internal as a list with
5500 a single word, in which all characters are quoted and
5501 separated by blanks. What we want to do is to turn it back
5502 into a list for the next piece of code. */
5503 if (list)
5504 dequote_list (list);
5505
5506 if (has_dollar_at)
5507 {
5508 quoted_dollar_at++;
5509 if (contains_dollar_at)
5510 *contains_dollar_at = 1;
5511 if (expanded_something)
5512 *expanded_something = 1;
5513 }
5514 }
5515 else
5516 {
5517 /* What we have is "". This is a minor optimization. */
5518 FREE (temp);
5519 list = (WORD_LIST *)NULL;
5520 }
5521
5522 /* The code above *might* return a list (consider the case of "$@",
5523 where it returns "$1", "$2", etc.). We can't throw away the
5524 rest of the list, and we have to make sure each word gets added
5525 as quoted. We test on tresult->next: if it is non-NULL, we
5526 quote the whole list, save it to a string with string_list, and
5527 add that string. We don't need to quote the results of this
5528 (and it would be wrong, since that would quote the separators
5529 as well), so we go directly to add_string. */
5530 if (list)
5531 {
5532 if (list->next)
5533 {
5534 /* Testing quoted_dollar_at makes sure that "$@" is
5535 split correctly when $IFS does not contain a space. */
5536 temp = quoted_dollar_at
5537 ? string_list_dollar_at (list, Q_DOUBLE_QUOTES)
5538 : string_list (quote_list (list));
5539 dispose_words (list);
5540 goto add_string;
5541 }
5542 else
5543 {
5544 temp = savestring (list->word->word);
5545 dispose_words (list);
5546 #if 1
5547 /* If the string is not a quoted null string, we want
5548 to remove any embedded unquoted CTLNUL characters.
5549 We do not want to turn quoted null strings back into
5550 the empty string, though. We do this because we
5551 want to remove any quoted nulls from expansions that
5552 contain other characters. For example, if we have
5553 x"$*"y or "x$*y" and there are no positional parameters,
5554 the $* should expand into nothing. */
5555 if (QUOTED_NULL (temp) == 0)
5556 remove_quoted_nulls (temp); /* XXX */
5557 #endif
5558 }
5559 }
5560 else
5561 temp = (char *)NULL;
5562
5563 /* We do not want to add quoted nulls to strings that are only
5564 partially quoted; we can throw them away. */
5565 if (temp == 0 && quoted_state == PARTIALLY_QUOTED)
5566 continue;
5567
5568 add_quoted_string:
5569
5570 if (temp)
5571 {
5572 temp1 = temp;
5573 temp = quote_string (temp);
5574 free (temp1);
5575 goto add_string;
5576 }
5577 else
5578 {
5579 /* Add NULL arg. */
5580 c = CTLNUL;
5581 sindex--; /* add_character: label increments sindex */
5582 goto add_character;
5583 }
5584
5585 /* break; */
5586
5587 case '\'':
5588 if (quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT|Q_NOQUOTE))
5589 goto add_character;
5590
5591 t_index = ++sindex;
5592 temp = string_extract_single_quoted (string, &sindex);
5593
5594 /* If the entire STRING was surrounded by single quotes,
5595 then the string is wholly quoted. */
5596 quoted_state = (t_index == 1 && string[sindex] == '\0')
5597 ? WHOLLY_QUOTED
5598 : PARTIALLY_QUOTED;
5599
5600 /* If all we had was '', it is a null expansion. */
5601 if (*temp == '\0')
5602 {
5603 free (temp);
5604 temp = (char *)NULL;
5605 }
5606 else
5607 remove_quoted_escapes (temp);
5608
5609 /* We do not want to add quoted nulls to strings that are only
5610 partially quoted; such nulls are discarded. */
5611 if (temp == 0 && (quoted_state == PARTIALLY_QUOTED))
5612 continue;
5613
5614 /* If we have a quoted null expansion, add a quoted NULL to istring. */
5615 if (temp == 0)
5616 {
5617 c = CTLNUL;
5618 sindex--; /* add_character: label increments sindex */
5619 goto add_character;
5620 }
5621 else
5622 goto add_quoted_string;
5623
5624 /* break; */
5625
5626 default:
5627 /* This is the fix for " $@ " */
5628 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || (isexp == 0 && ifscmap[c]))
5629 {
5630 if (string[sindex]) /* from old goto dollar_add_string */
5631 sindex++;
5632 if (c == 0)
5633 {
5634 c = CTLNUL;
5635 goto add_character;
5636 }
5637 else
5638 {
5639 twochars[0] = CTLESC;
5640 twochars[1] = c;
5641 goto add_twochars;
5642 }
5643 }
5644
5645 add_character:
5646 RESIZE_MALLOCED_BUFFER (istring, istring_index, 1, istring_size,
5647 DEFAULT_ARRAY_SIZE);
5648 istring[istring_index++] = c;
5649 istring[istring_index] = '\0';
5650
5651 /* Next character. */
5652 sindex++;
5653 }
5654 }
5655
5656 finished_with_string:
5657 /* OK, we're ready to return. If we have a quoted string, and
5658 quoted_dollar_at is not set, we do no splitting at all; otherwise
5659 we split on ' '. The routines that call this will handle what to
5660 do if nothing has been expanded. */
5661
5662 /* Partially and wholly quoted strings which expand to the empty
5663 string are retained as an empty arguments. Unquoted strings
5664 which expand to the empty string are discarded. The single
5665 exception is the case of expanding "$@" when there are no
5666 positional parameters. In that case, we discard the expansion. */
5667
5668 /* Because of how the code that handles "" and '' in partially
5669 quoted strings works, we need to make ISTRING into a QUOTED_NULL
5670 if we saw quoting characters, but the expansion was empty.
5671 "" and '' are tossed away before we get to this point when
5672 processing partially quoted strings. This makes "" and $xxx""
5673 equivalent when xxx is unset. We also look to see whether we
5674 saw a quoted null from a ${} expansion and add one back if we
5675 need to. */
5676
5677 /* If we expand to nothing and there were no single or double quotes
5678 in the word, we throw it away. Otherwise, we return a NULL word.
5679 The single exception is for $@ surrounded by double quotes when
5680 there are no positional parameters. In that case, we also throw
5681 the word away. */
5682
5683 if (*istring == '\0')
5684 {
5685 if (quoted_dollar_at == 0 && (had_quoted_null || quoted_state == PARTIALLY_QUOTED))
5686 {
5687 istring[0] = CTLNUL;
5688 istring[1] = '\0';
5689 tword = make_bare_word (istring);
5690 list = make_word_list (tword, (WORD_LIST *)NULL);
5691 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5692 tword->flags |= W_QUOTED;
5693 }
5694 /* According to sh, ksh, and Posix.2, if a word expands into nothing
5695 and a double-quoted "$@" appears anywhere in it, then the entire
5696 word is removed. */
5697 else if (quoted_state == UNQUOTED || quoted_dollar_at)
5698 list = (WORD_LIST *)NULL;
5699 #if 0
5700 else
5701 {
5702 tword = make_bare_word (istring);
5703 list = make_word_list (tword, (WORD_LIST *)NULL);
5704 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5705 tword->flags |= W_QUOTED;
5706 }
5707 #else
5708 else
5709 list = (WORD_LIST *)NULL;
5710 #endif
5711 }
5712 else if (word->flags & W_NOSPLIT)
5713 {
5714 tword = make_bare_word (istring);
5715 list = make_word_list (tword, (WORD_LIST *)NULL);
5716 if (word->flags & W_ASSIGNMENT)
5717 tword->flags |= W_ASSIGNMENT; /* XXX */
5718 if (word->flags & W_NOGLOB)
5719 tword->flags |= W_NOGLOB; /* XXX */
5720 if (quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES))
5721 tword->flags |= W_QUOTED;
5722 }
5723 else
5724 {
5725 char *ifs_chars;
5726
5727 ifs_chars = (quoted_dollar_at || has_dollar_at) ? getifs () : (char *)NULL;
5728
5729 /* If we have $@, we need to split the results no matter what. If
5730 IFS is unset or NULL, string_list_dollar_at has separated the
5731 positional parameters with a space, so we split on space (we have
5732 set ifs_chars to " \t\n" above if ifs is unset). If IFS is set,
5733 string_list_dollar_at has separated the positional parameters
5734 with the first character of $IFS, so we split on $IFS. */
5735 if (has_dollar_at && ifs_chars)
5736 list = list_string (istring, *ifs_chars ? ifs_chars : " ", 1);
5737 else
5738 {
5739 tword = make_bare_word (istring);
5740 list = make_word_list (tword, (WORD_LIST *)NULL);
5741 if ((quoted & (Q_DOUBLE_QUOTES|Q_HERE_DOCUMENT)) || (quoted_state == WHOLLY_QUOTED))
5742 tword->flags |= W_QUOTED;
5743 if (word->flags & W_ASSIGNMENT)
5744 tword->flags |= W_ASSIGNMENT;
5745 if (word->flags & W_NOGLOB)
5746 tword->flags |= W_NOGLOB;
5747 }
5748 }
5749
5750 free (istring);
5751 return (list);
5752 }
5753
5754 /* **************************************************************** */
5755 /* */
5756 /* Functions for Quote Removal */
5757 /* */
5758 /* **************************************************************** */
5759
5760 /* Perform quote removal on STRING. If QUOTED > 0, assume we are obeying the
5761 backslash quoting rules for within double quotes. */
5762 char *
5763 string_quote_removal (string, quoted)
5764 char *string;
5765 int quoted;
5766 {
5767 char *r, *result_string, *temp;
5768 int sindex, tindex, dquote;
5769 unsigned char c;
5770
5771 /* The result can be no longer than the original string. */
5772 r = result_string = (char *)xmalloc (strlen (string) + 1);
5773
5774 for (dquote = sindex = 0; c = string[sindex];)
5775 {
5776 switch (c)
5777 {
5778 case '\\':
5779 c = string[++sindex];
5780 if (((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote) && (sh_syntaxtab[c] & CBSDQUOTE) == 0)
5781 *r++ = '\\';
5782 /* FALLTHROUGH */
5783
5784 default:
5785 *r++ = c;
5786 sindex++;
5787 break;
5788
5789 case '\'':
5790 if ((quoted & (Q_HERE_DOCUMENT|Q_DOUBLE_QUOTES)) || dquote)
5791 {
5792 *r++ = c;
5793 sindex++;
5794 break;
5795 }
5796 tindex = sindex + 1;
5797 temp = string_extract_single_quoted (string, &tindex);
5798 if (temp)
5799 {
5800 strcpy (r, temp);
5801 r += strlen (r);
5802 free (temp);
5803 }
5804 sindex = tindex;
5805 break;
5806
5807 case '"':
5808 dquote = 1 - dquote;
5809 sindex++;
5810 break;
5811 }
5812 }
5813 *r = '\0';
5814 return (result_string);
5815 }
5816
5817 #if 0
5818 /* UNUSED */
5819 /* Perform quote removal on word WORD. This allocates and returns a new
5820 WORD_DESC *. */
5821 WORD_DESC *
5822 word_quote_removal (word, quoted)
5823 WORD_DESC *word;
5824 int quoted;
5825 {
5826 WORD_DESC *w;
5827 char *t;
5828
5829 t = string_quote_removal (word->word, quoted);
5830 w = make_bare_word (t);
5831 free (t);
5832 return (w);
5833 }
5834
5835 /* Perform quote removal on all words in LIST. If QUOTED is non-zero,
5836 the members of the list are treated as if they are surrounded by
5837 double quotes. Return a new list, or NULL if LIST is NULL. */
5838 WORD_LIST *
5839 word_list_quote_removal (list, quoted)
5840 WORD_LIST *list;
5841 int quoted;
5842 {
5843 WORD_LIST *result, *t, *tresult;
5844
5845 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5846 {
5847 tresult = (WORD_LIST *)xmalloc (sizeof (WORD_LIST));
5848 tresult->word = word_quote_removal (t->word, quoted);
5849 tresult->next = (WORD_LIST *)NULL;
5850 result = (WORD_LIST *) list_append (result, tresult);
5851 }
5852 return (result);
5853 }
5854 #endif
5855
5856 /*******************************************
5857 * *
5858 * Functions to perform word splitting *
5859 * *
5860 *******************************************/
5861
5862 static char *
5863 getifs ()
5864 {
5865 SHELL_VAR *ifs;
5866
5867 ifs = find_variable ("IFS");
5868 /* If IFS is unset, it defaults to " \t\n". */
5869 return (ifs ? value_cell (ifs) : " \t\n");
5870 }
5871
5872 /* This splits a single word into a WORD LIST on $IFS, but only if the word
5873 is not quoted. list_string () performs quote removal for us, even if we
5874 don't do any splitting. */
5875 WORD_LIST *
5876 word_split (w)
5877 WORD_DESC *w;
5878 {
5879 WORD_LIST *result;
5880 SHELL_VAR *ifs;
5881 char *ifs_chars;
5882
5883 if (w)
5884 {
5885 ifs = find_variable ("IFS");
5886 /* If IFS is unset, it defaults to " \t\n". */
5887 ifs_chars = ifs ? value_cell (ifs) : " \t\n";
5888
5889 if ((w->flags & W_QUOTED) || !ifs_chars)
5890 ifs_chars = "";
5891
5892 result = list_string (w->word, ifs_chars, w->flags & W_QUOTED);
5893
5894 if (ifs && tempvar_p (ifs)) /* XXX */
5895 dispose_variable (ifs); /* XXX */
5896 }
5897 else
5898 result = (WORD_LIST *)NULL;
5899
5900 return (result);
5901 }
5902
5903 /* Perform word splitting on LIST and return the RESULT. It is possible
5904 to return (WORD_LIST *)NULL. */
5905 static WORD_LIST *
5906 word_list_split (list)
5907 WORD_LIST *list;
5908 {
5909 WORD_LIST *result, *t, *tresult;
5910
5911 for (t = list, result = (WORD_LIST *)NULL; t; t = t->next)
5912 {
5913 tresult = word_split (t->word);
5914 result = (WORD_LIST *) list_append (result, tresult);
5915 }
5916 return (result);
5917 }
5918
5919 /**************************************************
5920 * *
5921 * Functions to expand an entire WORD_LIST *
5922 * *
5923 **************************************************/
5924
5925 /* Put NLIST (which is a WORD_LIST * of only one element) at the front of
5926 ELIST, and set ELIST to the new list. */
5927 #define PREPEND_LIST(nlist, elist) \
5928 do { nlist->next = elist; elist = nlist; } while (0)
5929
5930 /* Separate out any initial variable assignments from TLIST. If set -k has
5931 been executed, remove all assignment statements from TLIST. Initial
5932 variable assignments and other environment assignments are placed
5933 on SUBST_ASSIGN_VARLIST. */
5934 static WORD_LIST *
5935 separate_out_assignments (tlist)
5936 WORD_LIST *tlist;
5937 {
5938 register WORD_LIST *vp, *lp;
5939
5940 if (!tlist)
5941 return ((WORD_LIST *)NULL);
5942
5943 if (subst_assign_varlist)
5944 dispose_words (subst_assign_varlist); /* Clean up after previous error */
5945
5946 subst_assign_varlist = (WORD_LIST *)NULL;
5947 vp = lp = tlist;
5948
5949 /* Separate out variable assignments at the start of the command.
5950 Loop invariant: vp->next == lp
5951 Loop postcondition:
5952 lp = list of words left after assignment statements skipped
5953 tlist = original list of words
5954 */
5955 while (lp && (lp->word->flags & W_ASSIGNMENT))
5956 {
5957 vp = lp;
5958 lp = lp->next;
5959 }
5960
5961 /* If lp != tlist, we have some initial assignment statements.
5962 We make SUBST_ASSIGN_VARLIST point to the list of assignment
5963 words and TLIST point to the remaining words. */
5964 if (lp != tlist)
5965 {
5966 subst_assign_varlist = tlist;
5967 /* ASSERT(vp->next == lp); */
5968 vp->next = (WORD_LIST *)NULL; /* terminate variable list */
5969 tlist = lp; /* remainder of word list */
5970 }
5971
5972 /* vp == end of variable list */
5973 /* tlist == remainder of original word list without variable assignments */
5974 if (!tlist)
5975 /* All the words in tlist were assignment statements */
5976 return ((WORD_LIST *)NULL);
5977
5978 /* ASSERT(tlist != NULL); */
5979 /* ASSERT((tlist->word->flags & W_ASSIGNMENT) == 0); */
5980
5981 /* If the -k option is in effect, we need to go through the remaining
5982 words, separate out the assignment words, and place them on
5983 SUBST_ASSIGN_VARLIST. */
5984 if (place_keywords_in_env)
5985 {
5986 WORD_LIST *tp; /* tp == running pointer into tlist */
5987
5988 tp = tlist;
5989 lp = tlist->next;
5990
5991 /* Loop Invariant: tp->next == lp */
5992 /* Loop postcondition: tlist == word list without assignment statements */
5993 while (lp)
5994 {
5995 if (lp->word->flags & W_ASSIGNMENT)
5996 {
5997 /* Found an assignment statement, add this word to end of
5998 subst_assign_varlist (vp). */
5999 if (!subst_assign_varlist)
6000 subst_assign_varlist = vp = lp;
6001 else
6002 {
6003 vp->next = lp;
6004 vp = lp;
6005 }
6006
6007 /* Remove the word pointed to by LP from TLIST. */
6008 tp->next = lp->next;
6009 /* ASSERT(vp == lp); */
6010 lp->next = (WORD_LIST *)NULL;
6011 lp = tp->next;
6012 }
6013 else
6014 {
6015 tp = lp;
6016 lp = lp->next;
6017 }
6018 }
6019 }
6020 return (tlist);
6021 }
6022
6023 #define WEXP_VARASSIGN 0x001
6024 #define WEXP_BRACEEXP 0x002
6025 #define WEXP_TILDEEXP 0x004
6026 #define WEXP_PARAMEXP 0x008
6027 #define WEXP_PATHEXP 0x010
6028
6029 /* All of the expansions, including variable assignments at the start of
6030 the list. */
6031 #define WEXP_ALL (WEXP_VARASSIGN|WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6032
6033 /* All of the expansions except variable assignments at the start of
6034 the list. */
6035 #define WEXP_NOVARS (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP|WEXP_PATHEXP)
6036
6037 /* All of the `shell expansions': brace expansion, tilde expansion, parameter
6038 expansion, command substitution, arithmetic expansion, word splitting, and
6039 quote removal. */
6040 #define WEXP_SHELLEXP (WEXP_BRACEEXP|WEXP_TILDEEXP|WEXP_PARAMEXP)
6041
6042 /* Take the list of words in LIST and do the various substitutions. Return
6043 a new list of words which is the expanded list, and without things like
6044 variable assignments. */
6045
6046 WORD_LIST *
6047 expand_words (list)
6048 WORD_LIST *list;
6049 {
6050 return (expand_word_list_internal (list, WEXP_ALL));
6051 }
6052
6053 /* Same as expand_words (), but doesn't hack variable or environment
6054 variables. */
6055 WORD_LIST *
6056 expand_words_no_vars (list)
6057 WORD_LIST *list;
6058 {
6059 return (expand_word_list_internal (list, WEXP_NOVARS));
6060 }
6061
6062 WORD_LIST *
6063 expand_words_shellexp (list)
6064 WORD_LIST *list;
6065 {
6066 return (expand_word_list_internal (list, WEXP_SHELLEXP));
6067 }
6068
6069 static WORD_LIST *
6070 glob_expand_word_list (tlist, eflags)
6071 WORD_LIST *tlist;
6072 int eflags;
6073 {
6074 char **glob_array, *temp_string;
6075 register int glob_index;
6076 WORD_LIST *glob_list, *output_list, *disposables, *next;
6077 WORD_DESC *tword;
6078
6079 output_list = disposables = (WORD_LIST *)NULL;
6080 glob_array = (char **)NULL;
6081 while (tlist)
6082 {
6083 /* For each word, either globbing is attempted or the word is
6084 added to orig_list. If globbing succeeds, the results are
6085 added to orig_list and the word (tlist) is added to the list
6086 of disposable words. If globbing fails and failed glob
6087 expansions are left unchanged (the shell default), the
6088 original word is added to orig_list. If globbing fails and
6089 failed glob expansions are removed, the original word is
6090 added to the list of disposable words. orig_list ends up
6091 in reverse order and requires a call to reverse_list to
6092 be set right. After all words are examined, the disposable
6093 words are freed. */
6094 next = tlist->next;
6095
6096 /* If the word isn't an assignment and contains an unquoted
6097 pattern matching character, then glob it. */
6098 if ((tlist->word->flags & W_NOGLOB) == 0 &&
6099 unquoted_glob_pattern_p (tlist->word->word))
6100 {
6101 glob_array = shell_glob_filename (tlist->word->word);
6102
6103 /* Handle error cases.
6104 I don't think we should report errors like "No such file
6105 or directory". However, I would like to report errors
6106 like "Read failed". */
6107
6108 if (GLOB_FAILED (glob_array))
6109 {
6110 glob_array = (char **)xmalloc (sizeof (char *));
6111 glob_array[0] = (char *)NULL;
6112 }
6113
6114 /* Dequote the current word in case we have to use it. */
6115 if (glob_array[0] == NULL)
6116 {
6117 temp_string = dequote_string (tlist->word->word);
6118 free (tlist->word->word);
6119 tlist->word->word = temp_string;
6120 }
6121
6122 /* Make the array into a word list. */
6123 glob_list = (WORD_LIST *)NULL;
6124 for (glob_index = 0; glob_array[glob_index]; glob_index++)
6125 {
6126 tword = make_bare_word (glob_array[glob_index]);
6127 tword->flags |= W_GLOBEXP; /* XXX */
6128 glob_list = make_word_list (tword, glob_list);
6129 }
6130
6131 if (glob_list)
6132 {
6133 output_list = (WORD_LIST *)list_append (glob_list, output_list);
6134 PREPEND_LIST (tlist, disposables);
6135 }
6136 else if (allow_null_glob_expansion == 0)
6137 {
6138 /* Failed glob expressions are left unchanged. */
6139 PREPEND_LIST (tlist, output_list);
6140 }
6141 else
6142 {
6143 /* Failed glob expressions are removed. */
6144 PREPEND_LIST (tlist, disposables);
6145 }
6146 }
6147 else
6148 {
6149 /* Dequote the string. */
6150 temp_string = dequote_string (tlist->word->word);
6151 free (tlist->word->word);
6152 tlist->word->word = temp_string;
6153 PREPEND_LIST (tlist, output_list);
6154 }
6155
6156 free_array (glob_array);
6157 glob_array = (char **)NULL;
6158
6159 tlist = next;
6160 }
6161
6162 if (disposables)
6163 dispose_words (disposables);
6164
6165 if (output_list)
6166 output_list = REVERSE_LIST (output_list, WORD_LIST *);
6167
6168 return (output_list);
6169 }
6170
6171 #if defined (BRACE_EXPANSION)
6172 static WORD_LIST *
6173 brace_expand_word_list (tlist, eflags)
6174 WORD_LIST *tlist;
6175 int eflags;
6176 {
6177 register char **expansions;
6178 char *temp_string;
6179 WORD_LIST *disposables, *output_list, *next;
6180 WORD_DESC *w;
6181 int eindex;
6182
6183 for (disposables = output_list = (WORD_LIST *)NULL; tlist; tlist = next)
6184 {
6185 next = tlist->next;
6186
6187 /* Only do brace expansion if the word has a brace character. If
6188 not, just add the word list element to BRACES and continue. In
6189 the common case, at least when running shell scripts, this will
6190 degenerate to a bunch of calls to `strchr', and then what is
6191 basically a reversal of TLIST into BRACES, which is corrected
6192 by a call to reverse_list () on BRACES when the end of TLIST
6193 is reached. */
6194 if (strchr (tlist->word->word, LBRACE))
6195 {
6196 expansions = brace_expand (tlist->word->word);
6197
6198 for (eindex = 0; temp_string = expansions[eindex]; eindex++)
6199 {
6200 w = make_word (temp_string);
6201 /* If brace expansion didn't change the word, preserve
6202 the flags. We may want to preserve the flags
6203 unconditionally someday -- XXX */
6204 if (STREQ (temp_string, tlist->word->word))
6205 w->flags = tlist->word->flags;
6206 output_list = make_word_list (w, output_list);
6207 free (expansions[eindex]);
6208 }
6209 free (expansions);
6210
6211 /* Add TLIST to the list of words to be freed after brace
6212 expansion has been performed. */
6213 PREPEND_LIST (tlist, disposables);
6214 }
6215 else
6216 PREPEND_LIST (tlist, output_list);
6217 }
6218
6219 if (disposables)
6220 dispose_words (disposables);
6221
6222 if (output_list)
6223 output_list = REVERSE_LIST (output_list, WORD_LIST *);
6224
6225 return (output_list);
6226 }
6227 #endif
6228
6229 static WORD_LIST *
6230 shell_expand_word_list (tlist, eflags)
6231 WORD_LIST *tlist;
6232 int eflags;
6233 {
6234 WORD_LIST *expanded, *orig_list, *new_list, *next, *temp_list;
6235 int expanded_something, has_dollar_at;
6236 char *temp_string;
6237
6238 /* We do tilde expansion all the time. This is what 1003.2 says. */
6239 new_list = (WORD_LIST *)NULL;
6240 for (orig_list = tlist; tlist; tlist = next)
6241 {
6242 temp_string = tlist->word->word;
6243
6244 next = tlist->next;
6245
6246 /* Posix.2 section 3.6.1 says that tildes following `=' in words
6247 which are not assignment statements are not expanded. We do
6248 this only if POSIXLY_CORRECT is enabled. Essentially, we do
6249 tilde expansion on unquoted assignment statements (flags include
6250 W_ASSIGNMENT but not W_QUOTED). */
6251 if (temp_string[0] == '~' ||
6252 (((tlist->word->flags & (W_ASSIGNMENT|W_QUOTED)) == W_ASSIGNMENT) &&
6253 posixly_correct == 0 &&
6254 strchr (temp_string, '~') &&
6255 (unquoted_substring ("=~", temp_string) || unquoted_substring (":~", temp_string))))
6256 {
6257 tlist->word->word = bash_tilde_expand (temp_string);
6258 free (temp_string);
6259 }
6260
6261 expanded_something = 0;
6262 expanded = expand_word_internal
6263 (tlist->word, 0, 0, &has_dollar_at, &expanded_something);
6264
6265 if (expanded == &expand_word_error || expanded == &expand_word_fatal)
6266 {
6267 /* By convention, each time this error is returned,
6268 tlist->word->word has already been freed. */
6269 tlist->word->word = (char *)NULL;
6270
6271 /* Dispose our copy of the original list. */
6272 dispose_words (orig_list);
6273 /* Dispose the new list we're building. */
6274 dispose_words (new_list);
6275
6276 last_command_exit_value = EXECUTION_FAILURE;
6277 if (expanded == &expand_word_error)
6278 jump_to_top_level (DISCARD);
6279 else
6280 jump_to_top_level (FORCE_EOF);
6281 }
6282
6283 /* Don't split words marked W_NOSPLIT. */
6284 if (expanded_something && (tlist->word->flags & W_NOSPLIT) == 0)
6285 {
6286 temp_list = word_list_split (expanded);
6287 dispose_words (expanded);
6288 }
6289 else
6290 {
6291 /* If no parameter expansion, command substitution, process
6292 substitution, or arithmetic substitution took place, then
6293 do not do word splitting. We still have to remove quoted
6294 null characters from the result. */
6295 word_list_remove_quoted_nulls (expanded);
6296 temp_list = expanded;
6297 }
6298
6299 expanded = REVERSE_LIST (temp_list, WORD_LIST *);
6300 new_list = (WORD_LIST *)list_append (expanded, new_list);
6301 }
6302
6303 if (orig_list)
6304 dispose_words (orig_list);
6305
6306 if (new_list)
6307 new_list = REVERSE_LIST (new_list, WORD_LIST *);
6308
6309 return (new_list);
6310 }
6311
6312 /* The workhorse for expand_words () and expand_words_no_vars ().
6313 First arg is LIST, a WORD_LIST of words.
6314 Second arg EFLAGS is a flags word controlling which expansions are
6315 performed.
6316
6317 This does all of the substitutions: brace expansion, tilde expansion,
6318 parameter expansion, command substitution, arithmetic expansion,
6319 process substitution, word splitting, and pathname expansion, according
6320 to the bits set in EFLAGS. Words with the W_QUOTED or W_NOSPLIT bits
6321 set, or for which no expansion is done, do not undergo word splitting.
6322 Words with the W_NOGLOB bit set do not undergo pathname expansion. */
6323 static WORD_LIST *
6324 expand_word_list_internal (list, eflags)
6325 WORD_LIST *list;
6326 int eflags;
6327 {
6328 WORD_LIST *new_list, *temp_list;
6329 int tint;
6330
6331 if (list == 0)
6332 return ((WORD_LIST *)NULL);
6333
6334 garglist = new_list = copy_word_list (list);
6335 if (eflags & WEXP_VARASSIGN)
6336 {
6337 garglist = new_list = separate_out_assignments (new_list);
6338 if (new_list == 0)
6339 {
6340 if (subst_assign_varlist)
6341 {
6342 /* All the words were variable assignments, so they are placed
6343 into the shell's environment. */
6344 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
6345 {
6346 this_command_name = (char *)NULL; /* no arithmetic errors */
6347 tint = do_assignment (temp_list->word->word);
6348 /* Variable assignment errors in non-interactive shells
6349 running in Posix.2 mode cause the shell to exit. */
6350 if (tint == 0)
6351 {
6352 last_command_exit_value = EXECUTION_FAILURE;
6353 if (interactive_shell == 0 && posixly_correct)
6354 jump_to_top_level (FORCE_EOF);
6355 else
6356 jump_to_top_level (DISCARD);
6357 }
6358 }
6359 dispose_words (subst_assign_varlist);
6360 subst_assign_varlist = (WORD_LIST *)NULL;
6361 }
6362 return ((WORD_LIST *)NULL);
6363 }
6364 }
6365
6366 /* Begin expanding the words that remain. The expansions take place on
6367 things that aren't really variable assignments. */
6368
6369 #if defined (BRACE_EXPANSION)
6370 /* Do brace expansion on this word if there are any brace characters
6371 in the string. */
6372 if ((eflags & WEXP_BRACEEXP) && brace_expansion && new_list)
6373 new_list = brace_expand_word_list (new_list, eflags);
6374 #endif /* BRACE_EXPANSION */
6375
6376 /* Perform the `normal' shell expansions: tilde expansion, parameter and
6377 variable substitution, command substitution, arithmetic expansion,
6378 and word splitting. */
6379 new_list = shell_expand_word_list (new_list, eflags);
6380
6381 /* Okay, we're almost done. Now let's just do some filename
6382 globbing. */
6383 if (new_list)
6384 {
6385 if ((eflags & WEXP_PATHEXP) && disallow_filename_globbing == 0)
6386 /* Glob expand the word list unless globbing has been disabled. */
6387 new_list = glob_expand_word_list (new_list, eflags);
6388 else
6389 /* Dequote the words, because we're not performing globbing. */
6390 new_list = dequote_list (new_list);
6391 }
6392
6393 if ((eflags & WEXP_VARASSIGN) && subst_assign_varlist)
6394 {
6395 sh_assign_func_t *assign_func;
6396
6397 /* If the remainder of the words expand to nothing, Posix.2 requires
6398 that the variable and environment assignments affect the shell's
6399 environment. */
6400 assign_func = new_list ? assign_in_env : do_assignment;
6401
6402 for (temp_list = subst_assign_varlist; temp_list; temp_list = temp_list->next)
6403 {
6404 this_command_name = (char *)NULL;
6405 tint = (*assign_func) (temp_list->word->word);
6406 /* Variable assignment errors in non-interactive shells running
6407 in Posix.2 mode cause the shell to exit. */
6408 if (tint == 0 && assign_func == do_assignment)
6409 {
6410 last_command_exit_value = EXECUTION_FAILURE;
6411 if (interactive_shell == 0 && posixly_correct)
6412 jump_to_top_level (FORCE_EOF);
6413 else
6414 jump_to_top_level (DISCARD);
6415 }
6416 }
6417
6418 dispose_words (subst_assign_varlist);
6419 subst_assign_varlist = (WORD_LIST *)NULL;
6420 }
6421
6422 #if 0
6423 tint = list_length (new_list) + 1;
6424 RESIZE_MALLOCED_BUFFER (glob_argv_flags, 0, tint, glob_argv_flags_size, 16);
6425 for (tint = 0, temp_list = new_list; temp_list; temp_list = temp_list->next)
6426 glob_argv_flags[tint++] = (temp_list->word->flags & W_GLOBEXP) ? '1' : '0';
6427 glob_argv_flags[tint] = '\0';
6428 #endif
6429
6430 return (new_list);
6431 }